• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 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/quic/port_suggester.h"
6 
7 #include "base/logging.h"
8 #include "net/base/host_port_pair.h"
9 
10 namespace net {
11 
PortSuggester(const HostPortPair & server,uint64 seed)12 PortSuggester::PortSuggester(const HostPortPair& server, uint64 seed)
13     : call_count_(0),
14       previous_suggestion_(-1) {
15   unsigned char hash_bytes[base::kSHA1Length];
16   base::SHA1HashBytes(
17       reinterpret_cast<const unsigned char*>(server.host().data()),
18       server.host().length(), hash_bytes);
19   COMPILE_ASSERT(sizeof(seed_) < sizeof(hash_bytes), seed_larger_than_hash);
20   memcpy(&seed_, hash_bytes, sizeof(seed_));
21   seed_ ^= seed ^ server.port();
22 }
23 
SuggestPort(int min,int max)24 int PortSuggester::SuggestPort(int min, int max) {
25   // Sometimes our suggestion can't be used, so we ensure that if additional
26   // calls are made, then each call (probably) provides a new suggestion.
27   if (++call_count_ > 1) {
28     // Evolve the seed.
29     unsigned char hash_bytes[base::kSHA1Length];
30     base::SHA1HashBytes(reinterpret_cast<const unsigned char *>(&seed_),
31                         sizeof(seed_), hash_bytes);
32     memcpy(&seed_, hash_bytes, sizeof(seed_));
33   }
34   DCHECK_LE(min, max);
35   DCHECK_GT(min, 0);
36   int range = max - min + 1;
37   // Ports (and hence the extent of the |range|) are generally under 2^16, so
38   // the tiny non-uniformity in the pseudo-random distribution is not
39   // significant.
40   previous_suggestion_ = static_cast<int>(seed_ % range) + min;
41   return previous_suggestion_;
42 }
43 
previous_suggestion() const44 int PortSuggester::previous_suggestion() const {
45   DCHECK_LT(0u, call_count_);
46   return previous_suggestion_;
47 }
48 
49 }  // namespace net
50