summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic/core/quic_config.h
blob: 95a26cb0d8f2d213d3e7ef5df763adae7448565f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef QUICHE_QUIC_CORE_QUIC_CONFIG_H_
#define QUICHE_QUIC_CORE_QUIC_CONFIG_H_

#include <cstddef>
#include <cstdint>
#include <string>

#include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h"
#include "net/third_party/quiche/src/quic/core/quic_packets.h"
#include "net/third_party/quiche/src/quic/core/quic_time.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h"

namespace quic {

namespace test {
class QuicConfigPeer;
}  // namespace test

class CryptoHandshakeMessage;

// Describes whether or not a given QuicTag is required or optional in the
// handshake message.
enum QuicConfigPresence {
  // This negotiable value can be absent from the handshake message. Default
  // value is selected as the negotiated value in such a case.
  PRESENCE_OPTIONAL,
  // This negotiable value is required in the handshake message otherwise the
  // Process*Hello function returns an error.
  PRESENCE_REQUIRED,
};

// Whether the CryptoHandshakeMessage is from the client or server.
enum HelloType {
  CLIENT,
  SERVER,
};

// An abstract base class that stores a value that can be sent in CHLO/SHLO
// message. These values can be OPTIONAL or REQUIRED, depending on |presence_|.
class QUIC_EXPORT_PRIVATE QuicConfigValue {
 public:
  QuicConfigValue(QuicTag tag, QuicConfigPresence presence);
  virtual ~QuicConfigValue();

  // Serialises tag name and value(s) to |out|.
  virtual void ToHandshakeMessage(CryptoHandshakeMessage* out) const = 0;

  // Selects a mutually acceptable value from those offered in |peer_hello|
  // and those defined in the subclass.
  virtual QuicErrorCode ProcessPeerHello(
      const CryptoHandshakeMessage& peer_hello,
      HelloType hello_type,
      std::string* error_details) = 0;

 protected:
  const QuicTag tag_;
  const QuicConfigPresence presence_;
};

class QUIC_EXPORT_PRIVATE QuicNegotiableValue : public QuicConfigValue {
 public:
  QuicNegotiableValue(QuicTag tag, QuicConfigPresence presence);
  ~QuicNegotiableValue() override;

  bool negotiated() const { return negotiated_; }

 protected:
  void set_negotiated(bool negotiated) { negotiated_ = negotiated; }

 private:
  bool negotiated_;
};

class QUIC_EXPORT_PRIVATE QuicNegotiableUint32 : public QuicNegotiableValue {
  // TODO(fayang): some negotiated values use uint32 as bool (e.g., silent
  // close). Consider adding a QuicNegotiableBool type.
 public:
  // Default and max values default to 0.
  QuicNegotiableUint32(QuicTag name, QuicConfigPresence presence);
  ~QuicNegotiableUint32() override;

  // Sets the maximum possible value that can be achieved after negotiation and
  // also the default values to be assumed if PRESENCE_OPTIONAL and the *HLO msg
  // doesn't contain a value corresponding to |name_|. |max| is serialised via
  // ToHandshakeMessage call if |negotiated_| is false.
  void set(uint32_t max, uint32_t default_value);

  // Returns the value negotiated if |negotiated_| is true, otherwise returns
  // default_value_ (used to set default values before negotiation finishes).
  uint32_t GetUint32() const;

  // Returns the maximum value negotiable.
  uint32_t GetMax() const;

  // Serialises |name_| and value to |out|. If |negotiated_| is true then
  // |negotiated_value_| is serialised, otherwise |max_value_| is serialised.
  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;

  // Processes the corresponding value from |peer_hello| and if present calls
  // ReceiveValue with it. If the corresponding value is missing and
  // PRESENCE_OPTIONAL then |negotiated_value_| is set to |default_value_|.
  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
                                 HelloType hello_type,
                                 std::string* error_details) override;

  // Takes a value |value| parsed from a handshake message (whether a TLS
  // ClientHello/ServerHello or a CryptoHandshakeMessage) whose sender was
  // |hello_type|, and sets |negotiated_value_| to the minimum of |value| and
  // |max_value_|. On success this function returns QUIC_NO_ERROR; if there is
  // an error, details are put in |*error_details|.
  QuicErrorCode ReceiveValue(uint32_t value,
                             HelloType hello_type,
                             std::string* error_details);

 private:
  uint32_t max_value_;
  uint32_t default_value_;
  uint32_t negotiated_value_;
};

// Stores uint32_t from CHLO or SHLO messages that are not negotiated.
class QUIC_EXPORT_PRIVATE QuicFixedUint32 : public QuicConfigValue {
 public:
  QuicFixedUint32(QuicTag name, QuicConfigPresence presence);
  ~QuicFixedUint32() override;

