blob: 796c641051b8d131163ea7058b55c897739753f5 [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
QUICHE team5be974e2020-12-29 18:35:24 -05005#include "quic/core/quic_config.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -05006
7#include <algorithm>
dschinazi52127d72019-04-17 15:12:38 -07008#include <cstring>
dschinazif1e7b422020-04-30 12:21:28 -07009#include <limits>
vasilvv872e7a32019-03-12 16:42:44 -070010#include <string>
bnc463f2352019-10-10 04:49:34 -070011#include <utility>
QUICHE teama6ef0a62019-03-07 20:34:33 -050012
vasilvv8f9591b2020-10-26 17:01:14 -070013#include "absl/base/attributes.h"
vasilvvc872ee42020-10-07 19:50:22 -070014#include "absl/strings/string_view.h"
QUICHE team5be974e2020-12-29 18:35:24 -050015#include "quic/core/crypto/crypto_handshake_message.h"
16#include "quic/core/crypto/crypto_protocol.h"
17#include "quic/core/quic_connection_id.h"
18#include "quic/core/quic_constants.h"
19#include "quic/core/quic_socket_address_coder.h"
haoyuewang2a6cbc52021-01-13 06:49:02 -080020#include "quic/core/quic_types.h"
QUICHE team5be974e2020-12-29 18:35:24 -050021#include "quic/core/quic_utils.h"
22#include "quic/platform/api/quic_bug_tracker.h"
23#include "quic/platform/api/quic_flag_utils.h"
24#include "quic/platform/api/quic_flags.h"
25#include "quic/platform/api/quic_logging.h"
26#include "quic/platform/api/quic_socket_address.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050027
28namespace 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|.
33QuicErrorCode ReadUint32(const CryptoHandshakeMessage& msg,
34 QuicTag tag,
35 QuicConfigPresence presence,
36 uint32_t default_value,
37 uint32_t* out,
vasilvvc48c8712019-03-11 13:38:16 -070038 std::string* error_details) {
vasilvvf8035162021-02-01 14:49:14 -080039 QUICHE_DCHECK(error_details != nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -050040 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
59QuicConfigValue::QuicConfigValue(QuicTag tag, QuicConfigPresence presence)
60 : tag_(tag), presence_(presence) {}
61QuicConfigValue::~QuicConfigValue() {}
62
QUICHE teama6ef0a62019-03-07 20:34:33 -050063QuicFixedUint32::QuicFixedUint32(QuicTag tag, QuicConfigPresence presence)
64 : QuicConfigValue(tag, presence),
65 has_send_value_(false),
66 has_receive_value_(false) {}
67QuicFixedUint32::~QuicFixedUint32() {}
68
69bool QuicFixedUint32::HasSendValue() const {
70 return has_send_value_;
71}
72
73uint32_t QuicFixedUint32::GetSendValue() const {
QUICHE teamd6d05e52021-03-16 14:22:01 -070074 QUIC_BUG_IF(quic_bug_12743_1, !has_send_value_)
QUICHE teama6ef0a62019-03-07 20:34:33 -050075 << "No send value to get for tag:" << QuicTagToString(tag_);
76 return send_value_;
77}
78
79void QuicFixedUint32::SetSendValue(uint32_t value) {
80 has_send_value_ = true;
81 send_value_ = value;
82}
83
84bool QuicFixedUint32::HasReceivedValue() const {
85 return has_receive_value_;
86}
87
88uint32_t QuicFixedUint32::GetReceivedValue() const {
QUICHE teamd6d05e52021-03-16 14:22:01 -070089 QUIC_BUG_IF(quic_bug_12743_2, !has_receive_value_)
QUICHE teama6ef0a62019-03-07 20:34:33 -050090 << "No receive value to get for tag:" << QuicTagToString(tag_);
91 return receive_value_;
92}
93
94void QuicFixedUint32::SetReceivedValue(uint32_t value) {
95 has_receive_value_ = true;
96 receive_value_ = value;
97}
98
99void QuicFixedUint32::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
dschinazif1e7b422020-04-30 12:21:28 -0700100 if (tag_ == 0) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700101 QUIC_BUG(quic_bug_12743_3)
dschinazif1e7b422020-04-30 12:21:28 -0700102 << "This parameter does not support writing to CryptoHandshakeMessage";
103 return;
104 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500105 if (has_send_value_) {
106 out->SetValue(tag_, send_value_);
107 }
108}
109
110QuicErrorCode QuicFixedUint32::ProcessPeerHello(
111 const CryptoHandshakeMessage& peer_hello,
dschinazi17d42422019-06-18 16:35:07 -0700112 HelloType /*hello_type*/,
vasilvvc48c8712019-03-11 13:38:16 -0700113 std::string* error_details) {
vasilvvf8035162021-02-01 14:49:14 -0800114 QUICHE_DCHECK(error_details != nullptr);
dschinazif1e7b422020-04-30 12:21:28 -0700115 if (tag_ == 0) {
116 *error_details =
117 "This parameter does not support reading from CryptoHandshakeMessage";
QUICHE teamd6d05e52021-03-16 14:22:01 -0700118 QUIC_BUG(quic_bug_10575_1) << *error_details;
dschinazif1e7b422020-04-30 12:21:28 -0700119 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
120 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500121 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
dschinazif1e7b422020-04-30 12:21:28 -0700139QuicFixedUint62::QuicFixedUint62(QuicTag name, QuicConfigPresence presence)
140 : QuicConfigValue(name, presence),
141 has_send_value_(false),
142 has_receive_value_(false) {}
143
144QuicFixedUint62::~QuicFixedUint62() {}
145
146bool QuicFixedUint62::HasSendValue() const {
147 return has_send_value_;
148}
149
150uint64_t QuicFixedUint62::GetSendValue() const {
151 if (!has_send_value_) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700152 QUIC_BUG(quic_bug_10575_2)
QUICHE team5c9cddc2021-03-09 15:52:30 -0800153 << "No send value to get for tag:" << QuicTagToString(tag_);
dschinazif1e7b422020-04-30 12:21:28 -0700154 return 0;
155 }
156 return send_value_;
157}
158
159void QuicFixedUint62::SetSendValue(uint64_t value) {
160 if (value > kVarInt62MaxValue) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700161 QUIC_BUG(quic_bug_10575_3) << "QuicFixedUint62 invalid value " << value;
dschinazif1e7b422020-04-30 12:21:28 -0700162 value = kVarInt62MaxValue;
163 }
164 has_send_value_ = true;
165 send_value_ = value;
166}
167
168bool QuicFixedUint62::HasReceivedValue() const {
169 return has_receive_value_;
170}
171
172uint64_t QuicFixedUint62::GetReceivedValue() const {
173 if (!has_receive_value_) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700174 QUIC_BUG(quic_bug_10575_4)
QUICHE team5c9cddc2021-03-09 15:52:30 -0800175 << "No receive value to get for tag:" << QuicTagToString(tag_);
dschinazif1e7b422020-04-30 12:21:28 -0700176 return 0;
177 }
178 return receive_value_;
179}
180
181void QuicFixedUint62::SetReceivedValue(uint64_t value) {
182 has_receive_value_ = true;
183 receive_value_ = value;
184}
185
186void QuicFixedUint62::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
187 if (!has_send_value_) {
188 return;
189 }
190 uint32_t send_value32;
191 if (send_value_ > std::numeric_limits<uint32_t>::max()) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700192 QUIC_BUG(quic_bug_10575_5) << "Attempting to send " << send_value_
193 << " for tag:" << QuicTagToString(tag_);
dschinazif1e7b422020-04-30 12:21:28 -0700194 send_value32 = std::numeric_limits<uint32_t>::max();
195 } else {
196 send_value32 = static_cast<uint32_t>(send_value_);
197 }
198 out->SetValue(tag_, send_value32);
199}
200
201QuicErrorCode QuicFixedUint62::ProcessPeerHello(
202 const CryptoHandshakeMessage& peer_hello,
203 HelloType /*hello_type*/,
204 std::string* error_details) {
vasilvvf8035162021-02-01 14:49:14 -0800205 QUICHE_DCHECK(error_details != nullptr);
dschinazif1e7b422020-04-30 12:21:28 -0700206 uint32_t receive_value32;
207 QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value32);
208 // GetUint32 is guaranteed to always initialize receive_value32.
209 receive_value_ = receive_value32;
210 switch (error) {
211 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
212 if (presence_ == PRESENCE_OPTIONAL) {
213 return QUIC_NO_ERROR;
214 }
215 *error_details = "Missing " + QuicTagToString(tag_);
216 break;
217 case QUIC_NO_ERROR:
218 has_receive_value_ = true;
219 break;
220 default:
221 *error_details = "Bad " + QuicTagToString(tag_);
222 break;
223 }
224 return error;
225}
226
bnc1ccd0bc2021-04-07 10:20:17 -0700227QuicFixedStatelessResetToken::QuicFixedStatelessResetToken(
228 QuicTag tag,
229 QuicConfigPresence presence)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500230 : QuicConfigValue(tag, presence),
231 has_send_value_(false),
232 has_receive_value_(false) {}
bnc1ccd0bc2021-04-07 10:20:17 -0700233QuicFixedStatelessResetToken::~QuicFixedStatelessResetToken() {}
QUICHE teama6ef0a62019-03-07 20:34:33 -0500234
bnc1ccd0bc2021-04-07 10:20:17 -0700235bool QuicFixedStatelessResetToken::HasSendValue() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500236 return has_send_value_;
237}
238
bnc1ccd0bc2021-04-07 10:20:17 -0700239const StatelessResetToken& QuicFixedStatelessResetToken::GetSendValue() const {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700240 QUIC_BUG_IF(quic_bug_12743_4, !has_send_value_)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500241 << "No send value to get for tag:" << QuicTagToString(tag_);
242 return send_value_;
243}
244
bnc1ccd0bc2021-04-07 10:20:17 -0700245void QuicFixedStatelessResetToken::SetSendValue(
246 const StatelessResetToken& value) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500247 has_send_value_ = true;
248 send_value_ = value;
249}
250
bnc1ccd0bc2021-04-07 10:20:17 -0700251bool QuicFixedStatelessResetToken::HasReceivedValue() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500252 return has_receive_value_;
253}
254
bnc1ccd0bc2021-04-07 10:20:17 -0700255const StatelessResetToken& QuicFixedStatelessResetToken::GetReceivedValue()
256 const {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700257 QUIC_BUG_IF(quic_bug_12743_5, !has_receive_value_)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500258 << "No receive value to get for tag:" << QuicTagToString(tag_);
259 return receive_value_;
260}
261
bnc1ccd0bc2021-04-07 10:20:17 -0700262void QuicFixedStatelessResetToken::SetReceivedValue(
263 const StatelessResetToken& value) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500264 has_receive_value_ = true;
265 receive_value_ = value;
266}
267
bnc1ccd0bc2021-04-07 10:20:17 -0700268void QuicFixedStatelessResetToken::ToHandshakeMessage(
269 CryptoHandshakeMessage* out) const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500270 if (has_send_value_) {
271 out->SetValue(tag_, send_value_);
272 }
273}
274
bnc1ccd0bc2021-04-07 10:20:17 -0700275QuicErrorCode QuicFixedStatelessResetToken::ProcessPeerHello(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500276 const CryptoHandshakeMessage& peer_hello,
dschinazi17d42422019-06-18 16:35:07 -0700277 HelloType /*hello_type*/,
vasilvvc48c8712019-03-11 13:38:16 -0700278 std::string* error_details) {
vasilvvf8035162021-02-01 14:49:14 -0800279 QUICHE_DCHECK(error_details != nullptr);
bnc1ccd0bc2021-04-07 10:20:17 -0700280 QuicErrorCode error =
281 peer_hello.GetStatelessResetToken(tag_, &receive_value_);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500282 switch (error) {
283 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
284 if (presence_ == PRESENCE_OPTIONAL) {
285 return QUIC_NO_ERROR;
286 }
287 *error_details = "Missing " + QuicTagToString(tag_);
288 break;
289 case QUIC_NO_ERROR:
290 has_receive_value_ = true;
291 break;
292 default:
293 *error_details = "Bad " + QuicTagToString(tag_);
294 break;
295 }
296 return error;
297}
298
299QuicFixedTagVector::QuicFixedTagVector(QuicTag name,
300 QuicConfigPresence presence)
301 : QuicConfigValue(name, presence),
302 has_send_values_(false),
303 has_receive_values_(false) {}
304
305QuicFixedTagVector::QuicFixedTagVector(const QuicFixedTagVector& other) =
306 default;
307
308QuicFixedTagVector::~QuicFixedTagVector() {}
309
310bool QuicFixedTagVector::HasSendValues() const {
311 return has_send_values_;
312}
313
wubbde76c32020-04-23 11:33:13 -0700314const QuicTagVector& QuicFixedTagVector::GetSendValues() const {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700315 QUIC_BUG_IF(quic_bug_12743_6, !has_send_values_)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500316 << "No send values to get for tag:" << QuicTagToString(tag_);
317 return send_values_;
318}
319
320void QuicFixedTagVector::SetSendValues(const QuicTagVector& values) {
321 has_send_values_ = true;
322 send_values_ = values;
323}
324
325bool QuicFixedTagVector::HasReceivedValues() const {
326 return has_receive_values_;
327}
328
wubbde76c32020-04-23 11:33:13 -0700329const QuicTagVector& QuicFixedTagVector::GetReceivedValues() const {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700330 QUIC_BUG_IF(quic_bug_12743_7, !has_receive_values_)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500331 << "No receive value to get for tag:" << QuicTagToString(tag_);
332 return receive_values_;
333}
334
335void QuicFixedTagVector::SetReceivedValues(const QuicTagVector& values) {
336 has_receive_values_ = true;
337 receive_values_ = values;
338}
339
340void QuicFixedTagVector::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
341 if (has_send_values_) {
342 out->SetVector(tag_, send_values_);
343 }
344}
345
346QuicErrorCode QuicFixedTagVector::ProcessPeerHello(
347 const CryptoHandshakeMessage& peer_hello,
dschinazi17d42422019-06-18 16:35:07 -0700348 HelloType /*hello_type*/,
vasilvvc48c8712019-03-11 13:38:16 -0700349 std::string* error_details) {
vasilvvf8035162021-02-01 14:49:14 -0800350 QUICHE_DCHECK(error_details != nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500351 QuicTagVector values;
352 QuicErrorCode error = peer_hello.GetTaglist(tag_, &values);
353 switch (error) {
354 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
355 if (presence_ == PRESENCE_OPTIONAL) {
356 return QUIC_NO_ERROR;
357 }
358 *error_details = "Missing " + QuicTagToString(tag_);
359 break;
360 case QUIC_NO_ERROR:
361 QUIC_DVLOG(1) << "Received Connection Option tags from receiver.";
362 has_receive_values_ = true;
363 receive_values_.insert(receive_values_.end(), values.begin(),
364 values.end());
365 break;
366 default:
367 *error_details = "Bad " + QuicTagToString(tag_);
368 break;
369 }
370 return error;
371}
372
373QuicFixedSocketAddress::QuicFixedSocketAddress(QuicTag tag,
374 QuicConfigPresence presence)
375 : QuicConfigValue(tag, presence),
376 has_send_value_(false),
377 has_receive_value_(false) {}
378
379QuicFixedSocketAddress::~QuicFixedSocketAddress() {}
380
381bool QuicFixedSocketAddress::HasSendValue() const {
382 return has_send_value_;
383}
384
385const QuicSocketAddress& QuicFixedSocketAddress::GetSendValue() const {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700386 QUIC_BUG_IF(quic_bug_12743_8, !has_send_value_)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500387 << "No send value to get for tag:" << QuicTagToString(tag_);
388 return send_value_;
389}
390
391void QuicFixedSocketAddress::SetSendValue(const QuicSocketAddress& value) {
392 has_send_value_ = true;
393 send_value_ = value;
394}
395
396bool QuicFixedSocketAddress::HasReceivedValue() const {
397 return has_receive_value_;
398}
399
400const QuicSocketAddress& QuicFixedSocketAddress::GetReceivedValue() const {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700401 QUIC_BUG_IF(quic_bug_12743_9, !has_receive_value_)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500402 << "No receive value to get for tag:" << QuicTagToString(tag_);
403 return receive_value_;
404}
405
406void QuicFixedSocketAddress::SetReceivedValue(const QuicSocketAddress& value) {
407 has_receive_value_ = true;
408 receive_value_ = value;
409}
410
411void QuicFixedSocketAddress::ToHandshakeMessage(
412 CryptoHandshakeMessage* out) const {
413 if (has_send_value_) {
414 QuicSocketAddressCoder address_coder(send_value_);
415 out->SetStringPiece(tag_, address_coder.Encode());
416 }
417}
418
419QuicErrorCode QuicFixedSocketAddress::ProcessPeerHello(
420 const CryptoHandshakeMessage& peer_hello,
dschinazi17d42422019-06-18 16:35:07 -0700421 HelloType /*hello_type*/,
vasilvvc48c8712019-03-11 13:38:16 -0700422 std::string* error_details) {
vasilvvc872ee42020-10-07 19:50:22 -0700423 absl::string_view address;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500424 if (!peer_hello.GetStringPiece(tag_, &address)) {
425 if (presence_ == PRESENCE_REQUIRED) {
426 *error_details = "Missing " + QuicTagToString(tag_);
427 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
428 }
429 } else {
430 QuicSocketAddressCoder address_coder;
431 if (address_coder.Decode(address.data(), address.length())) {
432 SetReceivedValue(
433 QuicSocketAddress(address_coder.ip(), address_coder.port()));
434 }
435 }
436 return QUIC_NO_ERROR;
437}
438
439QuicConfig::QuicConfig()
dschinazif7c6a912020-05-05 11:39:53 -0700440 : negotiated_(false),
441 max_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500442 max_idle_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
443 max_undecryptable_packets_(0),
444 connection_options_(kCOPT, PRESENCE_OPTIONAL),
445 client_connection_options_(kCLOP, PRESENCE_OPTIONAL),
dschinazi5a29bd52020-05-21 19:37:32 -0700446 max_idle_timeout_to_send_(QuicTime::Delta::Infinite()),
renjietange6d94672020-01-07 10:30:10 -0800447 max_bidirectional_streams_(kMIBS, PRESENCE_REQUIRED),
448 max_unidirectional_streams_(kMIUS, PRESENCE_OPTIONAL),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500449 bytes_for_connection_id_(kTCID, PRESENCE_OPTIONAL),
450 initial_round_trip_time_us_(kIRTT, PRESENCE_OPTIONAL),
rchb0451852019-09-11 21:17:01 -0700451 initial_max_stream_data_bytes_incoming_bidirectional_(0,
452 PRESENCE_OPTIONAL),
453 initial_max_stream_data_bytes_outgoing_bidirectional_(0,
454 PRESENCE_OPTIONAL),
455 initial_max_stream_data_bytes_unidirectional_(0, PRESENCE_OPTIONAL),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500456 initial_stream_flow_control_window_bytes_(kSFCW, PRESENCE_OPTIONAL),
457 initial_session_flow_control_window_bytes_(kCFCW, PRESENCE_OPTIONAL),
458 connection_migration_disabled_(kNCMR, PRESENCE_OPTIONAL),
mattm072a7e32020-10-09 16:16:56 -0700459 key_update_supported_remotely_(false),
460 key_update_supported_locally_(false),
dschinazifaa70a72020-04-30 16:56:51 -0700461 alternate_server_address_ipv6_(kASAD, PRESENCE_OPTIONAL),
462 alternate_server_address_ipv4_(kASAD, PRESENCE_OPTIONAL),
fkastenholzd3a1de92019-05-15 07:00:07 -0700463 stateless_reset_token_(kSRST, PRESENCE_OPTIONAL),
fkastenholz4dc4ba32019-07-30 09:55:25 -0700464 max_ack_delay_ms_(kMAD, PRESENCE_OPTIONAL),
haoyuewang7cffa542020-07-15 17:12:27 -0700465 min_ack_delay_ms_(0, PRESENCE_OPTIONAL),
dschinazi58881132019-11-11 11:34:02 -0800466 ack_delay_exponent_(kADE, PRESENCE_OPTIONAL),
dschinazi5a29bd52020-05-21 19:37:32 -0700467 max_udp_payload_size_(0, PRESENCE_OPTIONAL),
dschinazi46730232020-05-07 10:01:21 -0700468 max_datagram_frame_size_(0, PRESENCE_OPTIONAL),
469 active_connection_id_limit_(0, PRESENCE_OPTIONAL) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500470 SetDefaults();
471}
472
473QuicConfig::QuicConfig(const QuicConfig& other) = default;
474
475QuicConfig::~QuicConfig() {}
476
477bool QuicConfig::SetInitialReceivedConnectionOptions(
478 const QuicTagVector& tags) {
479 if (HasReceivedConnectionOptions()) {
480 // If we have already received connection options (via handshake or due to
481 // a previous call), don't re-initialize.
482 return false;
483 }
484 connection_options_.SetReceivedValues(tags);
485 return true;
486}
487
488void QuicConfig::SetConnectionOptionsToSend(
489 const QuicTagVector& connection_options) {
490 connection_options_.SetSendValues(connection_options);
491}
492
493bool QuicConfig::HasReceivedConnectionOptions() const {
494 return connection_options_.HasReceivedValues();
495}
496
wubbde76c32020-04-23 11:33:13 -0700497const QuicTagVector& QuicConfig::ReceivedConnectionOptions() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500498 return connection_options_.GetReceivedValues();
499}
500
501bool QuicConfig::HasSendConnectionOptions() const {
502 return connection_options_.HasSendValues();
503}
504
wubbde76c32020-04-23 11:33:13 -0700505const QuicTagVector& QuicConfig::SendConnectionOptions() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500506 return connection_options_.GetSendValues();
507}
508
509bool QuicConfig::HasClientSentConnectionOption(QuicTag tag,
510 Perspective perspective) const {
511 if (perspective == Perspective::IS_SERVER) {
512 if (HasReceivedConnectionOptions() &&
513 ContainsQuicTag(ReceivedConnectionOptions(), tag)) {
514 return true;
515 }
516 } else if (HasSendConnectionOptions() &&
517 ContainsQuicTag(SendConnectionOptions(), tag)) {
518 return true;
519 }
520 return false;
521}
522
523void QuicConfig::SetClientConnectionOptions(
524 const QuicTagVector& client_connection_options) {
525 client_connection_options_.SetSendValues(client_connection_options);
526}
527
528bool QuicConfig::HasClientRequestedIndependentOption(
529 QuicTag tag,
530 Perspective perspective) const {
531 if (perspective == Perspective::IS_SERVER) {
532 return (HasReceivedConnectionOptions() &&
533 ContainsQuicTag(ReceivedConnectionOptions(), tag));
534 }
535
536 return (client_connection_options_.HasSendValues() &&
537 ContainsQuicTag(client_connection_options_.GetSendValues(), tag));
538}
539
wubd09f1a62020-05-04 06:57:40 -0700540const QuicTagVector& QuicConfig::ClientRequestedIndependentOptions(
541 Perspective perspective) const {
542 static const QuicTagVector* no_options = new QuicTagVector;
543 if (perspective == Perspective::IS_SERVER) {
544 return HasReceivedConnectionOptions() ? ReceivedConnectionOptions()
545 : *no_options;
546 }
547
548 return client_connection_options_.HasSendValues()
549 ? client_connection_options_.GetSendValues()
550 : *no_options;
551}
552
dschinazibe284d12020-04-30 17:42:16 -0700553void QuicConfig::SetIdleNetworkTimeout(QuicTime::Delta idle_network_timeout) {
dschinazif7c6a912020-05-05 11:39:53 -0700554 if (idle_network_timeout.ToMicroseconds() <= 0) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700555 QUIC_BUG(quic_bug_10575_6)
QUICHE team5c9cddc2021-03-09 15:52:30 -0800556 << "Invalid idle network timeout " << idle_network_timeout;
dschinazif7c6a912020-05-05 11:39:53 -0700557 return;
558 }
dschinazi5a29bd52020-05-21 19:37:32 -0700559 max_idle_timeout_to_send_ = idle_network_timeout;
dschinazibe284d12020-04-30 17:42:16 -0700560}
561
QUICHE teama6ef0a62019-03-07 20:34:33 -0500562QuicTime::Delta QuicConfig::IdleNetworkTimeout() const {
dschinazif7c6a912020-05-05 11:39:53 -0700563 // TODO(b/152032210) add a QUIC_BUG to ensure that is not called before we've
564 // received the peer's values. This is true in production code but not in all
565 // of our tests that use a fake QuicConfig.
dschinazi5a29bd52020-05-21 19:37:32 -0700566 if (!received_max_idle_timeout_.has_value()) {
567 return max_idle_timeout_to_send_;
dschinazif7c6a912020-05-05 11:39:53 -0700568 }
dschinazi5a29bd52020-05-21 19:37:32 -0700569 return received_max_idle_timeout_.value();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500570}
571
renjietange6d94672020-01-07 10:30:10 -0800572void QuicConfig::SetMaxBidirectionalStreamsToSend(uint32_t max_streams) {
573 max_bidirectional_streams_.SetSendValue(max_streams);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500574}
575
renjietange6d94672020-01-07 10:30:10 -0800576uint32_t QuicConfig::GetMaxBidirectionalStreamsToSend() const {
577 return max_bidirectional_streams_.GetSendValue();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500578}
579
renjietange6d94672020-01-07 10:30:10 -0800580bool QuicConfig::HasReceivedMaxBidirectionalStreams() const {
581 return max_bidirectional_streams_.HasReceivedValue();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500582}
583
renjietange6d94672020-01-07 10:30:10 -0800584uint32_t QuicConfig::ReceivedMaxBidirectionalStreams() const {
585 return max_bidirectional_streams_.GetReceivedValue();
fkastenholzd3a1de92019-05-15 07:00:07 -0700586}
587
renjietange6d94672020-01-07 10:30:10 -0800588void QuicConfig::SetMaxUnidirectionalStreamsToSend(uint32_t max_streams) {
589 max_unidirectional_streams_.SetSendValue(max_streams);
fkastenholzd3a1de92019-05-15 07:00:07 -0700590}
591
renjietange6d94672020-01-07 10:30:10 -0800592uint32_t QuicConfig::GetMaxUnidirectionalStreamsToSend() const {
593 return max_unidirectional_streams_.GetSendValue();
fkastenholzd3a1de92019-05-15 07:00:07 -0700594}
595
renjietange6d94672020-01-07 10:30:10 -0800596bool QuicConfig::HasReceivedMaxUnidirectionalStreams() const {
597 return max_unidirectional_streams_.HasReceivedValue();
fkastenholzd3a1de92019-05-15 07:00:07 -0700598}
599
renjietange6d94672020-01-07 10:30:10 -0800600uint32_t QuicConfig::ReceivedMaxUnidirectionalStreams() const {
601 return max_unidirectional_streams_.GetReceivedValue();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500602}
603
fkastenholz4c7303c2019-07-29 08:17:07 -0700604void QuicConfig::SetMaxAckDelayToSendMs(uint32_t max_ack_delay_ms) {
haoyuewang7cffa542020-07-15 17:12:27 -0700605 max_ack_delay_ms_.SetSendValue(max_ack_delay_ms);
fkastenholz4c7303c2019-07-29 08:17:07 -0700606}
607
dschinazif67b5c52020-05-18 15:18:14 -0700608uint32_t QuicConfig::GetMaxAckDelayToSendMs() const {
fkastenholz4c7303c2019-07-29 08:17:07 -0700609 return max_ack_delay_ms_.GetSendValue();
610}
611
612bool QuicConfig::HasReceivedMaxAckDelayMs() const {
613 return max_ack_delay_ms_.HasReceivedValue();
614}
615
616uint32_t QuicConfig::ReceivedMaxAckDelayMs() const {
617 return max_ack_delay_ms_.GetReceivedValue();
618}
619
haoyuewang7cffa542020-07-15 17:12:27 -0700620void QuicConfig::SetMinAckDelayMs(uint32_t min_ack_delay_ms) {
621 min_ack_delay_ms_.SetSendValue(min_ack_delay_ms);
622}
623
624uint32_t QuicConfig::GetMinAckDelayToSendMs() const {
625 return min_ack_delay_ms_.GetSendValue();
626}
627
628bool QuicConfig::HasReceivedMinAckDelayMs() const {
629 return min_ack_delay_ms_.HasReceivedValue();
630}
631
632uint32_t QuicConfig::ReceivedMinAckDelayMs() const {
633 return min_ack_delay_ms_.GetReceivedValue();
634}
635
fkastenholz4dc4ba32019-07-30 09:55:25 -0700636void QuicConfig::SetAckDelayExponentToSend(uint32_t exponent) {
637 ack_delay_exponent_.SetSendValue(exponent);
638}
639
dschinazi90165ee2019-10-15 15:11:41 -0700640uint32_t QuicConfig::GetAckDelayExponentToSend() const {
fkastenholz4dc4ba32019-07-30 09:55:25 -0700641 return ack_delay_exponent_.GetSendValue();
642}
643
644bool QuicConfig::HasReceivedAckDelayExponent() const {
645 return ack_delay_exponent_.HasReceivedValue();
646}
647
648uint32_t QuicConfig::ReceivedAckDelayExponent() const {
649 return ack_delay_exponent_.GetReceivedValue();
650}
651
dschinazi5a29bd52020-05-21 19:37:32 -0700652void QuicConfig::SetMaxPacketSizeToSend(uint64_t max_udp_payload_size) {
653 max_udp_payload_size_.SetSendValue(max_udp_payload_size);
dschinazi58881132019-11-11 11:34:02 -0800654}
655
dschinazif1e7b422020-04-30 12:21:28 -0700656uint64_t QuicConfig::GetMaxPacketSizeToSend() const {
dschinazi5a29bd52020-05-21 19:37:32 -0700657 return max_udp_payload_size_.GetSendValue();
dschinazi58881132019-11-11 11:34:02 -0800658}
659
660bool QuicConfig::HasReceivedMaxPacketSize() const {
dschinazi5a29bd52020-05-21 19:37:32 -0700661 return max_udp_payload_size_.HasReceivedValue();
dschinazi58881132019-11-11 11:34:02 -0800662}
663
dschinazif1e7b422020-04-30 12:21:28 -0700664uint64_t QuicConfig::ReceivedMaxPacketSize() const {
dschinazi5a29bd52020-05-21 19:37:32 -0700665 return max_udp_payload_size_.GetReceivedValue();
dschinazi58881132019-11-11 11:34:02 -0800666}
667
dschinazicd86dd12019-11-14 10:11:13 -0800668void QuicConfig::SetMaxDatagramFrameSizeToSend(
dschinazif1e7b422020-04-30 12:21:28 -0700669 uint64_t max_datagram_frame_size) {
dschinazicd86dd12019-11-14 10:11:13 -0800670 max_datagram_frame_size_.SetSendValue(max_datagram_frame_size);
671}
672
dschinazif1e7b422020-04-30 12:21:28 -0700673uint64_t QuicConfig::GetMaxDatagramFrameSizeToSend() const {
dschinazicd86dd12019-11-14 10:11:13 -0800674 return max_datagram_frame_size_.GetSendValue();
675}
676
677bool QuicConfig::HasReceivedMaxDatagramFrameSize() const {
678 return max_datagram_frame_size_.HasReceivedValue();
679}
680
dschinazif1e7b422020-04-30 12:21:28 -0700681uint64_t QuicConfig::ReceivedMaxDatagramFrameSize() const {
dschinazicd86dd12019-11-14 10:11:13 -0800682 return max_datagram_frame_size_.GetReceivedValue();
683}
684
dschinazi46730232020-05-07 10:01:21 -0700685void QuicConfig::SetActiveConnectionIdLimitToSend(
686 uint64_t active_connection_id_limit) {
687 active_connection_id_limit_.SetSendValue(active_connection_id_limit);
688}
689
690uint64_t QuicConfig::GetActiveConnectionIdLimitToSend() const {
691 return active_connection_id_limit_.GetSendValue();
692}
693
694bool QuicConfig::HasReceivedActiveConnectionIdLimit() const {
695 return active_connection_id_limit_.HasReceivedValue();
696}
697
698uint64_t QuicConfig::ReceivedActiveConnectionIdLimit() const {
699 return active_connection_id_limit_.GetReceivedValue();
700}
701
QUICHE teama6ef0a62019-03-07 20:34:33 -0500702bool QuicConfig::HasSetBytesForConnectionIdToSend() const {
703 return bytes_for_connection_id_.HasSendValue();
704}
705
706void QuicConfig::SetBytesForConnectionIdToSend(uint32_t bytes) {
707 bytes_for_connection_id_.SetSendValue(bytes);
708}
709
710bool QuicConfig::HasReceivedBytesForConnectionId() const {
711 return bytes_for_connection_id_.HasReceivedValue();
712}
713
714uint32_t QuicConfig::ReceivedBytesForConnectionId() const {
715 return bytes_for_connection_id_.GetReceivedValue();
716}
717
dschinazi7e51f6b2020-05-13 17:36:44 -0700718void QuicConfig::SetInitialRoundTripTimeUsToSend(uint64_t rtt) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500719 initial_round_trip_time_us_.SetSendValue(rtt);
720}
721
722bool QuicConfig::HasReceivedInitialRoundTripTimeUs() const {
723 return initial_round_trip_time_us_.HasReceivedValue();
724}
725
dschinazi7e51f6b2020-05-13 17:36:44 -0700726uint64_t QuicConfig::ReceivedInitialRoundTripTimeUs() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500727 return initial_round_trip_time_us_.GetReceivedValue();
728}
729
730bool QuicConfig::HasInitialRoundTripTimeUsToSend() const {
731 return initial_round_trip_time_us_.HasSendValue();
732}
733
dschinazi7e51f6b2020-05-13 17:36:44 -0700734uint64_t QuicConfig::GetInitialRoundTripTimeUsToSend() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500735 return initial_round_trip_time_us_.GetSendValue();
736}
737
738void QuicConfig::SetInitialStreamFlowControlWindowToSend(
dschinazif1e7b422020-04-30 12:21:28 -0700739 uint64_t window_bytes) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500740 if (window_bytes < kMinimumFlowControlSendWindow) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700741 QUIC_BUG(quic_bug_10575_7)
QUICHE team5c9cddc2021-03-09 15:52:30 -0800742 << "Initial stream flow control receive window (" << window_bytes
743 << ") cannot be set lower than minimum ("
744 << kMinimumFlowControlSendWindow << ").";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500745 window_bytes = kMinimumFlowControlSendWindow;
746 }
747 initial_stream_flow_control_window_bytes_.SetSendValue(window_bytes);
748}
749
dschinazif1e7b422020-04-30 12:21:28 -0700750uint64_t QuicConfig::GetInitialStreamFlowControlWindowToSend() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500751 return initial_stream_flow_control_window_bytes_.GetSendValue();
752}
753
754bool QuicConfig::HasReceivedInitialStreamFlowControlWindowBytes() const {
755 return initial_stream_flow_control_window_bytes_.HasReceivedValue();
756}
757
dschinazif1e7b422020-04-30 12:21:28 -0700758uint64_t QuicConfig::ReceivedInitialStreamFlowControlWindowBytes() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500759 return initial_stream_flow_control_window_bytes_.GetReceivedValue();
760}
761
rchb0451852019-09-11 21:17:01 -0700762void QuicConfig::SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
dschinazif1e7b422020-04-30 12:21:28 -0700763 uint64_t window_bytes) {
rchb0451852019-09-11 21:17:01 -0700764 initial_max_stream_data_bytes_incoming_bidirectional_.SetSendValue(
765 window_bytes);
766}
767
dschinazif1e7b422020-04-30 12:21:28 -0700768uint64_t QuicConfig::GetInitialMaxStreamDataBytesIncomingBidirectionalToSend()
rchb0451852019-09-11 21:17:01 -0700769 const {
dschinazi90165ee2019-10-15 15:11:41 -0700770 if (initial_max_stream_data_bytes_incoming_bidirectional_.HasSendValue()) {
771 return initial_max_stream_data_bytes_incoming_bidirectional_.GetSendValue();
772 }
773 return initial_stream_flow_control_window_bytes_.GetSendValue();
rchb0451852019-09-11 21:17:01 -0700774}
775
776bool QuicConfig::HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()
777 const {
778 return initial_max_stream_data_bytes_incoming_bidirectional_
779 .HasReceivedValue();
780}
781
dschinazif1e7b422020-04-30 12:21:28 -0700782uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesIncomingBidirectional()
rchb0451852019-09-11 21:17:01 -0700783 const {
784 return initial_max_stream_data_bytes_incoming_bidirectional_
785 .GetReceivedValue();
786}
787
788void QuicConfig::SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
dschinazif1e7b422020-04-30 12:21:28 -0700789 uint64_t window_bytes) {
rchb0451852019-09-11 21:17:01 -0700790 initial_max_stream_data_bytes_outgoing_bidirectional_.SetSendValue(
791 window_bytes);
792}
793
dschinazif1e7b422020-04-30 12:21:28 -0700794uint64_t QuicConfig::GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend()
rchb0451852019-09-11 21:17:01 -0700795 const {
dschinazi90165ee2019-10-15 15:11:41 -0700796 if (initial_max_stream_data_bytes_outgoing_bidirectional_.HasSendValue()) {
797 return initial_max_stream_data_bytes_outgoing_bidirectional_.GetSendValue();
798 }
799 return initial_stream_flow_control_window_bytes_.GetSendValue();
rchb0451852019-09-11 21:17:01 -0700800}
801
802bool QuicConfig::HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()
803 const {
804 return initial_max_stream_data_bytes_outgoing_bidirectional_
805 .HasReceivedValue();
806}
807
dschinazif1e7b422020-04-30 12:21:28 -0700808uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesOutgoingBidirectional()
rchb0451852019-09-11 21:17:01 -0700809 const {
810 return initial_max_stream_data_bytes_outgoing_bidirectional_
811 .GetReceivedValue();
812}
813
814void QuicConfig::SetInitialMaxStreamDataBytesUnidirectionalToSend(
dschinazif1e7b422020-04-30 12:21:28 -0700815 uint64_t window_bytes) {
rchb0451852019-09-11 21:17:01 -0700816 initial_max_stream_data_bytes_unidirectional_.SetSendValue(window_bytes);
817}
818
dschinazif1e7b422020-04-30 12:21:28 -0700819uint64_t QuicConfig::GetInitialMaxStreamDataBytesUnidirectionalToSend() const {
dschinazi90165ee2019-10-15 15:11:41 -0700820 if (initial_max_stream_data_bytes_unidirectional_.HasSendValue()) {
821 return initial_max_stream_data_bytes_unidirectional_.GetSendValue();
822 }
823 return initial_stream_flow_control_window_bytes_.GetSendValue();
rchb0451852019-09-11 21:17:01 -0700824}
825
826bool QuicConfig::HasReceivedInitialMaxStreamDataBytesUnidirectional() const {
827 return initial_max_stream_data_bytes_unidirectional_.HasReceivedValue();
828}
829
dschinazif1e7b422020-04-30 12:21:28 -0700830uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesUnidirectional() const {
rchb0451852019-09-11 21:17:01 -0700831 return initial_max_stream_data_bytes_unidirectional_.GetReceivedValue();
832}
833
QUICHE teama6ef0a62019-03-07 20:34:33 -0500834void QuicConfig::SetInitialSessionFlowControlWindowToSend(
dschinazif1e7b422020-04-30 12:21:28 -0700835 uint64_t window_bytes) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500836 if (window_bytes < kMinimumFlowControlSendWindow) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700837 QUIC_BUG(quic_bug_10575_8)
QUICHE team5c9cddc2021-03-09 15:52:30 -0800838 << "Initial session flow control receive window (" << window_bytes
839 << ") cannot be set lower than default ("
840 << kMinimumFlowControlSendWindow << ").";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500841 window_bytes = kMinimumFlowControlSendWindow;
842 }
843 initial_session_flow_control_window_bytes_.SetSendValue(window_bytes);
844}
845
dschinazif1e7b422020-04-30 12:21:28 -0700846uint64_t QuicConfig::GetInitialSessionFlowControlWindowToSend() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500847 return initial_session_flow_control_window_bytes_.GetSendValue();
848}
849
850bool QuicConfig::HasReceivedInitialSessionFlowControlWindowBytes() const {
851 return initial_session_flow_control_window_bytes_.HasReceivedValue();
852}
853
dschinazif1e7b422020-04-30 12:21:28 -0700854uint64_t QuicConfig::ReceivedInitialSessionFlowControlWindowBytes() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500855 return initial_session_flow_control_window_bytes_.GetReceivedValue();
856}
857
858void QuicConfig::SetDisableConnectionMigration() {
859 connection_migration_disabled_.SetSendValue(1);
860}
861
862bool QuicConfig::DisableConnectionMigration() const {
863 return connection_migration_disabled_.HasReceivedValue();
864}
865
mattm072a7e32020-10-09 16:16:56 -0700866void QuicConfig::SetKeyUpdateSupportedLocally() {
867 key_update_supported_locally_ = true;
868}
869
870bool QuicConfig::KeyUpdateSupportedForConnection() const {
mattmf7f203a2020-10-23 12:19:32 -0700871 return KeyUpdateSupportedRemotely() && KeyUpdateSupportedLocally();
mattm072a7e32020-10-09 16:16:56 -0700872}
873
874bool QuicConfig::KeyUpdateSupportedLocally() const {
875 return key_update_supported_locally_;
876}
877
mattmf7f203a2020-10-23 12:19:32 -0700878bool QuicConfig::KeyUpdateSupportedRemotely() const {
879 return key_update_supported_remotely_;
880}
881
dschinazifaa70a72020-04-30 16:56:51 -0700882void QuicConfig::SetIPv6AlternateServerAddressToSend(
883 const QuicSocketAddress& alternate_server_address_ipv6) {
884 if (!alternate_server_address_ipv6.host().IsIPv6()) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700885 QUIC_BUG(quic_bug_10575_9)
QUICHE team5c9cddc2021-03-09 15:52:30 -0800886 << "Cannot use SetIPv6AlternateServerAddressToSend with "
887 << alternate_server_address_ipv6;
dschinazifaa70a72020-04-30 16:56:51 -0700888 return;
889 }
890 alternate_server_address_ipv6_.SetSendValue(alternate_server_address_ipv6);
891}
892
haoyuewang2a6cbc52021-01-13 06:49:02 -0800893void QuicConfig::SetIPv6AlternateServerAddressToSend(
894 const QuicSocketAddress& alternate_server_address_ipv6,
895 const QuicConnectionId& connection_id,
bnc1ccd0bc2021-04-07 10:20:17 -0700896 const StatelessResetToken& stateless_reset_token) {
haoyuewang2a6cbc52021-01-13 06:49:02 -0800897 if (!alternate_server_address_ipv6.host().IsIPv6()) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700898 QUIC_BUG(quic_bug_10575_10)
QUICHE team5c9cddc2021-03-09 15:52:30 -0800899 << "Cannot use SetIPv6AlternateServerAddressToSend with "
900 << alternate_server_address_ipv6;
haoyuewang2a6cbc52021-01-13 06:49:02 -0800901 return;
902 }
903 alternate_server_address_ipv6_.SetSendValue(alternate_server_address_ipv6);
904 preferred_address_connection_id_and_token_ =
905 std::make_pair(connection_id, stateless_reset_token);
906}
907
dschinazifaa70a72020-04-30 16:56:51 -0700908bool QuicConfig::HasReceivedIPv6AlternateServerAddress() const {
909 return alternate_server_address_ipv6_.HasReceivedValue();
910}
911
912const QuicSocketAddress& QuicConfig::ReceivedIPv6AlternateServerAddress()
913 const {
914 return alternate_server_address_ipv6_.GetReceivedValue();
915}
916
917void QuicConfig::SetIPv4AlternateServerAddressToSend(
918 const QuicSocketAddress& alternate_server_address_ipv4) {
919 if (!alternate_server_address_ipv4.host().IsIPv4()) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700920 QUIC_BUG(quic_bug_10575_11)
QUICHE team5c9cddc2021-03-09 15:52:30 -0800921 << "Cannot use SetIPv4AlternateServerAddressToSend with "
922 << alternate_server_address_ipv4;
dschinazifaa70a72020-04-30 16:56:51 -0700923 return;
924 }
925 alternate_server_address_ipv4_.SetSendValue(alternate_server_address_ipv4);
926}
927
haoyuewang2a6cbc52021-01-13 06:49:02 -0800928void QuicConfig::SetIPv4AlternateServerAddressToSend(
929 const QuicSocketAddress& alternate_server_address_ipv4,
930 const QuicConnectionId& connection_id,
bnc1ccd0bc2021-04-07 10:20:17 -0700931 const StatelessResetToken& stateless_reset_token) {
haoyuewang2a6cbc52021-01-13 06:49:02 -0800932 if (!alternate_server_address_ipv4.host().IsIPv4()) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700933 QUIC_BUG(quic_bug_10575_12)
QUICHE team5c9cddc2021-03-09 15:52:30 -0800934 << "Cannot use SetIPv4AlternateServerAddressToSend with "
935 << alternate_server_address_ipv4;
haoyuewang2a6cbc52021-01-13 06:49:02 -0800936 return;
937 }
938 alternate_server_address_ipv4_.SetSendValue(alternate_server_address_ipv4);
939 preferred_address_connection_id_and_token_ =
940 std::make_pair(connection_id, stateless_reset_token);
941}
942
dschinazifaa70a72020-04-30 16:56:51 -0700943bool QuicConfig::HasReceivedIPv4AlternateServerAddress() const {
944 return alternate_server_address_ipv4_.HasReceivedValue();
945}
946
947const QuicSocketAddress& QuicConfig::ReceivedIPv4AlternateServerAddress()
948 const {
949 return alternate_server_address_ipv4_.GetReceivedValue();
950}
951
haoyuewang2a6cbc52021-01-13 06:49:02 -0800952bool QuicConfig::HasReceivedPreferredAddressConnectionIdAndToken() const {
953 return (HasReceivedIPv6AlternateServerAddress() ||
954 HasReceivedIPv4AlternateServerAddress()) &&
955 preferred_address_connection_id_and_token_.has_value();
956}
957
bnc1ccd0bc2021-04-07 10:20:17 -0700958const std::pair<QuicConnectionId, StatelessResetToken>&
haoyuewang2a6cbc52021-01-13 06:49:02 -0800959QuicConfig::ReceivedPreferredAddressConnectionIdAndToken() const {
vasilvvf8035162021-02-01 14:49:14 -0800960 QUICHE_DCHECK(HasReceivedPreferredAddressConnectionIdAndToken());
haoyuewang2a6cbc52021-01-13 06:49:02 -0800961 return *preferred_address_connection_id_and_token_;
962}
963
dschinazi39e5e552020-05-06 13:55:24 -0700964void QuicConfig::SetOriginalConnectionIdToSend(
dschinazi5a29bd52020-05-21 19:37:32 -0700965 const QuicConnectionId& original_destination_connection_id) {
966 original_destination_connection_id_to_send_ =
967 original_destination_connection_id;
dschinazi39e5e552020-05-06 13:55:24 -0700968}
969
970bool QuicConfig::HasReceivedOriginalConnectionId() const {
dschinazi5a29bd52020-05-21 19:37:32 -0700971 return received_original_destination_connection_id_.has_value();
dschinazi39e5e552020-05-06 13:55:24 -0700972}
973
974QuicConnectionId QuicConfig::ReceivedOriginalConnectionId() const {
975 if (!HasReceivedOriginalConnectionId()) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700976 QUIC_BUG(quic_bug_10575_13) << "No received original connection ID";
dschinazi39e5e552020-05-06 13:55:24 -0700977 return EmptyQuicConnectionId();
978 }
dschinazi5a29bd52020-05-21 19:37:32 -0700979 return received_original_destination_connection_id_.value();
dschinazi39e5e552020-05-06 13:55:24 -0700980}
981
dschinazid7beb602020-05-28 16:47:21 -0700982void QuicConfig::SetInitialSourceConnectionIdToSend(
983 const QuicConnectionId& initial_source_connection_id) {
984 initial_source_connection_id_to_send_ = initial_source_connection_id;
985}
986
987bool QuicConfig::HasReceivedInitialSourceConnectionId() const {
988 return received_initial_source_connection_id_.has_value();
989}
990
991QuicConnectionId QuicConfig::ReceivedInitialSourceConnectionId() const {
992 if (!HasReceivedInitialSourceConnectionId()) {
QUICHE teamd6d05e52021-03-16 14:22:01 -0700993 QUIC_BUG(quic_bug_10575_14) << "No received initial source connection ID";
dschinazid7beb602020-05-28 16:47:21 -0700994 return EmptyQuicConnectionId();
995 }
996 return received_initial_source_connection_id_.value();
997}
998
999void QuicConfig::SetRetrySourceConnectionIdToSend(
1000 const QuicConnectionId& retry_source_connection_id) {
1001 retry_source_connection_id_to_send_ = retry_source_connection_id;
1002}
1003
1004bool QuicConfig::HasReceivedRetrySourceConnectionId() const {
1005 return received_retry_source_connection_id_.has_value();
1006}
1007
1008QuicConnectionId QuicConfig::ReceivedRetrySourceConnectionId() const {
1009 if (!HasReceivedRetrySourceConnectionId()) {
QUICHE teamd6d05e52021-03-16 14:22:01 -07001010 QUIC_BUG(quic_bug_10575_15) << "No received retry source connection ID";
dschinazid7beb602020-05-28 16:47:21 -07001011 return EmptyQuicConnectionId();
1012 }
1013 return received_retry_source_connection_id_.value();
1014}
1015
QUICHE teama6ef0a62019-03-07 20:34:33 -05001016void QuicConfig::SetStatelessResetTokenToSend(
bnc1ccd0bc2021-04-07 10:20:17 -07001017 const StatelessResetToken& stateless_reset_token) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001018 stateless_reset_token_.SetSendValue(stateless_reset_token);
1019}
1020
1021bool QuicConfig::HasReceivedStatelessResetToken() const {
1022 return stateless_reset_token_.HasReceivedValue();
1023}
1024
bnc1ccd0bc2021-04-07 10:20:17 -07001025const StatelessResetToken& QuicConfig::ReceivedStatelessResetToken() const {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001026 return stateless_reset_token_.GetReceivedValue();
1027}
1028
1029bool QuicConfig::negotiated() const {
dschinazif7c6a912020-05-05 11:39:53 -07001030 return negotiated_;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001031}
1032
1033void QuicConfig::SetCreateSessionTagIndicators(QuicTagVector tags) {
1034 create_session_tag_indicators_ = std::move(tags);
1035}
1036
1037const QuicTagVector& QuicConfig::create_session_tag_indicators() const {
1038 return create_session_tag_indicators_;
1039}
1040
1041void QuicConfig::SetDefaults() {
dschinazi027366e2020-05-01 14:31:19 -07001042 SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
renjietange6d94672020-01-07 10:30:10 -08001043 SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
1044 SetMaxUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001045 max_time_before_crypto_handshake_ =
1046 QuicTime::Delta::FromSeconds(kMaxTimeForCryptoHandshakeSecs);
1047 max_idle_time_before_crypto_handshake_ =
1048 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs);
1049 max_undecryptable_packets_ = kDefaultMaxUndecryptablePackets;
1050
1051 SetInitialStreamFlowControlWindowToSend(kMinimumFlowControlSendWindow);
1052 SetInitialSessionFlowControlWindowToSend(kMinimumFlowControlSendWindow);
fkastenholz4c7303c2019-07-29 08:17:07 -07001053 SetMaxAckDelayToSendMs(kDefaultDelayedAckTimeMs);
fkastenholz4dc4ba32019-07-30 09:55:25 -07001054 SetAckDelayExponentToSend(kDefaultAckDelayExponent);
dschinazi58881132019-11-11 11:34:02 -08001055 SetMaxPacketSizeToSend(kMaxIncomingPacketSize);
dschinazicd86dd12019-11-14 10:11:13 -08001056 SetMaxDatagramFrameSizeToSend(kMaxAcceptedDatagramFrameSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001057}
1058
fkastenholzd3a1de92019-05-15 07:00:07 -07001059void QuicConfig::ToHandshakeMessage(
1060 CryptoHandshakeMessage* out,
1061 QuicTransportVersion transport_version) const {
dschinazif7c6a912020-05-05 11:39:53 -07001062 // Idle timeout has custom rules that are different from other values.
1063 // We configure ourselves with the minumum value between the one sent and
1064 // the one received. Additionally, when QUIC_CRYPTO is used, the server
1065 // MUST send an idle timeout no greater than the idle timeout it received
1066 // from the client. We therefore send the received value if it is lower.
dschinazi5a29bd52020-05-21 19:37:32 -07001067 QuicFixedUint32 max_idle_timeout_seconds(kICSL, PRESENCE_REQUIRED);
1068 uint32_t max_idle_timeout_to_send_seconds =
1069 max_idle_timeout_to_send_.ToSeconds();
1070 if (received_max_idle_timeout_.has_value() &&
1071 received_max_idle_timeout_->ToSeconds() <
1072 max_idle_timeout_to_send_seconds) {
1073 max_idle_timeout_to_send_seconds = received_max_idle_timeout_->ToSeconds();
dschinazif7c6a912020-05-05 11:39:53 -07001074 }
dschinazi5a29bd52020-05-21 19:37:32 -07001075 max_idle_timeout_seconds.SetSendValue(max_idle_timeout_to_send_seconds);
1076 max_idle_timeout_seconds.ToHandshakeMessage(out);
dschinazif7c6a912020-05-05 11:39:53 -07001077
fkastenholzd3a1de92019-05-15 07:00:07 -07001078 // Do not need a version check here, max...bi... will encode
1079 // as "MIDS" -- the max initial dynamic streams tag -- if
fkastenholz305e1732019-06-18 05:01:22 -07001080 // doing some version other than IETF QUIC.
renjietange6d94672020-01-07 10:30:10 -08001081 max_bidirectional_streams_.ToHandshakeMessage(out);
fkastenholz305e1732019-06-18 05:01:22 -07001082 if (VersionHasIetfQuicFrames(transport_version)) {
renjietange6d94672020-01-07 10:30:10 -08001083 max_unidirectional_streams_.ToHandshakeMessage(out);
fkastenholz4dc4ba32019-07-30 09:55:25 -07001084 ack_delay_exponent_.ToHandshakeMessage(out);
fkastenholzd3a1de92019-05-15 07:00:07 -07001085 }
dschinazi74d2c0a2020-08-10 12:08:54 -07001086 if (max_ack_delay_ms_.GetSendValue() != kDefaultDelayedAckTimeMs) {
1087 // Only send max ack delay if it is using a non-default value, because
1088 // the default value is used by QuicSentPacketManager if it is not
1089 // sent during the handshake, and we want to save bytes.
dschinazi46d05bc2020-06-17 19:17:54 -07001090 max_ack_delay_ms_.ToHandshakeMessage(out);
1091 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001092 bytes_for_connection_id_.ToHandshakeMessage(out);
1093 initial_round_trip_time_us_.ToHandshakeMessage(out);
1094 initial_stream_flow_control_window_bytes_.ToHandshakeMessage(out);
1095 initial_session_flow_control_window_bytes_.ToHandshakeMessage(out);
1096 connection_migration_disabled_.ToHandshakeMessage(out);
1097 connection_options_.ToHandshakeMessage(out);
dschinazifaa70a72020-04-30 16:56:51 -07001098 if (alternate_server_address_ipv6_.HasSendValue()) {
1099 alternate_server_address_ipv6_.ToHandshakeMessage(out);
1100 } else {
1101 alternate_server_address_ipv4_.ToHandshakeMessage(out);
1102 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001103 stateless_reset_token_.ToHandshakeMessage(out);
1104}
1105
1106QuicErrorCode QuicConfig::ProcessPeerHello(
1107 const CryptoHandshakeMessage& peer_hello,
1108 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -07001109 std::string* error_details) {
vasilvvf8035162021-02-01 14:49:14 -08001110 QUICHE_DCHECK(error_details != nullptr);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001111
1112 QuicErrorCode error = QUIC_NO_ERROR;
1113 if (error == QUIC_NO_ERROR) {
dschinazif7c6a912020-05-05 11:39:53 -07001114 // Idle timeout has custom rules that are different from other values.
1115 // We configure ourselves with the minumum value between the one sent and
1116 // the one received. Additionally, when QUIC_CRYPTO is used, the server
1117 // MUST send an idle timeout no greater than the idle timeout it received
1118 // from the client.
dschinazi5a29bd52020-05-21 19:37:32 -07001119 QuicFixedUint32 max_idle_timeout_seconds(kICSL, PRESENCE_REQUIRED);
1120 error = max_idle_timeout_seconds.ProcessPeerHello(peer_hello, hello_type,
1121 error_details);
dschinazif7c6a912020-05-05 11:39:53 -07001122 if (error == QUIC_NO_ERROR) {
dschinazi5a29bd52020-05-21 19:37:32 -07001123 if (max_idle_timeout_seconds.GetReceivedValue() >
1124 max_idle_timeout_to_send_.ToSeconds()) {
dschinazif7c6a912020-05-05 11:39:53 -07001125 // The received value is higher than ours, ignore it if from the client
1126 // and raise an error if from the server.
1127 if (hello_type == SERVER) {
1128 error = QUIC_INVALID_NEGOTIATED_VALUE;
1129 *error_details =
1130 "Invalid value received for " + QuicTagToString(kICSL);
1131 }
1132 } else {
dschinazi5a29bd52020-05-21 19:37:32 -07001133 received_max_idle_timeout_ = QuicTime::Delta::FromSeconds(
1134 max_idle_timeout_seconds.GetReceivedValue());
dschinazif7c6a912020-05-05 11:39:53 -07001135 }
1136 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001137 }
1138 if (error == QUIC_NO_ERROR) {
renjietange6d94672020-01-07 10:30:10 -08001139 error = max_bidirectional_streams_.ProcessPeerHello(peer_hello, hello_type,
1140 error_details);
fkastenholzd3a1de92019-05-15 07:00:07 -07001141 }
1142 if (error == QUIC_NO_ERROR) {
renjietange6d94672020-01-07 10:30:10 -08001143 error = max_unidirectional_streams_.ProcessPeerHello(peer_hello, hello_type,
1144 error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001145 }
1146 if (error == QUIC_NO_ERROR) {
1147 error = bytes_for_connection_id_.ProcessPeerHello(peer_hello, hello_type,
1148 error_details);
1149 }
1150 if (error == QUIC_NO_ERROR) {
1151 error = initial_round_trip_time_us_.ProcessPeerHello(peer_hello, hello_type,
1152 error_details);
1153 }
1154 if (error == QUIC_NO_ERROR) {
1155 error = initial_stream_flow_control_window_bytes_.ProcessPeerHello(
1156 peer_hello, hello_type, error_details);
1157 }
1158 if (error == QUIC_NO_ERROR) {
1159 error = initial_session_flow_control_window_bytes_.ProcessPeerHello(
1160 peer_hello, hello_type, error_details);
1161 }
1162 if (error == QUIC_NO_ERROR) {
1163 error = connection_migration_disabled_.ProcessPeerHello(
1164 peer_hello, hello_type, error_details);
1165 }
1166 if (error == QUIC_NO_ERROR) {
1167 error = connection_options_.ProcessPeerHello(peer_hello, hello_type,
1168 error_details);
1169 }
1170 if (error == QUIC_NO_ERROR) {
dschinazifaa70a72020-04-30 16:56:51 -07001171 QuicFixedSocketAddress alternate_server_address(kASAD, PRESENCE_OPTIONAL);
1172 error = alternate_server_address.ProcessPeerHello(peer_hello, hello_type,
1173 error_details);
1174 if (error == QUIC_NO_ERROR && alternate_server_address.HasReceivedValue()) {
1175 const QuicSocketAddress& received_address =
1176 alternate_server_address.GetReceivedValue();
1177 if (received_address.host().IsIPv6()) {
1178 alternate_server_address_ipv6_.SetReceivedValue(received_address);
1179 } else if (received_address.host().IsIPv4()) {
1180 alternate_server_address_ipv4_.SetReceivedValue(received_address);
1181 }
1182 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001183 }
1184 if (error == QUIC_NO_ERROR) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001185 error = stateless_reset_token_.ProcessPeerHello(peer_hello, hello_type,
1186 error_details);
1187 }
fkastenholz4c7303c2019-07-29 08:17:07 -07001188
dschinazi40975ad2020-06-17 18:18:01 -07001189 if (error == QUIC_NO_ERROR) {
fkastenholz4c7303c2019-07-29 08:17:07 -07001190 error = max_ack_delay_ms_.ProcessPeerHello(peer_hello, hello_type,
1191 error_details);
1192 }
fkastenholz4dc4ba32019-07-30 09:55:25 -07001193 if (error == QUIC_NO_ERROR) {
1194 error = ack_delay_exponent_.ProcessPeerHello(peer_hello, hello_type,
1195 error_details);
1196 }
dschinazif7c6a912020-05-05 11:39:53 -07001197 if (error == QUIC_NO_ERROR) {
1198 negotiated_ = true;
1199 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001200 return error;
1201}
1202
1203bool QuicConfig::FillTransportParameters(TransportParameters* params) const {
dschinazi5a29bd52020-05-21 19:37:32 -07001204 if (original_destination_connection_id_to_send_.has_value()) {
1205 params->original_destination_connection_id =
1206 original_destination_connection_id_to_send_.value();
dschinazi39e5e552020-05-06 13:55:24 -07001207 }
1208
dschinazi5a29bd52020-05-21 19:37:32 -07001209 params->max_idle_timeout_ms.set_value(
1210 max_idle_timeout_to_send_.ToMilliseconds());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001211
dschinazi52127d72019-04-17 15:12:38 -07001212 if (stateless_reset_token_.HasSendValue()) {
bnc1ccd0bc2021-04-07 10:20:17 -07001213 StatelessResetToken stateless_reset_token =
1214 stateless_reset_token_.GetSendValue();
dschinazi52127d72019-04-17 15:12:38 -07001215 params->stateless_reset_token.assign(
1216 reinterpret_cast<const char*>(&stateless_reset_token),
1217 reinterpret_cast<const char*>(&stateless_reset_token) +
1218 sizeof(stateless_reset_token));
QUICHE teama6ef0a62019-03-07 20:34:33 -05001219 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001220
dschinazi5a29bd52020-05-21 19:37:32 -07001221 params->max_udp_payload_size.set_value(GetMaxPacketSizeToSend());
dschinazicd86dd12019-11-14 10:11:13 -08001222 params->max_datagram_frame_size.set_value(GetMaxDatagramFrameSizeToSend());
dschinazi52127d72019-04-17 15:12:38 -07001223 params->initial_max_data.set_value(
dschinazi90165ee2019-10-15 15:11:41 -07001224 GetInitialSessionFlowControlWindowToSend());
dschinazi18cdf132019-10-09 16:08:18 -07001225 // The max stream data bidirectional transport parameters can be either local
1226 // or remote. A stream is local iff it is initiated by the endpoint that sent
1227 // the transport parameter (see the Transport Parameter Definitions section of
1228 // draft-ietf-quic-transport). In this function we are sending transport
1229 // parameters, so a local stream is one we initiated, which means an outgoing
1230 // stream.
dschinazi52127d72019-04-17 15:12:38 -07001231 params->initial_max_stream_data_bidi_local.set_value(
dschinazi90165ee2019-10-15 15:11:41 -07001232 GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
dschinazi18cdf132019-10-09 16:08:18 -07001233 params->initial_max_stream_data_bidi_remote.set_value(
dschinazi90165ee2019-10-15 15:11:41 -07001234 GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
dschinazi52127d72019-04-17 15:12:38 -07001235 params->initial_max_stream_data_uni.set_value(
dschinazi90165ee2019-10-15 15:11:41 -07001236 GetInitialMaxStreamDataBytesUnidirectionalToSend());
dschinazi52127d72019-04-17 15:12:38 -07001237 params->initial_max_streams_bidi.set_value(
renjietange6d94672020-01-07 10:30:10 -08001238 GetMaxBidirectionalStreamsToSend());
dschinazi52127d72019-04-17 15:12:38 -07001239 params->initial_max_streams_uni.set_value(
renjietange6d94672020-01-07 10:30:10 -08001240 GetMaxUnidirectionalStreamsToSend());
dschinazi40975ad2020-06-17 18:18:01 -07001241 params->max_ack_delay.set_value(GetMaxAckDelayToSendMs());
haoyuewang7cffa542020-07-15 17:12:27 -07001242 if (min_ack_delay_ms_.HasSendValue()) {
1243 params->min_ack_delay_us.set_value(min_ack_delay_ms_.GetSendValue() *
1244 kNumMicrosPerMilli);
1245 }
dschinazi90165ee2019-10-15 15:11:41 -07001246 params->ack_delay_exponent.set_value(GetAckDelayExponentToSend());
dschinazi5a29bd52020-05-21 19:37:32 -07001247 params->disable_active_migration =
dschinazi52127d72019-04-17 15:12:38 -07001248 connection_migration_disabled_.HasSendValue() &&
1249 connection_migration_disabled_.GetSendValue() != 0;
1250
dschinazifaa70a72020-04-30 16:56:51 -07001251 if (alternate_server_address_ipv6_.HasSendValue() ||
1252 alternate_server_address_ipv4_.HasSendValue()) {
dschinazi52127d72019-04-17 15:12:38 -07001253 TransportParameters::PreferredAddress preferred_address;
dschinazifaa70a72020-04-30 16:56:51 -07001254 if (alternate_server_address_ipv6_.HasSendValue()) {
1255 preferred_address.ipv6_socket_address =
1256 alternate_server_address_ipv6_.GetSendValue();
1257 }
1258 if (alternate_server_address_ipv4_.HasSendValue()) {
1259 preferred_address.ipv4_socket_address =
1260 alternate_server_address_ipv4_.GetSendValue();
dschinazi52127d72019-04-17 15:12:38 -07001261 }
haoyuewang2a6cbc52021-01-13 06:49:02 -08001262 if (preferred_address_connection_id_and_token_) {
1263 preferred_address.connection_id =
1264 preferred_address_connection_id_and_token_->first;
1265 auto* begin = reinterpret_cast<const char*>(
1266 &preferred_address_connection_id_and_token_->second);
1267 auto* end =
1268 begin + sizeof(preferred_address_connection_id_and_token_->second);
1269 preferred_address.stateless_reset_token.assign(begin, end);
1270 }
dschinazi52127d72019-04-17 15:12:38 -07001271 params->preferred_address =
vasilvv0fc587f2019-09-06 13:33:08 -07001272 std::make_unique<TransportParameters::PreferredAddress>(
dschinazi52127d72019-04-17 15:12:38 -07001273 preferred_address);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001274 }
QUICHE teama6ef0a62019-03-07 20:34:33 -05001275
dschinazi46730232020-05-07 10:01:21 -07001276 if (active_connection_id_limit_.HasSendValue()) {
1277 params->active_connection_id_limit.set_value(
1278 active_connection_id_limit_.GetSendValue());
1279 }
1280
dschinazid7beb602020-05-28 16:47:21 -07001281 if (initial_source_connection_id_to_send_.has_value()) {
1282 params->initial_source_connection_id =
1283 initial_source_connection_id_to_send_.value();
1284 }
1285
1286 if (retry_source_connection_id_to_send_.has_value()) {
1287 params->retry_source_connection_id =
1288 retry_source_connection_id_to_send_.value();
1289 }
1290
dschinazi83c586a2020-07-07 11:50:45 -07001291 if (initial_round_trip_time_us_.HasSendValue()) {
1292 params->initial_round_trip_time_us.set_value(
1293 initial_round_trip_time_us_.GetSendValue());
1294 }
1295 if (connection_options_.HasSendValues() &&
1296 !connection_options_.GetSendValues().empty()) {
1297 params->google_connection_options = connection_options_.GetSendValues();
QUICHE teama6ef0a62019-03-07 20:34:33 -05001298 }
dschinazi7e51f6b2020-05-13 17:36:44 -07001299
mattm072a7e32020-10-09 16:16:56 -07001300 if (!KeyUpdateSupportedLocally()) {
1301 params->key_update_not_yet_supported = true;
1302 }
dschinazid73dc1f2020-08-12 15:10:04 -07001303
vasilvva2ef3012019-09-12 18:32:14 -07001304 params->custom_parameters = custom_transport_parameters_to_send_;
dschinazi52127d72019-04-17 15:12:38 -07001305
QUICHE teama6ef0a62019-03-07 20:34:33 -05001306 return true;
1307}
1308
1309QuicErrorCode QuicConfig::ProcessTransportParameters(
1310 const TransportParameters& params,
renjietangc31106b2020-05-06 10:44:17 -07001311 bool is_resumption,
vasilvvc48c8712019-03-11 13:38:16 -07001312 std::string* error_details) {
dschinazi5a29bd52020-05-21 19:37:32 -07001313 if (!is_resumption && params.original_destination_connection_id.has_value()) {
1314 received_original_destination_connection_id_ =
1315 params.original_destination_connection_id.value();
dschinazi39e5e552020-05-06 13:55:24 -07001316 }
1317
dschinazi5a29bd52020-05-21 19:37:32 -07001318 if (params.max_idle_timeout_ms.value() > 0 &&
1319 params.max_idle_timeout_ms.value() <
1320 static_cast<uint64_t>(max_idle_timeout_to_send_.ToMilliseconds())) {
dschinazif7c6a912020-05-05 11:39:53 -07001321 // An idle timeout of zero indicates it is disabled.
1322 // We also ignore values higher than ours which will cause us to use the
1323 // smallest value between ours and our peer's.
dschinazi5a29bd52020-05-21 19:37:32 -07001324 received_max_idle_timeout_ =
1325 QuicTime::Delta::FromMilliseconds(params.max_idle_timeout_ms.value());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001326 }
dschinazi52127d72019-04-17 15:12:38 -07001327
renjietangc31106b2020-05-06 10:44:17 -07001328 if (!is_resumption && !params.stateless_reset_token.empty()) {
bnc1ccd0bc2021-04-07 10:20:17 -07001329 StatelessResetToken stateless_reset_token;
dschinazi52127d72019-04-17 15:12:38 -07001330 if (params.stateless_reset_token.size() != sizeof(stateless_reset_token)) {
QUICHE teamd6d05e52021-03-16 14:22:01 -07001331 QUIC_BUG(quic_bug_10575_16) << "Bad stateless reset token length "
1332 << params.stateless_reset_token.size();
dschinazi52127d72019-04-17 15:12:38 -07001333 *error_details = "Bad stateless reset token length";
1334 return QUIC_INTERNAL_ERROR;
1335 }
1336 memcpy(&stateless_reset_token, params.stateless_reset_token.data(),
1337 params.stateless_reset_token.size());
1338 stateless_reset_token_.SetReceivedValue(stateless_reset_token);
1339 }
1340
dschinazi5a29bd52020-05-21 19:37:32 -07001341 if (params.max_udp_payload_size.IsValid()) {
1342 max_udp_payload_size_.SetReceivedValue(params.max_udp_payload_size.value());
dschinazi52127d72019-04-17 15:12:38 -07001343 }
1344
dschinazicd86dd12019-11-14 10:11:13 -08001345 if (params.max_datagram_frame_size.IsValid()) {
1346 max_datagram_frame_size_.SetReceivedValue(
1347 params.max_datagram_frame_size.value());
dschinazicd86dd12019-11-14 10:11:13 -08001348 }
1349
dschinazi52127d72019-04-17 15:12:38 -07001350 initial_session_flow_control_window_bytes_.SetReceivedValue(
dschinazif1e7b422020-04-30 12:21:28 -07001351 params.initial_max_data.value());
1352
1353 // IETF QUIC specifies stream IDs and stream counts as 62-bit integers but
1354 // our implementation uses uint32_t to represent them to save memory.
renjietange6d94672020-01-07 10:30:10 -08001355 max_bidirectional_streams_.SetReceivedValue(
dschinazi52127d72019-04-17 15:12:38 -07001356 std::min<uint64_t>(params.initial_max_streams_bidi.value(),
1357 std::numeric_limits<uint32_t>::max()));
renjietange6d94672020-01-07 10:30:10 -08001358 max_unidirectional_streams_.SetReceivedValue(
fkastenholzd3a1de92019-05-15 07:00:07 -07001359 std::min<uint64_t>(params.initial_max_streams_uni.value(),
1360 std::numeric_limits<uint32_t>::max()));
dschinazi52127d72019-04-17 15:12:38 -07001361
dschinazi18cdf132019-10-09 16:08:18 -07001362 // The max stream data bidirectional transport parameters can be either local
1363 // or remote. A stream is local iff it is initiated by the endpoint that sent
1364 // the transport parameter (see the Transport Parameter Definitions section of
1365 // draft-ietf-quic-transport). However in this function we are processing
1366 // received transport parameters, so a local stream is one initiated by our
1367 // peer, which means an incoming stream.
rchb0451852019-09-11 21:17:01 -07001368 initial_max_stream_data_bytes_incoming_bidirectional_.SetReceivedValue(
dschinazif1e7b422020-04-30 12:21:28 -07001369 params.initial_max_stream_data_bidi_local.value());
rchb0451852019-09-11 21:17:01 -07001370 initial_max_stream_data_bytes_outgoing_bidirectional_.SetReceivedValue(
dschinazif1e7b422020-04-30 12:21:28 -07001371 params.initial_max_stream_data_bidi_remote.value());
rchb0451852019-09-11 21:17:01 -07001372 initial_max_stream_data_bytes_unidirectional_.SetReceivedValue(
dschinazif1e7b422020-04-30 12:21:28 -07001373 params.initial_max_stream_data_uni.value());
rchb0451852019-09-11 21:17:01 -07001374
renjietangc31106b2020-05-06 10:44:17 -07001375 if (!is_resumption) {
dschinazi40975ad2020-06-17 18:18:01 -07001376 max_ack_delay_ms_.SetReceivedValue(params.max_ack_delay.value());
renjietangc31106b2020-05-06 10:44:17 -07001377 if (params.ack_delay_exponent.IsValid()) {
1378 ack_delay_exponent_.SetReceivedValue(params.ack_delay_exponent.value());
1379 }
1380 if (params.preferred_address != nullptr) {
1381 if (params.preferred_address->ipv6_socket_address.port() != 0) {
1382 alternate_server_address_ipv6_.SetReceivedValue(
1383 params.preferred_address->ipv6_socket_address);
1384 }
1385 if (params.preferred_address->ipv4_socket_address.port() != 0) {
1386 alternate_server_address_ipv4_.SetReceivedValue(
1387 params.preferred_address->ipv4_socket_address);
1388 }
haoyuewang2a6cbc52021-01-13 06:49:02 -08001389 // TODO(haoyuewang) Treat 0 length connection ID sent in preferred_address
1390 // as a connection error of type TRANSPORT_PARAMETER_ERROR when server
1391 // fully supports it.
1392 if (!params.preferred_address->connection_id.IsEmpty()) {
1393 preferred_address_connection_id_and_token_ = std::make_pair(
1394 params.preferred_address->connection_id,
bnc1ccd0bc2021-04-07 10:20:17 -07001395 *reinterpret_cast<const StatelessResetToken*>(
haoyuewang2a6cbc52021-01-13 06:49:02 -08001396 &params.preferred_address->stateless_reset_token.front()));
1397 }
renjietangc31106b2020-05-06 10:44:17 -07001398 }
haoyuewang042cc3f2020-11-30 11:50:09 -08001399 if (params.min_ack_delay_us.value() != 0) {
1400 if (params.min_ack_delay_us.value() >
1401 params.max_ack_delay.value() * kNumMicrosPerMilli) {
1402 *error_details = "MinAckDelay is greater than MaxAckDelay.";
1403 return IETF_QUIC_PROTOCOL_VIOLATION;
haoyuewang7cffa542020-07-15 17:12:27 -07001404 }
haoyuewang042cc3f2020-11-30 11:50:09 -08001405 min_ack_delay_ms_.SetReceivedValue(params.min_ack_delay_us.value() /
1406 kNumMicrosPerMilli);
haoyuewang7cffa542020-07-15 17:12:27 -07001407 }
dschinazi8067d552019-11-13 19:44:00 -08001408 }
dschinazi52127d72019-04-17 15:12:38 -07001409
dschinazi5a29bd52020-05-21 19:37:32 -07001410 if (params.disable_active_migration) {
renjietangc31106b2020-05-06 10:44:17 -07001411 connection_migration_disabled_.SetReceivedValue(1u);
dschinazi52127d72019-04-17 15:12:38 -07001412 }
mattm072a7e32020-10-09 16:16:56 -07001413 if (!is_resumption && !params.key_update_not_yet_supported) {
1414 key_update_supported_remotely_ = true;
1415 }
dschinazi52127d72019-04-17 15:12:38 -07001416
dschinazi46730232020-05-07 10:01:21 -07001417 active_connection_id_limit_.SetReceivedValue(
1418 params.active_connection_id_limit.value());
1419
dschinazid7beb602020-05-28 16:47:21 -07001420 if (!is_resumption) {
1421 if (params.initial_source_connection_id.has_value()) {
1422 received_initial_source_connection_id_ =
1423 params.initial_source_connection_id.value();
1424 }
1425 if (params.retry_source_connection_id.has_value()) {
1426 received_retry_source_connection_id_ =
1427 params.retry_source_connection_id.value();
1428 }
1429 }
1430
dschinazi83c586a2020-07-07 11:50:45 -07001431 if (params.initial_round_trip_time_us.value() > 0) {
dschinazi83c586a2020-07-07 11:50:45 -07001432 initial_round_trip_time_us_.SetReceivedValue(
1433 params.initial_round_trip_time_us.value());
1434 }
1435 if (params.google_connection_options.has_value()) {
dschinazi83c586a2020-07-07 11:50:45 -07001436 connection_options_.SetReceivedValues(
1437 params.google_connection_options.value());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001438 }
1439
vasilvva2ef3012019-09-12 18:32:14 -07001440 received_custom_transport_parameters_ = params.custom_parameters;
1441
renjietangc31106b2020-05-06 10:44:17 -07001442 if (!is_resumption) {
1443 negotiated_ = true;
1444 }
dschinazi6464c4a2019-09-11 16:25:01 -07001445 *error_details = "";
QUICHE teama6ef0a62019-03-07 20:34:33 -05001446 return QUIC_NO_ERROR;
1447}
1448
1449} // namespace quic