summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic/core/crypto/transport_parameters.h
blob: 8c7970c29d53ad13e43f8c6f082a29f748dccb32 (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
// Copyright (c) 2018 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_CRYPTO_TRANSPORT_PARAMETERS_H_
#define QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_

#include <memory>
#include <vector>

#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
#include "net/third_party/quiche/src/quic/core/quic_data_reader.h"
#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
#include "net/third_party/quiche/src/quic/core/quic_tag.h"
#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/core/quic_versions.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"

namespace quic {

// TransportParameters contains parameters for QUIC's transport layer that are
// exchanged during the TLS handshake. This struct is a mirror of the struct in
// the "Transport Parameter Encoding" section of draft-ietf-quic-transport.
// This struct currently uses the values from draft 20.
struct QUIC_EXPORT_PRIVATE TransportParameters {
  // The identifier used to differentiate transport parameters.
  enum TransportParameterId : uint64_t;
  // A map used to specify custom parameters.
  using ParameterMap = QuicHashMap<TransportParameterId, std::string>;
  // Represents an individual QUIC transport parameter that only encodes a
  // variable length integer. Can only be created inside the constructor for
  // TransportParameters.
  class QUIC_EXPORT_PRIVATE IntegerParameter {
   public:
    // Forbid constructing and copying apart from TransportParameters.
    IntegerParameter() = delete;
    IntegerParameter& operator=(const IntegerParameter&) = delete;
    // Sets the value of this transport parameter.
    void set_value(uint64_t value);
    // Gets the value of this transport parameter.
    uint64_t value() const;
    // Validates whether the current value is valid.
    bool IsValid() const;
    // Writes to a crypto byte buffer, used during serialization. Does not write
    // anything if the value is equal to the parameter's default value.
    // Returns whether the write was successful.
    bool Write(QuicDataWriter* writer, ParsedQuicVersion version) const;
    // Reads from a crypto byte string, used during parsing.
    // Returns whether the read was successful.
    // On failure, this method will write a human-readable error message to
    // |error_details|.
    bool Read(QuicDataReader* reader, std::string* error_details);
    // operator<< allows easily logging integer transport parameters.
    friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
        std::ostream& os,
        const IntegerParameter& param);

   private:
    friend struct TransportParameters;
    // Constructors for initial setup used by TransportParameters only.
    // This constructor sets |default_value| and |min_value| to 0, and
    // |max_value| to kVarInt62MaxValue.
    explicit IntegerParameter(TransportParameterId param_id);
    IntegerParameter(TransportParameterId param_id,
                     uint64_t default_value,
                     uint64_t min_value,
                     uint64_t max_value);
    IntegerParameter(const IntegerParameter& other) = default;
    IntegerParameter(IntegerParameter&& other) = default;
    // Human-readable string representation.
    std::string ToString(bool for_use_in_list) const;

    // Number used to indicate this transport parameter.
    TransportParameterId param_id_;
    // Current value of the transport parameter.
    uint64_t value_;
    // Default value of this transport parameter, as per IETF specification.
    const uint64_t default_value_;
    // Minimum value of this transport parameter, as per IETF specification.
    const uint64_t min_value_;
    // Maximum value of this transport parameter, as per IETF specification.
    const uint64_t max_value_;
    // Ensures this parameter is not parsed twice in the same message.
    bool has_been_read_;
  };

  // Represents the preferred_address transport parameter that a server can
  // send to clients.
  struct QUIC_EXPORT_PRIVATE PreferredAddress {
    PreferredAddress();
    PreferredAddress(const PreferredAddress& other) = default;
    PreferredAddress(PreferredAddress&& other) = default;
    ~PreferredAddress();
    bool operator==(const PreferredAddress& rhs) const;
    bool operator!=(const PreferredAddress& rhs) const;

    QuicSocketAddress ipv4_socket_address;
    QuicSocketAddress ipv6_socket_address;
    QuicConnectionId connection_id;
    std::vector<uint8_t> stateless_reset_token;

    // Allows easily logging.
    std::string ToString() const;
    friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
        std::ostream& os,
        const TransportParameters& params);
  };

  TransportParameters();
  TransportParameters(const TransportParameters& other);
  ~TransportParameters();
  bool operator==(const TransportParameters& rhs) const;
  bool operator!=(const TransportParameters& rhs) const;

  // Represents the sender of the transport parameters. When |perspective| is
  // Perspective::IS_CLIENT, this struct is being used in the client_hello
  // handshake message; when it is Perspective::IS_SERVER, it is being used in
  // the encrypted_extensions handshake message.
  Perspective perspective;

  // When Perspective::IS_CLIENT, |version| is the initial version offered by
  // the client (before any version negotiation packets) for this connection.
  // When Perspective::IS_SERVER, |version| is the version that is in use.
  QuicVersionLabel version;

  // |supported_versions| contains a list of all versions that the server would
  // send in a version negotiation packet. It is not used if |perspective ==
  // Perspective::IS_CLIENT|.
  QuicVersionLabelVector supported_versions;

  // The value of the Destination Connection ID field from the first
  // Initial packet sent by the client.
  absl::optional<QuicConnectionId> original_destination_connection_id;

  // Maximum idle timeout expressed in milliseconds.
  IntegerParameter max_idle_timeout_ms;

  // Stateless reset token used in verifying stateless resets.
  std::vector<uint8_t> stateless_reset_token;

  // Limits the size of packets that the endpoint is willing to receive.
  // This indicates that packets larger than this limit will be dropped.
  IntegerParameter max_udp_payload_size;

  // Contains the initial value for the maximum amount of data that can
  // be sent on the connection.
  IntegerParameter initial_max_data;

  // Initial flow control limit for locally-initiated bidirectional streams.
  IntegerParameter initial_max_stream_data_bidi_local;

  // Initial flow control limit for peer-initiated bidirectional streams.
  IntegerParameter initial_max_stream_data_bidi_remote;

  // Initial flow control limit for unidirectional streams.
  IntegerParameter initial_max_stream_data_uni;

  // Initial maximum number of bidirectional streams the peer may initiate.
  IntegerParameter initial_max_streams_bidi;

  // Initial maximum number of unidirectional streams the peer may initiate.
  IntegerParameter initial_max_streams_uni;

  // Exponent used to decode the ACK Delay field in ACK frames.
  IntegerParameter ack_delay_exponent;

  // Maximum amount of time in milliseconds by which the endpoint will
  // delay sending acknowledgments.
  IntegerParameter max_ack_delay;

  // Minimum amount of time in microseconds by which the endpoint will
  // delay sending acknowledgments. Used to enable sender control of ack delay.
  IntegerParameter min_ack_delay_us;

  // Indicates lack of support for connection migration.
  bool disable_active_migration;

  // Used to effect a change in server address at the end of the handshake.
  std::unique_ptr<PreferredAddress> preferred_address;

  // Maximum number of connection IDs from the peer that an endpoint is willing
  // to store.
  IntegerParameter active_connection_id_limit;

  // The value that the endpoint included in the Source Connection ID field of
  // the first Initial packet it sent.
  absl::optional<QuicConnectionId> initial_source_connection_id;

  // The value that the server included in the Source Connection ID field of a
  // Retry packet it sent.
  absl::optional<QuicConnectionId> retry_source_connection_id;

  // Indicates support for the DATAGRAM frame and the maximum frame size that
  // the sender accepts. See draft-ietf-quic-datagram.
  IntegerParameter max_datagram_frame_size;

  // Google-specific transport parameter that carries an estimate of the
  // initial round-trip time in microseconds.
  IntegerParameter initial_round_trip_time_us;

  // Google-specific connection options.
  absl::optional<QuicTagVector> google_connection_options;

  // Google-specific user agent identifier.
  absl::optional<std::string> user_agent_id;

  // Google-specific handshake done support. This is only used for T050.
  bool support_handshake_done;

  // Google-specific mechanism to indicate that IETF QUIC Key Update has not
  // yet been implemented. This will be removed once we implement it.
  bool key_update_not_yet_supported;

  // Validates whether transport parameters are valid according to
  // the specification. If the transport parameters are not valid, this method
  // will write a human-readable error message to |error_details|.
  bool AreValid(std::string* error_details) const;

  // Custom parameters that may be specific to application protocol.
  ParameterMap custom_parameters;

  // Allows easily logging transport parameters.
  std::string ToString() const;
  friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
      std::ostream& os,
      const TransportParameters& params);
};