  bool HasSendValue() const;

  uint32_t GetSendValue() const;

  void SetSendValue(uint32_t value);

  bool HasReceivedValue() const;

  uint32_t GetReceivedValue() const;

  void SetReceivedValue(uint32_t value);

  // If has_send_value is true, serialises |tag_| and |send_value_| to |out|.
  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;

  // Sets |value_| to the corresponding value from |peer_hello_| if it exists.
  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
                                 HelloType hello_type,
                                 std::string* error_details) override;

 private:
  uint32_t send_value_;
  bool has_send_value_;
  uint32_t receive_value_;
  bool has_receive_value_;
};

// Stores uint128 from CHLO or SHLO messages that are not negotiated.
class QUIC_EXPORT_PRIVATE QuicFixedUint128 : public QuicConfigValue {
 public:
  QuicFixedUint128(QuicTag tag, QuicConfigPresence presence);
  ~QuicFixedUint128() override;

  bool HasSendValue() const;

  QuicUint128 GetSendValue() const;

  void SetSendValue(QuicUint128 value);

  bool HasReceivedValue() const;

  QuicUint128 GetReceivedValue() const;

  void SetReceivedValue(QuicUint128 value);

  // If has_send_value is true, serialises |tag_| and |send_value_| to |out|.
  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;

  // Sets |value_| to the corresponding value from |peer_hello_| if it exists.
  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
                                 HelloType hello_type,
                                 std::string* error_details) override;

 private:
  QuicUint128 send_value_;
  bool has_send_value_;
  QuicUint128 receive_value_;
  bool has_receive_value_;
};

// Stores tag from CHLO or SHLO messages that are not negotiated.
class QUIC_EXPORT_PRIVATE QuicFixedTagVector : public QuicConfigValue {
 public:
  QuicFixedTagVector(QuicTag name, QuicConfigPresence presence);
  QuicFixedTagVector(const QuicFixedTagVector& other);
  ~QuicFixedTagVector() override;

  bool HasSendValues() const;

  QuicTagVector GetSendValues() const;

  void SetSendValues(const QuicTagVector& values);

  bool HasReceivedValues() const;

  QuicTagVector GetReceivedValues() const;

  void SetReceivedValues(const QuicTagVector& values);

  // If has_send_value is true, serialises |tag_vector_| and |send_value_| to
  // |out|.
  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;

  // Sets |receive_values_| to the corresponding value from |client_hello_| if
  // it exists.
  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
                                 HelloType hello_type,
                                 std::string* error_details) override;

 private:
  QuicTagVector send_values_;
  bool has_send_values_;
  QuicTagVector receive_values_;
  bool has_receive_values_;
};

// Stores QuicSocketAddress from CHLO or SHLO messages that are not negotiated.
class QUIC_EXPORT_PRIVATE QuicFixedSocketAddress : public QuicConfigValue {
 public:
  QuicFixedSocketAddress(QuicTag tag, QuicConfigPresence presence);
  ~QuicFixedSocketAddress() override;

  bool HasSendValue() const;

  const QuicSocketAddress& GetSendValue() const;

  void SetSendValue(const QuicSocketAddress& value);

  bool HasReceivedValue() const;

  const QuicSocketAddress& GetReceivedValue() const;

  void SetReceivedValue(const QuicSocketAddress& value);

  void ToHandshakeMessage(CryptoHandshakeMessage* out) const override;

  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
                                 HelloType hello_type,
                                 std::string* error_details) override;

 private:
  QuicSocketAddress send_value_;
  bool has_send_value_;
  QuicSocketAddress receive_value_;
  bool has_receive_value_;
};

// QuicConfig contains non-crypto configuration options that are negotiated in
// the crypto handshake.
class QUIC_EXPORT_PRIVATE QuicConfig {
 public:
  QuicConfig();
  QuicConfig(const QuicConfig& other);
  ~QuicConfig();

  void SetConnectionOptionsToSend(const QuicTagVector& connection_options);

  bool HasReceivedConnectionOptions() const;

  // Sets initial received connection options.  All received connection options
  // will be initialized with these fields. Initial received options may only be
  // set once per config, prior to the setting of any other options.  If options
  // have already been set (either by previous calls or via handshake), this
  // function does nothing and returns false.
  bool SetInitialReceivedConnectionOptions(const QuicTagVector& tags);

  QuicTagVector ReceivedConnectionOptions() const;

  bool HasSendConnectionOptions() const;

  QuicTagVector SendConnectionOptions() const;

