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.
5 #include "net/quic/quic_config.h"
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"
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
,
25 QuicConfigPresence presence
,
28 string
* error_details
) {
29 DCHECK(error_details
!= nullptr);
30 QuicErrorCode error
= msg
.GetUint32(tag
, out
);
32 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND
:
33 if (presence
== PRESENCE_REQUIRED
) {
34 *error_details
= "Missing " + QuicUtils::TagToString(tag
);
37 error
= QUIC_NO_ERROR
;
43 *error_details
= "Bad " + QuicUtils::TagToString(tag
);
50 QuicConfigValue::QuicConfigValue(QuicTag tag
,
51 QuicConfigPresence presence
)
55 QuicConfigValue::~QuicConfigValue() {}
57 QuicNegotiableValue::QuicNegotiableValue(QuicTag tag
,
58 QuicConfigPresence presence
)
59 : QuicConfigValue(tag
, presence
),
62 QuicNegotiableValue::~QuicNegotiableValue() {}
64 QuicNegotiableUint32::QuicNegotiableUint32(QuicTag tag
,
65 QuicConfigPresence presence
)
66 : QuicNegotiableValue(tag
, presence
),
70 QuicNegotiableUint32::~QuicNegotiableUint32() {}
72 void QuicNegotiableUint32::set(uint32 max
, uint32 default_value
) {
73 DCHECK_LE(default_value
, max
);
75 default_value_
= default_value
;
78 uint32
QuicNegotiableUint32::GetUint32() const {
80 return negotiated_value_
;
82 return default_value_
;
85 void QuicNegotiableUint32::ToHandshakeMessage(
86 CryptoHandshakeMessage
* out
) const {
88 out
->SetValue(tag_
, negotiated_value_
);
90 out
->SetValue(tag_
, max_value_
);
94 QuicErrorCode
QuicNegotiableUint32::ProcessPeerHello(
95 const CryptoHandshakeMessage
& peer_hello
,
97 string
* error_details
) {
99 DCHECK(error_details
!= nullptr);
101 QuicErrorCode error
= ReadUint32(peer_hello
,
107 if (error
!= QUIC_NO_ERROR
) {
110 if (hello_type
== SERVER
&& value
> max_value_
) {
112 "Invalid value received for " + QuicUtils::TagToString(tag_
);
113 return QUIC_INVALID_NEGOTIATED_VALUE
;
117 negotiated_value_
= min(value
, max_value_
);
118 return QUIC_NO_ERROR
;
121 QuicNegotiableTag::QuicNegotiableTag(QuicTag tag
, QuicConfigPresence presence
)
122 : QuicNegotiableValue(tag
, presence
),
127 QuicNegotiableTag::~QuicNegotiableTag() {}
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
;
136 QuicTag
QuicNegotiableTag::GetTag() const {
138 return negotiated_tag_
;
140 return default_value_
;
143 void QuicNegotiableTag::ToHandshakeMessage(CryptoHandshakeMessage
* out
) const {
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_
);
149 out
->SetVector(tag_
, possible_values_
);
153 QuicErrorCode
QuicNegotiableTag::ReadVector(
154 const CryptoHandshakeMessage
& msg
,
157 string
* error_details
) const {
158 DCHECK(error_details
!= nullptr);
159 QuicErrorCode error
= msg
.GetTaglist(tag_
, out
, out_length
);
161 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND
:
162 if (presence_
== PRESENCE_REQUIRED
) {
163 *error_details
= "Missing " + QuicUtils::TagToString(tag_
);
166 error
= QUIC_NO_ERROR
;
168 *out
= &default_value_
;
173 *error_details
= "Bad " + QuicUtils::TagToString(tag_
);
179 QuicErrorCode
QuicNegotiableTag::ProcessPeerHello(
180 const CryptoHandshakeMessage
& peer_hello
,
181 HelloType hello_type
,
182 string
* error_details
) {
183 DCHECK(!negotiated_
);
184 DCHECK(error_details
!= nullptr);
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
) {
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
;
199 negotiated_tag_
= *received_tags
;
201 QuicTag negotiated_tag
;
202 if (!QuicUtils::FindMutualTag(possible_values_
,
204 received_tags_length
,
205 QuicUtils::LOCAL_PRIORITY
,
208 *error_details
= "Unsupported " + QuicUtils::TagToString(tag_
);
209 return QUIC_CRYPTO_MESSAGE_PARAMETER_NO_OVERLAP
;
211 negotiated_tag_
= negotiated_tag
;
215 return QUIC_NO_ERROR
;
218 QuicFixedUint32::QuicFixedUint32(QuicTag tag
, QuicConfigPresence presence
)
219 : QuicConfigValue(tag
, presence
),
220 has_send_value_(false),
221 has_receive_value_(false) {
223 QuicFixedUint32::~QuicFixedUint32() {}
225 bool QuicFixedUint32::HasSendValue() const {
226 return has_send_value_
;
229 uint32
QuicFixedUint32::GetSendValue() const {
230 LOG_IF(DFATAL
, !has_send_value_
)
231 << "No send value to get for tag:" << QuicUtils::TagToString(tag_
);
235 void QuicFixedUint32::SetSendValue(uint32 value
) {
236 has_send_value_
= true;
240 bool QuicFixedUint32::HasReceivedValue() const {
241 return has_receive_value_
;
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_
;
250 void QuicFixedUint32::SetReceivedValue(uint32 value
) {
251 has_receive_value_
= true;
252 receive_value_
= value
;
255 void QuicFixedUint32::ToHandshakeMessage(CryptoHandshakeMessage
* out
) const {
256 if (has_send_value_
) {
257 out
->SetValue(tag_
, send_value_
);
261 QuicErrorCode
QuicFixedUint32::ProcessPeerHello(
262 const CryptoHandshakeMessage
& peer_hello
,
263 HelloType hello_type
,
264 string
* error_details
) {
265 DCHECK(error_details
!= nullptr);
266 QuicErrorCode error
= peer_hello
.GetUint32(tag_
, &receive_value_
);
268 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND
:
269 if (presence_
== PRESENCE_OPTIONAL
) {
270 return QUIC_NO_ERROR
;
272 *error_details
= "Missing " + QuicUtils::TagToString(tag_
);
275 has_receive_value_
= true;
278 *error_details
= "Bad " + QuicUtils::TagToString(tag_
);
284 QuicFixedTag::QuicFixedTag(QuicTag name
,
285 QuicConfigPresence presence
)
286 : QuicConfigValue(name
, presence
),
287 has_send_value_(false),
288 has_receive_value_(false) {
291 QuicFixedTag::~QuicFixedTag() {}
293 bool QuicFixedTag::HasSendValue() const {
294 return has_send_value_
;
297 uint32
QuicFixedTag::GetSendValue() const {
298 LOG_IF(DFATAL
, !has_send_value_
)
299 << "No send value to get for tag:" << QuicUtils::TagToString(tag_
);
303 void QuicFixedTag::SetSendValue(uint32 value
) {
304 has_send_value_
= true;
308 bool QuicFixedTag::HasReceivedValue() const {
309 return has_receive_value_
;
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_
;
318 void QuicFixedTag::SetReceivedValue(uint32 value
) {
319 has_receive_value_
= true;
320 receive_value_
= value
;
323 void QuicFixedTag::ToHandshakeMessage(CryptoHandshakeMessage
* out
) const {
324 if (has_send_value_
) {
325 out
->SetValue(tag_
, send_value_
);
329 QuicErrorCode
QuicFixedTag::ProcessPeerHello(
330 const CryptoHandshakeMessage
& peer_hello
,
331 HelloType hello_type
,
332 string
* error_details
) {
333 DCHECK(error_details
!= nullptr);
334 QuicErrorCode error
= peer_hello
.GetUint32(tag_
, &receive_value_
);
336 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND
:
337 if (presence_
== PRESENCE_OPTIONAL
) {
338 return QUIC_NO_ERROR
;
340 *error_details
= "Missing " + QuicUtils::TagToString(tag_
);
343 has_receive_value_
= true;
346 *error_details
= "Bad " + QuicUtils::TagToString(tag_
);
352 QuicFixedTagVector::QuicFixedTagVector(QuicTag name
,
353 QuicConfigPresence presence
)
354 : QuicConfigValue(name
, presence
),
355 has_send_values_(false),
356 has_receive_values_(false) {
359 QuicFixedTagVector::~QuicFixedTagVector() {}
361 bool QuicFixedTagVector::HasSendValues() const {
362 return has_send_values_
;
365 QuicTagVector
QuicFixedTagVector::GetSendValues() const {
366 LOG_IF(DFATAL
, !has_send_values_
)
367 << "No send values to get for tag:" << QuicUtils::TagToString(tag_
);
371 void QuicFixedTagVector::SetSendValues(const QuicTagVector
& values
) {
372 has_send_values_
= true;
373 send_values_
= values
;
376 bool QuicFixedTagVector::HasReceivedValues() const {
377 return has_receive_values_
;
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_
;
386 void QuicFixedTagVector::SetReceivedValues(const QuicTagVector
& values
) {
387 has_receive_values_
= true;
388 receive_values_
= values
;
391 void QuicFixedTagVector::ToHandshakeMessage(CryptoHandshakeMessage
* out
) const {
392 if (has_send_values_
) {
393 out
->SetVector(tag_
, send_values_
);
397 QuicErrorCode
QuicFixedTagVector::ProcessPeerHello(
398 const CryptoHandshakeMessage
& peer_hello
,
399 HelloType hello_type
,
400 string
* error_details
) {
401 DCHECK(error_details
!= nullptr);
402 const QuicTag
* received_tags
;
403 size_t received_tags_length
;
404 QuicErrorCode error
=
405 peer_hello
.GetTaglist(tag_
, &received_tags
, &received_tags_length
);
407 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND
:
408 if (presence_
== PRESENCE_OPTIONAL
) {
409 return QUIC_NO_ERROR
;
411 *error_details
= "Missing " + QuicUtils::TagToString(tag_
);
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
]);
421 *error_details
= "Bad " + QuicUtils::TagToString(tag_
);
427 QuicConfig::QuicConfig()
428 : max_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
429 max_idle_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
430 max_undecryptable_packets_(0),
431 congestion_feedback_(kCGST
, PRESENCE_REQUIRED
),
432 connection_options_(kCOPT
, PRESENCE_OPTIONAL
),
433 idle_connection_state_lifetime_seconds_(kICSL
, PRESENCE_REQUIRED
),
434 keepalive_timeout_seconds_(kKATO
, PRESENCE_OPTIONAL
),
435 max_streams_per_connection_(kMSPC
, PRESENCE_REQUIRED
),
436 initial_congestion_window_(kSWND
, PRESENCE_OPTIONAL
),
437 initial_round_trip_time_us_(kIRTT
, PRESENCE_OPTIONAL
),
438 // TODO(rjshade): Remove this when retiring QUIC_VERSION_19.
439 initial_flow_control_window_bytes_(kIFCW
, PRESENCE_OPTIONAL
),
440 // TODO(rjshade): Make this PRESENCE_REQUIRED when retiring
442 initial_stream_flow_control_window_bytes_(kSFCW
, PRESENCE_OPTIONAL
),
443 // TODO(rjshade): Make this PRESENCE_REQUIRED when retiring
445 initial_session_flow_control_window_bytes_(kCFCW
, PRESENCE_OPTIONAL
),
446 socket_receive_buffer_(kSRBF
, PRESENCE_OPTIONAL
) {
450 QuicConfig::~QuicConfig() {}
452 void QuicConfig::SetCongestionFeedback(
453 const QuicTagVector
& congestion_feedback
,
454 QuicTag default_congestion_feedback
) {
455 congestion_feedback_
.set(congestion_feedback
, default_congestion_feedback
);
458 QuicTag
QuicConfig::CongestionFeedback() const {
459 return congestion_feedback_
.GetTag();
462 void QuicConfig::SetConnectionOptionsToSend(
463 const QuicTagVector
& connection_options
) {
464 connection_options_
.SetSendValues(connection_options
);
467 bool QuicConfig::HasReceivedConnectionOptions() const {
468 return connection_options_
.HasReceivedValues();
471 QuicTagVector
QuicConfig::ReceivedConnectionOptions() const {
472 return connection_options_
.GetReceivedValues();
475 bool QuicConfig::HasSendConnectionOptions() const {
476 return connection_options_
.HasSendValues();
479 QuicTagVector
QuicConfig::SendConnectionOptions() const {
480 return connection_options_
.GetSendValues();
483 void QuicConfig::SetIdleConnectionStateLifetime(
484 QuicTime::Delta max_idle_connection_state_lifetime
,
485 QuicTime::Delta default_idle_conection_state_lifetime
) {
486 idle_connection_state_lifetime_seconds_
.set(
487 max_idle_connection_state_lifetime
.ToSeconds(),
488 default_idle_conection_state_lifetime
.ToSeconds());
491 QuicTime::Delta
QuicConfig::IdleConnectionStateLifetime() const {
492 return QuicTime::Delta::FromSeconds(
493 idle_connection_state_lifetime_seconds_
.GetUint32());
496 QuicTime::Delta
QuicConfig::KeepaliveTimeout() const {
497 return QuicTime::Delta::FromSeconds(
498 keepalive_timeout_seconds_
.GetUint32());
501 void QuicConfig::SetMaxStreamsPerConnection(size_t max_streams
,
502 size_t default_streams
) {
503 max_streams_per_connection_
.set(max_streams
, default_streams
);
506 uint32
QuicConfig::MaxStreamsPerConnection() const {
507 return max_streams_per_connection_
.GetUint32();
510 void QuicConfig::SetInitialCongestionWindowToSend(size_t initial_window
) {
511 initial_congestion_window_
.SetSendValue(initial_window
);
514 bool QuicConfig::HasReceivedInitialCongestionWindow() const {
515 return initial_congestion_window_
.HasReceivedValue();
518 uint32
QuicConfig::ReceivedInitialCongestionWindow() const {
519 return initial_congestion_window_
.GetReceivedValue();
522 void QuicConfig::SetInitialRoundTripTimeUsToSend(size_t rtt
) {
523 initial_round_trip_time_us_
.SetSendValue(rtt
);
526 bool QuicConfig::HasReceivedInitialRoundTripTimeUs() const {
527 return initial_round_trip_time_us_
.HasReceivedValue();
530 uint32
QuicConfig::ReceivedInitialRoundTripTimeUs() const {
531 return initial_round_trip_time_us_
.GetReceivedValue();
534 bool QuicConfig::HasInitialRoundTripTimeUsToSend() const {
535 return initial_round_trip_time_us_
.HasSendValue();
538 uint32
QuicConfig::GetInitialRoundTripTimeUsToSend() const {
539 return initial_round_trip_time_us_
.GetSendValue();
542 void QuicConfig::SetInitialFlowControlWindowToSend(uint32 window_bytes
) {
543 if (window_bytes
< kDefaultFlowControlSendWindow
) {
544 LOG(DFATAL
) << "Initial flow control receive window (" << window_bytes
545 << ") cannot be set lower than default ("
546 << kDefaultFlowControlSendWindow
<< ").";
547 window_bytes
= kDefaultFlowControlSendWindow
;
549 initial_flow_control_window_bytes_
.SetSendValue(window_bytes
);
552 uint32
QuicConfig::GetInitialFlowControlWindowToSend() const {
553 return initial_flow_control_window_bytes_
.GetSendValue();
556 bool QuicConfig::HasReceivedInitialFlowControlWindowBytes() const {
557 return initial_flow_control_window_bytes_
.HasReceivedValue();
560 uint32
QuicConfig::ReceivedInitialFlowControlWindowBytes() const {
561 return initial_flow_control_window_bytes_
.GetReceivedValue();
564 void QuicConfig::SetInitialStreamFlowControlWindowToSend(uint32 window_bytes
) {
565 if (window_bytes
< kDefaultFlowControlSendWindow
) {
566 LOG(DFATAL
) << "Initial stream flow control receive window ("
567 << window_bytes
<< ") cannot be set lower than default ("
568 << kDefaultFlowControlSendWindow
<< ").";
569 window_bytes
= kDefaultFlowControlSendWindow
;
571 initial_stream_flow_control_window_bytes_
.SetSendValue(window_bytes
);
574 uint32
QuicConfig::GetInitialStreamFlowControlWindowToSend() const {
575 return initial_stream_flow_control_window_bytes_
.GetSendValue();
578 bool QuicConfig::HasReceivedInitialStreamFlowControlWindowBytes() const {
579 return initial_stream_flow_control_window_bytes_
.HasReceivedValue();
582 uint32
QuicConfig::ReceivedInitialStreamFlowControlWindowBytes() const {
583 return initial_stream_flow_control_window_bytes_
.GetReceivedValue();
586 void QuicConfig::SetInitialSessionFlowControlWindowToSend(uint32 window_bytes
) {
587 if (window_bytes
< kDefaultFlowControlSendWindow
) {
588 LOG(DFATAL
) << "Initial session flow control receive window ("
589 << window_bytes
<< ") cannot be set lower than default ("
590 << kDefaultFlowControlSendWindow
<< ").";
591 window_bytes
= kDefaultFlowControlSendWindow
;
593 initial_session_flow_control_window_bytes_
.SetSendValue(window_bytes
);
596 uint32
QuicConfig::GetInitialSessionFlowControlWindowToSend() const {
597 return initial_session_flow_control_window_bytes_
.GetSendValue();
600 bool QuicConfig::HasReceivedInitialSessionFlowControlWindowBytes() const {
601 return initial_session_flow_control_window_bytes_
.HasReceivedValue();
604 uint32
QuicConfig::ReceivedInitialSessionFlowControlWindowBytes() const {
605 return initial_session_flow_control_window_bytes_
.GetReceivedValue();
608 void QuicConfig::SetSocketReceiveBufferToSend(uint32 tcp_receive_window
) {
609 socket_receive_buffer_
.SetSendValue(tcp_receive_window
);
612 uint32
QuicConfig::GetSocketReceiveBufferToSend() const {
613 return socket_receive_buffer_
.GetSendValue();
616 bool QuicConfig::HasReceivedSocketReceiveBuffer() const {
617 return socket_receive_buffer_
.HasReceivedValue();
620 uint32
QuicConfig::ReceivedSocketReceiveBuffer() const {
621 return socket_receive_buffer_
.GetReceivedValue();
624 bool QuicConfig::negotiated() const {
625 // TODO(ianswett): Add the negotiated parameters once and iterate over all
626 // of them in negotiated, ToHandshakeMessage, ProcessClientHello, and
627 // ProcessServerHello.
628 return congestion_feedback_
.negotiated() &&
629 idle_connection_state_lifetime_seconds_
.negotiated() &&
630 keepalive_timeout_seconds_
.negotiated() &&
631 max_streams_per_connection_
.negotiated();
634 void QuicConfig::SetDefaults() {
635 QuicTagVector congestion_feedback
;
636 congestion_feedback
.push_back(kQBIC
);
637 congestion_feedback_
.set(congestion_feedback
, kQBIC
);
638 idle_connection_state_lifetime_seconds_
.set(kMaximumIdleTimeoutSecs
,
639 kDefaultIdleTimeoutSecs
);
640 // kKATO is optional. Return 0 if not negotiated.
641 keepalive_timeout_seconds_
.set(0, 0);
642 SetMaxStreamsPerConnection(kDefaultMaxStreamsPerConnection
,
643 kDefaultMaxStreamsPerConnection
);
644 max_time_before_crypto_handshake_
=
645 QuicTime::Delta::FromSeconds(kMaxTimeForCryptoHandshakeSecs
);
646 max_idle_time_before_crypto_handshake_
=
647 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs
);
648 max_undecryptable_packets_
= kDefaultMaxUndecryptablePackets
;
650 SetInitialFlowControlWindowToSend(kDefaultFlowControlSendWindow
);
651 SetInitialStreamFlowControlWindowToSend(kDefaultFlowControlSendWindow
);
652 SetInitialSessionFlowControlWindowToSend(kDefaultFlowControlSendWindow
);
655 void QuicConfig::ToHandshakeMessage(CryptoHandshakeMessage
* out
) const {
656 congestion_feedback_
.ToHandshakeMessage(out
);
657 idle_connection_state_lifetime_seconds_
.ToHandshakeMessage(out
);
658 keepalive_timeout_seconds_
.ToHandshakeMessage(out
);
659 max_streams_per_connection_
.ToHandshakeMessage(out
);
660 initial_congestion_window_
.ToHandshakeMessage(out
);
661 initial_round_trip_time_us_
.ToHandshakeMessage(out
);
662 initial_flow_control_window_bytes_
.ToHandshakeMessage(out
);
663 initial_stream_flow_control_window_bytes_
.ToHandshakeMessage(out
);
664 initial_session_flow_control_window_bytes_
.ToHandshakeMessage(out
);
665 socket_receive_buffer_
.ToHandshakeMessage(out
);
666 connection_options_
.ToHandshakeMessage(out
);
669 QuicErrorCode
QuicConfig::ProcessPeerHello(
670 const CryptoHandshakeMessage
& peer_hello
,
671 HelloType hello_type
,
672 string
* error_details
) {
673 DCHECK(error_details
!= nullptr);
675 QuicErrorCode error
= QUIC_NO_ERROR
;
676 if (error
== QUIC_NO_ERROR
) {
677 error
= congestion_feedback_
.ProcessPeerHello(
678 peer_hello
, hello_type
, error_details
);
680 if (error
== QUIC_NO_ERROR
) {
681 error
= idle_connection_state_lifetime_seconds_
.ProcessPeerHello(
682 peer_hello
, hello_type
, error_details
);
684 if (error
== QUIC_NO_ERROR
) {
685 error
= keepalive_timeout_seconds_
.ProcessPeerHello(
686 peer_hello
, hello_type
, error_details
);
688 if (error
== QUIC_NO_ERROR
) {
689 error
= max_streams_per_connection_
.ProcessPeerHello(
690 peer_hello
, hello_type
, error_details
);
692 if (error
== QUIC_NO_ERROR
) {
693 error
= initial_congestion_window_
.ProcessPeerHello(
694 peer_hello
, hello_type
, error_details
);
696 if (error
== QUIC_NO_ERROR
) {
697 error
= initial_round_trip_time_us_
.ProcessPeerHello(
698 peer_hello
, hello_type
, error_details
);
700 if (error
== QUIC_NO_ERROR
) {
701 error
= initial_flow_control_window_bytes_
.ProcessPeerHello(
702 peer_hello
, hello_type
, error_details
);
704 if (error
== QUIC_NO_ERROR
) {
705 error
= initial_stream_flow_control_window_bytes_
.ProcessPeerHello(
706 peer_hello
, hello_type
, error_details
);
708 if (error
== QUIC_NO_ERROR
) {
709 error
= initial_session_flow_control_window_bytes_
.ProcessPeerHello(
710 peer_hello
, hello_type
, error_details
);
712 if (error
== QUIC_NO_ERROR
) {
713 error
= socket_receive_buffer_
.ProcessPeerHello(
714 peer_hello
, hello_type
, error_details
);
716 if (error
== QUIC_NO_ERROR
) {
717 error
= connection_options_
.ProcessPeerHello(
718 peer_hello
, hello_type
, error_details
);