OLD | NEW |
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 <set> | 7 #include <set> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 // The set must reject values created on or before its own creation time. | 37 // The set must reject values created on or before its own creation time. |
38 StrikeRegister set(10 /* max size */, 1000 /* current time */, | 38 StrikeRegister set(10 /* max size */, 1000 /* current time */, |
39 100 /* window secs */, kOrbit, | 39 100 /* window secs */, kOrbit, |
40 StrikeRegister::DENY_REQUESTS_AT_STARTUP); | 40 StrikeRegister::DENY_REQUESTS_AT_STARTUP); |
41 uint8 nonce[32]; | 41 uint8 nonce[32]; |
42 SetNonce(nonce, 999, kOrbit); | 42 SetNonce(nonce, 999, kOrbit); |
43 ASSERT_FALSE(set.Insert(nonce, 1000)); | 43 ASSERT_FALSE(set.Insert(nonce, 1000)); |
44 SetNonce(nonce, 1000, kOrbit); | 44 SetNonce(nonce, 1000, kOrbit); |
45 ASSERT_FALSE(set.Insert(nonce, 1000)); | 45 ASSERT_FALSE(set.Insert(nonce, 1000)); |
46 | 46 |
47 EXPECT_EQ(0u, set.EffectiveWindowSecs(1000 /* current time */)); | 47 EXPECT_EQ(0u, set.GetCurrentValidWindowSecs(1000 /* current time */)); |
48 EXPECT_EQ(49u, set.EffectiveWindowSecs(1050 /* current time */)); | 48 EXPECT_EQ(0u, set.GetCurrentValidWindowSecs(1100 /* current time */)); |
49 EXPECT_EQ(99u, set.EffectiveWindowSecs(1100 /* current time */)); | 49 EXPECT_EQ(1u, set.GetCurrentValidWindowSecs(1101 /* current time */)); |
50 EXPECT_EQ(199u, set.EffectiveWindowSecs(1200 /* current time */)); | 50 EXPECT_EQ(50u, set.GetCurrentValidWindowSecs(1150 /* current time */)); |
51 EXPECT_EQ(200u, set.EffectiveWindowSecs(1300 /* current time */)); | 51 EXPECT_EQ(100u, set.GetCurrentValidWindowSecs(1200 /* current time */)); |
| 52 EXPECT_EQ(101u, set.GetCurrentValidWindowSecs(1300 /* current time */)); |
52 } | 53 } |
53 | 54 |
54 TEST(StrikeRegisterTest, NoStartupMode) { | 55 TEST(StrikeRegisterTest, NoStartupMode) { |
55 // Check that a strike register works immediately if NO_STARTUP_PERIOD_NEEDED | 56 // Check that a strike register works immediately if NO_STARTUP_PERIOD_NEEDED |
56 // is specified. | 57 // is specified. |
57 StrikeRegister set(10 /* max size */, 1000 /* current time */, | 58 StrikeRegister set(10 /* max size */, 1000 /* current time */, |
58 100 /* window secs */, kOrbit, | 59 100 /* window secs */, kOrbit, |
59 StrikeRegister::NO_STARTUP_PERIOD_NEEDED); | 60 StrikeRegister::NO_STARTUP_PERIOD_NEEDED); |
60 uint8 nonce[32]; | 61 uint8 nonce[32]; |
61 SetNonce(nonce, 1000, kOrbit); | 62 SetNonce(nonce, 1000, kOrbit); |
62 ASSERT_TRUE(set.Insert(nonce, 1000)); | 63 ASSERT_TRUE(set.Insert(nonce, 1000)); |
63 ASSERT_FALSE(set.Insert(nonce, 1000)); | 64 ASSERT_FALSE(set.Insert(nonce, 1000)); |
64 | 65 |
65 EXPECT_EQ(200u, set.EffectiveWindowSecs(1000 /* current time */)); | 66 EXPECT_EQ(101u, set.GetCurrentValidWindowSecs(1000 /* current time */)); |
66 EXPECT_EQ(200u, set.EffectiveWindowSecs(1050 /* current time */)); | 67 EXPECT_EQ(101u, set.GetCurrentValidWindowSecs(1050 /* current time */)); |
67 EXPECT_EQ(200u, set.EffectiveWindowSecs(1100 /* current time */)); | 68 EXPECT_EQ(101u, set.GetCurrentValidWindowSecs(1100 /* current time */)); |
68 EXPECT_EQ(200u, set.EffectiveWindowSecs(1200 /* current time */)); | 69 EXPECT_EQ(101u, set.GetCurrentValidWindowSecs(1200 /* current time */)); |
69 EXPECT_EQ(200u, set.EffectiveWindowSecs(1300 /* current time */)); | 70 EXPECT_EQ(101u, set.GetCurrentValidWindowSecs(1300 /* current time */)); |
70 } | 71 } |
71 | 72 |
72 TEST(StrikeRegisterTest, WindowFuture) { | 73 TEST(StrikeRegisterTest, WindowFuture) { |
73 // The set must reject values outside the window. | 74 // The set must reject values outside the window. |
74 StrikeRegister set(10 /* max size */, 1000 /* current time */, | 75 StrikeRegister set(10 /* max size */, 1000 /* current time */, |
75 100 /* window secs */, kOrbit, | 76 100 /* window secs */, kOrbit, |
76 StrikeRegister::DENY_REQUESTS_AT_STARTUP); | 77 StrikeRegister::DENY_REQUESTS_AT_STARTUP); |
77 uint8 nonce[32]; | 78 uint8 nonce[32]; |
78 SetNonce(nonce, 1101, kOrbit); | 79 SetNonce(nonce, 1101, kOrbit); |
79 ASSERT_FALSE(set.Insert(nonce, 1000)); | 80 ASSERT_FALSE(set.Insert(nonce, 1000)); |
(...skipping 11 matching lines...) Expand all Loading... |
91 SetNonce(nonce, 1101, kBadOrbit); | 92 SetNonce(nonce, 1101, kBadOrbit); |
92 ASSERT_FALSE(set.Insert(nonce, 1100)); | 93 ASSERT_FALSE(set.Insert(nonce, 1100)); |
93 } | 94 } |
94 | 95 |
95 TEST(StrikeRegisterTest, OneValue) { | 96 TEST(StrikeRegisterTest, OneValue) { |
96 StrikeRegister set(10 /* max size */, 1000 /* current time */, | 97 StrikeRegister set(10 /* max size */, 1000 /* current time */, |
97 100 /* window secs */, kOrbit, | 98 100 /* window secs */, kOrbit, |
98 StrikeRegister::DENY_REQUESTS_AT_STARTUP); | 99 StrikeRegister::DENY_REQUESTS_AT_STARTUP); |
99 uint8 nonce[32]; | 100 uint8 nonce[32]; |
100 SetNonce(nonce, 1101, kOrbit); | 101 SetNonce(nonce, 1101, kOrbit); |
101 ASSERT_TRUE(set.Insert(nonce, 1100)); | 102 ASSERT_TRUE(set.Insert(nonce, 1101)); |
102 } | 103 } |
103 | 104 |
104 TEST(StrikeRegisterTest, RejectDuplicate) { | 105 TEST(StrikeRegisterTest, RejectDuplicate) { |
105 // The set must reject values with the wrong orbit | 106 // The set must reject values with the wrong orbit |
106 StrikeRegister set(10 /* max size */, 1000 /* current time */, | 107 StrikeRegister set(10 /* max size */, 1000 /* current time */, |
107 100 /* window secs */, kOrbit, | 108 100 /* window secs */, kOrbit, |
108 StrikeRegister::DENY_REQUESTS_AT_STARTUP); | 109 StrikeRegister::DENY_REQUESTS_AT_STARTUP); |
109 uint8 nonce[32]; | 110 uint8 nonce[32]; |
110 SetNonce(nonce, 1101, kOrbit); | 111 SetNonce(nonce, 1101, kOrbit); |
111 ASSERT_TRUE(set.Insert(nonce, 1100)); | 112 ASSERT_TRUE(set.Insert(nonce, 1101)); |
112 ASSERT_FALSE(set.Insert(nonce, 1100)); | 113 ASSERT_FALSE(set.Insert(nonce, 1101)); |
113 } | 114 } |
114 | 115 |
115 TEST(StrikeRegisterTest, HorizonUpdating) { | 116 TEST(StrikeRegisterTest, HorizonUpdating) { |
116 StrikeRegister::StartupType startup_types[] = { | 117 StrikeRegister::StartupType startup_types[] = { |
117 StrikeRegister::DENY_REQUESTS_AT_STARTUP, | 118 StrikeRegister::DENY_REQUESTS_AT_STARTUP, |
118 StrikeRegister::NO_STARTUP_PERIOD_NEEDED | 119 StrikeRegister::NO_STARTUP_PERIOD_NEEDED |
119 }; | 120 }; |
120 | 121 |
121 for (size_t type_idx = 0; type_idx < arraysize(startup_types); ++type_idx) { | 122 for (size_t type_idx = 0; type_idx < arraysize(startup_types); ++type_idx) { |
122 StrikeRegister set(5 /* max size */, 500 /* current time */, | 123 StrikeRegister set(5 /* max size */, 500 /* current time */, |
123 100 /* window secs */, kOrbit, | 124 100 /* window secs */, kOrbit, |
124 startup_types[type_idx]); | 125 startup_types[type_idx]); |
125 uint8 nonce[6][32]; | 126 uint8 nonce[6][32]; |
126 for (unsigned i = 0; i < 5; i++) { | 127 for (unsigned i = 0; i < 5; i++) { |
127 SetNonce(nonce[i], 1101 + i, kOrbit); | 128 SetNonce(nonce[i], 1101 + i, kOrbit); |
128 nonce[i][31] = i; | 129 nonce[i][31] = i; |
129 ASSERT_TRUE(set.Insert(nonce[i], 1100)); | 130 ASSERT_TRUE(set.Insert(nonce[i], 1100)); |
130 } | 131 } |
131 | 132 |
132 // Effective horizon is still 2 * window. | 133 // Valid window is still equal to |window_secs + 1|. |
133 EXPECT_EQ(200u, set.EffectiveWindowSecs(1100)); | 134 EXPECT_EQ(101u, set.GetCurrentValidWindowSecs(1100)); |
134 | 135 |
135 // This should push the oldest value out and force the horizon to | 136 // This should push the oldest value out and force the horizon to |
136 // be updated. | 137 // be updated. |
137 SetNonce(nonce[5], 1110, kOrbit); | 138 SetNonce(nonce[5], 1110, kOrbit); |
138 ASSERT_TRUE(set.Insert(nonce[5], 1100)); | 139 ASSERT_TRUE(set.Insert(nonce[5], 1110)); |
139 // Effective horizon is computed based on the timestamp of the | 140 // Effective horizon is computed based on the timestamp of the |
140 // value that was pushed out. | 141 // value that was pushed out. |
141 EXPECT_EQ(98u, set.EffectiveWindowSecs(1100)); | 142 EXPECT_EQ(9u, set.GetCurrentValidWindowSecs(1110)); |
142 | 143 |
143 SetNonce(nonce[5], 1111, kOrbit); | 144 SetNonce(nonce[5], 1111, kOrbit); |
144 EXPECT_TRUE(set.Insert(nonce[5], 1100)); | 145 EXPECT_TRUE(set.Insert(nonce[5], 1110)); |
145 EXPECT_EQ(97u, set.EffectiveWindowSecs(1100)); | 146 EXPECT_EQ(8u, set.GetCurrentValidWindowSecs(1110)); |
146 | 147 |
147 // This should be behind the horizon now: | 148 // This should be behind the horizon now: |
148 SetNonce(nonce[5], 1101, kOrbit); | 149 SetNonce(nonce[5], 1101, kOrbit); |
149 nonce[5][31] = 10; | 150 nonce[5][31] = 10; |
150 ASSERT_FALSE(set.Insert(nonce[5], 1100)); | 151 EXPECT_FALSE(set.Insert(nonce[5], 1110)); |
| 152 |
| 153 // Insert beyond the valid range. |
| 154 SetNonce(nonce[5], 1117, kOrbit); |
| 155 nonce[5][31] = 2; |
| 156 EXPECT_FALSE(set.Insert(nonce[5], 1110)); |
| 157 |
| 158 // Insert at the upper valid range. |
| 159 SetNonce(nonce[5], 1116, kOrbit); |
| 160 nonce[5][31] = 1; |
| 161 EXPECT_TRUE(set.Insert(nonce[5], 1110)); |
| 162 |
| 163 // This should be beyond the upper valid range now: |
| 164 SetNonce(nonce[5], 1116, kOrbit); |
| 165 nonce[5][31] = 2; |
| 166 EXPECT_FALSE(set.Insert(nonce[5], 1110)); |
151 } | 167 } |
152 } | 168 } |
153 | 169 |
154 TEST(StrikeRegisterTest, InsertMany) { | 170 TEST(StrikeRegisterTest, InsertMany) { |
155 StrikeRegister set(5000 /* max size */, 1000 /* current time */, | 171 StrikeRegister set(5000 /* max size */, 1000 /* current time */, |
156 500 /* window secs */, kOrbit, | 172 500 /* window secs */, kOrbit, |
157 StrikeRegister::DENY_REQUESTS_AT_STARTUP); | 173 StrikeRegister::DENY_REQUESTS_AT_STARTUP); |
158 | 174 |
159 uint8 nonce[32]; | 175 uint8 nonce[32]; |
160 SetNonce(nonce, 1101, kOrbit); | 176 SetNonce(nonce, 1101, kOrbit); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 | 237 |
222 set<pair<uint32, string> >::const_iterator it = nonces_.find(nonce); | 238 set<pair<uint32, string> >::const_iterator it = nonces_.find(nonce); |
223 if (it != nonces_.end()) { | 239 if (it != nonces_.end()) { |
224 return false; | 240 return false; |
225 } | 241 } |
226 | 242 |
227 nonces_.insert(nonce); | 243 nonces_.insert(nonce); |
228 return true; | 244 return true; |
229 } | 245 } |
230 | 246 |
231 uint32 EffectiveWindowSecs(const uint32 current_time_external) const { | 247 uint32 GetCurrentValidWindowSecs(const uint32 current_time_external) const { |
232 const uint32 future_horizon = | 248 const uint32 current_time = ExternalTimeToInternal(current_time_external); |
233 ExternalTimeToInternal(current_time_external) + window_secs_; | 249 if (horizon_ > current_time) { |
234 if (horizon_ > future_horizon) { | |
235 return 0; | 250 return 0; |
236 } | 251 } |
237 return min(future_horizon - horizon_, 2 * window_secs_); | 252 return 1 + min(current_time - horizon_, window_secs_); |
238 } | 253 } |
239 | 254 |
240 private: | 255 private: |
241 // TimeFromBytes returns a big-endian uint32 from |d|. | 256 // TimeFromBytes returns a big-endian uint32 from |d|. |
242 static uint32 TimeFromBytes(const uint8 d[4]) { | 257 static uint32 TimeFromBytes(const uint8 d[4]) { |
243 return static_cast<uint32>(d[0]) << 24 | | 258 return static_cast<uint32>(d[0]) << 24 | |
244 static_cast<uint32>(d[1]) << 16 | | 259 static_cast<uint32>(d[1]) << 16 | |
245 static_cast<uint32>(d[2]) << 8 | | 260 static_cast<uint32>(d[2]) << 8 | |
246 static_cast<uint32>(d[3]); | 261 static_cast<uint32>(d[3]); |
247 } | 262 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 // There are 2048 possible nonce values: | 312 // There are 2048 possible nonce values: |
298 const uint32 v = rand() % 2048; | 313 const uint32 v = rand() % 2048; |
299 nonce[30] = v >> 8; | 314 nonce[30] = v >> 8; |
300 nonce[31] = v; | 315 nonce[31] = v; |
301 | 316 |
302 const bool r2 = s2->Insert(nonce, time, time); | 317 const bool r2 = s2->Insert(nonce, time, time); |
303 const bool r1 = s1->Insert(nonce, time); | 318 const bool r1 = s1->Insert(nonce, time); |
304 EXPECT_EQ(r1, r2); | 319 EXPECT_EQ(r1, r2); |
305 // Inserts succeed after the startup period. | 320 // Inserts succeed after the startup period. |
306 EXPECT_EQ(time > current_time + window, r1); | 321 EXPECT_EQ(time > current_time + window, r1); |
307 EXPECT_EQ(s1->EffectiveWindowSecs(time), | 322 EXPECT_EQ(s1->GetCurrentValidWindowSecs(time), |
308 s2->EffectiveWindowSecs(time)); | 323 s2->GetCurrentValidWindowSecs(time)); |
309 | 324 |
310 if (i % 10 == 0) { | 325 if (i % 10 == 0) { |
311 s1->Validate(); | 326 s1->Validate(); |
312 } | 327 } |
313 | 328 |
314 if (HasFailure()) { | 329 if (HasFailure()) { |
315 break; | 330 break; |
316 } | 331 } |
317 } | 332 } |
318 | 333 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 SetNonce(nonce, time, kOrbit); | 375 SetNonce(nonce, time, kOrbit); |
361 | 376 |
362 // There are 2048 possible nonce values: | 377 // There are 2048 possible nonce values: |
363 const uint32 v = rand() % 2048; | 378 const uint32 v = rand() % 2048; |
364 nonce[30] = v >> 8; | 379 nonce[30] = v >> 8; |
365 nonce[31] = v; | 380 nonce[31] = v; |
366 | 381 |
367 const bool r2 = s2->Insert(nonce, time, time); | 382 const bool r2 = s2->Insert(nonce, time, time); |
368 const bool r1 = s1->Insert(nonce, time); | 383 const bool r1 = s1->Insert(nonce, time); |
369 EXPECT_EQ(r1, r2); | 384 EXPECT_EQ(r1, r2); |
370 EXPECT_EQ(s1->EffectiveWindowSecs(time), | 385 EXPECT_EQ(s1->GetCurrentValidWindowSecs(time), |
371 s2->EffectiveWindowSecs(time)); | 386 s2->GetCurrentValidWindowSecs(time)); |
372 | 387 |
373 if (i % 10 == 0) { | 388 if (i % 10 == 0) { |
374 s1->Validate(); | 389 s1->Validate(); |
375 } | 390 } |
376 | 391 |
377 if (HasFailure()) { | 392 if (HasFailure()) { |
378 break; | 393 break; |
379 } | 394 } |
380 } | 395 } |
381 | 396 |
382 if (i != kMaxIterations) { | 397 if (i != kMaxIterations) { |
383 FAIL() << "Failed after " << i << " iterations"; | 398 FAIL() << "Failed after " << i << " iterations"; |
384 } | 399 } |
385 } | 400 } |
386 | 401 |
387 } // anonymous namespace | 402 } // anonymous namespace |
OLD | NEW |