  // Returns true if the client is sending or the server has received a
  // connection option.
  // TODO(ianswett): Rename to HasClientRequestedSharedOption
  bool HasClientSentConnectionOption(QuicTag tag,
                                     Perspective perspective) const;

  void SetClientConnectionOptions(
      const QuicTagVector& client_connection_options);

  // Returns true if the client has requested the specified connection option.
  // Checks the client connection options if the |perspective| is client and
  // connection options if the |perspective| is the server.
  bool HasClientRequestedIndependentOption(QuicTag tag,
                                           Perspective perspective) const;

  void SetIdleNetworkTimeout(QuicTime::Delta max_idle_network_timeout,
                             QuicTime::Delta default_idle_network_timeout);

  QuicTime::Delta IdleNetworkTimeout() const;

  void SetSilentClose(bool silent_close);

  bool SilentClose() const;

  // Sets the max bidirectional stream count that this endpoint supports.
  void SetMaxBidirectionalStreamsToSend(uint32_t max_streams);
  uint32_t GetMaxBidirectionalStreamsToSend() const;

  bool HasReceivedMaxBidirectionalStreams() const;
  // Gets the max bidirectional stream limit imposed by the peer.
  uint32_t ReceivedMaxBidirectionalStreams() const;

  // Sets the max unidirectional stream count that this endpoint supports.
  void SetMaxUnidirectionalStreamsToSend(uint32_t max_streams);
  uint32_t GetMaxUnidirectionalStreamsToSend() const;

  bool HasReceivedMaxUnidirectionalStreams() const;
  // Gets the max unidirectional stream limit imposed by the peer.
  uint32_t ReceivedMaxUnidirectionalStreams() const;

  void set_max_time_before_crypto_handshake(
      QuicTime::Delta max_time_before_crypto_handshake) {
    max_time_before_crypto_handshake_ = max_time_before_crypto_handshake;
  }

  QuicTime::Delta max_time_before_crypto_handshake() const {
    return max_time_before_crypto_handshake_;
  }

  void set_max_idle_time_before_crypto_handshake(
      QuicTime::Delta max_idle_time_before_crypto_handshake) {
    max_idle_time_before_crypto_handshake_ =
        max_idle_time_before_crypto_handshake;
  }

  QuicTime::Delta max_idle_time_before_crypto_handshake() const {
    return max_idle_time_before_crypto_handshake_;
  }

  QuicNegotiableUint32 idle_network_timeout_seconds() const {
    return idle_network_timeout_seconds_;
  }

  void set_max_undecryptable_packets(size_t max_undecryptable_packets) {
    max_undecryptable_packets_ = max_undecryptable_packets;
  }

  size_t max_undecryptable_packets() const {
    return max_undecryptable_packets_;
  }

  bool HasSetBytesForConnectionIdToSend() const;

  // Sets the peer's connection id length, in bytes.
  void SetBytesForConnectionIdToSend(uint32_t bytes);

  bool HasReceivedBytesForConnectionId() const;

  uint32_t ReceivedBytesForConnectionId() const;

  // Sets an estimated initial round trip time in us.
  void SetInitialRoundTripTimeUsToSend(uint32_t rtt_us);

  bool HasReceivedInitialRoundTripTimeUs() const;

  uint32_t ReceivedInitialRoundTripTimeUs() const;

  bool HasInitialRoundTripTimeUsToSend() const;

  uint32_t GetInitialRoundTripTimeUsToSend() const;

  // Sets an initial stream flow control window size to transmit to the peer.
  void SetInitialStreamFlowControlWindowToSend(uint32_t window_bytes);
  uint32_t GetInitialStreamFlowControlWindowToSend() const;
  bool HasReceivedInitialStreamFlowControlWindowBytes() const;
  uint32_t ReceivedInitialStreamFlowControlWindowBytes() const;

