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