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/third_party/quiche/src/quic/core/quic_config.h"
6
7 #include <algorithm>
8 #include <cstring>
9 #include <limits>
10 #include <string>
11 #include <utility>
12
13 #include "absl/base/attributes.h"
14 #include "absl/strings/string_view.h"
15 #include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h"
16 #include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
17 #include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
18 #include "net/third_party/quiche/src/quic/core/quic_constants.h"
19 #include "net/third_party/quiche/src/quic/core/quic_socket_address_coder.h"
20 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
21 #include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
22 #include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
23 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
24 #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
25 #include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
26 #include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h"
27
28 namespace quic {
29
30 // Reads the value corresponding to |name_| from |msg| into |out|. If the
31 // |name_| is absent in |msg| and |presence| is set to OPTIONAL |out| is set
32 // to |default_value|.
ReadUint32(const CryptoHandshakeMessage & msg,QuicTag tag,QuicConfigPresence presence,uint32_t default_value,uint32_t * out,std::string * error_details)33 QuicErrorCode ReadUint32(const CryptoHandshakeMessage& msg,
34 QuicTag tag,
35 QuicConfigPresence presence,
36 uint32_t default_value,
37 uint32_t* out,
38 std::string* error_details) {
39 DCHECK(error_details != nullptr);
40 QuicErrorCode error = msg.GetUint32(tag, out);
41 switch (error) {
42 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
43 if (presence == PRESENCE_REQUIRED) {
44 *error_details = "Missing " + QuicTagToString(tag);
45 break;
46 }
47 error = QUIC_NO_ERROR;
48 *out = default_value;
49 break;
50 case QUIC_NO_ERROR:
51 break;
52 default:
53 *error_details = "Bad " + QuicTagToString(tag);
54 break;
55 }
56 return error;
57 }
58
QuicConfigValue(QuicTag tag,QuicConfigPresence presence)59 QuicConfigValue::QuicConfigValue(QuicTag tag, QuicConfigPresence presence)
60 : tag_(tag), presence_(presence) {}
~QuicConfigValue()61 QuicConfigValue::~QuicConfigValue() {}
62
QuicFixedUint32(QuicTag tag,QuicConfigPresence presence)63 QuicFixedUint32::QuicFixedUint32(QuicTag tag, QuicConfigPresence presence)
64 : QuicConfigValue(tag, presence),
65 has_send_value_(false),
66 has_receive_value_(false) {}
~QuicFixedUint32()67 QuicFixedUint32::~QuicFixedUint32() {}
68
HasSendValue() const69 bool QuicFixedUint32::HasSendValue() const {
70 return has_send_value_;
71 }
72
GetSendValue() const73 uint32_t QuicFixedUint32::GetSendValue() const {
74 QUIC_BUG_IF(!has_send_value_)
75 << "No send value to get for tag:" << QuicTagToString(tag_);
76 return send_value_;
77 }
78
SetSendValue(uint32_t value)79 void QuicFixedUint32::SetSendValue(uint32_t value) {
80 has_send_value_ = true;
81 send_value_ = value;
82 }
83
HasReceivedValue() const84 bool QuicFixedUint32::HasReceivedValue() const {
85 return has_receive_value_;
86 }
87
GetReceivedValue() const88 uint32_t QuicFixedUint32::GetReceivedValue() const {
89 QUIC_BUG_IF(!has_receive_value_)
90 << "No receive value to get for tag:" << QuicTagToString(tag_);
91 return receive_value_;
92 }
93
SetReceivedValue(uint32_t value)94 void QuicFixedUint32::SetReceivedValue(uint32_t value) {
95 has_receive_value_ = true;
96 receive_value_ = value;
97 }
98
ToHandshakeMessage(CryptoHandshakeMessage * out) const99 void QuicFixedUint32::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
100 if (tag_ == 0) {
101 QUIC_BUG
102 << "This parameter does not support writing to CryptoHandshakeMessage";
103 return;
104 }
105 if (has_send_value_) {
106 out->SetValue(tag_, send_value_);
107 }
108 }
109
ProcessPeerHello(const CryptoHandshakeMessage & peer_hello,HelloType,std::string * error_details)110 QuicErrorCode QuicFixedUint32::ProcessPeerHello(
111 const CryptoHandshakeMessage& peer_hello,
112 HelloType /*hello_type*/,
113 std::string* error_details) {
114 DCHECK(error_details != nullptr);
115 if (tag_ == 0) {
116 *error_details =
117 "This parameter does not support reading from CryptoHandshakeMessage";
118 QUIC_BUG << *error_details;
119 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
120 }
121 QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value_);
122 switch (error) {
123 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
124 if (presence_ == PRESENCE_OPTIONAL) {
125 return QUIC_NO_ERROR;
126 }
127 *error_details = "Missing " + QuicTagToString(tag_);
128 break;
129 case QUIC_NO_ERROR:
130 has_receive_value_ = true;
131 break;
132 default:
133 *error_details = "Bad " + QuicTagToString(tag_);
134 break;
135 }
136 return error;
137 }
138
QuicFixedUint62(QuicTag name,QuicConfigPresence presence)139 QuicFixedUint62::QuicFixedUint62(QuicTag name, QuicConfigPresence presence)
140 : QuicConfigValue(name, presence),
141 has_send_value_(false),
142 has_receive_value_(false) {}
143
~QuicFixedUint62()144 QuicFixedUint62::~QuicFixedUint62() {}
145
HasSendValue() const146 bool QuicFixedUint62::HasSendValue() const {
147 return has_send_value_;
148 }
149
GetSendValue() const150 uint64_t QuicFixedUint62::GetSendValue() const {
151 if (!has_send_value_) {
152 QUIC_BUG << "No send value to get for tag:" << QuicTagToString(tag_);
153 return 0;
154 }
155 return send_value_;
156 }
157
SetSendValue(uint64_t value)158 void QuicFixedUint62::SetSendValue(uint64_t value) {
159 if (value > kVarInt62MaxValue) {
160 QUIC_BUG << "QuicFixedUint62 invalid value " << value;
161 value = kVarInt62MaxValue;
162 }
163 has_send_value_ = true;
164 send_value_ = value;
165 }
166
HasReceivedValue() const167 bool QuicFixedUint62::HasReceivedValue() const {
168 return has_receive_value_;
169 }
170
GetReceivedValue() const171 uint64_t QuicFixedUint62::GetReceivedValue() const {
172 if (!has_receive_value_) {
173 QUIC_BUG << "No receive value to get for tag:" << QuicTagToString(tag_);
174 return 0;
175 }
176 return receive_value_;
177 }
178
SetReceivedValue(uint64_t value)179 void QuicFixedUint62::SetReceivedValue(uint64_t value) {
180 has_receive_value_ = true;
181 receive_value_ = value;
182 }
183
ToHandshakeMessage(CryptoHandshakeMessage * out) const184 void QuicFixedUint62::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
185 if (!has_send_value_) {
186 return;
187 }
188 uint32_t send_value32;
189 if (send_value_ > std::numeric_limits<uint32_t>::max()) {
190 QUIC_BUG << "Attempting to send " << send_value_
191 << " for tag:" << QuicTagToString(tag_);
192 send_value32 = std::numeric_limits<uint32_t>::max();
193 } else {
194 send_value32 = static_cast<uint32_t>(send_value_);
195 }
196 out->SetValue(tag_, send_value32);
197 }
198
ProcessPeerHello(const CryptoHandshakeMessage & peer_hello,HelloType,std::string * error_details)199 QuicErrorCode QuicFixedUint62::ProcessPeerHello(
200 const CryptoHandshakeMessage& peer_hello,
201 HelloType /*hello_type*/,
202 std::string* error_details) {
203 DCHECK(error_details != nullptr);
204 uint32_t receive_value32;
205 QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value32);
206 // GetUint32 is guaranteed to always initialize receive_value32.
207 receive_value_ = receive_value32;
208 switch (error) {
209 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
210 if (presence_ == PRESENCE_OPTIONAL) {
211 return QUIC_NO_ERROR;
212 }
213 *error_details = "Missing " + QuicTagToString(tag_);
214 break;
215 case QUIC_NO_ERROR:
216 has_receive_value_ = true;
217 break;
218 default:
219 *error_details = "Bad " + QuicTagToString(tag_);
220 break;
221 }
222 return error;
223 }
224
QuicFixedUint128(QuicTag tag,QuicConfigPresence presence)225 QuicFixedUint128::QuicFixedUint128(QuicTag tag, QuicConfigPresence presence)
226 : QuicConfigValue(tag, presence),
227 has_send_value_(false),
228 has_receive_value_(false) {}
~QuicFixedUint128()229 QuicFixedUint128::~QuicFixedUint128() {}
230
HasSendValue() const231 bool QuicFixedUint128::HasSendValue() const {
232 return has_send_value_;
233 }
234
GetSendValue() const235 QuicUint128 QuicFixedUint128::GetSendValue() const {
236 QUIC_BUG_IF(!has_send_value_)
237 << "No send value to get for tag:" << QuicTagToString(tag_);
238 return send_value_;
239 }
240
SetSendValue(QuicUint128 value)241 void QuicFixedUint128::SetSendValue(QuicUint128 value) {
242 has_send_value_ = true;
243 send_value_ = value;
244 }
245
HasReceivedValue() const246 bool QuicFixedUint128::HasReceivedValue() const {
247 return has_receive_value_;
248 }
249
GetReceivedValue() const250 QuicUint128 QuicFixedUint128::GetReceivedValue() const {
251 QUIC_BUG_IF(!has_receive_value_)
252 << "No receive value to get for tag:" << QuicTagToString(tag_);
253 return receive_value_;
254 }
255
SetReceivedValue(QuicUint128 value)256 void QuicFixedUint128::SetReceivedValue(QuicUint128 value) {
257 has_receive_value_ = true;
258 receive_value_ = value;
259 }
260
ToHandshakeMessage(CryptoHandshakeMessage * out) const261 void QuicFixedUint128::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
262 if (has_send_value_) {
263 out->SetValue(tag_, send_value_);
264 }
265 }
266
ProcessPeerHello(const CryptoHandshakeMessage & peer_hello,HelloType,std::string * error_details)267 QuicErrorCode QuicFixedUint128::ProcessPeerHello(
268 const CryptoHandshakeMessage& peer_hello,
269 HelloType /*hello_type*/,
270 std::string* error_details) {
271 DCHECK(error_details != nullptr);
272 QuicErrorCode error = peer_hello.GetUint128(tag_, &receive_value_);
273 switch (error) {
274 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
275 if (presence_ == PRESENCE_OPTIONAL) {
276 return QUIC_NO_ERROR;
277 }
278 *error_details = "Missing " + QuicTagToString(tag_);
279 break;
280 case QUIC_NO_ERROR:
281 has_receive_value_ = true;
282 break;
283 default:
284 *error_details = "Bad " + QuicTagToString(tag_);
285 break;
286 }
287 return error;
288 }
289
QuicFixedTagVector(QuicTag name,QuicConfigPresence presence)290 QuicFixedTagVector::QuicFixedTagVector(QuicTag name,
291 QuicConfigPresence presence)
292 : QuicConfigValue(name, presence),
293 has_send_values_(false),
294 has_receive_values_(false) {}
295
296 QuicFixedTagVector::QuicFixedTagVector(const QuicFixedTagVector& other) =
297 default;
298
~QuicFixedTagVector()299 QuicFixedTagVector::~QuicFixedTagVector() {}
300
HasSendValues() const301 bool QuicFixedTagVector::HasSendValues() const {
302 return has_send_values_;
303 }
304
GetSendValues() const305 const QuicTagVector& QuicFixedTagVector::GetSendValues() const {
306 QUIC_BUG_IF(!has_send_values_)
307 << "No send values to get for tag:" << QuicTagToString(tag_);
308 return send_values_;
309 }
310
SetSendValues(const QuicTagVector & values)311 void QuicFixedTagVector::SetSendValues(const QuicTagVector& values) {
312 has_send_values_ = true;
313 send_values_ = values;
314 }
315
HasReceivedValues() const316 bool QuicFixedTagVector::HasReceivedValues() const {
317 return has_receive_values_;
318 }
319
GetReceivedValues() const320 const QuicTagVector& QuicFixedTagVector::GetReceivedValues() const {
321 QUIC_BUG_IF(!has_receive_values_)
322 << "No receive value to get for tag:" << QuicTagToString(tag_);
323 return receive_values_;
324 }
325
SetReceivedValues(const QuicTagVector & values)326 void QuicFixedTagVector::SetReceivedValues(const QuicTagVector& values) {
327 has_receive_values_ = true;
328 receive_values_ = values;
329 }
330
ToHandshakeMessage(CryptoHandshakeMessage * out) const331 void QuicFixedTagVector::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
332 if (has_send_values_) {
333 out->SetVector(tag_, send_values_);
334 }
335 }
336
ProcessPeerHello(const CryptoHandshakeMessage & peer_hello,HelloType,std::string * error_details)337 QuicErrorCode QuicFixedTagVector::ProcessPeerHello(
338 const CryptoHandshakeMessage& peer_hello,
339 HelloType /*hello_type*/,
340 std::string* error_details) {
341 DCHECK(error_details != nullptr);
342 QuicTagVector values;
343 QuicErrorCode error = peer_hello.GetTaglist(tag_, &values);
344 switch (error) {
345 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
346 if (presence_ == PRESENCE_OPTIONAL) {
347 return QUIC_NO_ERROR;
348 }
349 *error_details = "Missing " + QuicTagToString(tag_);
350 break;
351 case QUIC_NO_ERROR:
352 QUIC_DVLOG(1) << "Received Connection Option tags from receiver.";
353 has_receive_values_ = true;
354 receive_values_.insert(receive_values_.end(), values.begin(),
355 values.end());
356 break;
357 default:
358 *error_details = "Bad " + QuicTagToString(tag_);
359 break;
360 }
361 return error;
362 }
363
QuicFixedSocketAddress(QuicTag tag,QuicConfigPresence presence)364 QuicFixedSocketAddress::QuicFixedSocketAddress(QuicTag tag,
365 QuicConfigPresence presence)
366 : QuicConfigValue(tag, presence),
367 has_send_value_(false),
368 has_receive_value_(false) {}
369
~QuicFixedSocketAddress()370 QuicFixedSocketAddress::~QuicFixedSocketAddress() {}
371
HasSendValue() const372 bool QuicFixedSocketAddress::HasSendValue() const {
373 return has_send_value_;
374 }
375
GetSendValue() const376 const QuicSocketAddress& QuicFixedSocketAddress::GetSendValue() const {
377 QUIC_BUG_IF(!has_send_value_)
378 << "No send value to get for tag:" << QuicTagToString(tag_);
379 return send_value_;
380 }
381
SetSendValue(const QuicSocketAddress & value)382 void QuicFixedSocketAddress::SetSendValue(const QuicSocketAddress& value) {
383 has_send_value_ = true;
384 send_value_ = value;
385 }
386
HasReceivedValue() const387 bool QuicFixedSocketAddress::HasReceivedValue() const {
388 return has_receive_value_;
389 }
390
GetReceivedValue() const391 const QuicSocketAddress& QuicFixedSocketAddress::GetReceivedValue() const {
392 QUIC_BUG_IF(!has_receive_value_)
393 << "No receive value to get for tag:" << QuicTagToString(tag_);
394 return receive_value_;
395 }
396
SetReceivedValue(const QuicSocketAddress & value)397 void QuicFixedSocketAddress::SetReceivedValue(const QuicSocketAddress& value) {
398 has_receive_value_ = true;
399 receive_value_ = value;
400 }
401
ToHandshakeMessage(CryptoHandshakeMessage * out) const402 void QuicFixedSocketAddress::ToHandshakeMessage(
403 CryptoHandshakeMessage* out) const {
404 if (has_send_value_) {
405 QuicSocketAddressCoder address_coder(send_value_);
406 out->SetStringPiece(tag_, address_coder.Encode());
407 }
408 }
409
ProcessPeerHello(const CryptoHandshakeMessage & peer_hello,HelloType,std::string * error_details)410 QuicErrorCode QuicFixedSocketAddress::ProcessPeerHello(
411 const CryptoHandshakeMessage& peer_hello,
412 HelloType /*hello_type*/,
413 std::string* error_details) {
414 absl::string_view address;
415 if (!peer_hello.GetStringPiece(tag_, &address)) {
416 if (presence_ == PRESENCE_REQUIRED) {
417 *error_details = "Missing " + QuicTagToString(tag_);
418 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
419 }
420 } else {
421 QuicSocketAddressCoder address_coder;
422 if (address_coder.Decode(address.data(), address.length())) {
423 SetReceivedValue(
424 QuicSocketAddress(address_coder.ip(), address_coder.port()));
425 }
426 }
427 return QUIC_NO_ERROR;
428 }
429
QuicConfig()430 QuicConfig::QuicConfig()
431 : negotiated_(false),
432 max_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
433 max_idle_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
434 max_undecryptable_packets_(0),
435 connection_options_(kCOPT, PRESENCE_OPTIONAL),
436 client_connection_options_(kCLOP, PRESENCE_OPTIONAL),
437 max_idle_timeout_to_send_(QuicTime::Delta::Infinite()),
438 max_bidirectional_streams_(kMIBS, PRESENCE_REQUIRED),
439 max_unidirectional_streams_(kMIUS, PRESENCE_OPTIONAL),
440 bytes_for_connection_id_(kTCID, PRESENCE_OPTIONAL),
441 initial_round_trip_time_us_(kIRTT, PRESENCE_OPTIONAL),
442 initial_max_stream_data_bytes_incoming_bidirectional_(0,
443 PRESENCE_OPTIONAL),
444 initial_max_stream_data_bytes_outgoing_bidirectional_(0,
445 PRESENCE_OPTIONAL),
446 initial_max_stream_data_bytes_unidirectional_(0, PRESENCE_OPTIONAL),
447 initial_stream_flow_control_window_bytes_(kSFCW, PRESENCE_OPTIONAL),
448 initial_session_flow_control_window_bytes_(kCFCW, PRESENCE_OPTIONAL),
449 connection_migration_disabled_(kNCMR, PRESENCE_OPTIONAL),
450 support_handshake_done_(0, PRESENCE_OPTIONAL),
451 key_update_supported_remotely_(false),
452 key_update_supported_locally_(false),
453 alternate_server_address_ipv6_(kASAD, PRESENCE_OPTIONAL),
454 alternate_server_address_ipv4_(kASAD, PRESENCE_OPTIONAL),
455 stateless_reset_token_(kSRST, PRESENCE_OPTIONAL),
456 max_ack_delay_ms_(kMAD, PRESENCE_OPTIONAL),
457 min_ack_delay_ms_(0, PRESENCE_OPTIONAL),
458 ack_delay_exponent_(kADE, PRESENCE_OPTIONAL),
459 max_udp_payload_size_(0, PRESENCE_OPTIONAL),
460 max_datagram_frame_size_(0, PRESENCE_OPTIONAL),
461 active_connection_id_limit_(0, PRESENCE_OPTIONAL) {
462 SetDefaults();
463 }
464
465 QuicConfig::QuicConfig(const QuicConfig& other) = default;
466
~QuicConfig()467 QuicConfig::~QuicConfig() {}
468
SetInitialReceivedConnectionOptions(const QuicTagVector & tags)469 bool QuicConfig::SetInitialReceivedConnectionOptions(
470 const QuicTagVector& tags) {
471 if (HasReceivedConnectionOptions()) {
472 // If we have already received connection options (via handshake or due to
473 // a previous call), don't re-initialize.
474 return false;
475 }
476 connection_options_.SetReceivedValues(tags);
477 return true;
478 }
479
SetConnectionOptionsToSend(const QuicTagVector & connection_options)480 void QuicConfig::SetConnectionOptionsToSend(
481 const QuicTagVector& connection_options) {
482 connection_options_.SetSendValues(connection_options);
483 }
484
HasReceivedConnectionOptions() const485 bool QuicConfig::HasReceivedConnectionOptions() const {
486 return connection_options_.HasReceivedValues();
487 }
488
ReceivedConnectionOptions() const489 const QuicTagVector& QuicConfig::ReceivedConnectionOptions() const {
490 return connection_options_.GetReceivedValues();
491 }
492
HasSendConnectionOptions() const493 bool QuicConfig::HasSendConnectionOptions() const {
494 return connection_options_.HasSendValues();
495 }
496
SendConnectionOptions() const497 const QuicTagVector& QuicConfig::SendConnectionOptions() const {
498 return connection_options_.GetSendValues();
499 }
500
HasClientSentConnectionOption(QuicTag tag,Perspective perspective) const501 bool QuicConfig::HasClientSentConnectionOption(QuicTag tag,
502 Perspective perspective) const {
503 if (perspective == Perspective::IS_SERVER) {
504 if (HasReceivedConnectionOptions() &&
505 ContainsQuicTag(ReceivedConnectionOptions(), tag)) {
506 return true;
507 }
508 } else if (HasSendConnectionOptions() &&
509 ContainsQuicTag(SendConnectionOptions(), tag)) {
510 return true;
511 }
512 return false;
513 }
514
SetClientConnectionOptions(const QuicTagVector & client_connection_options)515 void QuicConfig::SetClientConnectionOptions(
516 const QuicTagVector& client_connection_options) {
517 client_connection_options_.SetSendValues(client_connection_options);
518 }
519
HasClientRequestedIndependentOption(QuicTag tag,Perspective perspective) const520 bool QuicConfig::HasClientRequestedIndependentOption(
521 QuicTag tag,
522 Perspective perspective) const {
523 if (perspective == Perspective::IS_SERVER) {
524 return (HasReceivedConnectionOptions() &&
525 ContainsQuicTag(ReceivedConnectionOptions(), tag));
526 }
527
528 return (client_connection_options_.HasSendValues() &&
529 ContainsQuicTag(client_connection_options_.GetSendValues(), tag));
530 }
531
ClientRequestedIndependentOptions(Perspective perspective) const532 const QuicTagVector& QuicConfig::ClientRequestedIndependentOptions(
533 Perspective perspective) const {
534 static const QuicTagVector* no_options = new QuicTagVector;
535 if (perspective == Perspective::IS_SERVER) {
536 return HasReceivedConnectionOptions() ? ReceivedConnectionOptions()
537 : *no_options;
538 }
539
540 return client_connection_options_.HasSendValues()
541 ? client_connection_options_.GetSendValues()
542 : *no_options;
543 }
544
SetIdleNetworkTimeout(QuicTime::Delta idle_network_timeout)545 void QuicConfig::SetIdleNetworkTimeout(QuicTime::Delta idle_network_timeout) {
546 if (idle_network_timeout.ToMicroseconds() <= 0) {
547 QUIC_BUG << "Invalid idle network timeout " << idle_network_timeout;
548 return;
549 }
550 max_idle_timeout_to_send_ = idle_network_timeout;
551 }
552
IdleNetworkTimeout() const553 QuicTime::Delta QuicConfig::IdleNetworkTimeout() const {
554 // TODO(b/152032210) add a QUIC_BUG to ensure that is not called before we've
555 // received the peer's values. This is true in production code but not in all
556 // of our tests that use a fake QuicConfig.
557 if (!received_max_idle_timeout_.has_value()) {
558 return max_idle_timeout_to_send_;
559 }
560 return received_max_idle_timeout_.value();
561 }
562
SetMaxBidirectionalStreamsToSend(uint32_t max_streams)563 void QuicConfig::SetMaxBidirectionalStreamsToSend(uint32_t max_streams) {
564 max_bidirectional_streams_.SetSendValue(max_streams);
565 }
566
GetMaxBidirectionalStreamsToSend() const567 uint32_t QuicConfig::GetMaxBidirectionalStreamsToSend() const {
568 return max_bidirectional_streams_.GetSendValue();
569 }
570
HasReceivedMaxBidirectionalStreams() const571 bool QuicConfig::HasReceivedMaxBidirectionalStreams() const {
572 return max_bidirectional_streams_.HasReceivedValue();
573 }
574
ReceivedMaxBidirectionalStreams() const575 uint32_t QuicConfig::ReceivedMaxBidirectionalStreams() const {
576 return max_bidirectional_streams_.GetReceivedValue();
577 }
578
SetMaxUnidirectionalStreamsToSend(uint32_t max_streams)579 void QuicConfig::SetMaxUnidirectionalStreamsToSend(uint32_t max_streams) {
580 max_unidirectional_streams_.SetSendValue(max_streams);
581 }
582
GetMaxUnidirectionalStreamsToSend() const583 uint32_t QuicConfig::GetMaxUnidirectionalStreamsToSend() const {
584 return max_unidirectional_streams_.GetSendValue();
585 }
586
HasReceivedMaxUnidirectionalStreams() const587 bool QuicConfig::HasReceivedMaxUnidirectionalStreams() const {
588 return max_unidirectional_streams_.HasReceivedValue();
589 }
590
ReceivedMaxUnidirectionalStreams() const591 uint32_t QuicConfig::ReceivedMaxUnidirectionalStreams() const {
592 return max_unidirectional_streams_.GetReceivedValue();
593 }
594
SetMaxAckDelayToSendMs(uint32_t max_ack_delay_ms)595 void QuicConfig::SetMaxAckDelayToSendMs(uint32_t max_ack_delay_ms) {
596 max_ack_delay_ms_.SetSendValue(max_ack_delay_ms);
597 }
598
GetMaxAckDelayToSendMs() const599 uint32_t QuicConfig::GetMaxAckDelayToSendMs() const {
600 return max_ack_delay_ms_.GetSendValue();
601 }
602
HasReceivedMaxAckDelayMs() const603 bool QuicConfig::HasReceivedMaxAckDelayMs() const {
604 return max_ack_delay_ms_.HasReceivedValue();
605 }
606
ReceivedMaxAckDelayMs() const607 uint32_t QuicConfig::ReceivedMaxAckDelayMs() const {
608 return max_ack_delay_ms_.GetReceivedValue();
609 }
610
SetMinAckDelayMs(uint32_t min_ack_delay_ms)611 void QuicConfig::SetMinAckDelayMs(uint32_t min_ack_delay_ms) {
612 min_ack_delay_ms_.SetSendValue(min_ack_delay_ms);
613 }
614
GetMinAckDelayToSendMs() const615 uint32_t QuicConfig::GetMinAckDelayToSendMs() const {
616 return min_ack_delay_ms_.GetSendValue();
617 }
618
HasReceivedMinAckDelayMs() const619 bool QuicConfig::HasReceivedMinAckDelayMs() const {
620 return min_ack_delay_ms_.HasReceivedValue();
621 }
622
ReceivedMinAckDelayMs() const623 uint32_t QuicConfig::ReceivedMinAckDelayMs() const {
624 return min_ack_delay_ms_.GetReceivedValue();
625 }
626
SetAckDelayExponentToSend(uint32_t exponent)627 void QuicConfig::SetAckDelayExponentToSend(uint32_t exponent) {
628 ack_delay_exponent_.SetSendValue(exponent);
629 }
630
GetAckDelayExponentToSend() const631 uint32_t QuicConfig::GetAckDelayExponentToSend() const {
632 return ack_delay_exponent_.GetSendValue();
633 }
634
HasReceivedAckDelayExponent() const635 bool QuicConfig::HasReceivedAckDelayExponent() const {
636 return ack_delay_exponent_.HasReceivedValue();
637 }
638
ReceivedAckDelayExponent() const639 uint32_t QuicConfig::ReceivedAckDelayExponent() const {
640 return ack_delay_exponent_.GetReceivedValue();
641 }
642
SetMaxPacketSizeToSend(uint64_t max_udp_payload_size)643 void QuicConfig::SetMaxPacketSizeToSend(uint64_t max_udp_payload_size) {
644 max_udp_payload_size_.SetSendValue(max_udp_payload_size);
645 }
646
GetMaxPacketSizeToSend() const647 uint64_t QuicConfig::GetMaxPacketSizeToSend() const {
648 return max_udp_payload_size_.GetSendValue();
649 }
650
HasReceivedMaxPacketSize() const651 bool QuicConfig::HasReceivedMaxPacketSize() const {
652 return max_udp_payload_size_.HasReceivedValue();
653 }
654
ReceivedMaxPacketSize() const655 uint64_t QuicConfig::ReceivedMaxPacketSize() const {
656 return max_udp_payload_size_.GetReceivedValue();
657 }
658
SetMaxDatagramFrameSizeToSend(uint64_t max_datagram_frame_size)659 void QuicConfig::SetMaxDatagramFrameSizeToSend(
660 uint64_t max_datagram_frame_size) {
661 max_datagram_frame_size_.SetSendValue(max_datagram_frame_size);
662 }
663
GetMaxDatagramFrameSizeToSend() const664 uint64_t QuicConfig::GetMaxDatagramFrameSizeToSend() const {
665 return max_datagram_frame_size_.GetSendValue();
666 }
667
HasReceivedMaxDatagramFrameSize() const668 bool QuicConfig::HasReceivedMaxDatagramFrameSize() const {
669 return max_datagram_frame_size_.HasReceivedValue();
670 }
671
ReceivedMaxDatagramFrameSize() const672 uint64_t QuicConfig::ReceivedMaxDatagramFrameSize() const {
673 return max_datagram_frame_size_.GetReceivedValue();
674 }
675
SetActiveConnectionIdLimitToSend(uint64_t active_connection_id_limit)676 void QuicConfig::SetActiveConnectionIdLimitToSend(
677 uint64_t active_connection_id_limit) {
678 active_connection_id_limit_.SetSendValue(active_connection_id_limit);
679 }
680
GetActiveConnectionIdLimitToSend() const681 uint64_t QuicConfig::GetActiveConnectionIdLimitToSend() const {
682 return active_connection_id_limit_.GetSendValue();
683 }
684
HasReceivedActiveConnectionIdLimit() const685 bool QuicConfig::HasReceivedActiveConnectionIdLimit() const {
686 return active_connection_id_limit_.HasReceivedValue();
687 }
688
ReceivedActiveConnectionIdLimit() const689 uint64_t QuicConfig::ReceivedActiveConnectionIdLimit() const {
690 return active_connection_id_limit_.GetReceivedValue();
691 }
692
HasSetBytesForConnectionIdToSend() const693 bool QuicConfig::HasSetBytesForConnectionIdToSend() const {
694 return bytes_for_connection_id_.HasSendValue();
695 }
696
SetBytesForConnectionIdToSend(uint32_t bytes)697 void QuicConfig::SetBytesForConnectionIdToSend(uint32_t bytes) {
698 bytes_for_connection_id_.SetSendValue(bytes);
699 }
700
HasReceivedBytesForConnectionId() const701 bool QuicConfig::HasReceivedBytesForConnectionId() const {
702 return bytes_for_connection_id_.HasReceivedValue();
703 }
704
ReceivedBytesForConnectionId() const705 uint32_t QuicConfig::ReceivedBytesForConnectionId() const {
706 return bytes_for_connection_id_.GetReceivedValue();
707 }
708
SetInitialRoundTripTimeUsToSend(uint64_t rtt)709 void QuicConfig::SetInitialRoundTripTimeUsToSend(uint64_t rtt) {
710 initial_round_trip_time_us_.SetSendValue(rtt);
711 }
712
HasReceivedInitialRoundTripTimeUs() const713 bool QuicConfig::HasReceivedInitialRoundTripTimeUs() const {
714 return initial_round_trip_time_us_.HasReceivedValue();
715 }
716
ReceivedInitialRoundTripTimeUs() const717 uint64_t QuicConfig::ReceivedInitialRoundTripTimeUs() const {
718 return initial_round_trip_time_us_.GetReceivedValue();
719 }
720
HasInitialRoundTripTimeUsToSend() const721 bool QuicConfig::HasInitialRoundTripTimeUsToSend() const {
722 return initial_round_trip_time_us_.HasSendValue();
723 }
724
GetInitialRoundTripTimeUsToSend() const725 uint64_t QuicConfig::GetInitialRoundTripTimeUsToSend() const {
726 return initial_round_trip_time_us_.GetSendValue();
727 }
728
SetInitialStreamFlowControlWindowToSend(uint64_t window_bytes)729 void QuicConfig::SetInitialStreamFlowControlWindowToSend(
730 uint64_t window_bytes) {
731 if (window_bytes < kMinimumFlowControlSendWindow) {
732 QUIC_BUG << "Initial stream flow control receive window (" << window_bytes
733 << ") cannot be set lower than minimum ("
734 << kMinimumFlowControlSendWindow << ").";
735 window_bytes = kMinimumFlowControlSendWindow;
736 }
737 initial_stream_flow_control_window_bytes_.SetSendValue(window_bytes);
738 }
739
GetInitialStreamFlowControlWindowToSend() const740 uint64_t QuicConfig::GetInitialStreamFlowControlWindowToSend() const {
741 return initial_stream_flow_control_window_bytes_.GetSendValue();
742 }
743
HasReceivedInitialStreamFlowControlWindowBytes() const744 bool QuicConfig::HasReceivedInitialStreamFlowControlWindowBytes() const {
745 return initial_stream_flow_control_window_bytes_.HasReceivedValue();
746 }
747
ReceivedInitialStreamFlowControlWindowBytes() const748 uint64_t QuicConfig::ReceivedInitialStreamFlowControlWindowBytes() const {
749 return initial_stream_flow_control_window_bytes_.GetReceivedValue();
750 }
751
SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(uint64_t window_bytes)752 void QuicConfig::SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
753 uint64_t window_bytes) {
754 initial_max_stream_data_bytes_incoming_bidirectional_.SetSendValue(
755 window_bytes);
756 }
757
GetInitialMaxStreamDataBytesIncomingBidirectionalToSend() const758 uint64_t QuicConfig::GetInitialMaxStreamDataBytesIncomingBidirectionalToSend()
759 const {
760 if (initial_max_stream_data_bytes_incoming_bidirectional_.HasSendValue()) {
761 return initial_max_stream_data_bytes_incoming_bidirectional_.GetSendValue();
762 }
763 return initial_stream_flow_control_window_bytes_.GetSendValue();
764 }
765
HasReceivedInitialMaxStreamDataBytesIncomingBidirectional() const766 bool QuicConfig::HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()
767 const {
768 return initial_max_stream_data_bytes_incoming_bidirectional_
769 .HasReceivedValue();
770 }
771
ReceivedInitialMaxStreamDataBytesIncomingBidirectional() const772 uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesIncomingBidirectional()
773 const {
774 return initial_max_stream_data_bytes_incoming_bidirectional_
775 .GetReceivedValue();
776 }
777
SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(uint64_t window_bytes)778 void QuicConfig::SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
779 uint64_t window_bytes) {
780 initial_max_stream_data_bytes_outgoing_bidirectional_.SetSendValue(
781 window_bytes);
782 }
783
GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend() const784 uint64_t QuicConfig::GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend()
785 const {
786 if (initial_max_stream_data_bytes_outgoing_bidirectional_.HasSendValue()) {
787 return initial_max_stream_data_bytes_outgoing_bidirectional_.GetSendValue();
788 }
789 return initial_stream_flow_control_window_bytes_.GetSendValue();
790 }
791
HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional() const792 bool QuicConfig::HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()
793 const {
794 return initial_max_stream_data_bytes_outgoing_bidirectional_
795 .HasReceivedValue();
796 }
797
ReceivedInitialMaxStreamDataBytesOutgoingBidirectional() const798 uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesOutgoingBidirectional()
799 const {
800 return initial_max_stream_data_bytes_outgoing_bidirectional_
801 .GetReceivedValue();
802 }
803
SetInitialMaxStreamDataBytesUnidirectionalToSend(uint64_t window_bytes)804 void QuicConfig::SetInitialMaxStreamDataBytesUnidirectionalToSend(
805 uint64_t window_bytes) {
806 initial_max_stream_data_bytes_unidirectional_.SetSendValue(window_bytes);
807 }
808
GetInitialMaxStreamDataBytesUnidirectionalToSend() const809 uint64_t QuicConfig::GetInitialMaxStreamDataBytesUnidirectionalToSend() const {
810 if (initial_max_stream_data_bytes_unidirectional_.HasSendValue()) {
811 return initial_max_stream_data_bytes_unidirectional_.GetSendValue();
812 }
813 return initial_stream_flow_control_window_bytes_.GetSendValue();
814 }
815
HasReceivedInitialMaxStreamDataBytesUnidirectional() const816 bool QuicConfig::HasReceivedInitialMaxStreamDataBytesUnidirectional() const {
817 return initial_max_stream_data_bytes_unidirectional_.HasReceivedValue();
818 }
819
ReceivedInitialMaxStreamDataBytesUnidirectional() const820 uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesUnidirectional() const {
821 return initial_max_stream_data_bytes_unidirectional_.GetReceivedValue();
822 }
823
SetInitialSessionFlowControlWindowToSend(uint64_t window_bytes)824 void QuicConfig::SetInitialSessionFlowControlWindowToSend(
825 uint64_t window_bytes) {
826 if (window_bytes < kMinimumFlowControlSendWindow) {
827 QUIC_BUG << "Initial session flow control receive window (" << window_bytes
828 << ") cannot be set lower than default ("
829 << kMinimumFlowControlSendWindow << ").";
830 window_bytes = kMinimumFlowControlSendWindow;
831 }
832 initial_session_flow_control_window_bytes_.SetSendValue(window_bytes);
833 }
834
GetInitialSessionFlowControlWindowToSend() const835 uint64_t QuicConfig::GetInitialSessionFlowControlWindowToSend() const {
836 return initial_session_flow_control_window_bytes_.GetSendValue();
837 }
838
HasReceivedInitialSessionFlowControlWindowBytes() const839 bool QuicConfig::HasReceivedInitialSessionFlowControlWindowBytes() const {
840 return initial_session_flow_control_window_bytes_.HasReceivedValue();
841 }
842
ReceivedInitialSessionFlowControlWindowBytes() const843 uint64_t QuicConfig::ReceivedInitialSessionFlowControlWindowBytes() const {
844 return initial_session_flow_control_window_bytes_.GetReceivedValue();
845 }
846
SetDisableConnectionMigration()847 void QuicConfig::SetDisableConnectionMigration() {
848 connection_migration_disabled_.SetSendValue(1);
849 }
850
DisableConnectionMigration() const851 bool QuicConfig::DisableConnectionMigration() const {
852 return connection_migration_disabled_.HasReceivedValue();
853 }
854
SetSupportHandshakeDone()855 void QuicConfig::SetSupportHandshakeDone() {
856 support_handshake_done_.SetSendValue(1);
857 }
858
HandshakeDoneSupported() const859 bool QuicConfig::HandshakeDoneSupported() const {
860 return support_handshake_done_.HasSendValue() &&
861 support_handshake_done_.GetSendValue() > 0;
862 }
863
PeerSupportsHandshakeDone() const864 bool QuicConfig::PeerSupportsHandshakeDone() const {
865 return support_handshake_done_.HasReceivedValue();
866 }
867
SetKeyUpdateSupportedLocally()868 void QuicConfig::SetKeyUpdateSupportedLocally() {
869 key_update_supported_locally_ = true;
870 }
871
KeyUpdateSupportedForConnection() const872 bool QuicConfig::KeyUpdateSupportedForConnection() const {
873 return KeyUpdateSupportedRemotely() && KeyUpdateSupportedLocally();
874 }
875
KeyUpdateSupportedLocally() const876 bool QuicConfig::KeyUpdateSupportedLocally() const {
877 return key_update_supported_locally_;
878 }
879
KeyUpdateSupportedRemotely() const880 bool QuicConfig::KeyUpdateSupportedRemotely() const {
881 return key_update_supported_remotely_;
882 }
883
SetIPv6AlternateServerAddressToSend(const QuicSocketAddress & alternate_server_address_ipv6)884 void QuicConfig::SetIPv6AlternateServerAddressToSend(
885 const QuicSocketAddress& alternate_server_address_ipv6) {
886 if (!alternate_server_address_ipv6.host().IsIPv6()) {
887 QUIC_BUG << "Cannot use SetIPv6AlternateServerAddressToSend with "
888 << alternate_server_address_ipv6;
889 return;
890 }
891 alternate_server_address_ipv6_.SetSendValue(alternate_server_address_ipv6);
892 }
893
HasReceivedIPv6AlternateServerAddress() const894 bool QuicConfig::HasReceivedIPv6AlternateServerAddress() const {
895 return alternate_server_address_ipv6_.HasReceivedValue();
896 }
897
ReceivedIPv6AlternateServerAddress() const898 const QuicSocketAddress& QuicConfig::ReceivedIPv6AlternateServerAddress()
899 const {
900 return alternate_server_address_ipv6_.GetReceivedValue();
901 }
902
SetIPv4AlternateServerAddressToSend(const QuicSocketAddress & alternate_server_address_ipv4)903 void QuicConfig::SetIPv4AlternateServerAddressToSend(
904 const QuicSocketAddress& alternate_server_address_ipv4) {
905 if (!alternate_server_address_ipv4.host().IsIPv4()) {
906 QUIC_BUG << "Cannot use SetIPv4AlternateServerAddressToSend with "
907 << alternate_server_address_ipv4;
908 return;
909 }
910 alternate_server_address_ipv4_.SetSendValue(alternate_server_address_ipv4);
911 }
912
HasReceivedIPv4AlternateServerAddress() const913 bool QuicConfig::HasReceivedIPv4AlternateServerAddress() const {
914 return alternate_server_address_ipv4_.HasReceivedValue();
915 }
916
ReceivedIPv4AlternateServerAddress() const917 const QuicSocketAddress& QuicConfig::ReceivedIPv4AlternateServerAddress()
918 const {
919 return alternate_server_address_ipv4_.GetReceivedValue();
920 }
921
SetOriginalConnectionIdToSend(const QuicConnectionId & original_destination_connection_id)922 void QuicConfig::SetOriginalConnectionIdToSend(
923 const QuicConnectionId& original_destination_connection_id) {
924 original_destination_connection_id_to_send_ =
925 original_destination_connection_id;
926 }
927
HasReceivedOriginalConnectionId() const928 bool QuicConfig::HasReceivedOriginalConnectionId() const {
929 return received_original_destination_connection_id_.has_value();
930 }
931
ReceivedOriginalConnectionId() const932 QuicConnectionId QuicConfig::ReceivedOriginalConnectionId() const {
933 if (!HasReceivedOriginalConnectionId()) {
934 QUIC_BUG << "No received original connection ID";
935 return EmptyQuicConnectionId();
936 }
937 return received_original_destination_connection_id_.value();
938 }
939
SetInitialSourceConnectionIdToSend(const QuicConnectionId & initial_source_connection_id)940 void QuicConfig::SetInitialSourceConnectionIdToSend(
941 const QuicConnectionId& initial_source_connection_id) {
942 initial_source_connection_id_to_send_ = initial_source_connection_id;
943 }
944
HasReceivedInitialSourceConnectionId() const945 bool QuicConfig::HasReceivedInitialSourceConnectionId() const {
946 return received_initial_source_connection_id_.has_value();
947 }
948
ReceivedInitialSourceConnectionId() const949 QuicConnectionId QuicConfig::ReceivedInitialSourceConnectionId() const {
950 if (!HasReceivedInitialSourceConnectionId()) {
951 QUIC_BUG << "No received initial source connection ID";
952 return EmptyQuicConnectionId();
953 }
954 return received_initial_source_connection_id_.value();
955 }
956
SetRetrySourceConnectionIdToSend(const QuicConnectionId & retry_source_connection_id)957 void QuicConfig::SetRetrySourceConnectionIdToSend(
958 const QuicConnectionId& retry_source_connection_id) {
959 retry_source_connection_id_to_send_ = retry_source_connection_id;
960 }
961
HasReceivedRetrySourceConnectionId() const962 bool QuicConfig::HasReceivedRetrySourceConnectionId() const {
963 return received_retry_source_connection_id_.has_value();
964 }
965
ReceivedRetrySourceConnectionId() const966 QuicConnectionId QuicConfig::ReceivedRetrySourceConnectionId() const {
967 if (!HasReceivedRetrySourceConnectionId()) {
968 QUIC_BUG << "No received retry source connection ID";
969 return EmptyQuicConnectionId();
970 }
971 return received_retry_source_connection_id_.value();
972 }
973
SetStatelessResetTokenToSend(QuicUint128 stateless_reset_token)974 void QuicConfig::SetStatelessResetTokenToSend(
975 QuicUint128 stateless_reset_token) {
976 stateless_reset_token_.SetSendValue(stateless_reset_token);
977 }
978
HasReceivedStatelessResetToken() const979 bool QuicConfig::HasReceivedStatelessResetToken() const {
980 return stateless_reset_token_.HasReceivedValue();
981 }
982
ReceivedStatelessResetToken() const983 QuicUint128 QuicConfig::ReceivedStatelessResetToken() const {
984 return stateless_reset_token_.GetReceivedValue();
985 }
986
negotiated() const987 bool QuicConfig::negotiated() const {
988 return negotiated_;
989 }
990
SetCreateSessionTagIndicators(QuicTagVector tags)991 void QuicConfig::SetCreateSessionTagIndicators(QuicTagVector tags) {
992 create_session_tag_indicators_ = std::move(tags);
993 }
994
create_session_tag_indicators() const995 const QuicTagVector& QuicConfig::create_session_tag_indicators() const {
996 return create_session_tag_indicators_;
997 }
998
SetDefaults()999 void QuicConfig::SetDefaults() {
1000 SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
1001 SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
1002 SetMaxUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
1003 max_time_before_crypto_handshake_ =
1004 QuicTime::Delta::FromSeconds(kMaxTimeForCryptoHandshakeSecs);
1005 max_idle_time_before_crypto_handshake_ =
1006 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs);
1007 max_undecryptable_packets_ = kDefaultMaxUndecryptablePackets;
1008
1009 SetInitialStreamFlowControlWindowToSend(kMinimumFlowControlSendWindow);
1010 SetInitialSessionFlowControlWindowToSend(kMinimumFlowControlSendWindow);
1011 SetMaxAckDelayToSendMs(kDefaultDelayedAckTimeMs);
1012 SetAckDelayExponentToSend(kDefaultAckDelayExponent);
1013 SetMaxPacketSizeToSend(kMaxIncomingPacketSize);
1014 SetMaxDatagramFrameSizeToSend(kMaxAcceptedDatagramFrameSize);
1015 }
1016
ToHandshakeMessage(CryptoHandshakeMessage * out,QuicTransportVersion transport_version) const1017 void QuicConfig::ToHandshakeMessage(
1018 CryptoHandshakeMessage* out,
1019 QuicTransportVersion transport_version) const {
1020 // Idle timeout has custom rules that are different from other values.
1021 // We configure ourselves with the minumum value between the one sent and
1022 // the one received. Additionally, when QUIC_CRYPTO is used, the server
1023 // MUST send an idle timeout no greater than the idle timeout it received
1024 // from the client. We therefore send the received value if it is lower.
1025 QuicFixedUint32 max_idle_timeout_seconds(kICSL, PRESENCE_REQUIRED);
1026 uint32_t max_idle_timeout_to_send_seconds =
1027 max_idle_timeout_to_send_.ToSeconds();
1028 if (received_max_idle_timeout_.has_value() &&
1029 received_max_idle_timeout_->ToSeconds() <
1030 max_idle_timeout_to_send_seconds) {
1031 max_idle_timeout_to_send_seconds = received_max_idle_timeout_->ToSeconds();
1032 }
1033 max_idle_timeout_seconds.SetSendValue(max_idle_timeout_to_send_seconds);
1034 max_idle_timeout_seconds.ToHandshakeMessage(out);
1035
1036 // Do not need a version check here, max...bi... will encode
1037 // as "MIDS" -- the max initial dynamic streams tag -- if
1038 // doing some version other than IETF QUIC.
1039 max_bidirectional_streams_.ToHandshakeMessage(out);
1040 if (VersionHasIetfQuicFrames(transport_version)) {
1041 max_unidirectional_streams_.ToHandshakeMessage(out);
1042 ack_delay_exponent_.ToHandshakeMessage(out);
1043 }
1044 if (max_ack_delay_ms_.GetSendValue() != kDefaultDelayedAckTimeMs) {
1045 // Only send max ack delay if it is using a non-default value, because
1046 // the default value is used by QuicSentPacketManager if it is not
1047 // sent during the handshake, and we want to save bytes.
1048 max_ack_delay_ms_.ToHandshakeMessage(out);
1049 }
1050 bytes_for_connection_id_.ToHandshakeMessage(out);
1051 initial_round_trip_time_us_.ToHandshakeMessage(out);
1052 initial_stream_flow_control_window_bytes_.ToHandshakeMessage(out);
1053 initial_session_flow_control_window_bytes_.ToHandshakeMessage(out);
1054 connection_migration_disabled_.ToHandshakeMessage(out);
1055 connection_options_.ToHandshakeMessage(out);
1056 if (alternate_server_address_ipv6_.HasSendValue()) {
1057 alternate_server_address_ipv6_.ToHandshakeMessage(out);
1058 } else {
1059 alternate_server_address_ipv4_.ToHandshakeMessage(out);
1060 }
1061 stateless_reset_token_.ToHandshakeMessage(out);
1062 }
1063
ProcessPeerHello(const CryptoHandshakeMessage & peer_hello,HelloType hello_type,std::string * error_details)1064 QuicErrorCode QuicConfig::ProcessPeerHello(
1065 const CryptoHandshakeMessage& peer_hello,
1066 HelloType hello_type,
1067 std::string* error_details) {
1068 DCHECK(error_details != nullptr);
1069
1070 QuicErrorCode error = QUIC_NO_ERROR;
1071 if (error == QUIC_NO_ERROR) {
1072 // Idle timeout has custom rules that are different from other values.
1073 // We configure ourselves with the minumum value between the one sent and
1074 // the one received. Additionally, when QUIC_CRYPTO is used, the server
1075 // MUST send an idle timeout no greater than the idle timeout it received
1076 // from the client.
1077 QuicFixedUint32 max_idle_timeout_seconds(kICSL, PRESENCE_REQUIRED);
1078 error = max_idle_timeout_seconds.ProcessPeerHello(peer_hello, hello_type,
1079 error_details);
1080 if (error == QUIC_NO_ERROR) {
1081 if (max_idle_timeout_seconds.GetReceivedValue() >
1082 max_idle_timeout_to_send_.ToSeconds()) {
1083 // The received value is higher than ours, ignore it if from the client
1084 // and raise an error if from the server.
1085 if (hello_type == SERVER) {
1086 error = QUIC_INVALID_NEGOTIATED_VALUE;
1087 *error_details =
1088 "Invalid value received for " + QuicTagToString(kICSL);
1089 }
1090 } else {
1091 received_max_idle_timeout_ = QuicTime::Delta::FromSeconds(
1092 max_idle_timeout_seconds.GetReceivedValue());
1093 }
1094 }
1095 }
1096 if (error == QUIC_NO_ERROR) {
1097 error = max_bidirectional_streams_.ProcessPeerHello(peer_hello, hello_type,
1098 error_details);
1099 }
1100 if (error == QUIC_NO_ERROR) {
1101 error = max_unidirectional_streams_.ProcessPeerHello(peer_hello, hello_type,
1102 error_details);
1103 }
1104 if (error == QUIC_NO_ERROR) {
1105 error = bytes_for_connection_id_.ProcessPeerHello(peer_hello, hello_type,
1106 error_details);
1107 }
1108 if (error == QUIC_NO_ERROR) {
1109 error = initial_round_trip_time_us_.ProcessPeerHello(peer_hello, hello_type,
1110 error_details);
1111 }
1112 if (error == QUIC_NO_ERROR) {
1113 error = initial_stream_flow_control_window_bytes_.ProcessPeerHello(
1114 peer_hello, hello_type, error_details);
1115 }
1116 if (error == QUIC_NO_ERROR) {
1117 error = initial_session_flow_control_window_bytes_.ProcessPeerHello(
1118 peer_hello, hello_type, error_details);
1119 }
1120 if (error == QUIC_NO_ERROR) {
1121 error = connection_migration_disabled_.ProcessPeerHello(
1122 peer_hello, hello_type, error_details);
1123 }
1124 if (error == QUIC_NO_ERROR) {
1125 error = connection_options_.ProcessPeerHello(peer_hello, hello_type,
1126 error_details);
1127 }
1128 if (error == QUIC_NO_ERROR) {
1129 QuicFixedSocketAddress alternate_server_address(kASAD, PRESENCE_OPTIONAL);
1130 error = alternate_server_address.ProcessPeerHello(peer_hello, hello_type,
1131 error_details);
1132 if (error == QUIC_NO_ERROR && alternate_server_address.HasReceivedValue()) {
1133 const QuicSocketAddress& received_address =
1134 alternate_server_address.GetReceivedValue();
1135 if (received_address.host().IsIPv6()) {
1136 alternate_server_address_ipv6_.SetReceivedValue(received_address);
1137 } else if (received_address.host().IsIPv4()) {
1138 alternate_server_address_ipv4_.SetReceivedValue(received_address);
1139 }
1140 }
1141 }
1142 if (error == QUIC_NO_ERROR) {
1143 error = stateless_reset_token_.ProcessPeerHello(peer_hello, hello_type,
1144 error_details);
1145 }
1146
1147 if (error == QUIC_NO_ERROR) {
1148 error = max_ack_delay_ms_.ProcessPeerHello(peer_hello, hello_type,
1149 error_details);
1150 }
1151 if (error == QUIC_NO_ERROR) {
1152 error = ack_delay_exponent_.ProcessPeerHello(peer_hello, hello_type,
1153 error_details);
1154 }
1155 if (error == QUIC_NO_ERROR) {
1156 negotiated_ = true;
1157 }
1158 return error;
1159 }
1160
FillTransportParameters(TransportParameters * params) const1161 bool QuicConfig::FillTransportParameters(TransportParameters* params) const {
1162 if (original_destination_connection_id_to_send_.has_value()) {
1163 params->original_destination_connection_id =
1164 original_destination_connection_id_to_send_.value();
1165 }
1166
1167 params->max_idle_timeout_ms.set_value(
1168 max_idle_timeout_to_send_.ToMilliseconds());
1169
1170 if (stateless_reset_token_.HasSendValue()) {
1171 QuicUint128 stateless_reset_token = stateless_reset_token_.GetSendValue();
1172 params->stateless_reset_token.assign(
1173 reinterpret_cast<const char*>(&stateless_reset_token),
1174 reinterpret_cast<const char*>(&stateless_reset_token) +
1175 sizeof(stateless_reset_token));
1176 }
1177
1178 params->max_udp_payload_size.set_value(GetMaxPacketSizeToSend());
1179 params->max_datagram_frame_size.set_value(GetMaxDatagramFrameSizeToSend());
1180 params->initial_max_data.set_value(
1181 GetInitialSessionFlowControlWindowToSend());
1182 // The max stream data bidirectional transport parameters can be either local
1183 // or remote. A stream is local iff it is initiated by the endpoint that sent
1184 // the transport parameter (see the Transport Parameter Definitions section of
1185 // draft-ietf-quic-transport). In this function we are sending transport
1186 // parameters, so a local stream is one we initiated, which means an outgoing
1187 // stream.
1188 params->initial_max_stream_data_bidi_local.set_value(
1189 GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
1190 params->initial_max_stream_data_bidi_remote.set_value(
1191 GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
1192 params->initial_max_stream_data_uni.set_value(
1193 GetInitialMaxStreamDataBytesUnidirectionalToSend());
1194 params->initial_max_streams_bidi.set_value(
1195 GetMaxBidirectionalStreamsToSend());
1196 params->initial_max_streams_uni.set_value(
1197 GetMaxUnidirectionalStreamsToSend());
1198 params->max_ack_delay.set_value(GetMaxAckDelayToSendMs());
1199 if (min_ack_delay_ms_.HasSendValue()) {
1200 params->min_ack_delay_us.set_value(min_ack_delay_ms_.GetSendValue() *
1201 kNumMicrosPerMilli);
1202 }
1203 params->ack_delay_exponent.set_value(GetAckDelayExponentToSend());
1204 params->disable_active_migration =
1205 connection_migration_disabled_.HasSendValue() &&
1206 connection_migration_disabled_.GetSendValue() != 0;
1207 params->support_handshake_done = HandshakeDoneSupported();
1208
1209 if (alternate_server_address_ipv6_.HasSendValue() ||
1210 alternate_server_address_ipv4_.HasSendValue()) {
1211 TransportParameters::PreferredAddress preferred_address;
1212 if (alternate_server_address_ipv6_.HasSendValue()) {
1213 preferred_address.ipv6_socket_address =
1214 alternate_server_address_ipv6_.GetSendValue();
1215 }
1216 if (alternate_server_address_ipv4_.HasSendValue()) {
1217 preferred_address.ipv4_socket_address =
1218 alternate_server_address_ipv4_.GetSendValue();
1219 }
1220 params->preferred_address =
1221 std::make_unique<TransportParameters::PreferredAddress>(
1222 preferred_address);
1223 }
1224
1225 if (active_connection_id_limit_.HasSendValue()) {
1226 params->active_connection_id_limit.set_value(
1227 active_connection_id_limit_.GetSendValue());
1228 }
1229
1230 if (initial_source_connection_id_to_send_.has_value()) {
1231 params->initial_source_connection_id =
1232 initial_source_connection_id_to_send_.value();
1233 }
1234
1235 if (retry_source_connection_id_to_send_.has_value()) {
1236 params->retry_source_connection_id =
1237 retry_source_connection_id_to_send_.value();
1238 }
1239
1240 if (initial_round_trip_time_us_.HasSendValue()) {
1241 params->initial_round_trip_time_us.set_value(
1242 initial_round_trip_time_us_.GetSendValue());
1243 }
1244 if (connection_options_.HasSendValues() &&
1245 !connection_options_.GetSendValues().empty()) {
1246 params->google_connection_options = connection_options_.GetSendValues();
1247 }
1248
1249 if (!KeyUpdateSupportedLocally()) {
1250 params->key_update_not_yet_supported = true;
1251 }
1252
1253 params->custom_parameters = custom_transport_parameters_to_send_;
1254
1255 return true;
1256 }
1257
ProcessTransportParameters(const TransportParameters & params,bool is_resumption,std::string * error_details)1258 QuicErrorCode QuicConfig::ProcessTransportParameters(
1259 const TransportParameters& params,
1260 bool is_resumption,
1261 std::string* error_details) {
1262 if (!is_resumption && params.original_destination_connection_id.has_value()) {
1263 received_original_destination_connection_id_ =
1264 params.original_destination_connection_id.value();
1265 }
1266
1267 if (params.max_idle_timeout_ms.value() > 0 &&
1268 params.max_idle_timeout_ms.value() <
1269 static_cast<uint64_t>(max_idle_timeout_to_send_.ToMilliseconds())) {
1270 // An idle timeout of zero indicates it is disabled.
1271 // We also ignore values higher than ours which will cause us to use the
1272 // smallest value between ours and our peer's.
1273 received_max_idle_timeout_ =
1274 QuicTime::Delta::FromMilliseconds(params.max_idle_timeout_ms.value());
1275 }
1276
1277 if (!is_resumption && !params.stateless_reset_token.empty()) {
1278 QuicUint128 stateless_reset_token;
1279 if (params.stateless_reset_token.size() != sizeof(stateless_reset_token)) {
1280 QUIC_BUG << "Bad stateless reset token length "
1281 << params.stateless_reset_token.size();
1282 *error_details = "Bad stateless reset token length";
1283 return QUIC_INTERNAL_ERROR;
1284 }
1285 memcpy(&stateless_reset_token, params.stateless_reset_token.data(),
1286 params.stateless_reset_token.size());
1287 stateless_reset_token_.SetReceivedValue(stateless_reset_token);
1288 }
1289
1290 if (params.max_udp_payload_size.IsValid()) {
1291 max_udp_payload_size_.SetReceivedValue(params.max_udp_payload_size.value());
1292 }
1293
1294 if (params.max_datagram_frame_size.IsValid()) {
1295 max_datagram_frame_size_.SetReceivedValue(
1296 params.max_datagram_frame_size.value());
1297 }
1298
1299 initial_session_flow_control_window_bytes_.SetReceivedValue(
1300 params.initial_max_data.value());
1301
1302 // IETF QUIC specifies stream IDs and stream counts as 62-bit integers but
1303 // our implementation uses uint32_t to represent them to save memory.
1304 max_bidirectional_streams_.SetReceivedValue(
1305 std::min<uint64_t>(params.initial_max_streams_bidi.value(),
1306 std::numeric_limits<uint32_t>::max()));
1307 max_unidirectional_streams_.SetReceivedValue(
1308 std::min<uint64_t>(params.initial_max_streams_uni.value(),
1309 std::numeric_limits<uint32_t>::max()));
1310
1311 // The max stream data bidirectional transport parameters can be either local
1312 // or remote. A stream is local iff it is initiated by the endpoint that sent
1313 // the transport parameter (see the Transport Parameter Definitions section of
1314 // draft-ietf-quic-transport). However in this function we are processing
1315 // received transport parameters, so a local stream is one initiated by our
1316 // peer, which means an incoming stream.
1317 initial_max_stream_data_bytes_incoming_bidirectional_.SetReceivedValue(
1318 params.initial_max_stream_data_bidi_local.value());
1319 initial_max_stream_data_bytes_outgoing_bidirectional_.SetReceivedValue(
1320 params.initial_max_stream_data_bidi_remote.value());
1321 initial_max_stream_data_bytes_unidirectional_.SetReceivedValue(
1322 params.initial_max_stream_data_uni.value());
1323
1324 if (!is_resumption) {
1325 max_ack_delay_ms_.SetReceivedValue(params.max_ack_delay.value());
1326 if (params.ack_delay_exponent.IsValid()) {
1327 ack_delay_exponent_.SetReceivedValue(params.ack_delay_exponent.value());
1328 }
1329 if (params.preferred_address != nullptr) {
1330 if (params.preferred_address->ipv6_socket_address.port() != 0) {
1331 alternate_server_address_ipv6_.SetReceivedValue(
1332 params.preferred_address->ipv6_socket_address);
1333 }
1334 if (params.preferred_address->ipv4_socket_address.port() != 0) {
1335 alternate_server_address_ipv4_.SetReceivedValue(
1336 params.preferred_address->ipv4_socket_address);
1337 }
1338 }
1339 if (GetQuicReloadableFlag(quic_record_received_min_ack_delay)) {
1340 if (params.min_ack_delay_us.value() != 0) {
1341 if (params.min_ack_delay_us.value() >
1342 params.max_ack_delay.value() * kNumMicrosPerMilli) {
1343 *error_details = "MinAckDelay is greater than MaxAckDelay.";
1344 return IETF_QUIC_PROTOCOL_VIOLATION;
1345 }
1346 QUIC_RELOADABLE_FLAG_COUNT(quic_record_received_min_ack_delay);
1347 min_ack_delay_ms_.SetReceivedValue(params.min_ack_delay_us.value() /
1348 kNumMicrosPerMilli);
1349 }
1350 }
1351 }
1352
1353 if (params.disable_active_migration) {
1354 connection_migration_disabled_.SetReceivedValue(1u);
1355 }
1356 if (params.support_handshake_done) {
1357 support_handshake_done_.SetReceivedValue(1u);
1358 }
1359 if (!is_resumption && !params.key_update_not_yet_supported) {
1360 key_update_supported_remotely_ = true;
1361 }
1362
1363 active_connection_id_limit_.SetReceivedValue(
1364 params.active_connection_id_limit.value());
1365
1366 if (!is_resumption) {
1367 if (params.initial_source_connection_id.has_value()) {
1368 received_initial_source_connection_id_ =
1369 params.initial_source_connection_id.value();
1370 }
1371 if (params.retry_source_connection_id.has_value()) {
1372 received_retry_source_connection_id_ =
1373 params.retry_source_connection_id.value();
1374 }
1375 }
1376
1377 if (params.initial_round_trip_time_us.value() > 0) {
1378 initial_round_trip_time_us_.SetReceivedValue(
1379 params.initial_round_trip_time_us.value());
1380 }
1381 if (params.google_connection_options.has_value()) {
1382 connection_options_.SetReceivedValues(
1383 params.google_connection_options.value());
1384 }
1385
1386 received_custom_transport_parameters_ = params.custom_parameters;
1387
1388 if (!is_resumption) {
1389 negotiated_ = true;
1390 }
1391 *error_details = "";
1392 return QUIC_NO_ERROR;
1393 }
1394
1395 } // namespace quic
1396