// Serializes a TransportParameters struct into the format for sending it in a
// TLS extension. The serialized bytes are written to |*out|. Returns if the
// parameters are valid and serialization succeeded.
QUIC_EXPORT_PRIVATE bool SerializeTransportParameters(
    ParsedQuicVersion version,
    const TransportParameters& in,
    std::vector<uint8_t>* out);

// Parses bytes from the quic_transport_parameters TLS extension and writes the
// parsed parameters into |*out|. Input is read from |in| for |in_len| bytes.
// |perspective| indicates whether the input came from a client or a server.
// This method returns true if the input was successfully parsed.
// On failure, this method will write a human-readable error message to
// |error_details|.
QUIC_EXPORT_PRIVATE bool ParseTransportParameters(ParsedQuicVersion version,
                                                  Perspective perspective,
                                                  const uint8_t* in,
                                                  size_t in_len,
                                                  TransportParameters* out,
                                                  std::string* error_details);

// Serializes |in| and |application_data| in a deterministic format so that
// multiple calls to SerializeTransportParametersForTicket with the same inputs
// will generate the same output, and if the inputs differ, then the output will
// differ. The output of this function is used by the server in
// SSL_set_quic_early_data_context to determine whether early data should be
// accepted: Early data will only be accepted if the inputs to this function
// match what they were on the connection that issued an early data capable
// ticket.
QUIC_EXPORT_PRIVATE bool SerializeTransportParametersForTicket(
    const TransportParameters& in,
    const std::vector<uint8_t>& application_data,
    std::vector<uint8_t>* out);

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_CRYPTO_TRANSPORT_PARAMETERS_H_