OLD | NEW |
| (Empty) |
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 | |
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 static_assert(sizeof(seed_) < sizeof(hash_bytes), "seed larger than hash"); | |
20 memcpy(&seed_, hash_bytes, sizeof(seed_)); | |
21 seed_ ^= seed ^ server.port(); | |
22 } | |
23 | |
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 | |
44 int PortSuggester::previous_suggestion() const { | |
45 DCHECK_LT(0u, call_count_); | |
46 return previous_suggestion_; | |
47 } | |
48 | |
49 } // namespace net | |
OLD | NEW |