Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Side by Side Diff: net/dns/dns_socket_pool.cc

Issue 10878090: Keep pool of pre-connected DNS sockets (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/dns/dns_socket_pool.h"
6
7 #include "base/logging.h"
8 #include "base/rand_util.h"
9 #include "base/stl_util.h"
10 #include "net/base/ip_endpoint.h"
11 #include "net/base/net_errors.h"
12 #include "net/base/rand_callback.h"
13 #include "net/socket/client_socket_factory.h"
14 #include "net/udp/datagram_client_socket.h"
15
16 namespace net {
17
18 namespace {
19
20 // When we initialize the SocketPool, we allocate kInitialPoolSize sockets.
21 // When we allocate a socket, we ensure we have at least kAllocateMinSize
22 // sockets to choose from. When we free a socket, we retain it if we have
23 // less than kRetainMaxSize sockets in the pool.
24
25 // On Windows, we can't request specific (random) ports, since that will
26 // trigger firewall prompts, so request default ones, but keep a pile of
27 // them. Everywhere else, request fresh, random ports each time.
28 #if defined(OS_WIN)
29 const DatagramSocket::BindType kBindType = DatagramSocket::DEFAULT_BIND;
30 const unsigned kInitialPoolSize = 256;
31 const unsigned kAllocateMinSize = 256;
32 const unsigned kRetainMaxSize = 0;
33 #else
34 const DatagramSocket::BindType kBindType = DatagramSocket::RANDOM_BIND;
35 const unsigned kInitialPoolSize = 0;
36 const unsigned kAllocateMinSize = 1;
37 const unsigned kRetainMaxSize = 0;
38 #endif
39
40 typedef std::vector<DatagramClientSocket*> SocketVector;
szym 2012/09/26 21:03:33 When reading, I'd expect this typedef to be inside
Deprecated (see juliatuttle) 2012/10/01 21:30:07 Done.
41
42 } // namespace
43
44 DnsSocketPool::DnsSocketPool(ClientSocketFactory* socket_factory)
45 : socket_factory_(socket_factory),
46 net_log_(NULL),
47 nameservers_(NULL),
48 initialized_(false) {
49 }
50
51 void DnsSocketPool::InitializeInternal(
52 const std::vector<IPEndPoint>* nameservers,
53 NetLog* net_log) {
54 DCHECK(nameservers);
55 DCHECK(!initialized_);
56
57 net_log_ = net_log;
58 nameservers_ = nameservers;
59 initialized_ = true;
60 }
61
62 scoped_ptr<DatagramClientSocket> DnsSocketPool::CreateConnectedSocket(
63 unsigned server_index) {
64 DCHECK_LT(server_index, nameservers_->size());
65
66 scoped_ptr<DatagramClientSocket> socket;
67
68 NetLog::Source no_source;
69 socket.reset(socket_factory_->CreateDatagramClientSocket(
70 kBindType, base::Bind(&base::RandInt), net_log_, no_source));
71
72 if (socket.get()) {
73 int rv = socket->Connect((*nameservers_)[server_index]);
74 if (rv != OK) {
75 LOG(WARNING) << "Failed to connect socket: " << rv;
76 socket.reset();
77 }
78 } else {
79 LOG(WARNING) << "Failed to create socket.";
80 }
81
82 return socket.Pass();
83 }
84
85 class DefaultDnsSocketPool : public DnsSocketPool {
86 public:
87 DefaultDnsSocketPool(ClientSocketFactory* factory)
88 : DnsSocketPool(factory) {
89 };
90
91 ~DefaultDnsSocketPool();
92
93 virtual void Initialize(
94 const std::vector<IPEndPoint>* nameservers,
95 NetLog* net_log) OVERRIDE;
96
97 virtual scoped_ptr<DatagramClientSocket> AllocateSocket(
98 unsigned server_index) OVERRIDE;
99
100 virtual void FreeSocket(
101 unsigned server_index,
102 scoped_ptr<DatagramClientSocket> socket) OVERRIDE;
103
104 private:
105 void FillPool(unsigned server_index, unsigned size);
106
107 std::vector<SocketVector> pools_;
108
109 DISALLOW_COPY_AND_ASSIGN(DefaultDnsSocketPool);
110 };
111
112 // static
113 scoped_ptr<DnsSocketPool> DnsSocketPool::CreateDefault(
114 ClientSocketFactory* factory) {
115 return scoped_ptr<DnsSocketPool>(new DefaultDnsSocketPool(factory));
116 }
117
118 void DefaultDnsSocketPool::Initialize(
119 const std::vector<IPEndPoint>* nameservers,
120 NetLog* net_log) OVERRIDE {
121 InitializeInternal(nameservers, net_log);
122
123 DCHECK(pools_.empty());
124 const unsigned num_servers = nameservers->size();
125 pools_.resize(num_servers);
126 for (unsigned server_index = 0; server_index < num_servers; ++server_index)
127 FillPool(server_index, kInitialPoolSize);
128 }
129
130 DefaultDnsSocketPool::~DefaultDnsSocketPool() {
131 unsigned num_servers = pools_.size();
132 for (unsigned server_index = 0; server_index < num_servers; ++server_index) {
133 SocketVector& pool = pools_[server_index];
134 STLDeleteElements(&pool);
135 }
136 }
137
138 scoped_ptr<DatagramClientSocket> DefaultDnsSocketPool::AllocateSocket(
139 unsigned server_index) {
140 DCHECK_LT(server_index, pools_.size());
141 SocketVector& pool = pools_[server_index];
142
143 FillPool(server_index, kAllocateMinSize);
144 if (pool.size() < kAllocateMinSize) {
145 LOG(WARNING) << "Low DNS port entropy: wanted " << kAllocateMinSize
146 << " sockets to choose from, but only have " << pool.size();
147 }
148
149 unsigned socket_index = base::RandInt(0, pool.size() - 1);
150 DatagramClientSocket* socket = pool[socket_index];
151 pool[socket_index] = pool.back();
152 pool.pop_back();
153
154 return scoped_ptr<DatagramClientSocket>(socket);
155 }
156
157 void DefaultDnsSocketPool::FreeSocket(
158 unsigned server_index,
159 scoped_ptr<DatagramClientSocket> socket) {
160 DCHECK_LT(server_index, pools_.size());
161 SocketVector& pool = pools_[server_index];
162
163 if (pool.size() < kRetainMaxSize)
164 pool.push_back(socket.release());
165 }
166
167 void DefaultDnsSocketPool::FillPool(unsigned server_index, unsigned size) {
168 SocketVector& pool = pools_[server_index];
169
170 for (unsigned pool_index = pool.size(); pool_index < size; ++pool_index) {
171 DatagramClientSocket* socket =
172 CreateConnectedSocket(server_index).release();
173 if (!socket)
174 break;
175 pool.push_back(socket);
176 }
177 }
178
179 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698