12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/dns/dns_socket_pool.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/rand_util.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/address_list.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/ip_endpoint.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/net_errors.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/rand_callback.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/socket/client_socket_factory.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/socket/stream_socket.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/udp/datagram_client_socket.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace net {
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// When we initialize the SocketPool, we allocate kInitialPoolSize sockets.
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// When we allocate a socket, we ensure we have at least kAllocateMinSize
2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// sockets to choose from.  Freed sockets are not retained.
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// On Windows, we can't request specific (random) ports, since that will
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// trigger firewall prompts, so request default ones, but keep a pile of
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// them.  Everywhere else, request fresh, random ports each time.
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const DatagramSocket::BindType kBindType = DatagramSocket::DEFAULT_BIND;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const unsigned kInitialPoolSize = 256;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const unsigned kAllocateMinSize = 256;
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const DatagramSocket::BindType kBindType = DatagramSocket::RANDOM_BIND;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const unsigned kInitialPoolSize = 0;
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const unsigned kAllocateMinSize = 1;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DnsSocketPool::DnsSocketPool(ClientSocketFactory* socket_factory)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : socket_factory_(socket_factory),
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      net_log_(NULL),
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      nameservers_(NULL),
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      initialized_(false) {
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DnsSocketPool::InitializeInternal(
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<IPEndPoint>* nameservers,
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NetLog* net_log) {
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(nameservers);
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!initialized_);
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  net_log_ = net_log;
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  nameservers_ = nameservers;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  initialized_ = true;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<StreamSocket> DnsSocketPool::CreateTCPSocket(
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned server_index,
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const NetLog::Source& source) {
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LT(server_index, nameservers_->size());
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return scoped_ptr<StreamSocket>(
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      socket_factory_->CreateTransportClientSocket(
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          AddressList((*nameservers_)[server_index]), net_log_, source));
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<DatagramClientSocket> DnsSocketPool::CreateConnectedSocket(
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned server_index) {
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LT(server_index, nameservers_->size());
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<DatagramClientSocket> socket;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NetLog::Source no_source;
763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  socket = socket_factory_->CreateDatagramClientSocket(
773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      kBindType, base::Bind(&base::RandInt), net_log_, no_source);
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (socket.get()) {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int rv = socket->Connect((*nameservers_)[server_index]);
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (rv != OK) {
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      VLOG(1) << "Failed to connect socket: " << rv;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      socket.reset();
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(WARNING) << "Failed to create socket.";
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return socket.Pass();
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class NullDnsSocketPool : public DnsSocketPool {
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NullDnsSocketPool(ClientSocketFactory* factory)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     : DnsSocketPool(factory) {
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Initialize(
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::vector<IPEndPoint>* nameservers,
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NetLog* net_log) OVERRIDE {
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InitializeInternal(nameservers, net_log);
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual scoped_ptr<DatagramClientSocket> AllocateSocket(
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      unsigned server_index) OVERRIDE {
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return CreateConnectedSocket(server_index);
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FreeSocket(
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      unsigned server_index,
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_ptr<DatagramClientSocket> socket) OVERRIDE {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(NullDnsSocketPool);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<DnsSocketPool> DnsSocketPool::CreateNull(
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ClientSocketFactory* factory) {
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return scoped_ptr<DnsSocketPool>(new NullDnsSocketPool(factory));
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DefaultDnsSocketPool : public DnsSocketPool {
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DefaultDnsSocketPool(ClientSocketFactory* factory)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     : DnsSocketPool(factory) {
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~DefaultDnsSocketPool();
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Initialize(
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::vector<IPEndPoint>* nameservers,
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      NetLog* net_log) OVERRIDE;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual scoped_ptr<DatagramClientSocket> AllocateSocket(
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      unsigned server_index) OVERRIDE;
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void FreeSocket(
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      unsigned server_index,
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_ptr<DatagramClientSocket> socket) OVERRIDE;
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void FillPool(unsigned server_index, unsigned size);
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef std::vector<DatagramClientSocket*> SocketVector;
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<SocketVector> pools_;
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DefaultDnsSocketPool);
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<DnsSocketPool> DnsSocketPool::CreateDefault(
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ClientSocketFactory* factory) {
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return scoped_ptr<DnsSocketPool>(new DefaultDnsSocketPool(factory));
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DefaultDnsSocketPool::Initialize(
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<IPEndPoint>* nameservers,
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NetLog* net_log) {
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitializeInternal(nameservers, net_log);
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(pools_.empty());
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const unsigned num_servers = nameservers->size();
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pools_.resize(num_servers);
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (unsigned server_index = 0; server_index < num_servers; ++server_index)
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FillPool(server_index, kInitialPoolSize);
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DefaultDnsSocketPool::~DefaultDnsSocketPool() {
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned num_servers = pools_.size();
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (unsigned server_index = 0; server_index < num_servers; ++server_index) {
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SocketVector& pool = pools_[server_index];
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    STLDeleteElements(&pool);
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<DatagramClientSocket> DefaultDnsSocketPool::AllocateSocket(
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned server_index) {
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LT(server_index, pools_.size());
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SocketVector& pool = pools_[server_index];
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FillPool(server_index, kAllocateMinSize);
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (pool.size() == 0) {
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(WARNING) << "No DNS sockets available in pool " << server_index << "!";
1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return scoped_ptr<DatagramClientSocket>();
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (pool.size() < kAllocateMinSize) {
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(WARNING) << "Low DNS port entropy: wanted " << kAllocateMinSize
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << " sockets to choose from, but only have " << pool.size()
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << " in pool " << server_index << ".";
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  unsigned socket_index = base::RandInt(0, pool.size() - 1);
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DatagramClientSocket* socket = pool[socket_index];
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pool[socket_index] = pool.back();
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  pool.pop_back();
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return scoped_ptr<DatagramClientSocket>(socket);
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DefaultDnsSocketPool::FreeSocket(
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    unsigned server_index,
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<DatagramClientSocket> socket) {
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK_LT(server_index, pools_.size());
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void DefaultDnsSocketPool::FillPool(unsigned server_index, unsigned size) {
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SocketVector& pool = pools_[server_index];
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (unsigned pool_index = pool.size(); pool_index < size; ++pool_index) {
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DatagramClientSocket* socket =
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        CreateConnectedSocket(server_index).release();
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!socket)
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    pool.push_back(socket);
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace net
223