  // Specifies the initial flow control window (max stream data) for
  // incoming bidirectional streams. Incoming means streams initiated by our
  // peer. If not set, GetInitialMaxStreamDataBytesIncomingBidirectionalToSend
  // returns the value passed to SetInitialStreamFlowControlWindowToSend.
  void SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
      uint32_t window_bytes);
  uint32_t GetInitialMaxStreamDataBytesIncomingBidirectionalToSend() const;
  bool HasReceivedInitialMaxStreamDataBytesIncomingBidirectional() const;
  uint32_t ReceivedInitialMaxStreamDataBytesIncomingBidirectional() const;

  // Specifies the initial flow control window (max stream data) for
  // outgoing bidirectional streams. Outgoing means streams initiated by us.
  // If not set, GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend
  // returns the value passed to SetInitialStreamFlowControlWindowToSend.
  void SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
      uint32_t window_bytes);
  uint32_t GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend() const;
  bool HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional() const;
  uint32_t ReceivedInitialMaxStreamDataBytesOutgoingBidirectional() const;

  // Specifies the initial flow control window (max stream data) for
  // unidirectional streams. If not set,
  // GetInitialMaxStreamDataBytesUnidirectionalToSend returns the value passed
  // to SetInitialStreamFlowControlWindowToSend.
  void SetInitialMaxStreamDataBytesUnidirectionalToSend(uint32_t window_bytes);
  uint32_t GetInitialMaxStreamDataBytesUnidirectionalToSend() const;
  bool HasReceivedInitialMaxStreamDataBytesUnidirectional() const;
  uint32_t ReceivedInitialMaxStreamDataBytesUnidirectional() const;

  // Sets an initial session flow control window size to transmit to the peer.
  void SetInitialSessionFlowControlWindowToSend(uint32_t window_bytes);

  uint32_t GetInitialSessionFlowControlWindowToSend() const;

  bool HasReceivedInitialSessionFlowControlWindowBytes() const;

  uint32_t ReceivedInitialSessionFlowControlWindowBytes() const;

  void SetDisableConnectionMigration();

  bool DisableConnectionMigration() const;

  void SetAlternateServerAddressToSend(
      const QuicSocketAddress& alternate_server_address);

  bool HasReceivedAlternateServerAddress() const;

  const QuicSocketAddress& ReceivedAlternateServerAddress() const;

  void SetSupportMaxHeaderListSize();

  bool SupportMaxHeaderListSize() const;

  void SetStatelessResetTokenToSend(QuicUint128 stateless_reset_token);

  bool HasReceivedStatelessResetToken() const;

  QuicUint128 ReceivedStatelessResetToken() const;

  // Manage the IETF QUIC Max ACK Delay transport parameter.
  // The sent value is the delay that this node uses
  // (QuicSentPacketManager::local_max_ack_delay_).
  // The received delay is the value received from
  // the peer (QuicSentPacketManager::peer_max_ack_delay_).
  void SetMaxAckDelayToSendMs(uint32_t max_ack_delay_ms);
  uint32_t GetMaxAckDelayToToSendMs() const;
  bool HasReceivedMaxAckDelayMs() const;
  uint32_t ReceivedMaxAckDelayMs() const;

  void SetAckDelayExponentToSend(uint32_t exponent);
  uint32_t GetAckDelayExponentToSend() const;
  bool HasReceivedAckDelayExponent() const;
  uint32_t ReceivedAckDelayExponent() const;

  // IETF QUIC max_packet_size transport parameter.
  void SetMaxPacketSizeToSend(uint32_t max_packet_size);
  uint32_t GetMaxPacketSizeToSend() const;
  bool HasReceivedMaxPacketSize() const;
  uint32_t ReceivedMaxPacketSize() const;

  // IETF QUIC max_datagram_frame_size transport parameter.
  void SetMaxDatagramFrameSizeToSend(uint32_t max_datagram_frame_size);
  uint32_t GetMaxDatagramFrameSizeToSend() const;
  bool HasReceivedMaxDatagramFrameSize() const;
  uint32_t ReceivedMaxDatagramFrameSize() const;

  bool negotiated() const;

  void SetCreateSessionTagIndicators(QuicTagVector tags);

  const QuicTagVector& create_session_tag_indicators() const;

  // ToHandshakeMessage serialises the settings in this object as a series of
  // tags /value pairs and adds them to |out|.
  void ToHandshakeMessage(CryptoHandshakeMessage* out,
                          QuicTransportVersion transport_version) const;

  // Calls ProcessPeerHello on each negotiable parameter. On failure returns
  // the corresponding QuicErrorCode and sets detailed error in |error_details|.
  QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello,
                                 HelloType hello_type,
                                 std::string* error_details);

  // FillTransportParameters writes the values to send for ICSL, MIDS, CFCW, and
  // SFCW to |*params|, returning true if the values could be written and false
  // if something prevents them from being written (e.g. a value is too large).
  bool FillTransportParameters(TransportParameters* params) const;

  // ProcessTransportParameters reads from |params| which was received from a
  // peer operating as a |hello_type|. It processes values for ICSL, MIDS, CFCW,
  // and SFCW and sets the corresponding members of this QuicConfig. On failure,
  // it returns a QuicErrorCode and puts a detailed error in |*error_details|.
  QuicErrorCode ProcessTransportParameters(const TransportParameters& params,
                                           HelloType hello_type,
                                           std::string* error_details);

  TransportParameters::ParameterMap& custom_transport_parameters_to_send() {
    return custom_transport_parameters_to_send_;
  }
  const TransportParameters::ParameterMap&
  received_custom_transport_parameters() const {
    return received_custom_transport_parameters_;
  }

 private:
  friend class test::QuicConfigPeer;

  // SetDefaults sets the members to sensible, default values.
  void SetDefaults();

  // Configurations options that are not negotiated.
  // Maximum time the session can be alive before crypto handshake is finished.
  QuicTime::Delta max_time_before_crypto_handshake_;
  // Maximum idle time before the crypto handshake has completed.
  QuicTime::Delta max_idle_time_before_crypto_handshake_;
  // Maximum number of undecryptable packets stored before CHLO/SHLO.
  size_t max_undecryptable_packets_;

  // Connection options which affect the server side.  May also affect the
  // client side in cases when identical behavior is desirable.
  QuicFixedTagVector connection_options_;
  // Connection options which only affect the client side.
  QuicFixedTagVector client_connection_options_;
  // Idle network timeout in seconds.
  QuicNegotiableUint32 idle_network_timeout_seconds_;
  // Whether to use silent close.  Defaults to 0 (false) and is otherwise true.
  QuicNegotiableUint32 silent_close_;
  // Maximum number of dynamic streams that a Google QUIC connection
  // can support or the maximum number of bidirectional streams that
  // an IETF QUIC connection can support.
  // The SendValue is the limit on peer-created streams that this endpoint is
  // advertising.
  // The ReceivedValue is the limit on locally-created streams that
  // the peer advertised.
  QuicFixedUint32 max_bidirectional_streams_;
  // Maximum number of unidirectional streams that the connection can
  // support.
  // The SendValue is the limit on peer-created streams that this endpoint is
  // advertising.
  // The ReceivedValue is the limit on locally-created streams that the peer
  // advertised.
  QuicFixedUint32 max_unidirectional_streams_;
  // The number of bytes required for the connection ID.
  QuicFixedUint32 bytes_for_connection_id_;
  // Initial round trip time estimate in microseconds.
  QuicFixedUint32 initial_round_trip_time_us_;

  // Initial IETF QUIC stream flow control receive windows in bytes.
  // Incoming bidirectional streams.
  QuicFixedUint32 initial_max_stream_data_bytes_incoming_bidirectional_;
  // Outgoing bidirectional streams.
  QuicFixedUint32 initial_max_stream_data_bytes_outgoing_bidirectional_;
  // Unidirectional streams.
  QuicFixedUint32 initial_max_stream_data_bytes_unidirectional_;

  // Initial Google QUIC stream flow control receive window in bytes.
  QuicFixedUint32 initial_stream_flow_control_window_bytes_;

  // Initial session flow control receive window in bytes.
  QuicFixedUint32 initial_session_flow_control_window_bytes_;

  // Whether tell peer not to attempt connection migration.
  QuicFixedUint32 connection_migration_disabled_;

  // An alternate server address the client could connect to.
  QuicFixedSocketAddress alternate_server_address_;

  // Whether support HTTP/2 SETTINGS_MAX_HEADER_LIST_SIZE SETTINGS frame.
  QuicFixedUint32 support_max_header_list_size_;

  // Stateless reset token used in IETF public reset packet.
  QuicFixedUint128 stateless_reset_token_;

  // List of QuicTags whose presence immediately causes the session to
  // be created. This allows for CHLOs that are larger than a single
  // packet to be processed.
  QuicTagVector create_session_tag_indicators_;

  // Maximum ack delay. The sent value is the value used on this node.
  // The received value is the value received from the peer and used by
  // the peer.
  QuicFixedUint32 max_ack_delay_ms_;

  // ack_delay_exponent parameter negotiated in IETF QUIC transport
  // parameter negotiation. The sent exponent is the exponent that this
  // node uses when serializing an ACK frame (and the peer should use when
  // deserializing the frame); the received exponent is the value the peer uses
  // to serialize frames and this node uses to deserialize them.
  QuicFixedUint32 ack_delay_exponent_;

  // max_packet_size IETF QUIC transport parameter.
  QuicFixedUint32 max_packet_size_;

  // max_datagram_frame_size IETF QUIC transport parameter.
  QuicFixedUint32 max_datagram_frame_size_;

  // Custom transport parameters that can be sent and received in the TLS
  // handshake.
  TransportParameters::ParameterMap custom_transport_parameters_to_send_;
  TransportParameters::ParameterMap received_custom_transport_parameters_;
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_QUIC_CONFIG_H_