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.
5 #include "net/quic/port_suggester.h"
7 #include "base/logging.h"
8 #include "net/base/host_port_pair.h"
12 PortSuggester::PortSuggester(const HostPortPair
& server
, uint64 seed
)
14 previous_suggestion_(-1) {
15 unsigned char hash_bytes
[base::kSHA1Length
];
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();
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) {
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_
));
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
40 previous_suggestion_
= static_cast<int>(seed_
% range
) + min
;
41 return previous_suggestion_
;
44 int PortSuggester::previous_suggestion() const {
45 DCHECK_LT(0u, call_count_
);
46 return previous_suggestion_
;