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 { |
| 365 LOG_IF(DFATAL, !has_send_values_) << "No send values to get for tag:" << tag_; |
| 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; |
| 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 |