blob: b4a4ca9ceaf39c90f33c2afa2ff315c377bf31fd [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#ifndef QUICHE_QUIC_CORE_QUIC_CONFIG_H_
6#define QUICHE_QUIC_CORE_QUIC_CONFIG_H_
7
8#include <cstddef>
9#include <cstdint>
vasilvv872e7a32019-03-12 16:42:44 -070010#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050011
12#include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h"
13#include "net/third_party/quiche/src/quic/core/quic_packets.h"
14#include "net/third_party/quiche/src/quic/core/quic_time.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050016#include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h"
17
18namespace quic {
19
20namespace test {
21class QuicConfigPeer;
22} // namespace test
23
24class CryptoHandshakeMessage;
25
26// Describes whether or not a given QuicTag is required or optional in the
27// handshake message.
28enum QuicConfigPresence {
29 // This negotiable value can be absent from the handshake message. Default
30 // value is selected as the negotiated value in such a case.
31 PRESENCE_OPTIONAL,
32 // This negotiable value is required in the handshake message otherwise the
33 // Process*Hello function returns an error.
34 PRESENCE_REQUIRED,
35};
36
37// Whether the CryptoHandshakeMessage is from the client or server.
38enum HelloType {
39 CLIENT,
40 SERVER,
41};
42
43// An abstract base class that stores a value that can be sent in CHLO/SHLO
44// message. These values can be OPTIONAL or REQUIRED, depending on |presence_|.
45class QUIC_EXPORT_PRIVATE QuicConfigValue {
46 public:
47 QuicConfigValue(QuicTag tag, QuicConfigPresence presence);
48 virtual ~QuicConfigValue();
49
50 // Serialises tag name and value(s) to |out|.
51 virtual void ToHandshakeMessage(CryptoHandshakeMessage* out) const = 0;
52
53 // Selects a mutually acceptable value from those offered in |peer_hello|
54 // and those defined in the subclass.
55 virtual QuicErrorCode ProcessPeerHello(
56 const CryptoHandshakeMessage& peer_hello,
57 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -070058 std::string* error_details) = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -050059
60 protected:
61 const QuicTag tag_;
62 const QuicConfigPresence presence_;
63};
64
65class QUIC_EXPORT_PRIVATE QuicNegotiableValue : public QuicConfigValue {
66 public:
67 QuicNegotiableValue(QuicTag tag, QuicConfigPresence presence);
68 ~QuicNegotiableValue() override;
69
70 bool negotiated() const { return negotiated_; }
71
72 protected:
73 void set_negotiated(bool negotiated) { negotiated_ = negotiated; }
74
75 private:
76 bool negotiated_;
77};
78
79class QUIC_EXPORT_PRIVATE QuicNegotiableUint32 : public QuicNegotiableValue {
80 // TODO(fayang): some negotiated values use uint32 as bool (e.g., silent
81 // close). Consider adding a QuicNegotiableBool type.
82 public:
83 // Default and max values default to 0.
84 QuicNegotiableUint32(QuicTag name, QuicConfigPresence presence);
85 ~QuicNegotiableUint32() override;
86
87 // Sets the maximum possible value that can be achieved after negotiation and
88 // also the default values to be assumed if PRESENCE_OPTIONAL and the *HLO msg
89 // doesn't contain a value corresponding to |name_|. |max| is serialised via
90 // ToHandshakeMessage call if |negotiated_| is false.
91 void set(uint32_t max, uint32_t default_value);
92
93 // Returns the value negotiated if |negotiated_| is true, otherwise returns
94 // default_value_ (used to set default values before negotiation finishes).
95 uint32_t GetUint32() const;
96
97 // Returns the maximum value negotiable.
98 uint32_t GetMax() const;
99
100 // Serialises |name_| and value to |out|. If |negotiated_| is true then
101 // |negotiated_value_| is serialised, otherwise |max_value_| is serialised.
102 void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
103
104 // Processes the corresponding value from |peer_hello| and if present calls
105 // ReceiveValue with it. If the corresponding value is missing and
106 // PRESENCE_OPTIONAL then |negotiated_value_| is set to |default_value_|.
107 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
108 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700109 std::string* error_details) override;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500110
111 // Takes a value |value| parsed from a handshake message (whether a TLS
112 // ClientHello/ServerHello or a CryptoHandshakeMessage) whose sender was
113 // |hello_type|, and sets |negotiated_value_| to the minimum of |value| and
114 // |max_value_|. On success this function returns QUIC_NO_ERROR; if there is
115 // an error, details are put in |*error_details|.
116 QuicErrorCode 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
120 private:
121 uint32_t max_value_;
122 uint32_t default_value_;
123 uint32_t negotiated_value_;
124};
125
126// Stores uint32_t from CHLO or SHLO messages that are not negotiated.
127class QUIC_EXPORT_PRIVATE QuicFixedUint32 : public QuicConfigValue {
128 public:
129 QuicFixedUint32(QuicTag name, QuicConfigPresence presence);
130 ~QuicFixedUint32() override;
131
132 bool HasSendValue() const;
133
134 uint32_t GetSendValue() const;
135
136 void SetSendValue(uint32_t value);
137
138 bool HasReceivedValue() const;
139
140 uint32_t GetReceivedValue() const;
141
142 void SetReceivedValue(uint32_t value);
143
144 // If has_send_value is true, serialises |tag_| and |send_value_| to |out|.
145 void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
146
147 // Sets |value_| to the corresponding value from |peer_hello_| if it exists.
148 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
149 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700150 std::string* error_details) override;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500151
152 private:
153 uint32_t send_value_;
154 bool has_send_value_;
155 uint32_t receive_value_;
156 bool has_receive_value_;
157};
158
159// Stores uint128 from CHLO or SHLO messages that are not negotiated.
160class QUIC_EXPORT_PRIVATE QuicFixedUint128 : public QuicConfigValue {
161 public:
162 QuicFixedUint128(QuicTag tag, QuicConfigPresence presence);
163 ~QuicFixedUint128() override;
164
165 bool HasSendValue() const;
166
167 QuicUint128 GetSendValue() const;
168
169 void SetSendValue(QuicUint128 value);
170
171 bool HasReceivedValue() const;
172
173 QuicUint128 GetReceivedValue() const;
174
175 void SetReceivedValue(QuicUint128 value);
176
177 // If has_send_value is true, serialises |tag_| and |send_value_| to |out|.
178 void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
179
180 // Sets |value_| to the corresponding value from |peer_hello_| if it exists.
181 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
182 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700183 std::string* error_details) override;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500184
185 private:
186 QuicUint128 send_value_;
187 bool has_send_value_;
188 QuicUint128 receive_value_;
189 bool has_receive_value_;
190};
191
192// Stores tag from CHLO or SHLO messages that are not negotiated.
193class QUIC_EXPORT_PRIVATE QuicFixedTagVector : public QuicConfigValue {
194 public:
195 QuicFixedTagVector(QuicTag name, QuicConfigPresence presence);
196 QuicFixedTagVector(const QuicFixedTagVector& other);
197 ~QuicFixedTagVector() override;
198
199 bool HasSendValues() const;
200
201 QuicTagVector GetSendValues() const;
202
203 void SetSendValues(const QuicTagVector& values);
204
205 bool HasReceivedValues() const;
206
207 QuicTagVector GetReceivedValues() const;
208
209 void SetReceivedValues(const QuicTagVector& values);
210
211 // If has_send_value is true, serialises |tag_vector_| and |send_value_| to
212 // |out|.
213 void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
214
215 // Sets |receive_values_| to the corresponding value from |client_hello_| if
216 // it exists.
217 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
218 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700219 std::string* error_details) override;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500220
221 private:
222 QuicTagVector send_values_;
223 bool has_send_values_;
224 QuicTagVector receive_values_;
225 bool has_receive_values_;
226};
227
228// Stores QuicSocketAddress from CHLO or SHLO messages that are not negotiated.
229class QUIC_EXPORT_PRIVATE QuicFixedSocketAddress : public QuicConfigValue {
230 public:
231 QuicFixedSocketAddress(QuicTag tag, QuicConfigPresence presence);
232 ~QuicFixedSocketAddress() override;
233
234 bool HasSendValue() const;
235
236 const QuicSocketAddress& GetSendValue() const;
237
238 void SetSendValue(const QuicSocketAddress& value);
239
240 bool HasReceivedValue() const;
241
242 const QuicSocketAddress& GetReceivedValue() const;
243
244 void SetReceivedValue(const QuicSocketAddress& value);
245
246 void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;
247
248 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
249 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700250 std::string* error_details) override;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500251
252 private:
253 QuicSocketAddress send_value_;
254 bool has_send_value_;
255 QuicSocketAddress receive_value_;
256 bool has_receive_value_;
257};
258
259// QuicConfig contains non-crypto configuration options that are negotiated in
260// the crypto handshake.
261class QUIC_EXPORT_PRIVATE QuicConfig {
262 public:
263 QuicConfig();
264 QuicConfig(const QuicConfig& other);
265 ~QuicConfig();
266
267 void SetConnectionOptionsToSend(const QuicTagVector& connection_options);
268
269 bool HasReceivedConnectionOptions() const;
270
271 // Sets initial received connection options. All received connection options
272 // will be initialized with these fields. Initial received options may only be
273 // set once per config, prior to the setting of any other options. If options
274 // have already been set (either by previous calls or via handshake), this
275 // function does nothing and returns false.
276 bool SetInitialReceivedConnectionOptions(const QuicTagVector& tags);
277
278 QuicTagVector ReceivedConnectionOptions() const;
279
280 bool HasSendConnectionOptions() const;
281
282 QuicTagVector SendConnectionOptions() const;
283
284 // Returns true if the client is sending or the server has received a
285 // connection option.
286 // TODO(ianswett): Rename to HasClientRequestedSharedOption
287 bool HasClientSentConnectionOption(QuicTag tag,
288 Perspective perspective) const;
289
290 void SetClientConnectionOptions(
291 const QuicTagVector& client_connection_options);
292
293 // Returns true if the client has requested the specified connection option.
294 // Checks the client connection options if the |perspective| is client and
295 // connection options if the |perspective| is the server.
296 bool HasClientRequestedIndependentOption(QuicTag tag,
297 Perspective perspective) const;
298
299 void SetIdleNetworkTimeout(QuicTime::Delta max_idle_network_timeout,
300 QuicTime::Delta default_idle_network_timeout);
301
302 QuicTime::Delta IdleNetworkTimeout() const;
303
304 void SetSilentClose(bool silent_close);
305
306 bool SilentClose() const;
307
fkastenholzd3a1de92019-05-15 07:00:07 -0700308 // Configuration for the Google QUIC and IETF QUIC stream ID managers. Note
309 // that the naming is a bit weird; it is from the perspective of the node
310 // generating (sending) the configuration and, thus, The "incoming" counts are
311 // the number of streams that the node sending the configuration is willing to
312 // accept and therefore the number that the node receiving the confguration
313 // can create .. the number of outbound streams that may be intiated..
314 // There are two sets, one for unidirectional streams and one for
315 // bidirectional. The bidirectional set also covers Google-QUICs
316 // dynamic stream count (which are bidirectional streams).
317 void SetMaxIncomingBidirectionalStreamsToSend(uint32_t max_streams);
318 uint32_t GetMaxIncomingBidirectionalStreamsToSend();
319 bool HasReceivedMaxIncomingBidirectionalStreams();
320 uint32_t ReceivedMaxIncomingBidirectionalStreams();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500321
fkastenholzd3a1de92019-05-15 07:00:07 -0700322 void SetMaxIncomingUnidirectionalStreamsToSend(uint32_t max_streams);
323 uint32_t GetMaxIncomingUnidirectionalStreamsToSend();
324 bool HasReceivedMaxIncomingUnidirectionalStreams();
325 uint32_t ReceivedMaxIncomingUnidirectionalStreams();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500326
327 void set_max_time_before_crypto_handshake(
328 QuicTime::Delta max_time_before_crypto_handshake) {
329 max_time_before_crypto_handshake_ = max_time_before_crypto_handshake;
330 }
331
332 QuicTime::Delta max_time_before_crypto_handshake() const {
333 return max_time_before_crypto_handshake_;
334 }
335
336 void set_max_idle_time_before_crypto_handshake(
337 QuicTime::Delta max_idle_time_before_crypto_handshake) {
338 max_idle_time_before_crypto_handshake_ =
339 max_idle_time_before_crypto_handshake;
340 }
341
342 QuicTime::Delta max_idle_time_before_crypto_handshake() const {
343 return max_idle_time_before_crypto_handshake_;
344 }
345
346 QuicNegotiableUint32 idle_network_timeout_seconds() const {
347 return idle_network_timeout_seconds_;
348 }
349
350 void set_max_undecryptable_packets(size_t max_undecryptable_packets) {
351 max_undecryptable_packets_ = max_undecryptable_packets;
352 }
353
354 size_t max_undecryptable_packets() const {
355 return max_undecryptable_packets_;
356 }
357
358 bool HasSetBytesForConnectionIdToSend() const;
359
360 // Sets the peer's connection id length, in bytes.
361 void SetBytesForConnectionIdToSend(uint32_t bytes);
362
363 bool HasReceivedBytesForConnectionId() const;
364
365 uint32_t ReceivedBytesForConnectionId() const;
366
367 // Sets an estimated initial round trip time in us.
368 void SetInitialRoundTripTimeUsToSend(uint32_t rtt_us);
369
370 bool HasReceivedInitialRoundTripTimeUs() const;
371
372 uint32_t ReceivedInitialRoundTripTimeUs() const;
373
374 bool HasInitialRoundTripTimeUsToSend() const;
375
376 uint32_t GetInitialRoundTripTimeUsToSend() const;
377
378 // Sets an initial stream flow control window size to transmit to the peer.
379 void SetInitialStreamFlowControlWindowToSend(uint32_t window_bytes);
380
381 uint32_t GetInitialStreamFlowControlWindowToSend() const;
382
383 bool HasReceivedInitialStreamFlowControlWindowBytes() const;
384
385 uint32_t ReceivedInitialStreamFlowControlWindowBytes() const;
386
387 // Sets an initial session flow control window size to transmit to the peer.
388 void SetInitialSessionFlowControlWindowToSend(uint32_t window_bytes);
389
390 uint32_t GetInitialSessionFlowControlWindowToSend() const;
391
392 bool HasReceivedInitialSessionFlowControlWindowBytes() const;
393
394 uint32_t ReceivedInitialSessionFlowControlWindowBytes() const;
395
396 void SetDisableConnectionMigration();
397
398 bool DisableConnectionMigration() const;
399
400 void SetAlternateServerAddressToSend(
401 const QuicSocketAddress& alternate_server_address);
402
403 bool HasReceivedAlternateServerAddress() const;
404
405 const QuicSocketAddress& ReceivedAlternateServerAddress() const;
406
407 void SetSupportMaxHeaderListSize();
408
409 bool SupportMaxHeaderListSize() const;
410
411 void SetStatelessResetTokenToSend(QuicUint128 stateless_reset_token);
412
413 bool HasReceivedStatelessResetToken() const;
414
415 QuicUint128 ReceivedStatelessResetToken() const;
416
fkastenholz4c7303c2019-07-29 08:17:07 -0700417 // Manage the IETF QUIC Max ACK Delay transport parameter.
418 // The sent value is the delay that this node uses
419 // (QuicSentPacketManager::local_max_ack_delay_).
420 // The received delay is the value received from
421 // the peer (QuicSentPacketManager::peer_max_ack_delay_).
422 void SetMaxAckDelayToSendMs(uint32_t max_ack_delay_ms);
423 uint32_t GetMaxAckDelayToToSendMs() const;
424 bool HasReceivedMaxAckDelayMs() const;
425 uint32_t ReceivedMaxAckDelayMs() const;
426
fkastenholz4dc4ba32019-07-30 09:55:25 -0700427 void SetAckDelayExponentToSend(uint32_t exponent);
428 uint32_t GetAckDelayExponentToSend();
429 bool HasReceivedAckDelayExponent() const;
430 uint32_t ReceivedAckDelayExponent() const;
431
QUICHE teama6ef0a62019-03-07 20:34:33 -0500432 bool negotiated() const;
433
434 void SetCreateSessionTagIndicators(QuicTagVector tags);
435
436 const QuicTagVector& create_session_tag_indicators() const;
437
438 // ToHandshakeMessage serialises the settings in this object as a series of
439 // tags /value pairs and adds them to |out|.
fkastenholzd3a1de92019-05-15 07:00:07 -0700440 void ToHandshakeMessage(CryptoHandshakeMessage* out,
441 QuicTransportVersion transport_version) const;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500442
443 // Calls ProcessPeerHello on each negotiable parameter. On failure returns
444 // the corresponding QuicErrorCode and sets detailed error in |error_details|.
445 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
446 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700447 std::string* error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500448
449 // FillTransportParameters writes the values to send for ICSL, MIDS, CFCW, and
450 // SFCW to |*params|, returning true if the values could be written and false
451 // if something prevents them from being written (e.g. a value is too large).
452 bool FillTransportParameters(TransportParameters* params) const;
453
454 // ProcessTransportParameters reads from |params| which was received from a
455 // peer operating as a |hello_type|. It processes values for ICSL, MIDS, CFCW,
456 // and SFCW and sets the corresponding members of this QuicConfig. On failure,
457 // it returns a QuicErrorCode and puts a detailed error in |*error_details|.
458 QuicErrorCode ProcessTransportParameters(const TransportParameters& params,
459 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700460 std::string* error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500461
462 private:
463 friend class test::QuicConfigPeer;
464
465 // SetDefaults sets the members to sensible, default values.
466 void SetDefaults();
467
468 // Configurations options that are not negotiated.
469 // Maximum time the session can be alive before crypto handshake is finished.
470 QuicTime::Delta max_time_before_crypto_handshake_;
471 // Maximum idle time before the crypto handshake has completed.
472 QuicTime::Delta max_idle_time_before_crypto_handshake_;
473 // Maximum number of undecryptable packets stored before CHLO/SHLO.
474 size_t max_undecryptable_packets_;
475
476 // Connection options which affect the server side. May also affect the
477 // client side in cases when identical behavior is desirable.
478 QuicFixedTagVector connection_options_;
479 // Connection options which only affect the client side.
480 QuicFixedTagVector client_connection_options_;
481 // Idle network timeout in seconds.
482 QuicNegotiableUint32 idle_network_timeout_seconds_;
483 // Whether to use silent close. Defaults to 0 (false) and is otherwise true.
484 QuicNegotiableUint32 silent_close_;
fkastenholzd3a1de92019-05-15 07:00:07 -0700485 // Maximum number of incoming dynamic streams that a Google QUIC connection
486 // can support or the maximum number of incoming bidirectional streams that
487 // an IETF QUIC connection can support.
488 QuicFixedUint32 max_incoming_bidirectional_streams_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500489 // The number of bytes required for the connection ID.
490 QuicFixedUint32 bytes_for_connection_id_;
491 // Initial round trip time estimate in microseconds.
492 QuicFixedUint32 initial_round_trip_time_us_;
493
494 // Initial stream flow control receive window in bytes.
495 QuicFixedUint32 initial_stream_flow_control_window_bytes_;
496 // Initial session flow control receive window in bytes.
497 QuicFixedUint32 initial_session_flow_control_window_bytes_;
498
499 // Whether tell peer not to attempt connection migration.
500 QuicFixedUint32 connection_migration_disabled_;
501
502 // An alternate server address the client could connect to.
503 QuicFixedSocketAddress alternate_server_address_;
504
505 // Whether support HTTP/2 SETTINGS_MAX_HEADER_LIST_SIZE SETTINGS frame.
506 QuicFixedUint32 support_max_header_list_size_;
507
508 // Stateless reset token used in IETF public reset packet.
509 QuicFixedUint128 stateless_reset_token_;
510
511 // List of QuicTags whose presence immediately causes the session to
512 // be created. This allows for CHLOs that are larger than a single
513 // packet to be processed.
514 QuicTagVector create_session_tag_indicators_;
fkastenholzd3a1de92019-05-15 07:00:07 -0700515
516 // Maximum number of incoming unidirectional streams that the connection can
517 // support.
518 QuicFixedUint32 max_incoming_unidirectional_streams_;
fkastenholz4c7303c2019-07-29 08:17:07 -0700519
520 // Maximum ack delay. The sent value is the value used on this node.
521 // The received value is the value received from the peer and used by
522 // the peer.
523 QuicFixedUint32 max_ack_delay_ms_;
fkastenholz4dc4ba32019-07-30 09:55:25 -0700524
525 // ack_delay_exponent parameter negotiated in IETF QUIC transport
526 // parameter negotiation. The sent exponent is the exponent that this
527 // node uses when serializing an ACK frame (and the peer should use when
528 // deserializing the frame); the received exponent is the value the peer uses
529 // to serialize frames and this node uses to deserialize them.
530 QuicFixedUint32 ack_delay_exponent_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500531};
532
533} // namespace quic
534
535#endif // QUICHE_QUIC_CORE_QUIC_CONFIG_H_