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

Unified Diff: net/dns/dns_session.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, 4 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 side-by-side diff with in-line comments
Download patch
Index: net/dns/dns_session.cc
diff --git a/net/dns/dns_session.cc b/net/dns/dns_session.cc
index fb6c4b4c5ba269157bf7ca29cc7d5c06052ccda1..6fa277fd616b4dc60370f875b7fbf884b64fd394 100644
--- a/net/dns/dns_session.cc
+++ b/net/dns/dns_session.cc
@@ -6,21 +6,36 @@
#include "base/basictypes.h"
#include "base/bind.h"
+#include "base/rand_util.h"
+#include "base/stl_util.h"
#include "base/time.h"
#include "net/base/ip_endpoint.h"
+#include "net/base/net_errors.h"
#include "net/dns/dns_config_service.h"
#include "net/socket/client_socket_factory.h"
namespace net {
+DnsSession::SocketLease::SocketLease(scoped_refptr<DnsSession> session,
+ int server_index,
+ scoped_ptr<DatagramClientSocket> socket)
+ : session_(session), server_index_(server_index), socket_(socket.Pass()) {}
+
+DnsSession::SocketLease::~SocketLease() {
+ session_->FreeSocket(server_index_, socket_.Pass());
+}
+
DnsSession::DnsSession(const DnsConfig& config,
ClientSocketFactory* factory,
const RandIntCallback& rand_int_callback,
+ bool bypass_pools,
NetLog* net_log)
: config_(config),
socket_factory_(factory),
rand_callback_(base::Bind(rand_int_callback, 0, kuint16max)),
+ bypass_pools_(bypass_pools),
net_log_(net_log),
+ pools_(config.nameservers.size()),
server_index_(0) {
}
@@ -41,7 +56,68 @@ base::TimeDelta DnsSession::NextTimeout(int attempt) {
return config_.timeout * (1 << (attempt / config_.nameservers.size()));
}
-DnsSession::~DnsSession() {}
+DnsSession::~DnsSession() {
+ for (size_t i = 0; i < pools_.size(); ++i)
+ STLDeleteElements(&pools_[i]);
+}
+
+// TODO(ttuttle): Pool and reuse sockets.
+
+#if defined(OS_WIN)
+// Don't request a specific port, since that will trigger firewall prompts.
+static const DatagramSocket::BindType kBindType = DatagramSocket::DEFAULT_BIND;
+// Since we can't request random ports, keep a pool of the arbitrary ones
+// we've been given, to add entropy.
+static const size_t kMinPoolSize = 512;
+static const size_t kMaxPoolSize = 1024;
+#else
+static const DatagramSocket::BindType kBindType = DatagramSocket::RANDOM_BIND;
+static const size_t kMinPoolSize = 0;
+static const size_t kMaxPoolSize = 0;
+#endif
+
+// Allocate a socket, already connected to the server address.
+scoped_ptr<DnsSession::SocketLease> DnsSession::AllocateSocket(int index) {
+ scoped_ptr<DatagramClientSocket> socket;
+
+ std::vector<DatagramClientSocket*>& pool = pools_[index];
+
+ if (!bypass_pools_ && (pool.size() > kMinPoolSize)) {
+ int pool_index = 0; // TODO(ttuttle): Random.
+ socket.reset(pool[pool_index]);
+ pool[pool_index] = pool.back();
+ pool.pop_back();
+ }
+
+ if (!socket.get()) {
+ socket.reset(
+ socket_factory_->CreateDatagramClientSocket(
+ kBindType,
+ base::Bind(&base::RandInt),
+ net_log_,
+ NetLog::Source()));
+
+ int rv = socket->Connect(config_.nameservers[index]);
+ if (rv != OK)
+ socket.reset(NULL);
cbentzel 2012/08/29 16:48:06 Is this always guaranteed to complete synchronousl
szym 2012/08/29 16:57:08 Connect? Yes. Note that it does not take a Complet
+ }
+
+ if (!socket.get())
+ return scoped_ptr<SocketLease>(NULL);
+
+
+ return scoped_ptr<SocketLease>(new SocketLease(this, index, socket.Pass()));
+}
+
+// Release a socket.
+void DnsSession::FreeSocket(int index,
+ scoped_ptr<DatagramClientSocket> socket) {
+ std::vector<DatagramClientSocket*>& pool = pools_[index];
+
+ if (!bypass_pools_ && (pool.size() < kMaxPoolSize))
+ pool.push_back(socket.release());
+}
+
} // namespace net

Powered by Google App Engine
This is Rietveld 408576698