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 3 // found in the LICENSE file. 4 5 #include "net/quic/quic_config.h" 6 7 #include <algorithm> 8 9 #include "base/logging.h" 10 #include "net/quic/crypto/crypto_handshake_message.h" 11 #include "net/quic/crypto/crypto_protocol.h" 12 #include "net/quic/quic_flags.h" 13 #include "net/quic/quic_utils.h" 14 15 using std::min; 16 using std::string; 17 18 namespace net { 19 20 // Reads the value corresponding to |name_| from |msg| into |out|. If the 21 // |name_| is absent in |msg| and |presence| is set to OPTIONAL |out| is set 22 // to |default_value|. 23 QuicErrorCode ReadUint32(const CryptoHandshakeMessage& msg, 24 QuicTag tag, 25 QuicConfigPresence presence, 26 uint32 default_value, 27 uint32* out, 28 string* error_details) { 29 DCHECK(error_details != NULL); 30 QuicErrorCode error = msg.GetUint32(tag, out); 31 switch (error) { 32 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: 33 if (presence == PRESENCE_REQUIRED) { 34 *error_details = "Missing " + QuicUtils::TagToString(tag); 35 break; 36 } 37 error = QUIC_NO_ERROR; 38 *out = default_value; 39 break; 40 case QUIC_NO_ERROR: 41 break; 42 default: 43 *error_details = "Bad " + QuicUtils::TagToString(tag); 44 break; 45 } 46 return error; 47 } 48 49 50 QuicConfigValue::QuicConfigValue(QuicTag tag, 51 QuicConfigPresence presence) 52 : tag_(tag), 53 presence_(presence) { 54 } 55 QuicConfigValue::~QuicConfigValue() {} 56 57 QuicNegotiableValue::QuicNegotiableValue(QuicTag tag, 58 QuicConfigPresence presence) 59 : QuicConfigValue(tag, presence), 60 negotiated_(false) { 61 } 62 QuicNegotiableValue::~QuicNegotiableValue() {} 63 64 QuicNegotiableUint32::QuicNegotiableUint32(QuicTag tag, 65 QuicConfigPresence presence) 66 : QuicNegotiableValue(tag, presence), 67 max_value_(0), 68 default_value_(0) { 69 } 70 QuicNegotiableUint32::~QuicNegotiableUint32() {} 71 72 void QuicNegotiableUint32::set(uint32 max, uint32 default_value) { 73 DCHECK_LE(default_value, max); 74 max_value_ = max; 75 default_value_ = default_value; 76 } 77 78 uint32 QuicNegotiableUint32::GetUint32() const { 79 if (negotiated_) { 80 return negotiated_value_; 81 } 82 return default_value_; 83 } 84 85 void QuicNegotiableUint32::ToHandshakeMessage( 86 CryptoHandshakeMessage* out) const { 87 if (negotiated_) { 88 out->SetValue(tag_, negotiated_value_); 89 } else { 90 out->SetValue(tag_, max_value_); 91 } 92 } 93 94 QuicErrorCode QuicNegotiableUint32::ProcessPeerHello( 95 const CryptoHandshakeMessage& peer_hello, 96 HelloType hello_type, 97 string* error_details) { 98 DCHECK(!negotiated_); 99 DCHECK(error_details != NULL); 100 uint32 value; 101 QuicErrorCode error = ReadUint32(peer_hello, 102 tag_, 103 presence_, 104 default_value_, 105 &value, 106 error_details); 107 if (error != QUIC_NO_ERROR) { 108 return error; 109 } 110 if (hello_type == SERVER && value > max_value_) { 111 *error_details = 112 "Invalid value received for " + QuicUtils::TagToString(tag_); 113 return QUIC_INVALID_NEGOTIATED_VALUE; 114 } 115 116 negotiated_ = true; 117 negotiated_value_ = min(value, max_value_); 118 return QUIC_NO_ERROR; 119 } 120 121 QuicNegotiableTag::QuicNegotiableTag(QuicTag tag, QuicConfigPresence presence) 122 : QuicNegotiableValue(tag, presence), 123 negotiated_tag_(0), 124 default_value_(0) { 125 } 126 127 QuicNegotiableTag::~QuicNegotiableTag() {} 128 129 void QuicNegotiableTag::set(const QuicTagVector& possible, 130 QuicTag default_value) { 131 DCHECK(ContainsQuicTag(possible, default_value)); 132 possible_values_ = possible; 133 default_value_ = default_value; 134 } 135 136 QuicTag QuicNegotiableTag::GetTag() const { 137 if (negotiated_) { 138 return negotiated_tag_; 139 } 140 return default_value_; 141 } 142 143 void QuicNegotiableTag::ToHandshakeMessage(CryptoHandshakeMessage* out) const { 144 if (negotiated_) { 145 // Because of the way we serialize and parse handshake messages we can 146 // serialize this as value and still parse it as a vector. 147 out->SetValue(tag_, negotiated_tag_); 148 } else { 149 out->SetVector(tag_, possible_values_); 150 } 151 } 152 153 QuicErrorCode QuicNegotiableTag::ReadVector( 154 const CryptoHandshakeMessage& msg, 155 const QuicTag** out, 156 size_t* out_length, 157 string* error_details) const { 158 DCHECK(error_details != NULL); 159 QuicErrorCode error = msg.GetTaglist(tag_, out, out_length); 160 switch (error) { 161 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: 162 if (presence_ == PRESENCE_REQUIRED) { 163 *error_details = "Missing " + QuicUtils::TagToString(tag_); 164 break; 165 } 166 error = QUIC_NO_ERROR; 167 *out_length = 1; 168 *out = &default_value_; 169 170 case QUIC_NO_ERROR: 171 break; 172 default: 173 *error_details = "Bad " + QuicUtils::TagToString(tag_); 174 break; 175 } 176 return error; 177 } 178 179 QuicErrorCode QuicNegotiableTag::ProcessPeerHello( 180 const CryptoHandshakeMessage& peer_hello, 181 HelloType hello_type, 182 string* error_details) { 183 DCHECK(!negotiated_); 184 DCHECK(error_details != NULL); 185 const QuicTag* received_tags; 186 size_t received_tags_length; 187 QuicErrorCode error = ReadVector(peer_hello, &received_tags, 188 &received_tags_length, error_details); 189 if (error != QUIC_NO_ERROR) { 190 return error; 191 } 192 193 if (hello_type == SERVER) { 194 if (received_tags_length != 1 || 195 !ContainsQuicTag(possible_values_, *received_tags)) { 196 *error_details = "Invalid " + QuicUtils::TagToString(tag_); 197 return QUIC_INVALID_NEGOTIATED_VALUE; 198 } 199 negotiated_tag_ = *received_tags; 200 } else { 201 QuicTag negotiated_tag; 202 if (!QuicUtils::FindMutualTag(possible_values_, 203 received_tags, 204 received_tags_length, 205 QuicUtils::LOCAL_PRIORITY, 206 &negotiated_tag, 207 NULL)) { 208 *error_details = "Unsupported " + QuicUtils::TagToString(tag_); 209 return QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP; 210 } 211 negotiated_tag_ = negotiated_tag; 212 } 213 214 negotiated_ = true; 215 return QUIC_NO_ERROR; 216 } 217 218 QuicFixedUint32::QuicFixedUint32(QuicTag tag, QuicConfigPresence presence) 219 : QuicConfigValue(tag, presence), 220 has_send_value_(false), 221 has_receive_value_(false) { 222 } 223 QuicFixedUint32::~QuicFixedUint32() {} 224 225 bool QuicFixedUint32::HasSendValue() const { 226 return has_send_value_; 227 } 228 229 uint32 QuicFixedUint32::GetSendValue() const { 230 LOG_IF(DFATAL, !has_send_value_) 231 << "No send value to get for tag:" << QuicUtils::TagToString(tag_); 232 return send_value_; 233 } 234 235 void QuicFixedUint32::SetSendValue(uint32 value) { 236 has_send_value_ = true; 237 send_value_ = value; 238 } 239 240 bool QuicFixedUint32::HasReceivedValue() const { 241 return has_receive_value_; 242 } 243 244 uint32 QuicFixedUint32::GetReceivedValue() const { 245 LOG_IF(DFATAL, !has_receive_value_) 246 << "No receive value to get for tag:" << QuicUtils::TagToString(tag_); 247 return receive_value_; 248 } 249 250 void QuicFixedUint32::SetReceivedValue(uint32 value) { 251 has_receive_value_ = true; 252 receive_value_ = value; 253 } 254 255 void QuicFixedUint32::ToHandshakeMessage(CryptoHandshakeMessage* out) const { 256 if (has_send_value_) { 257 out->SetValue(tag_, send_value_); 258 } 259 } 260 261 QuicErrorCode QuicFixedUint32::ProcessPeerHello( 262 const CryptoHandshakeMessage& peer_hello, 263 HelloType hello_type, 264 string* error_details) { 265 DCHECK(error_details != NULL); 266 QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value_); 267 switch (error) { 268 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: 269 if (presence_ == PRESENCE_OPTIONAL) { 270 return QUIC_NO_ERROR; 271 } 272 *error_details = "Missing " + QuicUtils::TagToString(tag_); 273 break; 274 case QUIC_NO_ERROR: 275 has_receive_value_ = true; 276 break; 277 default: 278 *error_details = "Bad " + QuicUtils::TagToString(tag_); 279 break; 280 } 281 return error; 282 } 283 284 QuicFixedTag::QuicFixedTag(QuicTag name, 285 QuicConfigPresence presence) 286 : QuicConfigValue(name, presence), 287 has_send_value_(false), 288 has_receive_value_(false) { 289 } 290 291 QuicFixedTag::~QuicFixedTag() {} 292 293 bool QuicFixedTag::HasSendValue() const { 294 return has_send_value_; 295 } 296 297 uint32 QuicFixedTag::GetSendValue() const { 298 LOG_IF(DFATAL, !has_send_value_) 299 << "No send value to get for tag:" << QuicUtils::TagToString(tag_); 300 return send_value_; 301 } 302 303 void QuicFixedTag::SetSendValue(uint32 value) { 304 has_send_value_ = true; 305 send_value_ = value; 306 } 307 308 bool QuicFixedTag::HasReceivedValue() const { 309 return has_receive_value_; 310 } 311 312 uint32 QuicFixedTag::GetReceivedValue() const { 313 LOG_IF(DFATAL, !has_receive_value_) 314 << "No receive value to get for tag:" << QuicUtils::TagToString(tag_); 315 return receive_value_; 316 } 317 318 void QuicFixedTag::SetReceivedValue(uint32 value) { 319 has_receive_value_ = true; 320 receive_value_ = value; 321 } 322 323 void QuicFixedTag::ToHandshakeMessage(CryptoHandshakeMessage* out) const { 324 if (has_send_value_) { 325 out->SetValue(tag_, send_value_); 326 } 327 } 328 329 QuicErrorCode QuicFixedTag::ProcessPeerHello( 330 const CryptoHandshakeMessage& peer_hello, 331 HelloType hello_type, 332 string* error_details) { 333 DCHECK(error_details != NULL); 334 QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value_); 335 switch (error) { 336 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: 337 if (presence_ == PRESENCE_OPTIONAL) { 338 return QUIC_NO_ERROR; 339 } 340 *error_details = "Missing " + QuicUtils::TagToString(tag_); 341 break; 342 case QUIC_NO_ERROR: 343 has_receive_value_ = true; 344 break; 345 default: 346 *error_details = "Bad " + QuicUtils::TagToString(tag_); 347 break; 348 } 349 return error; 350 } 351 352 QuicFixedTagVector::QuicFixedTagVector(QuicTag name, 353 QuicConfigPresence presence) 354 : QuicConfigValue(name, presence), 355 has_send_values_(false), 356 has_receive_values_(false) { 357 } 358 359 QuicFixedTagVector::~QuicFixedTagVector() {} 360 361 bool QuicFixedTagVector::HasSendValues() const { 362 return has_send_values_; 363 } 364 365 QuicTagVector QuicFixedTagVector::GetSendValues() const { 366 LOG_IF(DFATAL, !has_send_values_) 367 << "No send values to get for tag:" << QuicUtils::TagToString(tag_); 368 return send_values_; 369 } 370 371 void QuicFixedTagVector::SetSendValues(const QuicTagVector& values) { 372 has_send_values_ = true; 373 send_values_ = values; 374 } 375 376 bool QuicFixedTagVector::HasReceivedValues() const { 377 return has_receive_values_; 378 } 379 380 QuicTagVector QuicFixedTagVector::GetReceivedValues() const { 381 LOG_IF(DFATAL, !has_receive_values_) 382 << "No receive value to get for tag:" << QuicUtils::TagToString(tag_); 383 return receive_values_; 384 } 385 386 void QuicFixedTagVector::SetReceivedValues(const QuicTagVector& values) { 387 has_receive_values_ = true; 388 receive_values_ = values; 389 } 390 391 void QuicFixedTagVector::ToHandshakeMessage(CryptoHandshakeMessage* out) const { 392 if (has_send_values_) { 393 out->SetVector(tag_, send_values_); 394 } 395 } 396 397 QuicErrorCode QuicFixedTagVector::ProcessPeerHello( 398 const CryptoHandshakeMessage& peer_hello, 399 HelloType hello_type, 400 string* error_details) { 401 DCHECK(error_details != NULL); 402 const QuicTag* received_tags; 403 size_t received_tags_length; 404 QuicErrorCode error = 405 peer_hello.GetTaglist(tag_, &received_tags, &received_tags_length); 406 switch (error) { 407 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: 408 if (presence_ == PRESENCE_OPTIONAL) { 409 return QUIC_NO_ERROR; 410 } 411 *error_details = "Missing " + QuicUtils::TagToString(tag_); 412 break; 413 case QUIC_NO_ERROR: 414 DVLOG(1) << "Received Connection Option tags from receiver."; 415 has_receive_values_ = true; 416 for (size_t i = 0; i < received_tags_length; ++i) { 417 receive_values_.push_back(received_tags[i]); 418 } 419 break; 420 default: 421 *error_details = "Bad " + QuicUtils::TagToString(tag_); 422 break; 423 } 424 return error; 425 } 426 427 QuicConfig::QuicConfig() 428 : congestion_feedback_(kCGST, PRESENCE_REQUIRED), 429 connection_options_(kCOPT, PRESENCE_OPTIONAL), 430 loss_detection_(kLOSS, PRESENCE_OPTIONAL), 431 idle_connection_state_lifetime_seconds_(kICSL, PRESENCE_REQUIRED), 432 keepalive_timeout_seconds_(kKATO, PRESENCE_OPTIONAL), 433 max_streams_per_connection_(kMSPC, PRESENCE_REQUIRED), 434 max_time_before_crypto_handshake_(QuicTime::Delta::Zero()), 435 initial_congestion_window_(kSWND, PRESENCE_OPTIONAL), 436 initial_round_trip_time_us_(kIRTT, PRESENCE_OPTIONAL), 437 // TODO(rjshade): Make this PRESENCE_REQUIRED when QUIC_VERSION_16 is 438 // retired. 439 initial_flow_control_window_bytes_(kIFCW, PRESENCE_OPTIONAL), 440 // TODO(rjshade): Make this PRESENCE_REQUIRED when retiring 441 // QUIC_VERSION_19. 442 initial_stream_flow_control_window_bytes_(kSFCW, PRESENCE_OPTIONAL), 443 // TODO(rjshade): Make this PRESENCE_REQUIRED when retiring 444 // QUIC_VERSION_19. 445 initial_session_flow_control_window_bytes_(kCFCW, PRESENCE_OPTIONAL), 446 socket_receive_buffer_(kSRBF, PRESENCE_OPTIONAL) { 447 } 448 449 QuicConfig::~QuicConfig() {} 450 451 void QuicConfig::set_congestion_feedback( 452 const QuicTagVector& congestion_feedback, 453 QuicTag default_congestion_feedback) { 454 congestion_feedback_.set(congestion_feedback, default_congestion_feedback); 455 } 456 457 QuicTag QuicConfig::congestion_feedback() const { 458 return congestion_feedback_.GetTag(); 459 } 460 461 void QuicConfig::SetConnectionOptionsToSend( 462 const QuicTagVector& connection_options) { 463 connection_options_.SetSendValues(connection_options); 464 } 465 466 bool QuicConfig::HasReceivedConnectionOptions() const { 467 return connection_options_.HasReceivedValues(); 468 } 469 470 QuicTagVector QuicConfig::ReceivedConnectionOptions() const { 471 return connection_options_.GetReceivedValues(); 472 } 473 474 bool QuicConfig::HasSendConnectionOptions() const { 475 return connection_options_.HasSendValues(); 476 } 477 478 QuicTagVector QuicConfig::SendConnectionOptions() const { 479 return connection_options_.GetSendValues(); 480 } 481 482 void QuicConfig::SetLossDetectionToSend(QuicTag loss_detection) { 483 loss_detection_.SetSendValue(loss_detection); 484 } 485 486 bool QuicConfig::HasReceivedLossDetection() const { 487 return loss_detection_.HasReceivedValue(); 488 } 489 490 QuicTag QuicConfig::ReceivedLossDetection() const { 491 return loss_detection_.GetReceivedValue(); 492 } 493 494 void QuicConfig::set_idle_connection_state_lifetime( 495 QuicTime::Delta max_idle_connection_state_lifetime, 496 QuicTime::Delta default_idle_conection_state_lifetime) { 497 idle_connection_state_lifetime_seconds_.set( 498 max_idle_connection_state_lifetime.ToSeconds(), 499 default_idle_conection_state_lifetime.ToSeconds()); 500 } 501 502 QuicTime::Delta QuicConfig::idle_connection_state_lifetime() const { 503 return QuicTime::Delta::FromSeconds( 504 idle_connection_state_lifetime_seconds_.GetUint32()); 505 } 506 507 QuicTime::Delta QuicConfig::keepalive_timeout() const { 508 return QuicTime::Delta::FromSeconds( 509 keepalive_timeout_seconds_.GetUint32()); 510 } 511 512 void QuicConfig::set_max_streams_per_connection(size_t max_streams, 513 size_t default_streams) { 514 max_streams_per_connection_.set(max_streams, default_streams); 515 } 516 517 uint32 QuicConfig::max_streams_per_connection() const { 518 return max_streams_per_connection_.GetUint32(); 519 } 520 521 void QuicConfig::set_max_time_before_crypto_handshake( 522 QuicTime::Delta max_time_before_crypto_handshake) { 523 max_time_before_crypto_handshake_ = max_time_before_crypto_handshake; 524 } 525 526 QuicTime::Delta QuicConfig::max_time_before_crypto_handshake() const { 527 return max_time_before_crypto_handshake_; 528 } 529 530 void QuicConfig::SetInitialCongestionWindowToSend(size_t initial_window) { 531 initial_congestion_window_.SetSendValue(initial_window); 532 } 533 534 bool QuicConfig::HasReceivedInitialCongestionWindow() const { 535 return initial_congestion_window_.HasReceivedValue(); 536 } 537 538 uint32 QuicConfig::ReceivedInitialCongestionWindow() const { 539 return initial_congestion_window_.GetReceivedValue(); 540 } 541 542 void QuicConfig::SetInitialRoundTripTimeUsToSend(size_t rtt) { 543 initial_round_trip_time_us_.SetSendValue(rtt); 544 } 545 546 bool QuicConfig::HasReceivedInitialRoundTripTimeUs() const { 547 return initial_round_trip_time_us_.HasReceivedValue(); 548 } 549 550 uint32 QuicConfig::ReceivedInitialRoundTripTimeUs() const { 551 return initial_round_trip_time_us_.GetReceivedValue(); 552 } 553 554 bool QuicConfig::HasInitialRoundTripTimeUsToSend() const { 555 return initial_round_trip_time_us_.HasSendValue(); 556 } 557 558 uint32 QuicConfig::GetInitialRoundTripTimeUsToSend() const { 559 return initial_round_trip_time_us_.GetSendValue(); 560 } 561 562 void QuicConfig::SetInitialFlowControlWindowToSend(uint32 window_bytes) { 563 if (window_bytes < kDefaultFlowControlSendWindow) { 564 LOG(DFATAL) << "Initial flow control receive window (" << window_bytes 565 << ") cannot be set lower than default (" 566 << kDefaultFlowControlSendWindow << ")."; 567 window_bytes = kDefaultFlowControlSendWindow; 568 } 569 initial_flow_control_window_bytes_.SetSendValue(window_bytes); 570 } 571 572 uint32 QuicConfig::GetInitialFlowControlWindowToSend() const { 573 return initial_flow_control_window_bytes_.GetSendValue(); 574 } 575 576 bool QuicConfig::HasReceivedInitialFlowControlWindowBytes() const { 577 return initial_flow_control_window_bytes_.HasReceivedValue(); 578 } 579 580 uint32 QuicConfig::ReceivedInitialFlowControlWindowBytes() const { 581 return initial_flow_control_window_bytes_.GetReceivedValue(); 582 } 583 584 void QuicConfig::SetInitialStreamFlowControlWindowToSend(uint32 window_bytes) { 585 if (window_bytes < kDefaultFlowControlSendWindow) { 586 LOG(DFATAL) << "Initial stream flow control receive window (" 587 << window_bytes << ") cannot be set lower than default (" 588 << kDefaultFlowControlSendWindow << ")."; 589 window_bytes = kDefaultFlowControlSendWindow; 590 } 591 initial_stream_flow_control_window_bytes_.SetSendValue(window_bytes); 592 } 593 594 uint32 QuicConfig::GetInitialStreamFlowControlWindowToSend() const { 595 return initial_stream_flow_control_window_bytes_.GetSendValue(); 596 } 597 598 bool QuicConfig::HasReceivedInitialStreamFlowControlWindowBytes() const { 599 return initial_stream_flow_control_window_bytes_.HasReceivedValue(); 600 } 601 602 uint32 QuicConfig::ReceivedInitialStreamFlowControlWindowBytes() const { 603 return initial_stream_flow_control_window_bytes_.GetReceivedValue(); 604 } 605 606 void QuicConfig::SetInitialSessionFlowControlWindowToSend(uint32 window_bytes) { 607 if (window_bytes < kDefaultFlowControlSendWindow) { 608 LOG(DFATAL) << "Initial session flow control receive window (" 609 << window_bytes << ") cannot be set lower than default (" 610 << kDefaultFlowControlSendWindow << ")."; 611 window_bytes = kDefaultFlowControlSendWindow; 612 } 613 initial_session_flow_control_window_bytes_.SetSendValue(window_bytes); 614 } 615 616 uint32 QuicConfig::GetInitialSessionFlowControlWindowToSend() const { 617 return initial_session_flow_control_window_bytes_.GetSendValue(); 618 } 619 620 bool QuicConfig::HasReceivedInitialSessionFlowControlWindowBytes() const { 621 return initial_session_flow_control_window_bytes_.HasReceivedValue(); 622 } 623 624 uint32 QuicConfig::ReceivedInitialSessionFlowControlWindowBytes() const { 625 return initial_session_flow_control_window_bytes_.GetReceivedValue(); 626 } 627 628 void QuicConfig::SetSocketReceiveBufferToSend(uint32 tcp_receive_window) { 629 socket_receive_buffer_.SetSendValue(tcp_receive_window); 630 } 631 632 uint32 QuicConfig::GetSocketReceiveBufferToSend() const { 633 return socket_receive_buffer_.GetSendValue(); 634 } 635 636 bool QuicConfig::HasReceivedSocketReceiveBuffer() const { 637 return socket_receive_buffer_.HasReceivedValue(); 638 } 639 640 uint32 QuicConfig::ReceivedSocketReceiveBuffer() const { 641 return socket_receive_buffer_.GetReceivedValue(); 642 } 643 644 bool QuicConfig::negotiated() { 645 // TODO(ianswett): Add the negotiated parameters once and iterate over all 646 // of them in negotiated, ToHandshakeMessage, ProcessClientHello, and 647 // ProcessServerHello. 648 return congestion_feedback_.negotiated() && 649 idle_connection_state_lifetime_seconds_.negotiated() && 650 keepalive_timeout_seconds_.negotiated() && 651 max_streams_per_connection_.negotiated(); 652 } 653 654 void QuicConfig::SetDefaults() { 655 QuicTagVector congestion_feedback; 656 congestion_feedback.push_back(kQBIC); 657 congestion_feedback_.set(congestion_feedback, kQBIC); 658 idle_connection_state_lifetime_seconds_.set(kMaximumIdleTimeoutSecs, 659 kDefaultInitialTimeoutSecs); 660 // kKATO is optional. Return 0 if not negotiated. 661 keepalive_timeout_seconds_.set(0, 0); 662 set_max_streams_per_connection(kDefaultMaxStreamsPerConnection, 663 kDefaultMaxStreamsPerConnection); 664 max_time_before_crypto_handshake_ = QuicTime::Delta::FromSeconds( 665 kDefaultMaxTimeForCryptoHandshakeSecs); 666 667 SetInitialFlowControlWindowToSend(kDefaultFlowControlSendWindow); 668 SetInitialStreamFlowControlWindowToSend(kDefaultFlowControlSendWindow); 669 SetInitialSessionFlowControlWindowToSend(kDefaultFlowControlSendWindow); 670 } 671 672 void QuicConfig::ToHandshakeMessage(CryptoHandshakeMessage* out) const { 673 congestion_feedback_.ToHandshakeMessage(out); 674 idle_connection_state_lifetime_seconds_.ToHandshakeMessage(out); 675 keepalive_timeout_seconds_.ToHandshakeMessage(out); 676 max_streams_per_connection_.ToHandshakeMessage(out); 677 initial_congestion_window_.ToHandshakeMessage(out); 678 initial_round_trip_time_us_.ToHandshakeMessage(out); 679 loss_detection_.ToHandshakeMessage(out); 680 initial_flow_control_window_bytes_.ToHandshakeMessage(out); 681 initial_stream_flow_control_window_bytes_.ToHandshakeMessage(out); 682 initial_session_flow_control_window_bytes_.ToHandshakeMessage(out); 683 socket_receive_buffer_.ToHandshakeMessage(out); 684 connection_options_.ToHandshakeMessage(out); 685 } 686 687 QuicErrorCode QuicConfig::ProcessPeerHello( 688 const CryptoHandshakeMessage& peer_hello, 689 HelloType hello_type, 690 string* error_details) { 691 DCHECK(error_details != NULL); 692 693 QuicErrorCode error = QUIC_NO_ERROR; 694 if (error == QUIC_NO_ERROR) { 695 error = congestion_feedback_.ProcessPeerHello( 696 peer_hello, hello_type, error_details); 697 } 698 if (error == QUIC_NO_ERROR) { 699 error = idle_connection_state_lifetime_seconds_.ProcessPeerHello( 700 peer_hello, hello_type, error_details); 701 } 702 if (error == QUIC_NO_ERROR) { 703 error = keepalive_timeout_seconds_.ProcessPeerHello( 704 peer_hello, hello_type, error_details); 705 } 706 if (error == QUIC_NO_ERROR) { 707 error = max_streams_per_connection_.ProcessPeerHello( 708 peer_hello, hello_type, error_details); 709 } 710 if (error == QUIC_NO_ERROR) { 711 error = initial_congestion_window_.ProcessPeerHello( 712 peer_hello, hello_type, error_details); 713 } 714 if (error == QUIC_NO_ERROR) { 715 error = initial_round_trip_time_us_.ProcessPeerHello( 716 peer_hello, hello_type, error_details); 717 } 718 if (error == QUIC_NO_ERROR) { 719 error = initial_flow_control_window_bytes_.ProcessPeerHello( 720 peer_hello, hello_type, error_details); 721 } 722 if (error == QUIC_NO_ERROR) { 723 error = initial_stream_flow_control_window_bytes_.ProcessPeerHello( 724 peer_hello, hello_type, error_details); 725 } 726 if (error == QUIC_NO_ERROR) { 727 error = initial_session_flow_control_window_bytes_.ProcessPeerHello( 728 peer_hello, hello_type, error_details); 729 } 730 if (error == QUIC_NO_ERROR) { 731 error = socket_receive_buffer_.ProcessPeerHello( 732 peer_hello, hello_type, error_details); 733 } 734 if (error == QUIC_NO_ERROR) { 735 error = loss_detection_.ProcessPeerHello( 736 peer_hello, hello_type, error_details); 737 } 738 if (error == QUIC_NO_ERROR) { 739 error = connection_options_.ProcessPeerHello( 740 peer_hello, hello_type, error_details); 741 } 742 return error; 743 } 744 745 } // namespace net 746