OLD | NEW |
| (Empty) |
1 // 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 NET_QUIC_QUIC_CONFIG_H_ | |
6 #define NET_QUIC_QUIC_CONFIG_H_ | |
7 | |
8 #include <stddef.h> | |
9 #include <stdint.h> | |
10 | |
11 #include <string> | |
12 | |
13 #include "net/quic/quic_protocol.h" | |
14 #include "net/quic/quic_time.h" | |
15 | |
16 namespace net { | |
17 | |
18 namespace test { | |
19 class QuicConfigPeer; | |
20 } // namespace test | |
21 | |
22 class CryptoHandshakeMessage; | |
23 | |
24 // Describes whether or not a given QuicTag is required or optional in the | |
25 // handshake message. | |
26 enum QuicConfigPresence { | |
27 // This negotiable value can be absent from the handshake message. Default | |
28 // value is selected as the negotiated value in such a case. | |
29 PRESENCE_OPTIONAL, | |
30 // This negotiable value is required in the handshake message otherwise the | |
31 // Process*Hello function returns an error. | |
32 PRESENCE_REQUIRED, | |
33 }; | |
34 | |
35 // Whether the CryptoHandshakeMessage is from the client or server. | |
36 enum HelloType { | |
37 CLIENT, | |
38 SERVER, | |
39 }; | |
40 | |
41 // An abstract base class that stores a value that can be sent in CHLO/SHLO | |
42 // message. These values can be OPTIONAL or REQUIRED, depending on |presence_|. | |
43 class NET_EXPORT_PRIVATE QuicConfigValue { | |
44 public: | |
45 QuicConfigValue(QuicTag tag, QuicConfigPresence presence); | |
46 virtual ~QuicConfigValue(); | |
47 | |
48 // Serialises tag name and value(s) to |out|. | |
49 virtual void ToHandshakeMessage(CryptoHandshakeMessage* out) const = 0; | |
50 | |
51 // Selects a mutually acceptable value from those offered in |peer_hello| | |
52 // and those defined in the subclass. | |
53 virtual QuicErrorCode ProcessPeerHello( | |
54 const CryptoHandshakeMessage& peer_hello, | |
55 HelloType hello_type, | |
56 std::string* error_details) = 0; | |
57 | |
58 protected: | |
59 const QuicTag tag_; | |
60 const QuicConfigPresence presence_; | |
61 }; | |
62 | |
63 class NET_EXPORT_PRIVATE QuicNegotiableValue : public QuicConfigValue { | |
64 public: | |
65 QuicNegotiableValue(QuicTag tag, QuicConfigPresence presence); | |
66 ~QuicNegotiableValue() override; | |
67 | |
68 bool negotiated() const { return negotiated_; } | |
69 | |
70 protected: | |
71 void set_negotiated(bool negotiated) { negotiated_ = negotiated; } | |
72 | |
73 private: | |
74 bool negotiated_; | |
75 }; | |
76 | |
77 class NET_EXPORT_PRIVATE QuicNegotiableUint32 : public QuicNegotiableValue { | |
78 // TODO(fayang): some negotiated values use uint32 as bool (e.g., silent | |
79 // close). Consider adding a QuicNegotiableBool type. | |
80 public: | |
81 // Default and max values default to 0. | |
82 QuicNegotiableUint32(QuicTag name, QuicConfigPresence presence); | |
83 ~QuicNegotiableUint32() override; | |
84 | |
85 // Sets the maximum possible value that can be achieved after negotiation and | |
86 // also the default values to be assumed if PRESENCE_OPTIONAL and the *HLO msg | |
87 // doesn't contain a value corresponding to |name_|. |max| is serialised via | |
88 // ToHandshakeMessage call if |negotiated_| is false. | |
89 void set(uint32_t max, uint32_t default_value); | |
90 | |
91 // Returns the value negotiated if |negotiated_| is true, otherwise returns | |
92 // default_value_ (used to set default values before negotiation finishes). | |
93 uint32_t GetUint32() const; | |
94 | |
95 // Serialises |name_| and value to |out|. If |negotiated_| is true then | |
96 // |negotiated_value_| is serialised, otherwise |max_value_| is serialised. | |
97 void ToHandshakeMessage(CryptoHandshakeMessage* out) const override; | |
98 | |
99 // Sets |negotiated_value_| to the minimum of |max_value_| and the | |
100 // corresponding value from |peer_hello|. If the corresponding value is | |
101 // missing and PRESENCE_OPTIONAL then |negotiated_value_| is set to | |
102 // |default_value_|. | |
103 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello, | |
104 HelloType hello_type, | |
105 std::string* error_details) override; | |
106 | |
107 private: | |
108 uint32_t max_value_; | |
109 uint32_t default_value_; | |
110 uint32_t negotiated_value_; | |
111 }; | |
112 | |
113 class NET_EXPORT_PRIVATE QuicNegotiableTag : public QuicNegotiableValue { | |
114 public: | |
115 QuicNegotiableTag(QuicTag name, QuicConfigPresence presence); | |
116 ~QuicNegotiableTag() override; | |
117 | |
118 // Sets the possible values that |negotiated_tag_| can take after negotiation | |
119 // and the default value that |negotiated_tag_| takes if OPTIONAL and *HLO | |
120 // msg doesn't contain tag |name_|. | |
121 void set(const QuicTagVector& possible_values, QuicTag default_value); | |
122 | |
123 // Serialises |name_| and vector (either possible or negotiated) to |out|. If | |
124 // |negotiated_| is true then |negotiated_tag_| is serialised, otherwise | |
125 // |possible_values_| is serialised. | |
126 void ToHandshakeMessage(CryptoHandshakeMessage* out) const override; | |
127 | |
128 // Selects the tag common to both tags in |client_hello| for |name_| and | |
129 // |possible_values_| with preference to tag in |possible_values_|. The | |
130 // selected tag is set as |negotiated_tag_|. | |
131 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello, | |
132 HelloType hello_type, | |
133 std::string* error_details) override; | |
134 | |
135 private: | |
136 // Reads the vector corresponding to |name_| from |msg| into |out|. If the | |
137 // |name_| is absent in |msg| and |presence_| is set to OPTIONAL |out| is set | |
138 // to |possible_values_|. | |
139 QuicErrorCode ReadVector(const CryptoHandshakeMessage& msg, | |
140 const QuicTag** out, | |
141 size_t* out_length, | |
142 std::string* error_details) const; | |
143 | |
144 QuicTag negotiated_tag_; | |
145 QuicTagVector possible_values_; | |
146 QuicTag default_value_; | |
147 }; | |
148 | |
149 // Stores uint32_t from CHLO or SHLO messages that are not negotiated. | |
150 class NET_EXPORT_PRIVATE QuicFixedUint32 : public QuicConfigValue { | |
151 public: | |
152 QuicFixedUint32(QuicTag name, QuicConfigPresence presence); | |
153 ~QuicFixedUint32() override; | |
154 | |
155 bool HasSendValue() const; | |
156 | |
157 uint32_t GetSendValue() const; | |
158 | |
159 void SetSendValue(uint32_t value); | |
160 | |
161 bool HasReceivedValue() const; | |
162 | |
163 uint32_t GetReceivedValue() const; | |
164 | |
165 void SetReceivedValue(uint32_t value); | |
166 | |
167 // If has_send_value is true, serialises |tag_| and |send_value_| to |out|. | |
168 void ToHandshakeMessage(CryptoHandshakeMessage* out) const override; | |
169 | |
170 // Sets |value_| to the corresponding value from |peer_hello_| if it exists. | |
171 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello, | |
172 HelloType hello_type, | |
173 std::string* error_details) override; | |
174 | |
175 private: | |
176 uint32_t send_value_; | |
177 bool has_send_value_; | |
178 uint32_t receive_value_; | |
179 bool has_receive_value_; | |
180 }; | |
181 | |
182 // Stores tag from CHLO or SHLO messages that are not negotiated. | |
183 class NET_EXPORT_PRIVATE QuicFixedTagVector : public QuicConfigValue { | |
184 public: | |
185 QuicFixedTagVector(QuicTag name, QuicConfigPresence presence); | |
186 QuicFixedTagVector(const QuicFixedTagVector& other); | |
187 ~QuicFixedTagVector() override; | |
188 | |
189 bool HasSendValues() const; | |
190 | |
191 QuicTagVector GetSendValues() const; | |
192 | |
193 void SetSendValues(const QuicTagVector& values); | |
194 | |
195 bool HasReceivedValues() const; | |
196 | |
197 QuicTagVector GetReceivedValues() const; | |
198 | |
199 void SetReceivedValues(const QuicTagVector& values); | |
200 | |
201 // If has_send_value is true, serialises |tag_vector_| and |send_value_| to | |
202 // |out|. | |
203 void ToHandshakeMessage(CryptoHandshakeMessage* out) const override; | |
204 | |
205 // Sets |receive_values_| to the corresponding value from |client_hello_| if | |
206 // it exists. | |
207 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello, | |
208 HelloType hello_type, | |
209 std::string* error_details) override; | |
210 | |
211 private: | |
212 QuicTagVector send_values_; | |
213 bool has_send_values_; | |
214 QuicTagVector receive_values_; | |
215 bool has_receive_values_; | |
216 }; | |
217 | |
218 // Stores IPEndPoint from CHLO or SHLO messages that are not negotiated. | |
219 class NET_EXPORT_PRIVATE QuicFixedIPEndPoint : public QuicConfigValue { | |
220 public: | |
221 QuicFixedIPEndPoint(QuicTag tag, QuicConfigPresence presence); | |
222 ~QuicFixedIPEndPoint() override; | |
223 | |
224 bool HasSendValue() const; | |
225 | |
226 const IPEndPoint& GetSendValue() const; | |
227 | |
228 void SetSendValue(const IPEndPoint& value); | |
229 | |
230 bool HasReceivedValue() const; | |
231 | |
232 const IPEndPoint& GetReceivedValue() const; | |
233 | |
234 void SetReceivedValue(const IPEndPoint& value); | |
235 | |
236 void ToHandshakeMessage(CryptoHandshakeMessage* out) const override; | |
237 | |
238 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello, | |
239 HelloType hello_type, | |
240 std::string* error_details) override; | |
241 | |
242 private: | |
243 IPEndPoint send_value_; | |
244 bool has_send_value_; | |
245 IPEndPoint receive_value_; | |
246 bool has_receive_value_; | |
247 }; | |
248 | |
249 // QuicConfig contains non-crypto configuration options that are negotiated in | |
250 // the crypto handshake. | |
251 class NET_EXPORT_PRIVATE QuicConfig { | |
252 public: | |
253 QuicConfig(); | |
254 QuicConfig(const QuicConfig& other); | |
255 ~QuicConfig(); | |
256 | |
257 void SetConnectionOptionsToSend(const QuicTagVector& connection_options); | |
258 | |
259 bool HasReceivedConnectionOptions() const; | |
260 | |
261 // Sets initial received connection options. All received connection options | |
262 // will be initialized with these fields. Initial received options may only be | |
263 // set once per config, prior to the setting of any other options. If options | |
264 // have already been set (either by previous calls or via handshake), this | |
265 // function does nothing and returns false. | |
266 bool SetInitialReceivedConnectionOptions(const QuicTagVector& tags); | |
267 | |
268 QuicTagVector ReceivedConnectionOptions() const; | |
269 | |
270 bool HasSendConnectionOptions() const; | |
271 | |
272 QuicTagVector SendConnectionOptions() const; | |
273 | |
274 // Returns true if the client is sending or the server has received a | |
275 // connection option. | |
276 bool HasClientSentConnectionOption(QuicTag tag, | |
277 Perspective perspective) const; | |
278 | |
279 void SetIdleConnectionStateLifetime( | |
280 QuicTime::Delta max_idle_connection_state_lifetime, | |
281 QuicTime::Delta default_idle_conection_state_lifetime); | |
282 | |
283 QuicTime::Delta IdleConnectionStateLifetime() const; | |
284 | |
285 void SetSilentClose(bool silent_close); | |
286 | |
287 bool SilentClose() const; | |
288 | |
289 void SetMaxStreamsPerConnection(size_t max_streams, size_t default_streams); | |
290 | |
291 uint32_t MaxStreamsPerConnection() const; | |
292 | |
293 void SetMaxIncomingDynamicStreamsToSend( | |
294 uint32_t max_incoming_dynamic_streams); | |
295 | |
296 uint32_t GetMaxIncomingDynamicStreamsToSend(); | |
297 | |
298 bool HasReceivedMaxIncomingDynamicStreams(); | |
299 | |
300 uint32_t ReceivedMaxIncomingDynamicStreams(); | |
301 | |
302 void set_max_time_before_crypto_handshake( | |
303 QuicTime::Delta max_time_before_crypto_handshake) { | |
304 max_time_before_crypto_handshake_ = max_time_before_crypto_handshake; | |
305 } | |
306 | |
307 QuicTime::Delta max_time_before_crypto_handshake() const { | |
308 return max_time_before_crypto_handshake_; | |
309 } | |
310 | |
311 void set_max_idle_time_before_crypto_handshake( | |
312 QuicTime::Delta max_idle_time_before_crypto_handshake) { | |
313 max_idle_time_before_crypto_handshake_ = | |
314 max_idle_time_before_crypto_handshake; | |
315 } | |
316 | |
317 QuicTime::Delta max_idle_time_before_crypto_handshake() const { | |
318 return max_idle_time_before_crypto_handshake_; | |
319 } | |
320 | |
321 void set_max_undecryptable_packets(size_t max_undecryptable_packets) { | |
322 max_undecryptable_packets_ = max_undecryptable_packets; | |
323 } | |
324 | |
325 size_t max_undecryptable_packets() const { | |
326 return max_undecryptable_packets_; | |
327 } | |
328 | |
329 bool HasSetBytesForConnectionIdToSend() const; | |
330 | |
331 // Sets the peer's connection id length, in bytes. | |
332 void SetBytesForConnectionIdToSend(uint32_t bytes); | |
333 | |
334 bool HasReceivedBytesForConnectionId() const; | |
335 | |
336 uint32_t ReceivedBytesForConnectionId() const; | |
337 | |
338 // Sets an estimated initial round trip time in us. | |
339 void SetInitialRoundTripTimeUsToSend(uint32_t rtt_us); | |
340 | |
341 bool HasReceivedInitialRoundTripTimeUs() const; | |
342 | |
343 uint32_t ReceivedInitialRoundTripTimeUs() const; | |
344 | |
345 bool HasInitialRoundTripTimeUsToSend() const; | |
346 | |
347 uint32_t GetInitialRoundTripTimeUsToSend() const; | |
348 | |
349 // Sets an initial stream flow control window size to transmit to the peer. | |
350 void SetInitialStreamFlowControlWindowToSend(uint32_t window_bytes); | |
351 | |
352 uint32_t GetInitialStreamFlowControlWindowToSend() const; | |
353 | |
354 bool HasReceivedInitialStreamFlowControlWindowBytes() const; | |
355 | |
356 uint32_t ReceivedInitialStreamFlowControlWindowBytes() const; | |
357 | |
358 // Sets an initial session flow control window size to transmit to the peer. | |
359 void SetInitialSessionFlowControlWindowToSend(uint32_t window_bytes); | |
360 | |
361 uint32_t GetInitialSessionFlowControlWindowToSend() const; | |
362 | |
363 bool HasReceivedInitialSessionFlowControlWindowBytes() const; | |
364 | |
365 uint32_t ReceivedInitialSessionFlowControlWindowBytes() const; | |
366 | |
367 // Sets socket receive buffer to transmit to the peer. | |
368 void SetSocketReceiveBufferToSend(uint32_t window_bytes); | |
369 | |
370 bool HasReceivedSocketReceiveBuffer() const; | |
371 | |
372 uint32_t ReceivedSocketReceiveBuffer() const; | |
373 | |
374 void SetMultipathEnabled(bool multipath_enabled); | |
375 | |
376 bool MultipathEnabled() const; | |
377 | |
378 void SetDisableConnectionMigration(); | |
379 | |
380 bool DisableConnectionMigration() const; | |
381 | |
382 void SetAlternateServerAddressToSend( | |
383 const IPEndPoint& alternate_server_address); | |
384 | |
385 bool HasReceivedAlternateServerAddress() const; | |
386 | |
387 const IPEndPoint& ReceivedAlternateServerAddress() const; | |
388 | |
389 void SetForceHolBlocking(); | |
390 | |
391 bool ForceHolBlocking(Perspective perspective) const; | |
392 | |
393 bool negotiated() const; | |
394 | |
395 // ToHandshakeMessage serialises the settings in this object as a series of | |
396 // tags /value pairs and adds them to |out|. | |
397 void ToHandshakeMessage(CryptoHandshakeMessage* out) const; | |
398 | |
399 // Calls ProcessPeerHello on each negotiable parameter. On failure returns | |
400 // the corresponding QuicErrorCode and sets detailed error in |error_details|. | |
401 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello, | |
402 HelloType hello_type, | |
403 std::string* error_details); | |
404 | |
405 private: | |
406 friend class test::QuicConfigPeer; | |
407 | |
408 // SetDefaults sets the members to sensible, default values. | |
409 void SetDefaults(); | |
410 | |
411 // Configurations options that are not negotiated. | |
412 // Maximum time the session can be alive before crypto handshake is finished. | |
413 QuicTime::Delta max_time_before_crypto_handshake_; | |
414 // Maximum idle time before the crypto handshake has completed. | |
415 QuicTime::Delta max_idle_time_before_crypto_handshake_; | |
416 // Maximum number of undecryptable packets stored before CHLO/SHLO. | |
417 size_t max_undecryptable_packets_; | |
418 | |
419 // Connection options. | |
420 QuicFixedTagVector connection_options_; | |
421 // Idle connection state lifetime | |
422 QuicNegotiableUint32 idle_connection_state_lifetime_seconds_; | |
423 // Whether to use silent close. Defaults to 0 (false) and is otherwise true. | |
424 QuicNegotiableUint32 silent_close_; | |
425 // Maximum number of streams that the connection can support. | |
426 // TODO(rjshade): Remove when removing QUIC_VERSION_34 | |
427 QuicNegotiableUint32 max_streams_per_connection_; | |
428 // Maximum number of incoming dynamic streams that the connection can support. | |
429 QuicFixedUint32 max_incoming_dynamic_streams_; | |
430 // The number of bytes required for the connection ID. | |
431 QuicFixedUint32 bytes_for_connection_id_; | |
432 // Initial round trip time estimate in microseconds. | |
433 QuicFixedUint32 initial_round_trip_time_us_; | |
434 | |
435 // Initial stream flow control receive window in bytes. | |
436 QuicFixedUint32 initial_stream_flow_control_window_bytes_; | |
437 // Initial session flow control receive window in bytes. | |
438 QuicFixedUint32 initial_session_flow_control_window_bytes_; | |
439 | |
440 // Socket receive buffer in bytes. | |
441 // TODO(ianswett): Deprecate once QUIC_VERSION_34 is deprecated. | |
442 QuicFixedUint32 socket_receive_buffer_; | |
443 | |
444 // Whether to support multipath for this connection. | |
445 QuicNegotiableUint32 multipath_enabled_; | |
446 | |
447 // Whether tell peer not to attempt connection migration. | |
448 QuicFixedUint32 connection_migration_disabled_; | |
449 | |
450 // An alternate server address the client could connect to. | |
451 QuicFixedIPEndPoint alternate_server_address_; | |
452 | |
453 // Force HOL blocking for measurement purposes. | |
454 QuicFixedUint32 force_hol_blocking_; | |
455 }; | |
456 | |
457 } // namespace net | |
458 | |
459 #endif // NET_QUIC_QUIC_CONFIG_H_ | |
OLD | NEW |