OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <stddef.h> | 5 #include <stddef.h> |
6 #include <sys/epoll.h> | 6 #include <sys/epoll.h> |
7 | 7 |
8 #include <list> | 8 #include <list> |
9 #include <memory> | 9 #include <memory> |
10 #include <string> | 10 #include <string> |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 struct TestParams { | 96 struct TestParams { |
97 TestParams(const QuicVersionVector& client_supported_versions, | 97 TestParams(const QuicVersionVector& client_supported_versions, |
98 const QuicVersionVector& server_supported_versions, | 98 const QuicVersionVector& server_supported_versions, |
99 QuicVersion negotiated_version, | 99 QuicVersion negotiated_version, |
100 bool client_supports_stateless_rejects, | 100 bool client_supports_stateless_rejects, |
101 bool server_uses_stateless_rejects_if_peer_supported, | 101 bool server_uses_stateless_rejects_if_peer_supported, |
102 QuicTag congestion_control_tag, | 102 QuicTag congestion_control_tag, |
103 bool disable_hpack_dynamic_table, | 103 bool disable_hpack_dynamic_table, |
104 bool force_hol_blocking, | 104 bool force_hol_blocking, |
105 bool use_cheap_stateless_reject, | 105 bool use_cheap_stateless_reject, |
106 bool buffer_packet_till_chlo, | 106 bool buffer_packet_till_chlo) |
107 bool small_client_mtu) | |
108 : client_supported_versions(client_supported_versions), | 107 : client_supported_versions(client_supported_versions), |
109 server_supported_versions(server_supported_versions), | 108 server_supported_versions(server_supported_versions), |
110 negotiated_version(negotiated_version), | 109 negotiated_version(negotiated_version), |
111 client_supports_stateless_rejects(client_supports_stateless_rejects), | 110 client_supports_stateless_rejects(client_supports_stateless_rejects), |
112 server_uses_stateless_rejects_if_peer_supported( | 111 server_uses_stateless_rejects_if_peer_supported( |
113 server_uses_stateless_rejects_if_peer_supported), | 112 server_uses_stateless_rejects_if_peer_supported), |
114 congestion_control_tag(congestion_control_tag), | 113 congestion_control_tag(congestion_control_tag), |
115 disable_hpack_dynamic_table(disable_hpack_dynamic_table), | 114 disable_hpack_dynamic_table(disable_hpack_dynamic_table), |
116 force_hol_blocking(force_hol_blocking), | 115 force_hol_blocking(force_hol_blocking), |
117 use_cheap_stateless_reject(use_cheap_stateless_reject), | 116 use_cheap_stateless_reject(use_cheap_stateless_reject), |
118 buffer_packet_till_chlo(buffer_packet_till_chlo), | 117 buffer_packet_till_chlo(buffer_packet_till_chlo) {} |
119 small_client_mtu(small_client_mtu) {} | |
120 | 118 |
121 friend ostream& operator<<(ostream& os, const TestParams& p) { | 119 friend ostream& operator<<(ostream& os, const TestParams& p) { |
122 os << "{ server_supported_versions: " | 120 os << "{ server_supported_versions: " |
123 << QuicVersionVectorToString(p.server_supported_versions); | 121 << QuicVersionVectorToString(p.server_supported_versions); |
124 os << " client_supported_versions: " | 122 os << " client_supported_versions: " |
125 << QuicVersionVectorToString(p.client_supported_versions); | 123 << QuicVersionVectorToString(p.client_supported_versions); |
126 os << " negotiated_version: " << QuicVersionToString(p.negotiated_version); | 124 os << " negotiated_version: " << QuicVersionToString(p.negotiated_version); |
127 os << " client_supports_stateless_rejects: " | 125 os << " client_supports_stateless_rejects: " |
128 << p.client_supports_stateless_rejects; | 126 << p.client_supports_stateless_rejects; |
129 os << " server_uses_stateless_rejects_if_peer_supported: " | 127 os << " server_uses_stateless_rejects_if_peer_supported: " |
130 << p.server_uses_stateless_rejects_if_peer_supported; | 128 << p.server_uses_stateless_rejects_if_peer_supported; |
131 os << " congestion_control_tag: " | 129 os << " congestion_control_tag: " |
132 << QuicUtils::TagToString(p.congestion_control_tag); | 130 << QuicUtils::TagToString(p.congestion_control_tag); |
133 os << " disable_hpack_dynamic_table: " << p.disable_hpack_dynamic_table; | 131 os << " disable_hpack_dynamic_table: " << p.disable_hpack_dynamic_table; |
134 os << " force_hol_blocking: " << p.force_hol_blocking; | 132 os << " force_hol_blocking: " << p.force_hol_blocking; |
135 os << " use_cheap_stateless_reject: " << p.use_cheap_stateless_reject; | 133 os << " use_cheap_stateless_reject: " << p.use_cheap_stateless_reject; |
136 os << " buffer_packet_till_chlo: " << p.buffer_packet_till_chlo; | 134 os << " buffer_packet_till_chlo: " << p.buffer_packet_till_chlo << " }"; |
137 os << " small_client_mtu: " << p.small_client_mtu << " }"; | |
138 return os; | 135 return os; |
139 } | 136 } |
140 | 137 |
141 QuicVersionVector client_supported_versions; | 138 QuicVersionVector client_supported_versions; |
142 QuicVersionVector server_supported_versions; | 139 QuicVersionVector server_supported_versions; |
143 QuicVersion negotiated_version; | 140 QuicVersion negotiated_version; |
144 bool client_supports_stateless_rejects; | 141 bool client_supports_stateless_rejects; |
145 bool server_uses_stateless_rejects_if_peer_supported; | 142 bool server_uses_stateless_rejects_if_peer_supported; |
146 QuicTag congestion_control_tag; | 143 QuicTag congestion_control_tag; |
147 bool disable_hpack_dynamic_table; | 144 bool disable_hpack_dynamic_table; |
148 bool force_hol_blocking; | 145 bool force_hol_blocking; |
149 bool use_cheap_stateless_reject; | 146 bool use_cheap_stateless_reject; |
150 bool buffer_packet_till_chlo; | 147 bool buffer_packet_till_chlo; |
151 bool small_client_mtu; | |
152 }; | 148 }; |
153 | 149 |
154 // Constructs various test permutations. | 150 // Constructs various test permutations. |
155 vector<TestParams> GetTestParams() { | 151 vector<TestParams> GetTestParams() { |
156 // Divide the versions into buckets in which the intra-frame format | 152 // Divide the versions into buckets in which the intra-frame format |
157 // is compatible. When clients encounter QUIC version negotiation | 153 // is compatible. When clients encounter QUIC version negotiation |
158 // they simply retransmit all packets using the new version's | 154 // they simply retransmit all packets using the new version's |
159 // QUIC framing. However, they are unable to change the intra-frame | 155 // QUIC framing. However, they are unable to change the intra-frame |
160 // layout (for example to change HTTP2 headers to SPDY/3). So | 156 // layout (for example to change HTTP2 headers to SPDY/3). So |
161 // these tests need to ensure that clients are never attempting | 157 // these tests need to ensure that clients are never attempting |
162 // to do 0-RTT across incompatible versions. Chromium only supports | 158 // to do 0-RTT across incompatible versions. Chromium only supports |
163 // a single version at a time anyway. :) | 159 // a single version at a time anyway. :) |
164 QuicVersionVector all_supported_versions = AllSupportedVersions(); | 160 QuicVersionVector all_supported_versions = AllSupportedVersions(); |
165 QuicVersionVector version_buckets[4]; | 161 QuicVersionVector version_buckets[3]; |
166 | 162 |
167 for (const QuicVersion version : all_supported_versions) { | 163 for (const QuicVersion version : all_supported_versions) { |
168 if (version <= QUIC_VERSION_30) { | 164 if (version <= QUIC_VERSION_32) { |
169 // Versions: 30 | |
170 // v26 adds a hash of the expected leaf cert in the XLCT tag. | |
171 version_buckets[0].push_back(version); | |
172 } else if (version <= QUIC_VERSION_32) { | |
173 // Versions: 31-32 | 165 // Versions: 31-32 |
174 // v31 adds a hash of the CHLO into the proof signature. | 166 // v31 adds a hash of the CHLO into the proof signature. |
175 version_buckets[1].push_back(version); | 167 version_buckets[0].push_back(version); |
176 } else if (version <= QUIC_VERSION_33) { | 168 } else if (version <= QUIC_VERSION_33) { |
177 // Versions: 33 | 169 // Versions: 33 |
178 // v33 adds a diversification nonce into the hkdf. | 170 // v33 adds a diversification nonce into the hkdf. |
179 version_buckets[2].push_back(version); | 171 version_buckets[1].push_back(version); |
180 } else { | 172 } else { |
181 // Versions: 34+ | 173 // Versions: 34+ |
182 // QUIC_VERSION_34 deprecates entropy and uses new ack and stop waiting | 174 // QUIC_VERSION_34 deprecates entropy and uses new ack and stop waiting |
183 // wire formats. | 175 // wire formats. |
184 version_buckets[3].push_back(version); | 176 version_buckets[2].push_back(version); |
185 } | 177 } |
186 } | 178 } |
187 | 179 |
188 // This must be kept in sync with the number of nested for-loops below as it | 180 // This must be kept in sync with the number of nested for-loops below as it |
189 // is used to prune the number of tests that are run. | 181 // is used to prune the number of tests that are run. |
190 const int kMaxEnabledOptions = 7; | 182 const int kMaxEnabledOptions = 6; |
191 int max_enabled_options = 0; | 183 int max_enabled_options = 0; |
192 vector<TestParams> params; | 184 vector<TestParams> params; |
193 for (bool server_uses_stateless_rejects_if_peer_supported : {true, false}) { | 185 for (bool server_uses_stateless_rejects_if_peer_supported : {true, false}) { |
194 for (bool client_supports_stateless_rejects : {true, false}) { | 186 for (bool client_supports_stateless_rejects : {true, false}) { |
195 for (const QuicTag congestion_control_tag : {kRENO, kQBIC}) { | 187 for (const QuicTag congestion_control_tag : {kRENO, kQBIC}) { |
196 for (bool disable_hpack_dynamic_table : {false}) { | 188 for (bool disable_hpack_dynamic_table : {false}) { |
197 for (bool force_hol_blocking : {true, false}) { | 189 for (bool force_hol_blocking : {true, false}) { |
198 for (bool use_cheap_stateless_reject : {true, false}) { | 190 for (bool use_cheap_stateless_reject : {true, false}) { |
199 for (bool buffer_packet_till_chlo : {true, false}) { | 191 for (bool buffer_packet_till_chlo : {true, false}) { |
200 for (bool small_client_mtu : {true, false}) { | 192 if (!buffer_packet_till_chlo && use_cheap_stateless_reject) { |
201 if (!buffer_packet_till_chlo && use_cheap_stateless_reject) { | 193 // Doing stateless reject while not buffering packet |
202 // Doing stateless reject while not buffering packet | 194 // before CHLO is not allowed. |
203 // before CHLO is not allowed. | 195 break; |
204 break; | 196 } |
| 197 int enabled_options = 0; |
| 198 if (force_hol_blocking) { |
| 199 ++enabled_options; |
| 200 } |
| 201 if (congestion_control_tag != kQBIC) { |
| 202 ++enabled_options; |
| 203 } |
| 204 if (disable_hpack_dynamic_table) { |
| 205 ++enabled_options; |
| 206 } |
| 207 if (client_supports_stateless_rejects) { |
| 208 ++enabled_options; |
| 209 } |
| 210 if (server_uses_stateless_rejects_if_peer_supported) { |
| 211 ++enabled_options; |
| 212 } |
| 213 if (buffer_packet_till_chlo) { |
| 214 ++enabled_options; |
| 215 } |
| 216 if (use_cheap_stateless_reject) { |
| 217 ++enabled_options; |
| 218 } |
| 219 CHECK_GE(kMaxEnabledOptions, enabled_options); |
| 220 if (enabled_options > max_enabled_options) { |
| 221 max_enabled_options = enabled_options; |
| 222 } |
| 223 |
| 224 // Run tests with no options, a single option, or all the |
| 225 // options enabled to avoid a combinatorial explosion. |
| 226 if (enabled_options > 1 && |
| 227 enabled_options < kMaxEnabledOptions) { |
| 228 continue; |
| 229 } |
| 230 |
| 231 for (const QuicVersionVector& client_versions : |
| 232 version_buckets) { |
| 233 CHECK(!client_versions.empty()); |
| 234 if (FilterSupportedVersions(client_versions).empty()) { |
| 235 continue; |
205 } | 236 } |
206 int enabled_options = 0; | 237 // Add an entry for server and client supporting all |
207 if (force_hol_blocking) { | 238 // versions. |
208 ++enabled_options; | 239 params.push_back(TestParams( |
209 } | 240 client_versions, all_supported_versions, |
210 if (congestion_control_tag != kQBIC) { | 241 client_versions.front(), |
211 ++enabled_options; | 242 client_supports_stateless_rejects, |
212 } | 243 server_uses_stateless_rejects_if_peer_supported, |
213 if (disable_hpack_dynamic_table) { | 244 congestion_control_tag, disable_hpack_dynamic_table, |
214 ++enabled_options; | 245 force_hol_blocking, use_cheap_stateless_reject, |
215 } | 246 buffer_packet_till_chlo)); |
216 if (client_supports_stateless_rejects) { | |
217 ++enabled_options; | |
218 } | |
219 if (server_uses_stateless_rejects_if_peer_supported) { | |
220 ++enabled_options; | |
221 } | |
222 if (buffer_packet_till_chlo) { | |
223 ++enabled_options; | |
224 } | |
225 if (use_cheap_stateless_reject) { | |
226 ++enabled_options; | |
227 } | |
228 if (small_client_mtu) { | |
229 ++enabled_options; | |
230 } | |
231 CHECK_GE(kMaxEnabledOptions, enabled_options); | |
232 if (enabled_options > max_enabled_options) { | |
233 max_enabled_options = enabled_options; | |
234 } | |
235 | 247 |
236 // Run tests with no options, a single option, or all the | 248 // Run version negotiation tests tests with no options, or |
237 // options enabled to avoid a combinatorial explosion. | 249 // all the options enabled to avoid a combinatorial |
| 250 // explosion. |
238 if (enabled_options > 1 && | 251 if (enabled_options > 1 && |
239 enabled_options < kMaxEnabledOptions) { | 252 enabled_options < kMaxEnabledOptions) { |
240 continue; | 253 continue; |
241 } | 254 } |
242 | 255 |
243 for (const QuicVersionVector& client_versions : | 256 // Test client supporting all versions and server supporting |
244 version_buckets) { | 257 // 1 version. Simulate an old server and exercise version |
245 CHECK(!client_versions.empty()); | 258 // downgrade in the client. Protocol negotiation should |
246 if (FilterSupportedVersions(client_versions).empty()) { | 259 // occur. Skip the i = 0 case because it is essentially the |
| 260 // same as the default case. |
| 261 for (size_t i = 1; i < client_versions.size(); ++i) { |
| 262 QuicVersionVector server_supported_versions; |
| 263 server_supported_versions.push_back(client_versions[i]); |
| 264 if (FilterSupportedVersions(server_supported_versions) |
| 265 .empty()) { |
247 continue; | 266 continue; |
248 } | 267 } |
249 // Add an entry for server and client supporting all | |
250 // versions. | |
251 params.push_back(TestParams( | 268 params.push_back(TestParams( |
252 client_versions, all_supported_versions, | 269 client_versions, server_supported_versions, |
253 client_versions.front(), | 270 server_supported_versions.front(), |
254 client_supports_stateless_rejects, | 271 client_supports_stateless_rejects, |
255 server_uses_stateless_rejects_if_peer_supported, | 272 server_uses_stateless_rejects_if_peer_supported, |
256 congestion_control_tag, disable_hpack_dynamic_table, | 273 congestion_control_tag, disable_hpack_dynamic_table, |
257 force_hol_blocking, use_cheap_stateless_reject, | 274 force_hol_blocking, use_cheap_stateless_reject, |
258 buffer_packet_till_chlo, small_client_mtu)); | 275 buffer_packet_till_chlo)); |
259 | 276 } // End of version for loop. |
260 // Run version negotiation tests tests with no options, or | 277 } // End of 2nd version for loop. |
261 // all the options enabled to avoid a combinatorial | |
262 // explosion. | |
263 if (enabled_options > 1 && | |
264 enabled_options < kMaxEnabledOptions) { | |
265 continue; | |
266 } | |
267 | |
268 // Test client supporting all versions and server supporting | |
269 // 1 version. Simulate an old server and exercise version | |
270 // downgrade in the client. Protocol negotiation should | |
271 // occur. Skip the i = 0 case because it is essentially the | |
272 // same as the default case. | |
273 for (size_t i = 1; i < client_versions.size(); ++i) { | |
274 QuicVersionVector server_supported_versions; | |
275 server_supported_versions.push_back(client_versions[i]); | |
276 if (FilterSupportedVersions(server_supported_versions) | |
277 .empty()) { | |
278 continue; | |
279 } | |
280 params.push_back(TestParams( | |
281 client_versions, server_supported_versions, | |
282 server_supported_versions.front(), | |
283 client_supports_stateless_rejects, | |
284 server_uses_stateless_rejects_if_peer_supported, | |
285 congestion_control_tag, disable_hpack_dynamic_table, | |
286 force_hol_blocking, use_cheap_stateless_reject, | |
287 buffer_packet_till_chlo, small_client_mtu)); | |
288 } // End of version for loop. | |
289 } // End of 2nd version for loop. | |
290 } // End of small_client_mtu loop. | |
291 } // End of buffer_packet_till_chlo loop. | 278 } // End of buffer_packet_till_chlo loop. |
292 } // End of use_cheap_stateless_reject for loop. | 279 } // End of use_cheap_stateless_reject for loop. |
293 } // End of force_hol_blocking loop. | 280 } // End of force_hol_blocking loop. |
294 } // End of disable_hpack_dynamic_table for loop. | 281 } // End of disable_hpack_dynamic_table for loop. |
295 } // End of congestion_control_tag for loop. | 282 } // End of congestion_control_tag for loop. |
296 } // End of client_supports_stateless_rejects for loop. | 283 } // End of client_supports_stateless_rejects for loop. |
297 CHECK_EQ(kMaxEnabledOptions, max_enabled_options); | 284 CHECK_EQ(kMaxEnabledOptions, max_enabled_options); |
298 } // End of server_uses_stateless_rejects_if_peer_supported for loop. | 285 } // End of server_uses_stateless_rejects_if_peer_supported for loop. |
299 return params; | 286 return params; |
300 } | 287 } |
301 | 288 |
302 class SmallMtuPacketReader : public QuicPacketReader { | |
303 public: | |
304 bool ReadAndDispatchPackets(int fd, | |
305 int port, | |
306 bool potentially_small_mtu, | |
307 const QuicClock& clock, | |
308 ProcessPacketInterface* processor, | |
309 QuicPacketCount* packets_dropped) override { | |
310 return QuicPacketReader::ReadAndDispatchPackets(fd, port, true, clock, | |
311 processor, packets_dropped); | |
312 } | |
313 }; | |
314 | |
315 class ServerDelegate : public PacketDroppingTestWriter::Delegate { | 289 class ServerDelegate : public PacketDroppingTestWriter::Delegate { |
316 public: | 290 public: |
317 explicit ServerDelegate(QuicDispatcher* dispatcher) | 291 explicit ServerDelegate(QuicDispatcher* dispatcher) |
318 : dispatcher_(dispatcher) {} | 292 : dispatcher_(dispatcher) {} |
319 ~ServerDelegate() override {} | 293 ~ServerDelegate() override {} |
320 void OnCanWrite() override { dispatcher_->OnCanWrite(); } | 294 void OnCanWrite() override { dispatcher_->OnCanWrite(); } |
321 | 295 |
322 private: | 296 private: |
323 QuicDispatcher* dispatcher_; | 297 QuicDispatcher* dispatcher_; |
324 }; | 298 }; |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 void StartServer() { | 472 void StartServer() { |
499 FLAGS_quic_buffer_packet_till_chlo = GetParam().buffer_packet_till_chlo; | 473 FLAGS_quic_buffer_packet_till_chlo = GetParam().buffer_packet_till_chlo; |
500 FLAGS_quic_use_cheap_stateless_rejects = | 474 FLAGS_quic_use_cheap_stateless_rejects = |
501 GetParam().use_cheap_stateless_reject; | 475 GetParam().use_cheap_stateless_reject; |
502 if (!FLAGS_quic_buffer_packet_till_chlo) { | 476 if (!FLAGS_quic_buffer_packet_till_chlo) { |
503 FLAGS_quic_limit_num_new_sessions_per_epoll_loop = false; | 477 FLAGS_quic_limit_num_new_sessions_per_epoll_loop = false; |
504 } | 478 } |
505 auto test_server = | 479 auto test_server = |
506 new QuicTestServer(CryptoTestUtils::ProofSourceForTesting(), | 480 new QuicTestServer(CryptoTestUtils::ProofSourceForTesting(), |
507 server_config_, server_supported_versions_); | 481 server_config_, server_supported_versions_); |
508 if (GetParam().small_client_mtu) { | |
509 FLAGS_quic_enforce_mtu_limit = true; | |
510 QuicServerPeer::SetReader(test_server, new SmallMtuPacketReader); | |
511 server_writer_->set_max_allowed_packet_size(kMinimumSupportedPacketSize); | |
512 } | |
513 server_thread_.reset(new ServerThread(test_server, server_address_, | 482 server_thread_.reset(new ServerThread(test_server, server_address_, |
514 strike_register_no_startup_period_)); | 483 strike_register_no_startup_period_)); |
515 if (chlo_multiplier_ != 0) { | 484 if (chlo_multiplier_ != 0) { |
516 server_thread_->server()->SetChloMultiplier(chlo_multiplier_); | 485 server_thread_->server()->SetChloMultiplier(chlo_multiplier_); |
517 } | 486 } |
518 server_thread_->Initialize(); | 487 server_thread_->Initialize(); |
519 server_address_ = | 488 server_address_ = |
520 IPEndPoint(server_address_.address(), server_thread_->GetPort()); | 489 IPEndPoint(server_address_.address(), server_thread_->GetPort()); |
521 QuicDispatcher* dispatcher = | 490 QuicDispatcher* dispatcher = |
522 QuicServerPeer::GetDispatcher(server_thread_->server()); | 491 QuicServerPeer::GetDispatcher(server_thread_->server()); |
(...skipping 2432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2955 // Send a request before handshake finishes. | 2924 // Send a request before handshake finishes. |
2956 HTTPMessage request(HttpConstants::HTTP_1_1, HttpConstants::GET, "/bar"); | 2925 HTTPMessage request(HttpConstants::HTTP_1_1, HttpConstants::GET, "/bar"); |
2957 client_->SendMessage(request); | 2926 client_->SendMessage(request); |
2958 client_->WaitForResponse(); | 2927 client_->WaitForResponse(); |
2959 EXPECT_EQ(kBarResponseBody, client_->response_body()); | 2928 EXPECT_EQ(kBarResponseBody, client_->response_body()); |
2960 QuicConnectionStats client_stats = | 2929 QuicConnectionStats client_stats = |
2961 client_->client()->session()->connection()->GetStats(); | 2930 client_->client()->session()->connection()->GetStats(); |
2962 EXPECT_EQ(0u, client_stats.packets_lost); | 2931 EXPECT_EQ(0u, client_stats.packets_lost); |
2963 EXPECT_EQ(1, client_->client()->GetNumSentClientHellos()); | 2932 EXPECT_EQ(1, client_->client()->GetNumSentClientHellos()); |
2964 } | 2933 } |
2965 | |
2966 } // namespace | 2934 } // namespace |
2967 } // namespace test | 2935 } // namespace test |
2968 } // namespace net | 2936 } // namespace net |
OLD | NEW |