blob: 07b0132a5e24ccec1400308d7f924f43f4cc0988 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2018 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_CRYPTO_TRANSPORT_PARAMETERS_H_
6#define QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_
7
8#include <memory>
9#include <vector>
10
dschinazi52127d72019-04-17 15:12:38 -070011#include "third_party/boringssl/src/include/openssl/bytestring.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050012#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h"
dschinazi52127d72019-04-17 15:12:38 -070013#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
14#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050015#include "net/third_party/quiche/src/quic/core/quic_types.h"
16#include "net/third_party/quiche/src/quic/core/quic_versions.h"
vasilvva2ef3012019-09-12 18:32:14 -070017#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
dmcardle904ef182019-12-13 08:34:33 -080018#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050019
20namespace quic {
21
22// TransportParameters contains parameters for QUIC's transport layer that are
dschinazi52127d72019-04-17 15:12:38 -070023// exchanged during the TLS handshake. This struct is a mirror of the struct in
24// the "Transport Parameter Encoding" section of draft-ietf-quic-transport.
dschinazi6cf4d2a2019-04-30 16:20:23 -070025// This struct currently uses the values from draft 20.
QUICHE teama6ef0a62019-03-07 20:34:33 -050026struct QUIC_EXPORT_PRIVATE TransportParameters {
dschinazi52127d72019-04-17 15:12:38 -070027 // The identifier used to differentiate transport parameters.
28 enum TransportParameterId : uint16_t;
vasilvva2ef3012019-09-12 18:32:14 -070029 // A map used to specify custom parameters.
30 using ParameterMap = QuicUnorderedMap<TransportParameterId, std::string>;
dschinazi52127d72019-04-17 15:12:38 -070031 // Represents an individual QUIC transport parameter that only encodes a
32 // variable length integer. Can only be created inside the constructor for
33 // TransportParameters.
34 class QUIC_EXPORT_PRIVATE IntegerParameter {
35 public:
36 // Forbid constructing and copying apart from TransportParameters.
37 IntegerParameter() = delete;
38 IntegerParameter(const IntegerParameter&) = delete;
39 IntegerParameter& operator=(const IntegerParameter&) = delete;
40 // Sets the value of this transport parameter.
41 void set_value(uint64_t value);
42 // Gets the value of this transport parameter.
43 uint64_t value() const;
44 // Validates whether the current value is valid.
45 bool IsValid() const;
46 // Writes to a crypto byte buffer, used during serialization. Does not write
47 // anything if the value is equal to the parameter's default value.
48 // Returns whether the write was successful.
49 bool WriteToCbb(CBB* parent_cbb) const;
50 // Reads from a crypto byte string, used during parsing.
51 // Returns whether the read was successful.
52 bool ReadFromCbs(CBS* const value_cbs);
53 // operator<< allows easily logging integer transport parameters.
54 friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
55 std::ostream& os,
56 const IntegerParameter& param);
57
58 private:
dschinazicf6a3ee2019-04-17 17:03:28 -070059 friend struct TransportParameters;
dschinazi52127d72019-04-17 15:12:38 -070060 // Constructors for initial setup used by TransportParameters only.
61 // This constructor sets |default_value| and |min_value| to 0, and
62 // |max_value| to kVarInt62MaxValue.
63 explicit IntegerParameter(TransportParameterId param_id);
64 IntegerParameter(TransportParameterId param_id,
65 uint64_t default_value,
66 uint64_t min_value,
67 uint64_t max_value);
68 // Human-readable string representation.
69 std::string ToString(bool for_use_in_list) const;
70
71 // Number used to indicate this transport parameter.
72 TransportParameterId param_id_;
73 // Current value of the transport parameter.
74 uint64_t value_;
75 // Default value of this transport parameter, as per IETF specification.
76 const uint64_t default_value_;
77 // Minimum value of this transport parameter, as per IETF specification.
78 const uint64_t min_value_;
79 // Maximum value of this transport parameter, as per IETF specification.
80 const uint64_t max_value_;
81 // Ensures this parameter is not parsed twice in the same message.
82 bool has_been_read_from_cbs_;
83 };
84
85 // Represents the preferred_address transport parameter that a server can
86 // send to clients.
87 struct QUIC_EXPORT_PRIVATE PreferredAddress {
88 PreferredAddress();
89 ~PreferredAddress();
90
91 QuicSocketAddress ipv4_socket_address;
92 QuicSocketAddress ipv6_socket_address;
93 QuicConnectionId connection_id;
94 std::vector<uint8_t> stateless_reset_token;
95
96 // Allows easily logging.
97 std::string ToString() const;
98 friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
99 std::ostream& os,
100 const TransportParameters& params);
101 };
102
QUICHE teama6ef0a62019-03-07 20:34:33 -0500103 TransportParameters();
104 ~TransportParameters();
105
dschinazi52127d72019-04-17 15:12:38 -0700106 // Represents the sender of the transport parameters. When |perspective| is
107 // Perspective::IS_CLIENT, this struct is being used in the client_hello
108 // handshake message; when it is Perspective::IS_SERVER, it is being used in
109 // the encrypted_extensions handshake message.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500110 Perspective perspective;
111
112 // When Perspective::IS_CLIENT, |version| is the initial version offered by
113 // the client (before any version negotiation packets) for this connection.
114 // When Perspective::IS_SERVER, |version| is the version that is in use.
dschinazi52127d72019-04-17 15:12:38 -0700115 QuicVersionLabel version;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500116
117 // |supported_versions| contains a list of all versions that the server would
118 // send in a version negotiation packet. It is not used if |perspective ==
119 // Perspective::IS_CLIENT|.
120 QuicVersionLabelVector supported_versions;
121
dschinazi52127d72019-04-17 15:12:38 -0700122 // The value of the Destination Connection ID field from the first
123 // Initial packet sent by the client.
124 QuicConnectionId original_connection_id;
125
dschinazi6cf4d2a2019-04-30 16:20:23 -0700126 // Idle timeout expressed in milliseconds.
127 IntegerParameter idle_timeout_milliseconds;
dschinazi52127d72019-04-17 15:12:38 -0700128
129 // Stateless reset token used in verifying stateless resets.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500130 std::vector<uint8_t> stateless_reset_token;
131
dschinazi52127d72019-04-17 15:12:38 -0700132 // Limits the size of packets that the endpoint is willing to receive.
133 // This indicates that packets larger than this limit will be dropped.
134 IntegerParameter max_packet_size;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500135
dschinazi52127d72019-04-17 15:12:38 -0700136 // Contains the initial value for the maximum amount of data that can
137 // be sent on the connection.
138 IntegerParameter initial_max_data;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500139
dschinazi52127d72019-04-17 15:12:38 -0700140 // Initial flow control limit for locally-initiated bidirectional streams.
141 IntegerParameter initial_max_stream_data_bidi_local;
142
143 // Initial flow control limit for peer-initiated bidirectional streams.
144 IntegerParameter initial_max_stream_data_bidi_remote;
145
146 // Initial flow control limit for unidirectional streams.
147 IntegerParameter initial_max_stream_data_uni;
148
149 // Initial maximum number of bidirectional streams the peer may initiate.
150 IntegerParameter initial_max_streams_bidi;
151
152 // Initial maximum number of unidirectional streams the peer may initiate.
153 IntegerParameter initial_max_streams_uni;
154
155 // Exponent used to decode the ACK Delay field in ACK frames.
156 IntegerParameter ack_delay_exponent;
157
158 // Maximum amount of time in milliseconds by which the endpoint will
159 // delay sending acknowledgments.
160 IntegerParameter max_ack_delay;
161
162 // Indicates lack of support for connection migration.
163 bool disable_migration;
164
165 // Used to effect a change in server address at the end of the handshake.
166 std::unique_ptr<PreferredAddress> preferred_address;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500167
dschinazie9db63c2019-07-17 16:19:42 -0700168 // Maximum number of connection IDs from the peer that an endpoint is willing
169 // to store.
170 IntegerParameter active_connection_id_limit;
171
dschinazicd86dd12019-11-14 10:11:13 -0800172 // Indicates support for the DATAGRAM frame and the maximum frame size that
173 // the sender accepts. See draft-pauly-quic-datagram.
174 IntegerParameter max_datagram_frame_size;
175
QUICHE teama6ef0a62019-03-07 20:34:33 -0500176 // Transport parameters used by Google QUIC but not IETF QUIC. This is
177 // serialized into a TransportParameter struct with a TransportParameterId of
dschinazi52127d72019-04-17 15:12:38 -0700178 // kGoogleQuicParamId.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500179 std::unique_ptr<CryptoHandshakeMessage> google_quic_params;
180
dschinazi52127d72019-04-17 15:12:38 -0700181 // Validates whether transport parameters are valid according to
182 // the specification.
183 bool AreValid() const;
184
vasilvva2ef3012019-09-12 18:32:14 -0700185 // Custom parameters that may be specific to application protocol.
186 ParameterMap custom_parameters;
187
dschinazi52127d72019-04-17 15:12:38 -0700188 // Allows easily logging transport parameters.
189 std::string ToString() const;
190 friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
191 std::ostream& os,
192 const TransportParameters& params);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500193};
194
195// Serializes a TransportParameters struct into the format for sending it in a
dschinazi52127d72019-04-17 15:12:38 -0700196// TLS extension. The serialized bytes are written to |*out|. Returns if the
197// parameters are valid and serialization succeeded.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500198QUIC_EXPORT_PRIVATE bool SerializeTransportParameters(
dschinazi6c84c142019-07-31 09:11:49 -0700199 ParsedQuicVersion version,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500200 const TransportParameters& in,
201 std::vector<uint8_t>* out);
202
203// Parses bytes from the quic_transport_parameters TLS extension and writes the
204// parsed parameters into |*out|. Input is read from |in| for |in_len| bytes.
205// |perspective| indicates whether the input came from a client or a server.
dschinazi52127d72019-04-17 15:12:38 -0700206// This method returns true if the input was successfully parsed.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500207// TODO(nharper): Write fuzz tests for this method.
dschinazi6c84c142019-07-31 09:11:49 -0700208QUIC_EXPORT_PRIVATE bool ParseTransportParameters(ParsedQuicVersion version,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500209 Perspective perspective,
dschinazi6c84c142019-07-31 09:11:49 -0700210 const uint8_t* in,
211 size_t in_len,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500212 TransportParameters* out);
213
214} // namespace quic
215
216#endif // QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_