blob: e48d21a7c391970ce4cf93f0f87db23f85110f8d [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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>
dschinazi52127d72019-04-17 15:12:38 -07008#include <cstring>
vasilvv872e7a32019-03-12 16:42:44 -07009#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050010
11#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h"
12#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
dschinazi52127d72019-04-17 15:12:38 -070013#include "net/third_party/quiche/src/quic/core/quic_constants.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050014#include "net/third_party/quiche/src/quic/core/quic_socket_address_coder.h"
15#include "net/third_party/quiche/src/quic/core/quic_utils.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
17#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
18#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
19#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
20#include "net/third_party/quiche/src/quic/platform/api/quic_macros.h"
21#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
dschinazi52127d72019-04-17 15:12:38 -070022#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050023#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
dschinazi52127d72019-04-17 15:12:38 -070024#include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050025
26namespace quic {
27
28// Reads the value corresponding to |name_| from |msg| into |out|. If the
29// |name_| is absent in |msg| and |presence| is set to OPTIONAL |out| is set
30// to |default_value|.
31QuicErrorCode ReadUint32(const CryptoHandshakeMessage& msg,
32 QuicTag tag,
33 QuicConfigPresence presence,
34 uint32_t default_value,
35 uint32_t* out,
vasilvvc48c8712019-03-11 13:38:16 -070036 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050037 DCHECK(error_details != nullptr);
38 QuicErrorCode error = msg.GetUint32(tag, out);
39 switch (error) {
40 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
41 if (presence == PRESENCE_REQUIRED) {
42 *error_details = "Missing " + QuicTagToString(tag);
43 break;
44 }
45 error = QUIC_NO_ERROR;
46 *out = default_value;
47 break;
48 case QUIC_NO_ERROR:
49 break;
50 default:
51 *error_details = "Bad " + QuicTagToString(tag);
52 break;
53 }
54 return error;
55}
56
57QuicConfigValue::QuicConfigValue(QuicTag tag, QuicConfigPresence presence)
58 : tag_(tag), presence_(presence) {}
59QuicConfigValue::~QuicConfigValue() {}
60
61QuicNegotiableValue::QuicNegotiableValue(QuicTag tag,
62 QuicConfigPresence presence)
63 : QuicConfigValue(tag, presence), negotiated_(false) {}
64QuicNegotiableValue::~QuicNegotiableValue() {}
65
66QuicNegotiableUint32::QuicNegotiableUint32(QuicTag tag,
67 QuicConfigPresence presence)
68 : QuicNegotiableValue(tag, presence),
69 max_value_(0),
70 default_value_(0),
71 negotiated_value_(0) {}
72QuicNegotiableUint32::~QuicNegotiableUint32() {}
73
74void QuicNegotiableUint32::set(uint32_t max, uint32_t default_value) {
75 DCHECK_LE(default_value, max);
76 max_value_ = max;
77 default_value_ = default_value;
78}
79
80uint32_t QuicNegotiableUint32::GetUint32() const {
81 if (negotiated()) {
82 return negotiated_value_;
83 }
84 return default_value_;
85}
86
87// Returns the maximum value negotiable.
88uint32_t QuicNegotiableUint32::GetMax() const {
89 return max_value_;
90}
91
92void QuicNegotiableUint32::ToHandshakeMessage(
93 CryptoHandshakeMessage* out) const {
94 if (negotiated()) {
95 out->SetValue(tag_, negotiated_value_);
96 } else {
97 out->SetValue(tag_, max_value_);
98 }
99}
100
101QuicErrorCode QuicNegotiableUint32::ProcessPeerHello(
102 const CryptoHandshakeMessage& peer_hello,
103 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700104 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500105 DCHECK(!negotiated());
106 DCHECK(error_details != nullptr);
107 uint32_t value;
108 QuicErrorCode error = ReadUint32(peer_hello, tag_, presence_, default_value_,
109 &value, error_details);
110 if (error != QUIC_NO_ERROR) {
111 return error;
112 }
113 return ReceiveValue(value, hello_type, error_details);
114}
115
116QuicErrorCode QuicNegotiableUint32::ReceiveValue(uint32_t value,
117 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700118 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500119 if (hello_type == SERVER && value > max_value_) {
120 *error_details = "Invalid value received for " + QuicTagToString(tag_);
121 return QUIC_INVALID_NEGOTIATED_VALUE;
122 }
123
124 set_negotiated(true);
125 negotiated_value_ = std::min(value, max_value_);
126 return QUIC_NO_ERROR;
127}
128
129QuicFixedUint32::QuicFixedUint32(QuicTag tag, QuicConfigPresence presence)
130 : QuicConfigValue(tag, presence),
131 has_send_value_(false),
132 has_receive_value_(false) {}
133QuicFixedUint32::~QuicFixedUint32() {}
134
135bool QuicFixedUint32::HasSendValue() const {
136 return has_send_value_;
137}
138
139uint32_t QuicFixedUint32::GetSendValue() const {
140 QUIC_BUG_IF(!has_send_value_)
141 << "No send value to get for tag:" << QuicTagToString(tag_);
142 return send_value_;
143}
144
145void QuicFixedUint32::SetSendValue(uint32_t value) {
146 has_send_value_ = true;
147 send_value_ = value;
148}
149
150bool QuicFixedUint32::HasReceivedValue() const {
151 return has_receive_value_;
152}
153
154uint32_t QuicFixedUint32::GetReceivedValue() const {
155 QUIC_BUG_IF(!has_receive_value_)
156 << "No receive value to get for tag:" << QuicTagToString(tag_);
157 return receive_value_;
158}
159
160void QuicFixedUint32::SetReceivedValue(uint32_t value) {
161 has_receive_value_ = true;
162 receive_value_ = value;
163}
164
165void QuicFixedUint32::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
166 if (has_send_value_) {
167 out->SetValue(tag_, send_value_);
168 }
169}
170
171QuicErrorCode QuicFixedUint32::ProcessPeerHello(
172 const CryptoHandshakeMessage& peer_hello,
dschinazi17d42422019-06-18 16:35:07 -0700173 HelloType /*hello_type*/,
vasilvvc48c8712019-03-11 13:38:16 -0700174 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500175 DCHECK(error_details != nullptr);
176 QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value_);
177 switch (error) {
178 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
179 if (presence_ == PRESENCE_OPTIONAL) {
180 return QUIC_NO_ERROR;
181 }
182 *error_details = "Missing " + QuicTagToString(tag_);
183 break;
184 case QUIC_NO_ERROR:
185 has_receive_value_ = true;
186 break;
187 default:
188 *error_details = "Bad " + QuicTagToString(tag_);
189 break;
190 }
191 return error;
192}
193
194QuicFixedUint128::QuicFixedUint128(QuicTag tag, QuicConfigPresence presence)
195 : QuicConfigValue(tag, presence),
196 has_send_value_(false),
197 has_receive_value_(false) {}
198QuicFixedUint128::~QuicFixedUint128() {}
199
200bool QuicFixedUint128::HasSendValue() const {
201 return has_send_value_;
202}
203
204QuicUint128 QuicFixedUint128::GetSendValue() const {
205 QUIC_BUG_IF(!has_send_value_)
206 << "No send value to get for tag:" << QuicTagToString(tag_);
207 return send_value_;
208}
209
210void QuicFixedUint128::SetSendValue(QuicUint128 value) {
211 has_send_value_ = true;
212 send_value_ = value;
213}
214
215bool QuicFixedUint128::HasReceivedValue() const {
216 return has_receive_value_;
217}
218
219QuicUint128 QuicFixedUint128::GetReceivedValue() const {
220 QUIC_BUG_IF(!has_receive_value_)
221 << "No receive value to get for tag:" << QuicTagToString(tag_);
222 return receive_value_;
223}
224
225void QuicFixedUint128::SetReceivedValue(QuicUint128 value) {
226 has_receive_value_ = true;
227 receive_value_ = value;
228}
229
230void QuicFixedUint128::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
231 if (has_send_value_) {
232 out->SetValue(tag_, send_value_);
233 }
234}
235
236QuicErrorCode QuicFixedUint128::ProcessPeerHello(
237 const CryptoHandshakeMessage& peer_hello,
dschinazi17d42422019-06-18 16:35:07 -0700238 HelloType /*hello_type*/,
vasilvvc48c8712019-03-11 13:38:16 -0700239 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500240 DCHECK(error_details != nullptr);
241 QuicErrorCode error = peer_hello.GetUint128(tag_, &receive_value_);
242 switch (error) {
243 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
244 if (presence_ == PRESENCE_OPTIONAL) {
245 return QUIC_NO_ERROR;
246 }
247 *error_details = "Missing " + QuicTagToString(tag_);
248 break;
249 case QUIC_NO_ERROR:
250 has_receive_value_ = true;
251 break;
252 default:
253 *error_details = "Bad " + QuicTagToString(tag_);
254 break;
255 }
256 return error;
257}
258
259QuicFixedTagVector::QuicFixedTagVector(QuicTag name,
260 QuicConfigPresence presence)
261 : QuicConfigValue(name, presence),
262 has_send_values_(false),
263 has_receive_values_(false) {}
264
265QuicFixedTagVector::QuicFixedTagVector(const QuicFixedTagVector& other) =
266 default;
267
268QuicFixedTagVector::~QuicFixedTagVector() {}
269
270bool QuicFixedTagVector::HasSendValues() const {
271 return has_send_values_;
272}
273
274QuicTagVector QuicFixedTagVector::GetSendValues() const {
275 QUIC_BUG_IF(!has_send_values_)
276 << "No send values to get for tag:" << QuicTagToString(tag_);
277 return send_values_;
278}
279
280void QuicFixedTagVector::SetSendValues(const QuicTagVector& values) {
281 has_send_values_ = true;
282 send_values_ = values;
283}
284
285bool QuicFixedTagVector::HasReceivedValues() const {
286 return has_receive_values_;
287}
288
289QuicTagVector QuicFixedTagVector::GetReceivedValues() const {
290 QUIC_BUG_IF(!has_receive_values_)
291 << "No receive value to get for tag:" << QuicTagToString(tag_);
292 return receive_values_;
293}
294
295void QuicFixedTagVector::SetReceivedValues(const QuicTagVector& values) {
296 has_receive_values_ = true;
297 receive_values_ = values;
298}
299
300void QuicFixedTagVector::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
301 if (has_send_values_) {
302 out->SetVector(tag_, send_values_);
303 }
304}
305
306QuicErrorCode QuicFixedTagVector::ProcessPeerHello(
307 const CryptoHandshakeMessage& peer_hello,
dschinazi17d42422019-06-18 16:35:07 -0700308 HelloType /*hello_type*/,
vasilvvc48c8712019-03-11 13:38:16 -0700309 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500310 DCHECK(error_details != nullptr);
311 QuicTagVector values;
312 QuicErrorCode error = peer_hello.GetTaglist(tag_, &values);
313 switch (error) {
314 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
315 if (presence_ == PRESENCE_OPTIONAL) {
316 return QUIC_NO_ERROR;
317 }
318 *error_details = "Missing " + QuicTagToString(tag_);
319 break;
320 case QUIC_NO_ERROR:
321 QUIC_DVLOG(1) << "Received Connection Option tags from receiver.";
322 has_receive_values_ = true;
323 receive_values_.insert(receive_values_.end(), values.begin(),
324 values.end());
325 break;
326 default:
327 *error_details = "Bad " + QuicTagToString(tag_);
328 break;
329 }
330 return error;
331}
332
333QuicFixedSocketAddress::QuicFixedSocketAddress(QuicTag tag,
334 QuicConfigPresence presence)
335 : QuicConfigValue(tag, presence),
336 has_send_value_(false),
337 has_receive_value_(false) {}
338
339QuicFixedSocketAddress::~QuicFixedSocketAddress() {}
340
341bool QuicFixedSocketAddress::HasSendValue() const {
342 return has_send_value_;
343}
344
345const QuicSocketAddress& QuicFixedSocketAddress::GetSendValue() const {
346 QUIC_BUG_IF(!has_send_value_)
347 << "No send value to get for tag:" << QuicTagToString(tag_);
348 return send_value_;
349}
350
351void QuicFixedSocketAddress::SetSendValue(const QuicSocketAddress& value) {
352 has_send_value_ = true;
353 send_value_ = value;
354}
355
356bool QuicFixedSocketAddress::HasReceivedValue() const {
357 return has_receive_value_;
358}
359
360const QuicSocketAddress& QuicFixedSocketAddress::GetReceivedValue() const {
361 QUIC_BUG_IF(!has_receive_value_)
362 << "No receive value to get for tag:" << QuicTagToString(tag_);
363 return receive_value_;
364}
365
366void QuicFixedSocketAddress::SetReceivedValue(const QuicSocketAddress& value) {
367 has_receive_value_ = true;
368 receive_value_ = value;
369}
370
371void QuicFixedSocketAddress::ToHandshakeMessage(
372 CryptoHandshakeMessage* out) const {
373 if (has_send_value_) {
374 QuicSocketAddressCoder address_coder(send_value_);
375 out->SetStringPiece(tag_, address_coder.Encode());
376 }
377}
378
379QuicErrorCode QuicFixedSocketAddress::ProcessPeerHello(
380 const CryptoHandshakeMessage& peer_hello,
dschinazi17d42422019-06-18 16:35:07 -0700381 HelloType /*hello_type*/,
vasilvvc48c8712019-03-11 13:38:16 -0700382 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500383 QuicStringPiece address;
384 if (!peer_hello.GetStringPiece(tag_, &address)) {
385 if (presence_ == PRESENCE_REQUIRED) {
386 *error_details = "Missing " + QuicTagToString(tag_);
387 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
388 }
389 } else {
390 QuicSocketAddressCoder address_coder;
391 if (address_coder.Decode(address.data(), address.length())) {
392 SetReceivedValue(
393 QuicSocketAddress(address_coder.ip(), address_coder.port()));
394 }
395 }
396 return QUIC_NO_ERROR;
397}
398
399QuicConfig::QuicConfig()
400 : max_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
401 max_idle_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
402 max_undecryptable_packets_(0),
403 connection_options_(kCOPT, PRESENCE_OPTIONAL),
404 client_connection_options_(kCLOP, PRESENCE_OPTIONAL),
405 idle_network_timeout_seconds_(kICSL, PRESENCE_REQUIRED),
406 silent_close_(kSCLS, PRESENCE_OPTIONAL),
fkastenholzd3a1de92019-05-15 07:00:07 -0700407 max_incoming_bidirectional_streams_(kMIBS, PRESENCE_REQUIRED),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500408 bytes_for_connection_id_(kTCID, PRESENCE_OPTIONAL),
409 initial_round_trip_time_us_(kIRTT, PRESENCE_OPTIONAL),
rchb0451852019-09-11 21:17:01 -0700410 initial_max_stream_data_bytes_incoming_bidirectional_(0,
411 PRESENCE_OPTIONAL),
412 initial_max_stream_data_bytes_outgoing_bidirectional_(0,
413 PRESENCE_OPTIONAL),
414 initial_max_stream_data_bytes_unidirectional_(0, PRESENCE_OPTIONAL),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500415 initial_stream_flow_control_window_bytes_(kSFCW, PRESENCE_OPTIONAL),
416 initial_session_flow_control_window_bytes_(kCFCW, PRESENCE_OPTIONAL),
417 connection_migration_disabled_(kNCMR, PRESENCE_OPTIONAL),
418 alternate_server_address_(kASAD, PRESENCE_OPTIONAL),
419 support_max_header_list_size_(kSMHL, PRESENCE_OPTIONAL),
fkastenholzd3a1de92019-05-15 07:00:07 -0700420 stateless_reset_token_(kSRST, PRESENCE_OPTIONAL),
fkastenholz4c7303c2019-07-29 08:17:07 -0700421 max_incoming_unidirectional_streams_(kMIUS, PRESENCE_OPTIONAL),
fkastenholz4dc4ba32019-07-30 09:55:25 -0700422 max_ack_delay_ms_(kMAD, PRESENCE_OPTIONAL),
423 ack_delay_exponent_(kADE, PRESENCE_OPTIONAL) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500424 SetDefaults();
425}
426
427QuicConfig::QuicConfig(const QuicConfig& other) = default;
428
429QuicConfig::~QuicConfig() {}
430
431bool QuicConfig::SetInitialReceivedConnectionOptions(
432 const QuicTagVector& tags) {
433 if (HasReceivedConnectionOptions()) {
434 // If we have already received connection options (via handshake or due to
435 // a previous call), don't re-initialize.
436 return false;
437 }
438 connection_options_.SetReceivedValues(tags);
439 return true;
440}
441
442void QuicConfig::SetConnectionOptionsToSend(
443 const QuicTagVector& connection_options) {
444 connection_options_.SetSendValues(connection_options);
445}
446
447bool QuicConfig::HasReceivedConnectionOptions() const {
448 return connection_options_.HasReceivedValues();
449}
450
451QuicTagVector QuicConfig::ReceivedConnectionOptions() const {
452 return connection_options_.GetReceivedValues();
453}
454
455bool QuicConfig::HasSendConnectionOptions() const {
456 return connection_options_.HasSendValues();
457}
458
459QuicTagVector QuicConfig::SendConnectionOptions() const {
460 return connection_options_.GetSendValues();
461}
462
463bool QuicConfig::HasClientSentConnectionOption(QuicTag tag,
464 Perspective perspective) const {
465 if (perspective == Perspective::IS_SERVER) {
466 if (HasReceivedConnectionOptions() &&
467 ContainsQuicTag(ReceivedConnectionOptions(), tag)) {
468 return true;
469 }
470 } else if (HasSendConnectionOptions() &&
471 ContainsQuicTag(SendConnectionOptions(), tag)) {
472 return true;
473 }
474 return false;
475}
476
477void QuicConfig::SetClientConnectionOptions(
478 const QuicTagVector& client_connection_options) {
479 client_connection_options_.SetSendValues(client_connection_options);
480}
481
482bool QuicConfig::HasClientRequestedIndependentOption(
483 QuicTag tag,
484 Perspective perspective) const {
485 if (perspective == Perspective::IS_SERVER) {
486 return (HasReceivedConnectionOptions() &&
487 ContainsQuicTag(ReceivedConnectionOptions(), tag));
488 }
489
490 return (client_connection_options_.HasSendValues() &&
491 ContainsQuicTag(client_connection_options_.GetSendValues(), tag));
492}
493
494void QuicConfig::SetIdleNetworkTimeout(
495 QuicTime::Delta max_idle_network_timeout,
496 QuicTime::Delta default_idle_network_timeout) {
497 idle_network_timeout_seconds_.set(
498 static_cast<uint32_t>(max_idle_network_timeout.ToSeconds()),
499 static_cast<uint32_t>(default_idle_network_timeout.ToSeconds()));
500}
501
502QuicTime::Delta QuicConfig::IdleNetworkTimeout() const {
503 return QuicTime::Delta::FromSeconds(
504 idle_network_timeout_seconds_.GetUint32());
505}
506
507// TODO(ianswett) Use this for silent close on mobile, or delete.
508QUIC_UNUSED void QuicConfig::SetSilentClose(bool silent_close) {
509 silent_close_.set(silent_close ? 1 : 0, silent_close ? 1 : 0);
510}
511
512bool QuicConfig::SilentClose() const {
513 return silent_close_.GetUint32() > 0;
514}
515
fkastenholzd3a1de92019-05-15 07:00:07 -0700516void QuicConfig::SetMaxIncomingBidirectionalStreamsToSend(
517 uint32_t max_streams) {
518 max_incoming_bidirectional_streams_.SetSendValue(max_streams);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500519}
520
fkastenholzd3a1de92019-05-15 07:00:07 -0700521uint32_t QuicConfig::GetMaxIncomingBidirectionalStreamsToSend() {
522 return max_incoming_bidirectional_streams_.GetSendValue();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500523}
524
fkastenholzd3a1de92019-05-15 07:00:07 -0700525bool QuicConfig::HasReceivedMaxIncomingBidirectionalStreams() {
526 return max_incoming_bidirectional_streams_.HasReceivedValue();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500527}
528
fkastenholzd3a1de92019-05-15 07:00:07 -0700529uint32_t QuicConfig::ReceivedMaxIncomingBidirectionalStreams() {
530 return max_incoming_bidirectional_streams_.GetReceivedValue();
531}
532
533void QuicConfig::SetMaxIncomingUnidirectionalStreamsToSend(
534 uint32_t max_streams) {
535 max_incoming_unidirectional_streams_.SetSendValue(max_streams);
536}
537
538uint32_t QuicConfig::GetMaxIncomingUnidirectionalStreamsToSend() {
539 return max_incoming_unidirectional_streams_.GetSendValue();
540}
541
542bool QuicConfig::HasReceivedMaxIncomingUnidirectionalStreams() {
543 return max_incoming_unidirectional_streams_.HasReceivedValue();
544}
545
546uint32_t QuicConfig::ReceivedMaxIncomingUnidirectionalStreams() {
547 return max_incoming_unidirectional_streams_.GetReceivedValue();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500548}
549
fkastenholz4c7303c2019-07-29 08:17:07 -0700550void QuicConfig::SetMaxAckDelayToSendMs(uint32_t max_ack_delay_ms) {
551 return max_ack_delay_ms_.SetSendValue(max_ack_delay_ms);
552}
553
554uint32_t QuicConfig::GetMaxAckDelayToToSendMs() const {
555 return max_ack_delay_ms_.GetSendValue();
556}
557
558bool QuicConfig::HasReceivedMaxAckDelayMs() const {
559 return max_ack_delay_ms_.HasReceivedValue();
560}
561
562uint32_t QuicConfig::ReceivedMaxAckDelayMs() const {
563 return max_ack_delay_ms_.GetReceivedValue();
564}
565
fkastenholz4dc4ba32019-07-30 09:55:25 -0700566void QuicConfig::SetAckDelayExponentToSend(uint32_t exponent) {
567 ack_delay_exponent_.SetSendValue(exponent);
568}
569
570uint32_t QuicConfig::GetAckDelayExponentToSend() {
571 return ack_delay_exponent_.GetSendValue();
572}
573
574bool QuicConfig::HasReceivedAckDelayExponent() const {
575 return ack_delay_exponent_.HasReceivedValue();
576}
577
578uint32_t QuicConfig::ReceivedAckDelayExponent() const {
579 return ack_delay_exponent_.GetReceivedValue();
580}
581
QUICHE teama6ef0a62019-03-07 20:34:33 -0500582bool QuicConfig::HasSetBytesForConnectionIdToSend() const {
583 return bytes_for_connection_id_.HasSendValue();
584}
585
586void QuicConfig::SetBytesForConnectionIdToSend(uint32_t bytes) {
587 bytes_for_connection_id_.SetSendValue(bytes);
588}
589
590bool QuicConfig::HasReceivedBytesForConnectionId() const {
591 return bytes_for_connection_id_.HasReceivedValue();
592}
593
594uint32_t QuicConfig::ReceivedBytesForConnectionId() const {
595 return bytes_for_connection_id_.GetReceivedValue();
596}
597
598void QuicConfig::SetInitialRoundTripTimeUsToSend(uint32_t rtt) {
599 initial_round_trip_time_us_.SetSendValue(rtt);
600}
601
602bool QuicConfig::HasReceivedInitialRoundTripTimeUs() const {
603 return initial_round_trip_time_us_.HasReceivedValue();
604}
605
606uint32_t QuicConfig::ReceivedInitialRoundTripTimeUs() const {
607 return initial_round_trip_time_us_.GetReceivedValue();
608}
609
610bool QuicConfig::HasInitialRoundTripTimeUsToSend() const {
611 return initial_round_trip_time_us_.HasSendValue();
612}
613
614uint32_t QuicConfig::GetInitialRoundTripTimeUsToSend() const {
615 return initial_round_trip_time_us_.GetSendValue();
616}
617
618void QuicConfig::SetInitialStreamFlowControlWindowToSend(
619 uint32_t window_bytes) {
620 if (window_bytes < kMinimumFlowControlSendWindow) {
621 QUIC_BUG << "Initial stream flow control receive window (" << window_bytes
dschinazic7036122019-04-30 12:46:34 -0700622 << ") cannot be set lower than minimum ("
QUICHE teama6ef0a62019-03-07 20:34:33 -0500623 << kMinimumFlowControlSendWindow << ").";
624 window_bytes = kMinimumFlowControlSendWindow;
625 }
626 initial_stream_flow_control_window_bytes_.SetSendValue(window_bytes);
627}
628
629uint32_t QuicConfig::GetInitialStreamFlowControlWindowToSend() const {
630 return initial_stream_flow_control_window_bytes_.GetSendValue();
631}
632
633bool QuicConfig::HasReceivedInitialStreamFlowControlWindowBytes() const {
634 return initial_stream_flow_control_window_bytes_.HasReceivedValue();
635}
636
637uint32_t QuicConfig::ReceivedInitialStreamFlowControlWindowBytes() const {
638 return initial_stream_flow_control_window_bytes_.GetReceivedValue();
639}
640
rchb0451852019-09-11 21:17:01 -0700641void QuicConfig::SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
642 uint32_t window_bytes) {
643 if (window_bytes < kMinimumFlowControlSendWindow) {
644 QUIC_BUG << "Initial stream flow control receive window (" << window_bytes
645 << ") cannot be set lower than minimum ("
646 << kMinimumFlowControlSendWindow << ").";
647 window_bytes = kMinimumFlowControlSendWindow;
648 }
649 initial_max_stream_data_bytes_incoming_bidirectional_.SetSendValue(
650 window_bytes);
651}
652
653uint32_t QuicConfig::GetInitialMaxStreamDataBytesIncomingBidirectionalToSend()
654 const {
655 return initial_max_stream_data_bytes_incoming_bidirectional_.GetSendValue();
656}
657
658bool QuicConfig::HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()
659 const {
660 return initial_max_stream_data_bytes_incoming_bidirectional_
661 .HasReceivedValue();
662}
663
664uint32_t QuicConfig::ReceivedInitialMaxStreamDataBytesIncomingBidirectional()
665 const {
666 return initial_max_stream_data_bytes_incoming_bidirectional_
667 .GetReceivedValue();
668}
669
670void QuicConfig::SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
671 uint32_t window_bytes) {
672 if (window_bytes < kMinimumFlowControlSendWindow) {
673 QUIC_BUG << "Initial stream flow control receive window (" << window_bytes
674 << ") cannot be set lower than minimum ("
675 << kMinimumFlowControlSendWindow << ").";
676 window_bytes = kMinimumFlowControlSendWindow;
677 }
678 initial_max_stream_data_bytes_outgoing_bidirectional_.SetSendValue(
679 window_bytes);
680}
681
682uint32_t QuicConfig::GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend()
683 const {
684 return initial_max_stream_data_bytes_outgoing_bidirectional_.GetSendValue();
685}
686
687bool QuicConfig::HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()
688 const {
689 return initial_max_stream_data_bytes_outgoing_bidirectional_
690 .HasReceivedValue();
691}
692
693uint32_t QuicConfig::ReceivedInitialMaxStreamDataBytesOutgoingBidirectional()
694 const {
695 return initial_max_stream_data_bytes_outgoing_bidirectional_
696 .GetReceivedValue();
697}
698
699void QuicConfig::SetInitialMaxStreamDataBytesUnidirectionalToSend(
700 uint32_t window_bytes) {
701 if (window_bytes < kMinimumFlowControlSendWindow) {
702 QUIC_BUG << "Initial stream flow control receive window (" << window_bytes
703 << ") cannot be set lower than minimum ("
704 << kMinimumFlowControlSendWindow << ").";
705 window_bytes = kMinimumFlowControlSendWindow;
706 }
707 initial_max_stream_data_bytes_unidirectional_.SetSendValue(window_bytes);
708}
709
710uint32_t QuicConfig::GetInitialMaxStreamDataBytesUnidirectionalToSend() const {
711 return initial_max_stream_data_bytes_unidirectional_.GetSendValue();
712}
713
714bool QuicConfig::HasReceivedInitialMaxStreamDataBytesUnidirectional() const {
715 return initial_max_stream_data_bytes_unidirectional_.HasReceivedValue();
716}
717
718uint32_t QuicConfig::ReceivedInitialMaxStreamDataBytesUnidirectional() const {
719 return initial_max_stream_data_bytes_unidirectional_.GetReceivedValue();
720}
721
QUICHE teama6ef0a62019-03-07 20:34:33 -0500722void QuicConfig::SetInitialSessionFlowControlWindowToSend(
723 uint32_t window_bytes) {
724 if (window_bytes < kMinimumFlowControlSendWindow) {
725 QUIC_BUG << "Initial session flow control receive window (" << window_bytes
726 << ") cannot be set lower than default ("
727 << kMinimumFlowControlSendWindow << ").";
728 window_bytes = kMinimumFlowControlSendWindow;
729 }
730 initial_session_flow_control_window_bytes_.SetSendValue(window_bytes);
731}
732
733uint32_t QuicConfig::GetInitialSessionFlowControlWindowToSend() const {
734 return initial_session_flow_control_window_bytes_.GetSendValue();
735}
736
737bool QuicConfig::HasReceivedInitialSessionFlowControlWindowBytes() const {
738 return initial_session_flow_control_window_bytes_.HasReceivedValue();
739}
740
741uint32_t QuicConfig::ReceivedInitialSessionFlowControlWindowBytes() const {
742 return initial_session_flow_control_window_bytes_.GetReceivedValue();
743}
744
745void QuicConfig::SetDisableConnectionMigration() {
746 connection_migration_disabled_.SetSendValue(1);
747}
748
749bool QuicConfig::DisableConnectionMigration() const {
750 return connection_migration_disabled_.HasReceivedValue();
751}
752
753void QuicConfig::SetAlternateServerAddressToSend(
754 const QuicSocketAddress& alternate_server_address) {
755 alternate_server_address_.SetSendValue(alternate_server_address);
756}
757
758bool QuicConfig::HasReceivedAlternateServerAddress() const {
759 return alternate_server_address_.HasReceivedValue();
760}
761
762const QuicSocketAddress& QuicConfig::ReceivedAlternateServerAddress() const {
763 return alternate_server_address_.GetReceivedValue();
764}
765
766void QuicConfig::SetSupportMaxHeaderListSize() {
767 support_max_header_list_size_.SetSendValue(1);
768}
769
770bool QuicConfig::SupportMaxHeaderListSize() const {
771 return support_max_header_list_size_.HasReceivedValue();
772}
773
774void QuicConfig::SetStatelessResetTokenToSend(
775 QuicUint128 stateless_reset_token) {
776 stateless_reset_token_.SetSendValue(stateless_reset_token);
777}
778
779bool QuicConfig::HasReceivedStatelessResetToken() const {
780 return stateless_reset_token_.HasReceivedValue();
781}
782
783QuicUint128 QuicConfig::ReceivedStatelessResetToken() const {
784 return stateless_reset_token_.GetReceivedValue();
785}
786
787bool QuicConfig::negotiated() const {
788 // TODO(ianswett): Add the negotiated parameters once and iterate over all
789 // of them in negotiated, ToHandshakeMessage, and ProcessPeerHello.
790 return idle_network_timeout_seconds_.negotiated();
791}
792
793void QuicConfig::SetCreateSessionTagIndicators(QuicTagVector tags) {
794 create_session_tag_indicators_ = std::move(tags);
795}
796
797const QuicTagVector& QuicConfig::create_session_tag_indicators() const {
798 return create_session_tag_indicators_;
799}
800
801void QuicConfig::SetDefaults() {
802 idle_network_timeout_seconds_.set(kMaximumIdleTimeoutSecs,
803 kDefaultIdleTimeoutSecs);
804 silent_close_.set(1, 0);
fkastenholzd3a1de92019-05-15 07:00:07 -0700805 SetMaxIncomingBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
806 SetMaxIncomingUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500807 max_time_before_crypto_handshake_ =
808 QuicTime::Delta::FromSeconds(kMaxTimeForCryptoHandshakeSecs);
809 max_idle_time_before_crypto_handshake_ =
810 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs);
811 max_undecryptable_packets_ = kDefaultMaxUndecryptablePackets;
812
813 SetInitialStreamFlowControlWindowToSend(kMinimumFlowControlSendWindow);
rchb0451852019-09-11 21:17:01 -0700814 SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
815 kMinimumFlowControlSendWindow);
816 SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
817 kMinimumFlowControlSendWindow);
818 SetInitialMaxStreamDataBytesUnidirectionalToSend(
819 kMinimumFlowControlSendWindow);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500820 SetInitialSessionFlowControlWindowToSend(kMinimumFlowControlSendWindow);
fkastenholz4c7303c2019-07-29 08:17:07 -0700821 SetMaxAckDelayToSendMs(kDefaultDelayedAckTimeMs);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500822 SetSupportMaxHeaderListSize();
fkastenholz4dc4ba32019-07-30 09:55:25 -0700823 SetAckDelayExponentToSend(kDefaultAckDelayExponent);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500824}
825
fkastenholzd3a1de92019-05-15 07:00:07 -0700826void QuicConfig::ToHandshakeMessage(
827 CryptoHandshakeMessage* out,
828 QuicTransportVersion transport_version) const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500829 idle_network_timeout_seconds_.ToHandshakeMessage(out);
830 silent_close_.ToHandshakeMessage(out);
fkastenholzd3a1de92019-05-15 07:00:07 -0700831 // Do not need a version check here, max...bi... will encode
832 // as "MIDS" -- the max initial dynamic streams tag -- if
fkastenholz305e1732019-06-18 05:01:22 -0700833 // doing some version other than IETF QUIC.
fkastenholzd3a1de92019-05-15 07:00:07 -0700834 max_incoming_bidirectional_streams_.ToHandshakeMessage(out);
fkastenholz305e1732019-06-18 05:01:22 -0700835 if (VersionHasIetfQuicFrames(transport_version)) {
fkastenholzd3a1de92019-05-15 07:00:07 -0700836 max_incoming_unidirectional_streams_.ToHandshakeMessage(out);
fkastenholz4dc4ba32019-07-30 09:55:25 -0700837 ack_delay_exponent_.ToHandshakeMessage(out);
fkastenholzd3a1de92019-05-15 07:00:07 -0700838 }
fkastenholz4c7303c2019-07-29 08:17:07 -0700839 if (GetQuicReloadableFlag(quic_negotiate_ack_delay_time)) {
840 QUIC_RELOADABLE_FLAG_COUNT_N(quic_negotiate_ack_delay_time, 1, 4);
841 max_ack_delay_ms_.ToHandshakeMessage(out);
842 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500843 bytes_for_connection_id_.ToHandshakeMessage(out);
844 initial_round_trip_time_us_.ToHandshakeMessage(out);
845 initial_stream_flow_control_window_bytes_.ToHandshakeMessage(out);
846 initial_session_flow_control_window_bytes_.ToHandshakeMessage(out);
847 connection_migration_disabled_.ToHandshakeMessage(out);
848 connection_options_.ToHandshakeMessage(out);
849 alternate_server_address_.ToHandshakeMessage(out);
850 support_max_header_list_size_.ToHandshakeMessage(out);
851 stateless_reset_token_.ToHandshakeMessage(out);
852}
853
854QuicErrorCode QuicConfig::ProcessPeerHello(
855 const CryptoHandshakeMessage& peer_hello,
856 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700857 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500858 DCHECK(error_details != nullptr);
859
860 QuicErrorCode error = QUIC_NO_ERROR;
861 if (error == QUIC_NO_ERROR) {
862 error = idle_network_timeout_seconds_.ProcessPeerHello(
863 peer_hello, hello_type, error_details);
864 }
865 if (error == QUIC_NO_ERROR) {
866 error =
867 silent_close_.ProcessPeerHello(peer_hello, hello_type, error_details);
868 }
869 if (error == QUIC_NO_ERROR) {
fkastenholzd3a1de92019-05-15 07:00:07 -0700870 error = max_incoming_bidirectional_streams_.ProcessPeerHello(
871 peer_hello, hello_type, error_details);
872 }
873 if (error == QUIC_NO_ERROR) {
874 error = max_incoming_unidirectional_streams_.ProcessPeerHello(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500875 peer_hello, hello_type, error_details);
876 }
877 if (error == QUIC_NO_ERROR) {
878 error = bytes_for_connection_id_.ProcessPeerHello(peer_hello, hello_type,
879 error_details);
880 }
881 if (error == QUIC_NO_ERROR) {
882 error = initial_round_trip_time_us_.ProcessPeerHello(peer_hello, hello_type,
883 error_details);
884 }
885 if (error == QUIC_NO_ERROR) {
886 error = initial_stream_flow_control_window_bytes_.ProcessPeerHello(
887 peer_hello, hello_type, error_details);
888 }
889 if (error == QUIC_NO_ERROR) {
890 error = initial_session_flow_control_window_bytes_.ProcessPeerHello(
891 peer_hello, hello_type, error_details);
892 }
893 if (error == QUIC_NO_ERROR) {
894 error = connection_migration_disabled_.ProcessPeerHello(
895 peer_hello, hello_type, error_details);
896 }
897 if (error == QUIC_NO_ERROR) {
898 error = connection_options_.ProcessPeerHello(peer_hello, hello_type,
899 error_details);
900 }
901 if (error == QUIC_NO_ERROR) {
902 error = alternate_server_address_.ProcessPeerHello(peer_hello, hello_type,
903 error_details);
904 }
905 if (error == QUIC_NO_ERROR) {
906 error = support_max_header_list_size_.ProcessPeerHello(
907 peer_hello, hello_type, error_details);
908 }
909 if (error == QUIC_NO_ERROR) {
910 error = stateless_reset_token_.ProcessPeerHello(peer_hello, hello_type,
911 error_details);
912 }
fkastenholz4c7303c2019-07-29 08:17:07 -0700913
914 if (GetQuicReloadableFlag(quic_negotiate_ack_delay_time) &&
915 error == QUIC_NO_ERROR) {
916 QUIC_RELOADABLE_FLAG_COUNT_N(quic_negotiate_ack_delay_time, 2, 4);
917 error = max_ack_delay_ms_.ProcessPeerHello(peer_hello, hello_type,
918 error_details);
919 }
fkastenholz4dc4ba32019-07-30 09:55:25 -0700920 if (error == QUIC_NO_ERROR) {
921 error = ack_delay_exponent_.ProcessPeerHello(peer_hello, hello_type,
922 error_details);
923 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500924 return error;
925}
926
927bool QuicConfig::FillTransportParameters(TransportParameters* params) const {
dschinazi6cf4d2a2019-04-30 16:20:23 -0700928 params->idle_timeout_milliseconds.set_value(
929 idle_network_timeout_seconds_.GetUint32() * kNumMillisPerSecond);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500930
dschinazi52127d72019-04-17 15:12:38 -0700931 if (stateless_reset_token_.HasSendValue()) {
932 QuicUint128 stateless_reset_token = stateless_reset_token_.GetSendValue();
933 params->stateless_reset_token.assign(
934 reinterpret_cast<const char*>(&stateless_reset_token),
935 reinterpret_cast<const char*>(&stateless_reset_token) +
936 sizeof(stateless_reset_token));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500937 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500938
dschinazi52127d72019-04-17 15:12:38 -0700939 params->max_packet_size.set_value(kMaxIncomingPacketSize);
940 params->initial_max_data.set_value(
941 initial_session_flow_control_window_bytes_.GetSendValue());
942 params->initial_max_stream_data_bidi_local.set_value(
rchb0451852019-09-11 21:17:01 -0700943 initial_max_stream_data_bytes_incoming_bidirectional_.GetSendValue());
dschinazi52127d72019-04-17 15:12:38 -0700944 params->initial_max_stream_data_bidi_remote.set_value(
rchb0451852019-09-11 21:17:01 -0700945 initial_max_stream_data_bytes_outgoing_bidirectional_.GetSendValue());
dschinazi52127d72019-04-17 15:12:38 -0700946 params->initial_max_stream_data_uni.set_value(
rchb0451852019-09-11 21:17:01 -0700947 initial_max_stream_data_bytes_unidirectional_.GetSendValue());
dschinazi52127d72019-04-17 15:12:38 -0700948 params->initial_max_streams_bidi.set_value(
fkastenholzd3a1de92019-05-15 07:00:07 -0700949 max_incoming_bidirectional_streams_.GetSendValue());
dschinazi52127d72019-04-17 15:12:38 -0700950 params->initial_max_streams_uni.set_value(
fkastenholzd3a1de92019-05-15 07:00:07 -0700951 max_incoming_unidirectional_streams_.GetSendValue());
fkastenholz4c7303c2019-07-29 08:17:07 -0700952 if (GetQuicReloadableFlag(quic_negotiate_ack_delay_time)) {
953 QUIC_RELOADABLE_FLAG_COUNT_N(quic_negotiate_ack_delay_time, 3, 4);
954 params->max_ack_delay.set_value(kDefaultDelayedAckTimeMs);
955 }
fkastenholz4dc4ba32019-07-30 09:55:25 -0700956 params->ack_delay_exponent.set_value(ack_delay_exponent_.GetSendValue());
dschinazi52127d72019-04-17 15:12:38 -0700957 params->disable_migration =
958 connection_migration_disabled_.HasSendValue() &&
959 connection_migration_disabled_.GetSendValue() != 0;
960
961 if (alternate_server_address_.HasSendValue()) {
962 TransportParameters::PreferredAddress preferred_address;
963 QuicSocketAddress socket_address = alternate_server_address_.GetSendValue();
964 if (socket_address.host().IsIPv6()) {
965 preferred_address.ipv6_socket_address = socket_address;
966 } else {
967 preferred_address.ipv4_socket_address = socket_address;
968 }
969 params->preferred_address =
vasilvv0fc587f2019-09-06 13:33:08 -0700970 std::make_unique<TransportParameters::PreferredAddress>(
dschinazi52127d72019-04-17 15:12:38 -0700971 preferred_address);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500972 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500973
974 if (!params->google_quic_params) {
vasilvv0fc587f2019-09-06 13:33:08 -0700975 params->google_quic_params = std::make_unique<CryptoHandshakeMessage>();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500976 }
977 silent_close_.ToHandshakeMessage(params->google_quic_params.get());
978 initial_round_trip_time_us_.ToHandshakeMessage(
979 params->google_quic_params.get());
980 connection_options_.ToHandshakeMessage(params->google_quic_params.get());
vasilvva2ef3012019-09-12 18:32:14 -0700981 params->custom_parameters = custom_transport_parameters_to_send_;
dschinazi52127d72019-04-17 15:12:38 -0700982
QUICHE teama6ef0a62019-03-07 20:34:33 -0500983 return true;
984}
985
986QuicErrorCode QuicConfig::ProcessTransportParameters(
987 const TransportParameters& params,
988 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700989 std::string* error_details) {
dschinazi6cf4d2a2019-04-30 16:20:23 -0700990 // Intentionally round down to probe too often rather than not often enough.
991 uint64_t idle_timeout_seconds =
992 params.idle_timeout_milliseconds.value() / kNumMillisPerSecond;
dschinazi7bf7c3c2019-05-01 21:19:47 -0700993 // An idle timeout of zero indicates it is disabled (in other words, it is
994 // set to infinity). When the idle timeout is very high, we set it to our
995 // preferred maximum and still probe that often.
dschinazi6464c4a2019-09-11 16:25:01 -0700996 if (idle_timeout_seconds > idle_network_timeout_seconds_.GetMax() ||
dschinazi7bf7c3c2019-05-01 21:19:47 -0700997 idle_timeout_seconds == 0) {
dschinazi6464c4a2019-09-11 16:25:01 -0700998 idle_timeout_seconds = idle_network_timeout_seconds_.GetMax();
dschinazi52127d72019-04-17 15:12:38 -0700999 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001000 QuicErrorCode error = idle_network_timeout_seconds_.ReceiveValue(
dschinazi52127d72019-04-17 15:12:38 -07001001 idle_timeout_seconds, hello_type, error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001002 if (error != QUIC_NO_ERROR) {
dschinazid1967a22019-04-03 16:11:32 -07001003 DCHECK(!error_details->empty());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001004 return error;
1005 }
dschinazi52127d72019-04-17 15:12:38 -07001006
1007 if (!params.stateless_reset_token.empty()) {
1008 QuicUint128 stateless_reset_token;
1009 if (params.stateless_reset_token.size() != sizeof(stateless_reset_token)) {
1010 QUIC_BUG << "Bad stateless reset token length "
1011 << params.stateless_reset_token.size();
1012 *error_details = "Bad stateless reset token length";
1013 return QUIC_INTERNAL_ERROR;
1014 }
1015 memcpy(&stateless_reset_token, params.stateless_reset_token.data(),
1016 params.stateless_reset_token.size());
1017 stateless_reset_token_.SetReceivedValue(stateless_reset_token);
1018 }
1019
1020 if (params.max_packet_size.value() < kMaxOutgoingPacketSize) {
1021 // TODO(dschinazi) act on this.
1022 QUIC_DLOG(ERROR) << "Ignoring peer's requested max packet size of "
1023 << params.max_packet_size.value();
1024 }
1025
1026 initial_session_flow_control_window_bytes_.SetReceivedValue(
1027 std::min<uint64_t>(params.initial_max_data.value(),
1028 std::numeric_limits<uint32_t>::max()));
fkastenholzd3a1de92019-05-15 07:00:07 -07001029 max_incoming_bidirectional_streams_.SetReceivedValue(
dschinazi52127d72019-04-17 15:12:38 -07001030 std::min<uint64_t>(params.initial_max_streams_bidi.value(),
1031 std::numeric_limits<uint32_t>::max()));
fkastenholzd3a1de92019-05-15 07:00:07 -07001032 max_incoming_unidirectional_streams_.SetReceivedValue(
1033 std::min<uint64_t>(params.initial_max_streams_uni.value(),
1034 std::numeric_limits<uint32_t>::max()));
dschinazi52127d72019-04-17 15:12:38 -07001035
rchb0451852019-09-11 21:17:01 -07001036 initial_max_stream_data_bytes_incoming_bidirectional_.SetReceivedValue(
dschinazi52127d72019-04-17 15:12:38 -07001037 std::min<uint64_t>(params.initial_max_stream_data_bidi_local.value(),
1038 std::numeric_limits<uint32_t>::max()));
rchb0451852019-09-11 21:17:01 -07001039 initial_max_stream_data_bytes_outgoing_bidirectional_.SetReceivedValue(
1040 std::min<uint64_t>(params.initial_max_stream_data_bidi_remote.value(),
1041 std::numeric_limits<uint32_t>::max()));
1042 initial_max_stream_data_bytes_unidirectional_.SetReceivedValue(
1043 std::min<uint64_t>(params.initial_max_stream_data_uni.value(),
1044 std::numeric_limits<uint32_t>::max()));
1045
fkastenholz4c7303c2019-07-29 08:17:07 -07001046 if (GetQuicReloadableFlag(quic_negotiate_ack_delay_time)) {
1047 QUIC_RELOADABLE_FLAG_COUNT_N(quic_negotiate_ack_delay_time, 4, 4);
1048 max_ack_delay_ms_.SetReceivedValue(std::min<uint32_t>(
1049 params.max_ack_delay.value(), std::numeric_limits<uint32_t>::max()));
1050 }
fkastenholz4dc4ba32019-07-30 09:55:25 -07001051 if (params.ack_delay_exponent.IsValid()) {
1052 ack_delay_exponent_.SetReceivedValue(params.ack_delay_exponent.value());
1053 }
dschinazi52127d72019-04-17 15:12:38 -07001054 connection_migration_disabled_.SetReceivedValue(
1055 params.disable_migration ? 1u : 0u);
1056
1057 if (params.preferred_address != nullptr) {
1058 if (params.preferred_address->ipv6_socket_address.port() != 0) {
1059 alternate_server_address_.SetReceivedValue(
1060 params.preferred_address->ipv6_socket_address);
1061 } else if (params.preferred_address->ipv4_socket_address.port() != 0) {
1062 alternate_server_address_.SetReceivedValue(
1063 params.preferred_address->ipv4_socket_address);
1064 }
1065 }
1066
QUICHE teama6ef0a62019-03-07 20:34:33 -05001067 const CryptoHandshakeMessage* peer_params = params.google_quic_params.get();
dschinazid1967a22019-04-03 16:11:32 -07001068 if (peer_params != nullptr) {
1069 error =
1070 silent_close_.ProcessPeerHello(*peer_params, hello_type, error_details);
1071 if (error != QUIC_NO_ERROR) {
1072 DCHECK(!error_details->empty());
1073 return error;
1074 }
1075 error = initial_round_trip_time_us_.ProcessPeerHello(
1076 *peer_params, hello_type, error_details);
1077 if (error != QUIC_NO_ERROR) {
1078 DCHECK(!error_details->empty());
1079 return error;
1080 }
1081 error = connection_options_.ProcessPeerHello(*peer_params, hello_type,
1082 error_details);
1083 if (error != QUIC_NO_ERROR) {
1084 DCHECK(!error_details->empty());
1085 return error;
1086 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001087 }
1088
vasilvva2ef3012019-09-12 18:32:14 -07001089 received_custom_transport_parameters_ = params.custom_parameters;
1090
dschinazi6464c4a2019-09-11 16:25:01 -07001091 *error_details = "";
QUICHE teama6ef0a62019-03-07 20:34:33 -05001092 return QUIC_NO_ERROR;
1093}
1094
1095} // namespace quic