summaryrefslogtreecommitdiffstats
path: root/net/quic/port_suggester.cc
diff options
context:
space:
mode:
authorjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-13 22:47:07 +0000
committerjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-13 22:47:07 +0000
commit7034cf181121456f6727037faa8b8cc80810cc83 (patch)
tree0efaaebb23f2a4b6a8b751741c648ce770c4faa7 /net/quic/port_suggester.cc
parent474b1f3ba06c77487d48507f9bd114b46c6ae2b7 (diff)
downloadchromium_src-7034cf181121456f6727037faa8b8cc80810cc83.zip
chromium_src-7034cf181121456f6727037faa8b8cc80810cc83.tar.gz
chromium_src-7034cf181121456f6727037faa8b8cc80810cc83.tar.bz2
Create and use a seeded random number generator
(PortSuggester) to suggest what ephemeral source port should be used when opening a UDP client socket in QUIC. This should increase the likelihood of 0-RTT connections, even if a strike server is not used across a server cluster. BUG=326545 Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=239426 Review URL: https://codereview.chromium.org/107803002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@240782 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/quic/port_suggester.cc')
-rw-r--r--net/quic/port_suggester.cc49
1 files changed, 49 insertions, 0 deletions
diff --git a/net/quic/port_suggester.cc b/net/quic/port_suggester.cc
new file mode 100644
index 0000000..6b7940e
--- /dev/null
+++ b/net/quic/port_suggester.cc
@@ -0,0 +1,49 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/port_suggester.h"
+
+#include "base/logging.h"
+#include "net/base/host_port_pair.h"
+
+namespace net {
+
+PortSuggester::PortSuggester(const HostPortPair& server, uint64 seed)
+ : call_count_(0),
+ previous_suggestion_(-1) {
+ unsigned char hash_bytes[base::kSHA1Length];
+ base::SHA1HashBytes(
+ reinterpret_cast<const unsigned char*>(server.host().data()),
+ server.host().length(), hash_bytes);
+ COMPILE_ASSERT(sizeof(seed_) < sizeof(hash_bytes), seed_larger_than_hash);
+ memcpy(&seed_, hash_bytes, sizeof(seed_));
+ seed_ ^= seed ^ server.port();
+}
+
+int PortSuggester::SuggestPort(int min, int max) {
+ // Sometimes our suggestion can't be used, so we ensure that if additional
+ // calls are made, then each call (probably) provides a new suggestion.
+ if (++call_count_ > 1) {
+ // Evolve the seed.
+ unsigned char hash_bytes[base::kSHA1Length];
+ base::SHA1HashBytes(reinterpret_cast<const unsigned char *>(&seed_),
+ sizeof(seed_), hash_bytes);
+ memcpy(&seed_, hash_bytes, sizeof(seed_));
+ }
+ DCHECK_LE(min, max);
+ DCHECK_GT(min, 0);
+ int range = max - min + 1;
+ // Ports (and hence the extent of the |range|) are generally under 2^16, so
+ // the tiny non-uniformity in the pseudo-random distribution is not
+ // significant.
+ previous_suggestion_ = static_cast<int>(seed_ % range) + min;
+ return previous_suggestion_;
+}
+
+int PortSuggester::previous_suggestion() const {
+ DCHECK_LT(0u, call_count_);
+ return previous_suggestion_;
+}
+
+} // namespace net