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

Side by Side Diff: net/quic/crypto/strike_register.cc

Issue 15937012: Land Recent QUIC changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Small bug fixes Created 7 years, 6 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/crypto/strike_register.h" 5 #include "net/quic/crypto/strike_register.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 8
9 using std::pair; 9 using std::pair;
10 using std::set; 10 using std::set;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 uint8 otherbits() const { return data_[1]; } 48 uint8 otherbits() const { return data_[1]; }
49 49
50 // These bytes are organised thus: 50 // These bytes are organised thus:
51 // <24 bits> left child 51 // <24 bits> left child
52 // <8 bits> crit-byte 52 // <8 bits> crit-byte
53 // <24 bits> right child 53 // <24 bits> right child
54 // <8 bits> other-bits 54 // <8 bits> other-bits
55 uint32 data_[2]; 55 uint32 data_[2];
56 }; 56 };
57 57
58 // kCreationTimeFromInternalEpoch contains the number of seconds between the
59 // start of the internal epoch and |creation_time_external_|. This allows us
60 // to consider times that are before |creation_time_external_|.
61 static const uint32 kCreationTimeFromInternalEpoch = 63115200.0; // 2 years.
62
58 StrikeRegister::StrikeRegister(unsigned max_entries, 63 StrikeRegister::StrikeRegister(unsigned max_entries,
59 uint32 current_time, 64 uint32 current_time,
60 uint32 window_secs, 65 uint32 window_secs,
61 const uint8 orbit[8]) 66 const uint8 orbit[8],
67 StartupType startup)
62 : max_entries_(max_entries), 68 : max_entries_(max_entries),
63 window_secs_(window_secs), 69 window_secs_(window_secs),
64 // The horizon is initially set |window_secs| into the future because, if 70 // The horizon is initially set |window_secs| into the future because, if
65 // we just crashed, then we may have accepted nonces in the span 71 // we just crashed, then we may have accepted nonces in the span
66 // [current_time...current_time+window_secs) and so we conservatively 72 // [current_time...current_time+window_secs) and so we conservatively
67 // reject the whole timespan. 73 // reject the whole timespan unless |startup| tells us otherwise.
68 horizon_(current_time + window_secs) { 74 creation_time_external_(current_time),
75 internal_epoch_(current_time > kCreationTimeFromInternalEpoch
76 ? current_time - kCreationTimeFromInternalEpoch
77 : 0),
78 horizon_(ExternalTimeToInternal(current_time) + window_secs),
79 horizon_valid_(startup == DENY_REQUESTS_AT_STARTUP) {
69 memcpy(orbit_, orbit, sizeof(orbit_)); 80 memcpy(orbit_, orbit, sizeof(orbit_));
70 81
82 // TODO(rtenneti): Remove the following check, Added the following to silence
83 // "is not used" error.
84 CHECK_GE(creation_time_external_, 0u);
85
71 // We only have 23 bits of index available. 86 // We only have 23 bits of index available.
72 CHECK_LT(max_entries, 1u << 23); 87 CHECK_LT(max_entries, 1u << 23);
73 CHECK_GT(max_entries, 1u); // There must be at least two entries. 88 CHECK_GT(max_entries, 1u); // There must be at least two entries.
74 CHECK_EQ(sizeof(InternalNode), 8u); // in case of compiler changes. 89 CHECK_EQ(sizeof(InternalNode), 8u); // in case of compiler changes.
75 internal_nodes_ = new InternalNode[max_entries]; 90 internal_nodes_ = new InternalNode[max_entries];
76 external_nodes_.reset(new uint8[kExternalNodeSize * max_entries]); 91 external_nodes_.reset(new uint8[kExternalNodeSize * max_entries]);
77 92
78 Reset(); 93 Reset();
79 } 94 }
80 95
81 StrikeRegister::~StrikeRegister() { delete[] internal_nodes_; } 96 StrikeRegister::~StrikeRegister() { delete[] internal_nodes_; }
82 97
83 void StrikeRegister::Reset() { 98 void StrikeRegister::Reset() {
84 // Thread a free list through all of the internal nodes. 99 // Thread a free list through all of the internal nodes.
85 internal_node_free_head_ = 0; 100 internal_node_free_head_ = 0;
86 for (unsigned i = 0; i < max_entries_ - 1; i++) 101 for (unsigned i = 0; i < max_entries_ - 1; i++)
87 internal_nodes_[i].SetNextPtr(i + 1); 102 internal_nodes_[i].SetNextPtr(i + 1);
88 internal_nodes_[max_entries_ - 1].SetNextPtr(kNil); 103 internal_nodes_[max_entries_ - 1].SetNextPtr(kNil);
89 104
90 // Also thread a free list through the external nodes. 105 // Also thread a free list through the external nodes.
91 external_node_free_head_ = 0; 106 external_node_free_head_ = 0;
92 for (unsigned i = 0; i < max_entries_ - 1; i++) 107 for (unsigned i = 0; i < max_entries_ - 1; i++)
93 external_node_next_ptr(i) = i + 1; 108 external_node_next_ptr(i) = i + 1;
94 external_node_next_ptr(max_entries_ - 1) = kNil; 109 external_node_next_ptr(max_entries_ - 1) = kNil;
95 110
96 // This is the root of the tree. 111 // This is the root of the tree.
97 internal_node_head_ = kNil; 112 internal_node_head_ = kNil;
98 } 113 }
99 114
100 bool StrikeRegister::Insert(const uint8 nonce[32], 115 bool StrikeRegister::Insert(const uint8 nonce[32],
101 const uint32 current_time) { 116 const uint32 current_time_external) {
102 // If current_time is very small or very large then we assume that we have 117 const uint32 current_time = ExternalTimeToInternal(current_time_external);
103 // just rolled over / are about to roll over and it's 2038 or 2106. Since
104 // we don't deal with this situation we flush everything and start over.
105 // This means that we reject everything for 2 * |window_secs_| every 68
106 // years.
107 if (current_time < window_secs_ ||
108 current_time + window_secs_ < current_time) {
109 if (internal_node_head_ != kNil) {
110 Reset();
111 }
112 horizon_ = current_time;
113 return false;
114 }
115 118
116 // Check to see if the orbit is correct. 119 // Check to see if the orbit is correct.
117 if (memcmp(nonce + sizeof(current_time), orbit_, sizeof(orbit_))) { 120 if (memcmp(nonce + sizeof(current_time), orbit_, sizeof(orbit_))) {
118 return false; 121 return false;
119 } 122 }
120 const uint32 nonce_time = TimeFromBytes(nonce); 123 const uint32 nonce_time = ExternalTimeToInternal(TimeFromBytes(nonce));
121 // We have dropped one or more nonces with a time value of |horizon_|, so 124 // We have dropped one or more nonces with a time value of |horizon_|, so
122 // we have to reject anything with a timestamp less than or equal to that. 125 // we have to reject anything with a timestamp less than or equal to that.
123 if (nonce_time <= horizon_) { 126 if (horizon_valid_ && nonce_time <= horizon_) {
124 return false; 127 return false;
125 } 128 }
126 129
127 // Check that the timestamp is in the current window. 130 // Check that the timestamp is in the current window.
128 if (nonce_time < (current_time - window_secs_) || 131 if ((current_time > window_secs_ &&
132 nonce_time < (current_time - window_secs_)) ||
129 nonce_time > (current_time + window_secs_)) { 133 nonce_time > (current_time + window_secs_)) {
130 return false; 134 return false;
131 } 135 }
132 136
133 // We strip the orbit out of the nonce. 137 // We strip the orbit out of the nonce.
134 uint8 value[24]; 138 uint8 value[24];
135 memcpy(value, nonce, sizeof(current_time)); 139 memcpy(value, &nonce_time, sizeof(nonce_time));
136 memcpy(value + sizeof(current_time), 140 memcpy(value + sizeof(nonce_time),
137 nonce + sizeof(current_time) + sizeof(orbit_), 141 nonce + sizeof(nonce_time) + sizeof(orbit_),
138 sizeof(value) - sizeof(current_time)); 142 sizeof(value) - sizeof(nonce_time));
139 143
140 // Find the best match to |value| in the crit-bit tree. The best match is 144 // Find the best match to |value| in the crit-bit tree. The best match is
141 // simply the value which /could/ match |value|, if any does, so we still 145 // simply the value which /could/ match |value|, if any does, so we still
142 // need a memcmp to check. 146 // need a memcmp to check.
143 uint32 best_match_index = BestMatch(value); 147 uint32 best_match_index = BestMatch(value);
144 if (best_match_index == kNil) { 148 if (best_match_index == kNil) {
145 // Empty tree. Just insert the new value at the root. 149 // Empty tree. Just insert the new value at the root.
146 uint32 index = GetFreeExternalNode(); 150 uint32 index = GetFreeExternalNode();
147 memcpy(external_node(index), value, sizeof(value)); 151 memcpy(external_node(index), value, sizeof(value));
148 internal_node_head_ = (index | kExternalFlag) << 8; 152 internal_node_head_ = (index | kExternalFlag) << 8;
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 } 274 }
271 275
272 // static 276 // static
273 uint32 StrikeRegister::TimeFromBytes(const uint8 d[4]) { 277 uint32 StrikeRegister::TimeFromBytes(const uint8 d[4]) {
274 return static_cast<uint32>(d[0]) << 24 | 278 return static_cast<uint32>(d[0]) << 24 |
275 static_cast<uint32>(d[1]) << 16 | 279 static_cast<uint32>(d[1]) << 16 |
276 static_cast<uint32>(d[2]) << 8 | 280 static_cast<uint32>(d[2]) << 8 |
277 static_cast<uint32>(d[3]); 281 static_cast<uint32>(d[3]);
278 } 282 }
279 283
284 uint32 StrikeRegister::ExternalTimeToInternal(uint32 external_time) {
285 return external_time - internal_epoch_;
286 }
287
280 uint32 StrikeRegister::BestMatch(const uint8 v[24]) const { 288 uint32 StrikeRegister::BestMatch(const uint8 v[24]) const {
281 if (internal_node_head_ == kNil) { 289 if (internal_node_head_ == kNil) {
282 return kNil; 290 return kNil;
283 } 291 }
284 292
285 uint32 next = internal_node_head_ >> 8; 293 uint32 next = internal_node_head_ >> 8;
286 while ((next & kExternalFlag) == 0) { 294 while ((next & kExternalFlag) == 0) {
287 InternalNode* node = &internal_nodes_[next]; 295 InternalNode* node = &internal_nodes_[next];
288 uint8 b = v[node->critbyte()]; 296 uint8 b = v[node->critbyte()];
289 unsigned direction = 297 unsigned direction =
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 CHECK_EQ(free_internal_nodes.count(inter), 0u); 452 CHECK_EQ(free_internal_nodes.count(inter), 0u);
445 CHECK_EQ(used_internal_nodes->count(inter), 0u); 453 CHECK_EQ(used_internal_nodes->count(inter), 0u);
446 used_internal_nodes->insert(inter); 454 used_internal_nodes->insert(inter);
447 ValidateTree(inter, bit, bits, free_internal_nodes, free_external_nodes, 455 ValidateTree(inter, bit, bits, free_internal_nodes, free_external_nodes,
448 used_internal_nodes, used_external_nodes); 456 used_internal_nodes, used_external_nodes);
449 } 457 }
450 } 458 }
451 } 459 }
452 460
453 } // namespace net 461 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698