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/quic_config.h" | 5 #include "net/quic/quic_config.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "net/quic/crypto/crypto_handshake_message.h" | 10 #include "net/quic/crypto/crypto_handshake_message.h" |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
122 QuicNegotiableTag::QuicNegotiableTag(QuicTag tag, QuicConfigPresence presence) | 122 QuicNegotiableTag::QuicNegotiableTag(QuicTag tag, QuicConfigPresence presence) |
123 : QuicNegotiableValue(tag, presence), | 123 : QuicNegotiableValue(tag, presence), |
124 negotiated_tag_(0), | 124 negotiated_tag_(0), |
125 default_value_(0) { | 125 default_value_(0) { |
126 } | 126 } |
127 | 127 |
128 QuicNegotiableTag::~QuicNegotiableTag() {} | 128 QuicNegotiableTag::~QuicNegotiableTag() {} |
129 | 129 |
130 void QuicNegotiableTag::set(const QuicTagVector& possible, | 130 void QuicNegotiableTag::set(const QuicTagVector& possible, |
131 QuicTag default_value) { | 131 QuicTag default_value) { |
132 DCHECK(std::find(possible.begin(), possible.end(), default_value) != | 132 DCHECK(ContainsQuicTag(possible, default_value)); |
133 possible.end()); | |
134 possible_values_ = possible; | 133 possible_values_ = possible; |
135 default_value_ = default_value; | 134 default_value_ = default_value; |
136 } | 135 } |
137 | 136 |
138 QuicTag QuicNegotiableTag::GetTag() const { | 137 QuicTag QuicNegotiableTag::GetTag() const { |
139 if (negotiated_) { | 138 if (negotiated_) { |
140 return negotiated_tag_; | 139 return negotiated_tag_; |
141 } | 140 } |
142 return default_value_; | 141 return default_value_; |
143 } | 142 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
187 const QuicTag* received_tags; | 186 const QuicTag* received_tags; |
188 size_t received_tags_length; | 187 size_t received_tags_length; |
189 QuicErrorCode error = ReadVector(peer_hello, &received_tags, | 188 QuicErrorCode error = ReadVector(peer_hello, &received_tags, |
190 &received_tags_length, error_details); | 189 &received_tags_length, error_details); |
191 if (error != QUIC_NO_ERROR) { | 190 if (error != QUIC_NO_ERROR) { |
192 return error; | 191 return error; |
193 } | 192 } |
194 | 193 |
195 if (hello_type == SERVER) { | 194 if (hello_type == SERVER) { |
196 if (received_tags_length != 1 || | 195 if (received_tags_length != 1 || |
197 std::find(possible_values_.begin(), possible_values_.end(), | 196 !ContainsQuicTag(possible_values_, *received_tags)) { |
198 *received_tags) == possible_values_.end()) { | |
199 *error_details = "Invalid " + QuicUtils::TagToString(tag_); | 197 *error_details = "Invalid " + QuicUtils::TagToString(tag_); |
200 return QUIC_INVALID_NEGOTIATED_VALUE; | 198 return QUIC_INVALID_NEGOTIATED_VALUE; |
201 } | 199 } |
202 negotiated_tag_ = *received_tags; | 200 negotiated_tag_ = *received_tags; |
203 } else { | 201 } else { |
204 QuicTag negotiated_tag; | 202 QuicTag negotiated_tag; |
205 if (!QuicUtils::FindMutualTag(possible_values_, | 203 if (!QuicUtils::FindMutualTag(possible_values_, |
206 received_tags, | 204 received_tags, |
207 received_tags_length, | 205 received_tags_length, |
208 QuicUtils::LOCAL_PRIORITY, | 206 QuicUtils::LOCAL_PRIORITY, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
261 } | 259 } |
262 | 260 |
263 QuicErrorCode QuicFixedUint32::ProcessPeerHello( | 261 QuicErrorCode QuicFixedUint32::ProcessPeerHello( |
264 const CryptoHandshakeMessage& peer_hello, | 262 const CryptoHandshakeMessage& peer_hello, |
265 HelloType hello_type, | 263 HelloType hello_type, |
266 string* error_details) { | 264 string* error_details) { |
267 DCHECK(error_details != NULL); | 265 DCHECK(error_details != NULL); |
268 QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value_); | 266 QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value_); |
269 switch (error) { | 267 switch (error) { |
270 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: | 268 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: |
271 if (presence_ == PRESENCE_REQUIRED) { | 269 if (presence_ == PRESENCE_OPTIONAL) { |
272 *error_details = "Missing " + QuicUtils::TagToString(tag_); | 270 return QUIC_NO_ERROR; |
273 break; | |
274 } | 271 } |
275 error = QUIC_NO_ERROR; | 272 *error_details = "Missing " + QuicUtils::TagToString(tag_); |
276 break; | 273 break; |
277 case QUIC_NO_ERROR: | 274 case QUIC_NO_ERROR: |
278 has_receive_value_ = true; | 275 has_receive_value_ = true; |
279 break; | 276 break; |
280 default: | 277 default: |
281 *error_details = "Bad " + QuicUtils::TagToString(tag_); | 278 *error_details = "Bad " + QuicUtils::TagToString(tag_); |
282 break; | 279 break; |
283 } | 280 } |
284 return error; | 281 return error; |
285 } | 282 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
322 receive_value_ = value; | 319 receive_value_ = value; |
323 } | 320 } |
324 | 321 |
325 void QuicFixedTag::ToHandshakeMessage(CryptoHandshakeMessage* out) const { | 322 void QuicFixedTag::ToHandshakeMessage(CryptoHandshakeMessage* out) const { |
326 if (has_send_value_) { | 323 if (has_send_value_) { |
327 out->SetValue(tag_, send_value_); | 324 out->SetValue(tag_, send_value_); |
328 } | 325 } |
329 } | 326 } |
330 | 327 |
331 QuicErrorCode QuicFixedTag::ProcessPeerHello( | 328 QuicErrorCode QuicFixedTag::ProcessPeerHello( |
332 const CryptoHandshakeMessage& client_hello, | 329 const CryptoHandshakeMessage& peer_hello, |
333 HelloType hello_type, | 330 HelloType hello_type, |
334 string* error_details) { | 331 string* error_details) { |
335 DCHECK(error_details != NULL); | 332 DCHECK(error_details != NULL); |
336 QuicErrorCode error = client_hello.GetUint32(tag_, &receive_value_); | 333 QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value_); |
337 switch (error) { | 334 switch (error) { |
338 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: | 335 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: |
339 if (presence_ == PRESENCE_REQUIRED) { | 336 if (presence_ == PRESENCE_OPTIONAL) { |
340 *error_details = "Missing " + QuicUtils::TagToString(tag_); | 337 return QUIC_NO_ERROR; |
341 break; | |
342 } | 338 } |
343 error = QUIC_NO_ERROR; | 339 *error_details = "Missing " + QuicUtils::TagToString(tag_); |
344 break; | 340 break; |
345 case QUIC_NO_ERROR: | 341 case QUIC_NO_ERROR: |
346 has_receive_value_ = true; | 342 has_receive_value_ = true; |
347 break; | 343 break; |
348 default: | 344 default: |
349 *error_details = "Bad " + QuicUtils::TagToString(tag_); | 345 *error_details = "Bad " + QuicUtils::TagToString(tag_); |
350 break; | 346 break; |
351 } | 347 } |
352 return error; | 348 return error; |
353 } | 349 } |
354 | 350 |
351 QuicFixedTagVector::QuicFixedTagVector(QuicTag name, | |
352 QuicConfigPresence presence) | |
353 : QuicConfigValue(name, presence), | |
354 has_send_values_(false), | |
355 has_receive_values_(false) { | |
356 } | |
357 | |
358 QuicFixedTagVector::~QuicFixedTagVector() {} | |
359 | |
360 bool QuicFixedTagVector::HasSendValues() const { | |
361 return has_send_values_; | |
362 } | |
363 | |
364 QuicTagVector QuicFixedTagVector::GetSendValues() const { | |
wtc
2014/06/03 02:00:53
Another design is to make the getter method return
Ian Swett
2014/06/03 13:31:29
I prefer get methods which have return values, but
| |
365 LOG_IF(DFATAL, !has_send_values_) << "No send values to get for tag:" << tag_; | |
wtc
2014/06/03 02:00:53
This check seems too strict. If presence_ == PRESE
Ian Swett
2014/06/03 13:31:29
The contract is that you should never call GetSend
| |
366 return send_values_; | |
367 } | |
368 | |
369 void QuicFixedTagVector::SetSendValues(const QuicTagVector& values) { | |
370 has_send_values_ = true; | |
371 send_values_ = values; | |
372 } | |
373 | |
374 bool QuicFixedTagVector::HasReceivedValues() const { | |
375 return has_receive_values_; | |
376 } | |
377 | |
378 QuicTagVector QuicFixedTagVector::GetReceivedValues() const { | |
379 LOG_IF(DFATAL, !has_receive_values_) | |
380 << "No receive value to get for tag:" << tag_; | |
381 return receive_values_; | |
382 } | |
383 | |
384 void QuicFixedTagVector::SetReceivedValues(const QuicTagVector& values) { | |
385 has_receive_values_ = true; | |
386 receive_values_ = values; | |
387 } | |
388 | |
389 void QuicFixedTagVector::ToHandshakeMessage(CryptoHandshakeMessage* out) const { | |
390 if (has_send_values_) { | |
391 out->SetVector(tag_, send_values_); | |
392 } | |
393 } | |
394 | |
395 QuicErrorCode QuicFixedTagVector::ProcessPeerHello( | |
396 const CryptoHandshakeMessage& peer_hello, | |
397 HelloType hello_type, | |
398 string* error_details) { | |
399 DCHECK(error_details != NULL); | |
400 const QuicTag* received_tags; | |
401 size_t received_tags_length; | |
402 QuicErrorCode error = | |
403 peer_hello.GetTaglist(tag_, &received_tags, &received_tags_length); | |
404 switch (error) { | |
405 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: | |
406 if (presence_ == PRESENCE_OPTIONAL) { | |
407 return QUIC_NO_ERROR; | |
408 } | |
409 *error_details = "Missing " + QuicUtils::TagToString(tag_); | |
410 break; | |
411 case QUIC_NO_ERROR: | |
412 has_receive_values_ = true; | |
wtc
2014/06/03 02:00:53
Nit: should we do receive_values_.clear() first?
Ian Swett
2014/06/03 13:31:29
We could, though we never process the same tag twi
| |
413 for (size_t i = 0; i < received_tags_length; ++i) { | |
414 receive_values_.push_back(received_tags[i]); | |
415 } | |
416 break; | |
417 default: | |
418 *error_details = "Bad " + QuicUtils::TagToString(tag_); | |
419 break; | |
420 } | |
421 return error; | |
422 } | |
423 | |
355 QuicConfig::QuicConfig() | 424 QuicConfig::QuicConfig() |
356 : congestion_control_(kCGST, PRESENCE_REQUIRED), | 425 : congestion_feedback_(kCGST, PRESENCE_REQUIRED), |
426 congestion_options_(kCOPT, PRESENCE_OPTIONAL), | |
357 loss_detection_(kLOSS, PRESENCE_OPTIONAL), | 427 loss_detection_(kLOSS, PRESENCE_OPTIONAL), |
358 idle_connection_state_lifetime_seconds_(kICSL, PRESENCE_REQUIRED), | 428 idle_connection_state_lifetime_seconds_(kICSL, PRESENCE_REQUIRED), |
359 keepalive_timeout_seconds_(kKATO, PRESENCE_OPTIONAL), | 429 keepalive_timeout_seconds_(kKATO, PRESENCE_OPTIONAL), |
360 max_streams_per_connection_(kMSPC, PRESENCE_REQUIRED), | 430 max_streams_per_connection_(kMSPC, PRESENCE_REQUIRED), |
361 max_time_before_crypto_handshake_(QuicTime::Delta::Zero()), | 431 max_time_before_crypto_handshake_(QuicTime::Delta::Zero()), |
362 initial_congestion_window_(kSWND, PRESENCE_OPTIONAL), | 432 initial_congestion_window_(kSWND, PRESENCE_OPTIONAL), |
363 initial_round_trip_time_us_(kIRTT, PRESENCE_OPTIONAL), | 433 initial_round_trip_time_us_(kIRTT, PRESENCE_OPTIONAL), |
364 // TODO(rjshade): Make this PRESENCE_REQUIRED when retiring | 434 // TODO(rjshade): Make this PRESENCE_REQUIRED when retiring |
365 // QUIC_VERSION_17. | 435 // QUIC_VERSION_17. |
366 initial_flow_control_window_bytes_(kIFCW, PRESENCE_OPTIONAL) { | 436 initial_flow_control_window_bytes_(kIFCW, PRESENCE_OPTIONAL) { |
367 } | 437 } |
368 | 438 |
369 QuicConfig::~QuicConfig() {} | 439 QuicConfig::~QuicConfig() {} |
370 | 440 |
371 void QuicConfig::set_congestion_control( | 441 void QuicConfig::set_congestion_feedback( |
372 const QuicTagVector& congestion_control, | 442 const QuicTagVector& congestion_feedback, |
373 QuicTag default_congestion_control) { | 443 QuicTag default_congestion_feedback) { |
374 congestion_control_.set(congestion_control, default_congestion_control); | 444 congestion_feedback_.set(congestion_feedback, default_congestion_feedback); |
375 } | 445 } |
376 | 446 |
377 QuicTag QuicConfig::congestion_control() const { | 447 QuicTag QuicConfig::congestion_feedback() const { |
378 return congestion_control_.GetTag(); | 448 return congestion_feedback_.GetTag(); |
449 } | |
450 | |
451 void QuicConfig::SetCongestionOptionsToSend( | |
452 const QuicTagVector& congestion_options) { | |
453 congestion_options_.SetSendValues(congestion_options); | |
454 } | |
455 | |
456 bool QuicConfig::HasReceivedCongestionOptions() const { | |
457 return congestion_options_.HasReceivedValues(); | |
458 } | |
459 | |
460 QuicTagVector QuicConfig::ReceivedCongestionOptions() const { | |
461 return congestion_options_.GetReceivedValues(); | |
379 } | 462 } |
380 | 463 |
381 void QuicConfig::SetLossDetectionToSend(QuicTag loss_detection) { | 464 void QuicConfig::SetLossDetectionToSend(QuicTag loss_detection) { |
382 loss_detection_.SetSendValue(loss_detection); | 465 loss_detection_.SetSendValue(loss_detection); |
383 } | 466 } |
384 | 467 |
385 bool QuicConfig::HasReceivedLossDetection() const { | 468 bool QuicConfig::HasReceivedLossDetection() const { |
386 return loss_detection_.HasReceivedValue(); | 469 return loss_detection_.HasReceivedValue(); |
387 } | 470 } |
388 | 471 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
459 } | 542 } |
460 | 543 |
461 uint32 QuicConfig::ReceivedInitialFlowControlWindowBytes() const { | 544 uint32 QuicConfig::ReceivedInitialFlowControlWindowBytes() const { |
462 return initial_flow_control_window_bytes_.GetReceivedValue(); | 545 return initial_flow_control_window_bytes_.GetReceivedValue(); |
463 } | 546 } |
464 | 547 |
465 bool QuicConfig::negotiated() { | 548 bool QuicConfig::negotiated() { |
466 // TODO(ianswett): Add the negotiated parameters once and iterate over all | 549 // TODO(ianswett): Add the negotiated parameters once and iterate over all |
467 // of them in negotiated, ToHandshakeMessage, ProcessClientHello, and | 550 // of them in negotiated, ToHandshakeMessage, ProcessClientHello, and |
468 // ProcessServerHello. | 551 // ProcessServerHello. |
469 return congestion_control_.negotiated() && | 552 return congestion_feedback_.negotiated() && |
470 idle_connection_state_lifetime_seconds_.negotiated() && | 553 idle_connection_state_lifetime_seconds_.negotiated() && |
471 keepalive_timeout_seconds_.negotiated() && | 554 keepalive_timeout_seconds_.negotiated() && |
472 max_streams_per_connection_.negotiated(); | 555 max_streams_per_connection_.negotiated(); |
473 } | 556 } |
474 | 557 |
475 void QuicConfig::SetDefaults() { | 558 void QuicConfig::SetDefaults() { |
476 QuicTagVector congestion_control; | 559 QuicTagVector congestion_feedback; |
477 if (FLAGS_enable_quic_pacing) { | 560 if (FLAGS_enable_quic_pacing) { |
478 congestion_control.push_back(kPACE); | 561 congestion_feedback.push_back(kPACE); |
479 } | 562 } |
480 congestion_control.push_back(kQBIC); | 563 congestion_feedback.push_back(kQBIC); |
481 congestion_control_.set(congestion_control, kQBIC); | 564 congestion_feedback_.set(congestion_feedback, kQBIC); |
482 idle_connection_state_lifetime_seconds_.set(kDefaultTimeoutSecs, | 565 idle_connection_state_lifetime_seconds_.set(kDefaultTimeoutSecs, |
483 kDefaultInitialTimeoutSecs); | 566 kDefaultInitialTimeoutSecs); |
484 // kKATO is optional. Return 0 if not negotiated. | 567 // kKATO is optional. Return 0 if not negotiated. |
485 keepalive_timeout_seconds_.set(0, 0); | 568 keepalive_timeout_seconds_.set(0, 0); |
486 max_streams_per_connection_.set(kDefaultMaxStreamsPerConnection, | 569 max_streams_per_connection_.set(kDefaultMaxStreamsPerConnection, |
487 kDefaultMaxStreamsPerConnection); | 570 kDefaultMaxStreamsPerConnection); |
488 max_time_before_crypto_handshake_ = QuicTime::Delta::FromSeconds( | 571 max_time_before_crypto_handshake_ = QuicTime::Delta::FromSeconds( |
489 kDefaultMaxTimeForCryptoHandshakeSecs); | 572 kDefaultMaxTimeForCryptoHandshakeSecs); |
490 } | 573 } |
491 | 574 |
492 void QuicConfig::EnablePacing(bool enable_pacing) { | 575 void QuicConfig::EnablePacing(bool enable_pacing) { |
493 QuicTagVector congestion_control; | 576 QuicTagVector congestion_feedback; |
494 if (enable_pacing) { | 577 if (enable_pacing) { |
495 congestion_control.push_back(kPACE); | 578 congestion_feedback.push_back(kPACE); |
496 } | 579 } |
497 congestion_control.push_back(kQBIC); | 580 congestion_feedback.push_back(kQBIC); |
498 congestion_control_.set(congestion_control, kQBIC); | 581 congestion_feedback_.set(congestion_feedback, kQBIC); |
499 } | 582 } |
500 | 583 |
501 void QuicConfig::ToHandshakeMessage(CryptoHandshakeMessage* out) const { | 584 void QuicConfig::ToHandshakeMessage(CryptoHandshakeMessage* out) const { |
502 congestion_control_.ToHandshakeMessage(out); | 585 congestion_feedback_.ToHandshakeMessage(out); |
503 idle_connection_state_lifetime_seconds_.ToHandshakeMessage(out); | 586 idle_connection_state_lifetime_seconds_.ToHandshakeMessage(out); |
504 keepalive_timeout_seconds_.ToHandshakeMessage(out); | 587 keepalive_timeout_seconds_.ToHandshakeMessage(out); |
505 max_streams_per_connection_.ToHandshakeMessage(out); | 588 max_streams_per_connection_.ToHandshakeMessage(out); |
506 initial_congestion_window_.ToHandshakeMessage(out); | 589 initial_congestion_window_.ToHandshakeMessage(out); |
507 initial_round_trip_time_us_.ToHandshakeMessage(out); | 590 initial_round_trip_time_us_.ToHandshakeMessage(out); |
508 loss_detection_.ToHandshakeMessage(out); | 591 loss_detection_.ToHandshakeMessage(out); |
509 initial_flow_control_window_bytes_.ToHandshakeMessage(out); | 592 initial_flow_control_window_bytes_.ToHandshakeMessage(out); |
593 congestion_options_.ToHandshakeMessage(out); | |
510 } | 594 } |
511 | 595 |
512 QuicErrorCode QuicConfig::ProcessPeerHello( | 596 QuicErrorCode QuicConfig::ProcessPeerHello( |
513 const CryptoHandshakeMessage& peer_hello, | 597 const CryptoHandshakeMessage& peer_hello, |
514 HelloType hello_type, | 598 HelloType hello_type, |
515 string* error_details) { | 599 string* error_details) { |
516 DCHECK(error_details != NULL); | 600 DCHECK(error_details != NULL); |
517 | 601 |
518 QuicErrorCode error = QUIC_NO_ERROR; | 602 QuicErrorCode error = QUIC_NO_ERROR; |
519 if (error == QUIC_NO_ERROR) { | 603 if (error == QUIC_NO_ERROR) { |
520 error = congestion_control_.ProcessPeerHello( | 604 error = congestion_feedback_.ProcessPeerHello( |
521 peer_hello, hello_type, error_details); | 605 peer_hello, hello_type, error_details); |
522 } | 606 } |
523 if (error == QUIC_NO_ERROR) { | 607 if (error == QUIC_NO_ERROR) { |
524 error = idle_connection_state_lifetime_seconds_.ProcessPeerHello( | 608 error = idle_connection_state_lifetime_seconds_.ProcessPeerHello( |
525 peer_hello, hello_type, error_details); | 609 peer_hello, hello_type, error_details); |
526 } | 610 } |
527 if (error == QUIC_NO_ERROR) { | 611 if (error == QUIC_NO_ERROR) { |
528 error = keepalive_timeout_seconds_.ProcessPeerHello( | 612 error = keepalive_timeout_seconds_.ProcessPeerHello( |
529 peer_hello, hello_type, error_details); | 613 peer_hello, hello_type, error_details); |
530 } | 614 } |
(...skipping 10 matching lines...) Expand all Loading... | |
541 peer_hello, hello_type, error_details); | 625 peer_hello, hello_type, error_details); |
542 } | 626 } |
543 if (error == QUIC_NO_ERROR) { | 627 if (error == QUIC_NO_ERROR) { |
544 error = initial_flow_control_window_bytes_.ProcessPeerHello( | 628 error = initial_flow_control_window_bytes_.ProcessPeerHello( |
545 peer_hello, hello_type, error_details); | 629 peer_hello, hello_type, error_details); |
546 } | 630 } |
547 if (error == QUIC_NO_ERROR) { | 631 if (error == QUIC_NO_ERROR) { |
548 error = loss_detection_.ProcessPeerHello( | 632 error = loss_detection_.ProcessPeerHello( |
549 peer_hello, hello_type, error_details); | 633 peer_hello, hello_type, error_details); |
550 } | 634 } |
635 if (error == QUIC_NO_ERROR) { | |
636 error = congestion_options_.ProcessPeerHello( | |
637 peer_hello, hello_type, error_details); | |
638 } | |
551 return error; | 639 return error; |
552 } | 640 } |
553 | 641 |
554 } // namespace net | 642 } // namespace net |
OLD | NEW |