blob: 19d7abcf1f01b2974b2a1529f1cc8e09c8b5ee3a [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2012 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// A server side dispatcher which dispatches a given client's data to their
6// stream.
7
8#ifndef QUICHE_QUIC_CORE_QUIC_DISPATCHER_H_
9#define QUICHE_QUIC_CORE_QUIC_DISPATCHER_H_
10
11#include <memory>
vasilvv872e7a32019-03-12 16:42:44 -070012#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050013#include <vector>
14
vasilvvc872ee42020-10-07 19:50:22 -070015#include "absl/strings/string_view.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050016#include "net/third_party/quiche/src/quic/core/crypto/quic_compressed_certs_cache.h"
17#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
18#include "net/third_party/quiche/src/quic/core/quic_blocked_writer_interface.h"
19#include "net/third_party/quiche/src/quic/core/quic_buffered_packet_store.h"
20#include "net/third_party/quiche/src/quic/core/quic_connection.h"
nharperf6cb54d2020-02-27 14:14:21 -080021#include "net/third_party/quiche/src/quic/core/quic_crypto_server_stream_base.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050022#include "net/third_party/quiche/src/quic/core/quic_packets.h"
23#include "net/third_party/quiche/src/quic/core/quic_process_packet_interface.h"
24#include "net/third_party/quiche/src/quic/core/quic_session.h"
25#include "net/third_party/quiche/src/quic/core/quic_time_wait_list_manager.h"
26#include "net/third_party/quiche/src/quic/core/quic_version_manager.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050027#include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
28#include "net/third_party/quiche/src/quic/platform/api/quic_socket_address.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050029
30namespace quic {
31namespace test {
32class QuicDispatcherPeer;
33} // namespace test
34
35class QuicConfig;
36class QuicCryptoServerConfig;
37
dschinazie2116422019-10-29 11:54:26 -070038class QUIC_NO_EXPORT QuicDispatcher
dschinazif25169a2019-10-23 08:12:18 -070039 : public QuicTimeWaitListManager::Visitor,
40 public ProcessPacketInterface,
41 public QuicBufferedPacketStore::VisitorInterface {
QUICHE teama6ef0a62019-03-07 20:34:33 -050042 public:
43 // Ideally we'd have a linked_hash_set: the boolean is unused.
44 typedef QuicLinkedHashMap<QuicBlockedWriterInterface*, bool> WriteBlockedList;
45
nharper5f23a2d2020-02-20 10:44:09 -080046 QuicDispatcher(
47 const QuicConfig* config,
48 const QuicCryptoServerConfig* crypto_config,
49 QuicVersionManager* version_manager,
50 std::unique_ptr<QuicConnectionHelperInterface> helper,
51 std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
52 std::unique_ptr<QuicAlarmFactory> alarm_factory,
53 uint8_t expected_server_connection_id_length);
QUICHE teama6ef0a62019-03-07 20:34:33 -050054 QuicDispatcher(const QuicDispatcher&) = delete;
55 QuicDispatcher& operator=(const QuicDispatcher&) = delete;
56
57 ~QuicDispatcher() override;
58
59 // Takes ownership of |writer|.
60 void InitializeWithWriter(QuicPacketWriter* writer);
61
62 // Process the incoming packet by creating a new session, passing it to
63 // an existing session, or passing it to the time wait list.
64 void ProcessPacket(const QuicSocketAddress& self_address,
65 const QuicSocketAddress& peer_address,
66 const QuicReceivedPacket& packet) override;
67
68 // Called when the socket becomes writable to allow queued writes to happen.
69 virtual void OnCanWrite();
70
71 // Returns true if there's anything in the blocked writer list.
72 virtual bool HasPendingWrites() const;
73
74 // Sends ConnectionClose frames to all connected clients.
75 void Shutdown();
76
77 // QuicSession::Visitor interface implementation (via inheritance of
78 // QuicTimeWaitListManager::Visitor):
79 // Ensure that the closed connection is cleaned up asynchronously.
dschinazi7b9278c2019-05-20 07:36:21 -070080 void OnConnectionClosed(QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -050081 QuicErrorCode error,
vasilvvc48c8712019-03-11 13:38:16 -070082 const std::string& error_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -050083 ConnectionCloseSource source) override;
84
85 // QuicSession::Visitor interface implementation (via inheritance of
86 // QuicTimeWaitListManager::Visitor):
87 // Queues the blocked writer for later resumption.
88 void OnWriteBlocked(QuicBlockedWriterInterface* blocked_writer) override;
89
90 // QuicSession::Visitor interface implementation (via inheritance of
91 // QuicTimeWaitListManager::Visitor):
92 // Collects reset error code received on streams.
93 void OnRstStreamReceived(const QuicRstStreamFrame& frame) override;
94
95 // QuicSession::Visitor interface implementation (via inheritance of
96 // QuicTimeWaitListManager::Visitor):
97 // Collects reset error code received on streams.
98 void OnStopSendingReceived(const QuicStopSendingFrame& frame) override;
99
100 // QuicTimeWaitListManager::Visitor interface implementation
101 // Called whenever the time wait list manager adds a new connection to the
102 // time-wait list.
dschinazi7b9278c2019-05-20 07:36:21 -0700103 void OnConnectionAddedToTimeWaitList(
104 QuicConnectionId server_connection_id) override;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500105
wub05c3b782020-05-27 07:33:17 -0700106 using SessionMap = QuicHashMap<QuicConnectionId,
107 std::unique_ptr<QuicSession>,
108 QuicConnectionIdHash>;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500109
110 const SessionMap& session_map() const { return session_map_; }
111
112 // Deletes all sessions on the closed session list and clears the list.
113 virtual void DeleteSessions();
114
wub05c3b782020-05-27 07:33:17 -0700115 using ConnectionIdMap =
116 QuicHashMap<QuicConnectionId, QuicConnectionId, QuicConnectionIdHash>;
QUICHE teamc65d1d12019-03-19 20:58:04 -0700117
QUICHE teama6ef0a62019-03-07 20:34:33 -0500118 // QuicBufferedPacketStore::VisitorInterface implementation.
dschinazi7b9278c2019-05-20 07:36:21 -0700119 void OnExpiredPackets(QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500120 QuicBufferedPacketStore::BufferedPacketList
121 early_arrived_packets) override;
122
123 // Create connections for previously buffered CHLOs as many as allowed.
124 virtual void ProcessBufferedChlos(size_t max_connections_to_create);
125
126 // Return true if there is CHLO buffered.
127 virtual bool HasChlosBuffered() const;
128
danzh72e0dab2020-03-05 20:00:50 -0800129 // Start accepting new ConnectionIds.
130 void StartAcceptingNewConnections();
131
132 // Stop accepting new ConnectionIds, either as a part of the lame
133 // duck process or because explicitly configured.
134 void StopAcceptingNewConnections();
135
136 bool accept_new_connections() const { return accept_new_connections_; }
137
QUICHE teama6ef0a62019-03-07 20:34:33 -0500138 protected:
wub89490e02019-12-12 12:45:58 -0800139 virtual std::unique_ptr<QuicSession> CreateQuicSession(
140 QuicConnectionId server_connection_id,
wub4e3fb902020-07-15 13:37:29 -0700141 const QuicSocketAddress& self_address,
wub89490e02019-12-12 12:45:58 -0800142 const QuicSocketAddress& peer_address,
vasilvvc872ee42020-10-07 19:50:22 -0700143 absl::string_view alpn,
wub89490e02019-12-12 12:45:58 -0800144 const ParsedQuicVersion& version) = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500145
fayang91475c42019-06-19 08:04:26 -0700146 // Tries to validate and dispatch packet based on available information.
147 // Returns true if packet is dropped or successfully dispatched (e.g.,
148 // processed by existing session, processed by time wait list, etc.),
149 // otherwise, returns false and the packet needs further processing.
fayang1ed1f762019-06-24 11:40:04 -0700150 virtual bool MaybeDispatchPacket(const ReceivedPacketInfo& packet_info);
fayang91475c42019-06-19 08:04:26 -0700151
wub662a3d62019-08-16 14:10:50 -0700152 // Generate a connection ID with a length that is expected by the dispatcher.
dschinazi8963f602020-05-15 13:14:16 -0700153 // Called only when |server_connection_id| is shorter than
154 // |expected_connection_id_length|.
dschinaziadc75072019-08-19 10:54:45 -0700155 // Note that this MUST produce a deterministic result (calling this method
156 // with two connection IDs that are equal must produce the same result).
dschinazi8963f602020-05-15 13:14:16 -0700157 // Note that this is not used in general operation because our default
158 // |expected_server_connection_id_length| is 8, and the IETF specification
159 // requires clients to use an initial length of at least 8. However, we
160 // allow disabling that requirement via
161 // |allow_short_initial_server_connection_ids_|.
162 virtual QuicConnectionId ReplaceShortServerConnectionId(
163 const ParsedQuicVersion& version,
164 const QuicConnectionId& server_connection_id,
165 uint8_t expected_server_connection_id_length) const;
166
167 // Generate a connection ID with a length that is expected by the dispatcher.
168 // Called only when |server_connection_id| is longer than
169 // |expected_connection_id_length|.
170 // Note that this MUST produce a deterministic result (calling this method
171 // with two connection IDs that are equal must produce the same result).
172 virtual QuicConnectionId ReplaceLongServerConnectionId(
173 const ParsedQuicVersion& version,
174 const QuicConnectionId& server_connection_id,
175 uint8_t expected_server_connection_id_length) const;
wub662a3d62019-08-16 14:10:50 -0700176
QUICHE teama6ef0a62019-03-07 20:34:33 -0500177 // Values to be returned by ValidityChecks() to indicate what should be done
fayangd057e662019-07-10 13:29:41 -0700178 // with a packet. Fates with greater values are considered to be higher
179 // priority. ValidityChecks should return fate based on the priority order
180 // (i.e., returns higher priority fate first)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500181 enum QuicPacketFate {
182 // Process the packet normally, which is usually to establish a connection.
183 kFateProcess,
184 // Put the connection ID into time-wait state and send a public reset.
185 kFateTimeWait,
fayangd057e662019-07-10 13:29:41 -0700186 // Drop the packet.
187 kFateDrop,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500188 };
189
fayang91475c42019-06-19 08:04:26 -0700190 // This method is called by ProcessHeader on packets not associated with a
191 // known connection ID. It applies validity checks and returns a
QUICHE teama6ef0a62019-03-07 20:34:33 -0500192 // QuicPacketFate to tell what should be done with the packet.
fayang1ed1f762019-06-24 11:40:04 -0700193 // TODO(fayang): Merge ValidityChecks into MaybeDispatchPacket.
194 virtual QuicPacketFate ValidityChecks(const ReceivedPacketInfo& packet_info);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500195
196 // Create and return the time wait list manager for this dispatcher, which
197 // will be owned by the dispatcher as time_wait_list_manager_
198 virtual QuicTimeWaitListManager* CreateQuicTimeWaitListManager();
199
fayang1ed1f762019-06-24 11:40:04 -0700200 // Buffers packet until it can be delivered to a connection.
201 void BufferEarlyPacket(const ReceivedPacketInfo& packet_info);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500202
fayang1ed1f762019-06-24 11:40:04 -0700203 // Called when |packet_info| is a CHLO packet. Creates a new connection and
204 // delivers any buffered packets for that connection id.
dschinazi0e3c3482020-04-24 11:37:20 -0700205 void ProcessChlo(const std::vector<std::string>& alpns,
206 ReceivedPacketInfo* packet_info);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500207
208 // Return true if dispatcher wants to destroy session outside of
209 // OnConnectionClosed() call stack.
210 virtual bool ShouldDestroySessionAsynchronously();
211
212 QuicTimeWaitListManager* time_wait_list_manager() {
213 return time_wait_list_manager_.get();
214 }
215
216 const QuicTransportVersionVector& GetSupportedTransportVersions();
217
218 const ParsedQuicVersionVector& GetSupportedVersions();
219
fayange4524052020-04-03 09:09:20 -0700220 const ParsedQuicVersionVector& GetSupportedVersionsWithQuicCrypto();
221
QUICHE teama6ef0a62019-03-07 20:34:33 -0500222 const QuicConfig& config() const { return *config_; }
223
224 const QuicCryptoServerConfig* crypto_config() const { return crypto_config_; }
225
226 QuicCompressedCertsCache* compressed_certs_cache() {
227 return &compressed_certs_cache_;
228 }
229
230 QuicConnectionHelperInterface* helper() { return helper_.get(); }
231
nharper5f23a2d2020-02-20 10:44:09 -0800232 QuicCryptoServerStreamBase::Helper* session_helper() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500233 return session_helper_.get();
234 }
235
236 QuicAlarmFactory* alarm_factory() { return alarm_factory_.get(); }
237
238 QuicPacketWriter* writer() { return writer_.get(); }
239
240 // Returns true if a session should be created for a connection with an
241 // unknown version identified by |version_label|.
242 virtual bool ShouldCreateSessionForUnknownVersion(
243 QuicVersionLabel version_label);
244
245 void SetLastError(QuicErrorCode error);
246
fayang91475c42019-06-19 08:04:26 -0700247 // Called by MaybeDispatchPacket when current packet cannot be dispatched.
248 // Used by subclasses to conduct specific logic to dispatch packet. Returns
249 // true if packet is successfully dispatched.
fayang1ed1f762019-06-24 11:40:04 -0700250 virtual bool OnFailedToDispatchPacket(const ReceivedPacketInfo& packet_info);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500251
252 // Called when a new connection starts to be handled by this dispatcher.
253 // Either this connection is created or its packets is buffered while waiting
254 // for CHLO. Returns true if a new connection should be created or its packets
255 // should be buffered, false otherwise.
256 virtual bool ShouldCreateOrBufferPacketForConnection(
fayang1ed1f762019-06-24 11:40:04 -0700257 const ReceivedPacketInfo& packet_info);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500258
dschinazi7b9278c2019-05-20 07:36:21 -0700259 bool HasBufferedPackets(QuicConnectionId server_connection_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500260
261 // Called when BufferEarlyPacket() fail to buffer the packet.
262 virtual void OnBufferPacketFailure(
263 QuicBufferedPacketStore::EnqueuePacketResult result,
dschinazi7b9278c2019-05-20 07:36:21 -0700264 QuicConnectionId server_connection_id);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500265
266 // Removes the session from the session map and write blocked list, and adds
wub5f64ec42019-06-06 07:31:19 -0700267 // the ConnectionId to the time-wait list.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500268 virtual void CleanUpSession(SessionMap::iterator it,
269 QuicConnection* connection,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500270 ConnectionCloseSource source);
271
QUICHE teama6ef0a62019-03-07 20:34:33 -0500272 // Called to terminate a connection statelessly. Depending on |format|, either
273 // 1) send connection close with |error_code| and |error_details| and add
274 // connection to time wait list or 2) directly add connection to time wait
275 // list with |action|.
276 void StatelesslyTerminateConnection(
dschinazi7b9278c2019-05-20 07:36:21 -0700277 QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500278 PacketHeaderFormat format,
fayang1de67892019-04-19 05:59:45 -0700279 bool version_flag,
dschinazi48ac9192019-07-31 00:07:26 -0700280 bool use_length_prefix,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500281 ParsedQuicVersion version,
282 QuicErrorCode error_code,
vasilvvc48c8712019-03-11 13:38:16 -0700283 const std::string& error_details,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500284 QuicTimeWaitListManager::TimeWaitAction action);
285
wub2a5670f2019-06-13 13:39:16 -0700286 // Save/Restore per packet context.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500287 virtual std::unique_ptr<QuicPerPacketContext> GetPerPacketContext() const;
288 virtual void RestorePerPacketContext(
289 std::unique_ptr<QuicPerPacketContext> /*context*/) {}
290
QUICHE team4d9d6292019-03-11 14:25:33 -0700291 // If true, our framer will change its expected connection ID length
292 // to the received destination connection ID length of all IETF long headers.
dschinazi8ff74822019-05-28 16:37:20 -0700293 void SetShouldUpdateExpectedServerConnectionIdLength(
294 bool should_update_expected_server_connection_id_length) {
dschinazi8ff74822019-05-28 16:37:20 -0700295 should_update_expected_server_connection_id_length_ =
296 should_update_expected_server_connection_id_length;
QUICHE team4d9d6292019-03-11 14:25:33 -0700297 }
298
QUICHE team963d57e2019-03-21 10:58:47 -0700299 // If true, the dispatcher will allow incoming initial packets that have
dschinazi7b9278c2019-05-20 07:36:21 -0700300 // destination connection IDs shorter than 64 bits.
301 void SetAllowShortInitialServerConnectionIds(
302 bool allow_short_initial_server_connection_ids) {
303 allow_short_initial_server_connection_ids_ =
304 allow_short_initial_server_connection_ids;
QUICHE team963d57e2019-03-21 10:58:47 -0700305 }
306
danzh72e0dab2020-03-05 20:00:50 -0800307 // Called if a packet from an unseen connection is reset or rejected.
308 virtual void OnNewConnectionRejected() {}
309
dschinazi71116fd2020-04-22 16:07:04 -0700310 // Selects the preferred ALPN from a vector of ALPNs.
311 // This runs through the list of ALPNs provided by the client and picks the
312 // first one it supports. If no supported versions are found, the first
313 // element of the vector is returned.
314 std::string SelectAlpn(const std::vector<std::string>& alpns);
315
dschinazi7e098ae2020-05-12 10:25:15 -0700316 // If the connection ID length is different from what the dispatcher expects,
dschinazi8963f602020-05-15 13:14:16 -0700317 // replace the connection ID with one of the right length.
318 // Note that this MUST produce a deterministic result (calling this method
319 // with two connection IDs that are equal must produce the same result).
dschinazi7e098ae2020-05-12 10:25:15 -0700320 QuicConnectionId MaybeReplaceServerConnectionId(
dschinazi8963f602020-05-15 13:14:16 -0700321 const QuicConnectionId& server_connection_id,
322 const ParsedQuicVersion& version) const;
dschinazi7e098ae2020-05-12 10:25:15 -0700323
QUICHE team4feadcf2020-10-20 12:54:35 -0700324 // Sends public/stateless reset packets with no version and unknown
325 // connection ID according to the packet's size.
326 virtual void MaybeResetPacketsWithNoVersion(
327 const quic::ReceivedPacketInfo& packet_info);
328
QUICHE teama6ef0a62019-03-07 20:34:33 -0500329 private:
330 friend class test::QuicDispatcherPeer;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500331
fayang1ed1f762019-06-24 11:40:04 -0700332 // TODO(fayang): Consider to rename this function to
333 // ProcessValidatedPacketWithUnknownConnectionId.
334 void ProcessHeader(ReceivedPacketInfo* packet_info);
nharper55fa6132019-05-07 19:37:21 -0700335
QUICHE teama6ef0a62019-03-07 20:34:33 -0500336 // Deliver |packets| to |session| for further processing.
337 void DeliverPacketsToSession(
338 const std::list<QuicBufferedPacketStore::BufferedPacket>& packets,
339 QuicSession* session);
340
fayangccbab732019-05-13 10:11:25 -0700341 // Returns true if |version| is a supported protocol version.
342 bool IsSupportedVersion(const ParsedQuicVersion version);
343
QUICHE teama6ef0a62019-03-07 20:34:33 -0500344 const QuicConfig* config_;
345
346 const QuicCryptoServerConfig* crypto_config_;
347
348 // The cache for most recently compressed certs.
349 QuicCompressedCertsCache compressed_certs_cache_;
350
351 // The list of connections waiting to write.
352 WriteBlockedList write_blocked_list_;
353
354 SessionMap session_map_;
355
356 // Entity that manages connection_ids in time wait state.
357 std::unique_ptr<QuicTimeWaitListManager> time_wait_list_manager_;
358
359 // The list of closed but not-yet-deleted sessions.
360 std::vector<std::unique_ptr<QuicSession>> closed_session_list_;
361
362 // The helper used for all connections.
363 std::unique_ptr<QuicConnectionHelperInterface> helper_;
364
365 // The helper used for all sessions.
nharper5f23a2d2020-02-20 10:44:09 -0800366 std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500367
368 // Creates alarms.
369 std::unique_ptr<QuicAlarmFactory> alarm_factory_;
370
371 // An alarm which deletes closed sessions.
372 std::unique_ptr<QuicAlarm> delete_sessions_alarm_;
373
374 // The writer to write to the socket with.
375 std::unique_ptr<QuicPacketWriter> writer_;
376
377 // Packets which are buffered until a connection can be created to handle
378 // them.
379 QuicBufferedPacketStore buffered_packets_;
380
QUICHE teama6ef0a62019-03-07 20:34:33 -0500381 // Used to get the supported versions based on flag. Does not own.
382 QuicVersionManager* version_manager_;
383
fayang1ed1f762019-06-24 11:40:04 -0700384 // The last error set by SetLastError().
385 // TODO(fayang): consider removing last_error_.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500386 QuicErrorCode last_error_;
387
388 // A backward counter of how many new sessions can be create within current
389 // event loop. When reaches 0, it means can't create sessions for now.
390 int16_t new_sessions_allowed_per_event_loop_;
391
danzh72e0dab2020-03-05 20:00:50 -0800392 // True if this dispatcher is accepting new ConnectionIds (new client
393 // connections), false otherwise.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500394 bool accept_new_connections_;
QUICHE team963d57e2019-03-21 10:58:47 -0700395
396 // If false, the dispatcher follows the IETF spec and rejects packets with
dschinazi7b9278c2019-05-20 07:36:21 -0700397 // invalid destination connection IDs lengths below 64 bits.
398 // If true they are allowed.
399 bool allow_short_initial_server_connection_ids_;
fayangccbab732019-05-13 10:11:25 -0700400
fayangccbab732019-05-13 10:11:25 -0700401 // IETF short headers contain a destination connection ID but do not
402 // encode its length. This variable contains the length we expect to read.
403 // This is also used to signal an error when a long header packet with
404 // different destination connection ID length is received when
dschinazi8ff74822019-05-28 16:37:20 -0700405 // should_update_expected_server_connection_id_length_ is false and packet's
fayang1ed1f762019-06-24 11:40:04 -0700406 // version does not allow variable length connection ID.
dschinazi8ff74822019-05-28 16:37:20 -0700407 uint8_t expected_server_connection_id_length_;
fayangccbab732019-05-13 10:11:25 -0700408
dschinazi8ff74822019-05-28 16:37:20 -0700409 // If true, change expected_server_connection_id_length_ to be the received
fayang1ed1f762019-06-24 11:40:04 -0700410 // destination connection ID length of all IETF long headers.
dschinazi8ff74822019-05-28 16:37:20 -0700411 bool should_update_expected_server_connection_id_length_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500412};
413
414} // namespace quic
415
416#endif // QUICHE_QUIC_CORE_QUIC_DISPATCHER_H_