Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* This Source Code Form is subject to the terms of the Mozilla Public
3 : * License, v. 2.0. If a copy of the MPL was not distributed with this
4 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 :
6 : #ifndef mozilla_net_Http2Session_h
7 : #define mozilla_net_Http2Session_h
8 :
9 : // HTTP/2 - RFC 7540
10 : // https://www.rfc-editor.org/rfc/rfc7540.txt
11 :
12 : #include "ASpdySession.h"
13 : #include "mozilla/Attributes.h"
14 : #include "mozilla/UniquePtr.h"
15 : #include "nsAHttpConnection.h"
16 : #include "nsClassHashtable.h"
17 : #include "nsDataHashtable.h"
18 : #include "nsDeque.h"
19 : #include "nsHashKeys.h"
20 :
21 : #include "Http2Compression.h"
22 :
23 : class nsISocketTransport;
24 :
25 : namespace mozilla {
26 : namespace net {
27 :
28 : class Http2PushedStream;
29 : class Http2Stream;
30 : class nsHttpTransaction;
31 :
32 : class Http2Session final : public ASpdySession
33 : , public nsAHttpConnection
34 : , public nsAHttpSegmentReader
35 : , public nsAHttpSegmentWriter
36 : {
37 : ~Http2Session();
38 :
39 : public:
40 : NS_DECL_THREADSAFE_ISUPPORTS
41 : NS_DECL_NSAHTTPTRANSACTION
42 0 : NS_DECL_NSAHTTPCONNECTION(mConnection)
43 : NS_DECL_NSAHTTPSEGMENTREADER
44 : NS_DECL_NSAHTTPSEGMENTWRITER
45 :
46 : Http2Session(nsISocketTransport *, uint32_t version, bool attemptingEarlyData);
47 :
48 : MOZ_MUST_USE bool AddStream(nsAHttpTransaction *, int32_t,
49 : bool, nsIInterfaceRequestor *) override;
50 0 : bool CanReuse() override { return !mShouldGoAway && !mClosed; }
51 : bool RoomForMoreStreams() override;
52 : uint32_t SpdyVersion() override;
53 : bool TestJoinConnection(const nsACString &hostname, int32_t port) override;
54 : bool JoinConnection(const nsACString &hostname, int32_t port) override;
55 :
56 : // When the connection is active this is called up to once every 1 second
57 : // return the interval (in seconds) that the connection next wants to
58 : // have this invoked. It might happen sooner depending on the needs of
59 : // other connections.
60 : uint32_t ReadTimeoutTick(PRIntervalTime now) override;
61 :
62 : // Idle time represents time since "goodput".. e.g. a data or header frame
63 : PRIntervalTime IdleTime() override;
64 :
65 : // Registering with a newID of 0 means pick the next available odd ID
66 : uint32_t RegisterStreamID(Http2Stream *, uint32_t aNewID = 0);
67 :
68 : /*
69 : HTTP/2 framing
70 :
71 : 0 1 2 3
72 : 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
73 : +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
74 : | Length (16) | Type (8) | Flags (8) |
75 : +-+-------------+---------------+-------------------------------+
76 : |R| Stream Identifier (31) |
77 : +-+-------------------------------------------------------------+
78 : | Frame Data (0...) ...
79 : +---------------------------------------------------------------+
80 : */
81 :
82 : enum FrameType {
83 : FRAME_TYPE_DATA = 0x0,
84 : FRAME_TYPE_HEADERS = 0x1,
85 : FRAME_TYPE_PRIORITY = 0x2,
86 : FRAME_TYPE_RST_STREAM = 0x3,
87 : FRAME_TYPE_SETTINGS = 0x4,
88 : FRAME_TYPE_PUSH_PROMISE = 0x5,
89 : FRAME_TYPE_PING = 0x6,
90 : FRAME_TYPE_GOAWAY = 0x7,
91 : FRAME_TYPE_WINDOW_UPDATE = 0x8,
92 : FRAME_TYPE_CONTINUATION = 0x9,
93 : FRAME_TYPE_ALTSVC = 0xA,
94 : FRAME_TYPE_UNUSED = 0xB,
95 : FRAME_TYPE_ORIGIN = 0xC,
96 : FRAME_TYPE_LAST = 0xD
97 : };
98 :
99 : // NO_ERROR is a macro defined on windows, so we'll name the HTTP2 goaway
100 : // code NO_ERROR to be NO_HTTP_ERROR
101 : enum errorType {
102 : NO_HTTP_ERROR = 0,
103 : PROTOCOL_ERROR = 1,
104 : INTERNAL_ERROR = 2,
105 : FLOW_CONTROL_ERROR = 3,
106 : SETTINGS_TIMEOUT_ERROR = 4,
107 : STREAM_CLOSED_ERROR = 5,
108 : FRAME_SIZE_ERROR = 6,
109 : REFUSED_STREAM_ERROR = 7,
110 : CANCEL_ERROR = 8,
111 : COMPRESSION_ERROR = 9,
112 : CONNECT_ERROR = 10,
113 : ENHANCE_YOUR_CALM = 11,
114 : INADEQUATE_SECURITY = 12,
115 : HTTP_1_1_REQUIRED = 13,
116 : UNASSIGNED = 31
117 : };
118 :
119 : // These are frame flags. If they, or other undefined flags, are
120 : // used on frames other than the comments indicate they MUST be ignored.
121 : const static uint8_t kFlag_END_STREAM = 0x01; // data, headers
122 : const static uint8_t kFlag_END_HEADERS = 0x04; // headers, continuation
123 : const static uint8_t kFlag_END_PUSH_PROMISE = 0x04; // push promise
124 : const static uint8_t kFlag_ACK = 0x01; // ping and settings
125 : const static uint8_t kFlag_PADDED = 0x08; // data, headers, push promise, continuation
126 : const static uint8_t kFlag_PRIORITY = 0x20; // headers
127 :
128 : enum {
129 : SETTINGS_TYPE_HEADER_TABLE_SIZE = 1, // compression table size
130 : SETTINGS_TYPE_ENABLE_PUSH = 2, // can be used to disable push
131 : SETTINGS_TYPE_MAX_CONCURRENT = 3, // streams recvr allowed to initiate
132 : SETTINGS_TYPE_INITIAL_WINDOW = 4, // bytes for flow control default
133 : SETTINGS_TYPE_MAX_FRAME_SIZE = 5 // max frame size settings sender allows receipt of
134 : };
135 :
136 : // This should be big enough to hold all of your control packets,
137 : // but if it needs to grow for huge headers it can do so dynamically.
138 : const static uint32_t kDefaultBufferSize = 2048;
139 :
140 : // kDefaultQueueSize must be >= other queue size constants
141 : const static uint32_t kDefaultQueueSize = 32768;
142 : const static uint32_t kQueueMinimumCleanup = 24576;
143 : const static uint32_t kQueueTailRoom = 4096;
144 : const static uint32_t kQueueReserved = 1024;
145 :
146 : const static uint32_t kMaxStreamID = 0x7800000;
147 :
148 : // This is a sentinel for a deleted stream. It is not a valid
149 : // 31 bit stream ID.
150 : const static uint32_t kDeadStreamID = 0xffffdead;
151 :
152 : // below the emergency threshold of local window we ack every received
153 : // byte. Above that we coalesce bytes into the MinimumToAck size.
154 : const static int32_t kEmergencyWindowThreshold = 256 * 1024;
155 : const static uint32_t kMinimumToAck = 4 * 1024 * 1024;
156 :
157 : // The default rwin is 64KB - 1 unless updated by a settings frame
158 : const static uint32_t kDefaultRwin = 65535;
159 :
160 : // We limit frames to 2^14 bytes of length in order to preserve responsiveness
161 : // This is the smallest allowed value for SETTINGS_MAX_FRAME_SIZE
162 : const static uint32_t kMaxFrameData = 0x4000;
163 :
164 : const static uint8_t kFrameLengthBytes = 3;
165 : const static uint8_t kFrameStreamIDBytes = 4;
166 : const static uint8_t kFrameFlagBytes = 1;
167 : const static uint8_t kFrameTypeBytes = 1;
168 : const static uint8_t kFrameHeaderBytes = kFrameLengthBytes + kFrameFlagBytes +
169 : kFrameTypeBytes + kFrameStreamIDBytes;
170 :
171 : enum {
172 : kLeaderGroupID = 0x3,
173 : kOtherGroupID = 0x5,
174 : kBackgroundGroupID = 0x7,
175 : kSpeculativeGroupID = 0x9,
176 : kFollowerGroupID = 0xB,
177 : kUrgentStartGroupID = 0xD
178 : // Hey, you! YES YOU! If you add/remove any groups here, you almost
179 : // certainly need to change the lookup of the stream/ID hash in
180 : // Http2Session::OnTransportStatus. Yeah, that's right. YOU!
181 : };
182 :
183 : static nsresult RecvHeaders(Http2Session *);
184 : static nsresult RecvPriority(Http2Session *);
185 : static nsresult RecvRstStream(Http2Session *);
186 : static nsresult RecvSettings(Http2Session *);
187 : static nsresult RecvPushPromise(Http2Session *);
188 : static nsresult RecvPing(Http2Session *);
189 : static nsresult RecvGoAway(Http2Session *);
190 : static nsresult RecvWindowUpdate(Http2Session *);
191 : static nsresult RecvContinuation(Http2Session *);
192 : static nsresult RecvAltSvc(Http2Session *);
193 : static nsresult RecvUnused(Http2Session *);
194 : static nsresult RecvOrigin(Http2Session *);
195 :
196 : char *EnsureOutputBuffer(uint32_t needed);
197 :
198 : template<typename charType>
199 : void CreateFrameHeader(charType dest, uint16_t frameLength,
200 : uint8_t frameType, uint8_t frameFlags,
201 : uint32_t streamID);
202 :
203 : // For writing the data stream to LOG4
204 : static void LogIO(Http2Session *, Http2Stream *, const char *,
205 : const char *, uint32_t);
206 :
207 : // overload of nsAHttpConnection
208 : void TransactionHasDataToWrite(nsAHttpTransaction *) override;
209 : void TransactionHasDataToRecv(nsAHttpTransaction *) override;
210 :
211 : // a similar version for Http2Stream
212 : void TransactionHasDataToWrite(Http2Stream *);
213 :
214 : // an overload of nsAHttpSegementReader
215 : virtual MOZ_MUST_USE nsresult CommitToSegmentSize(uint32_t size,
216 : bool forceCommitment) override;
217 : MOZ_MUST_USE nsresult BufferOutput(const char *, uint32_t, uint32_t *);
218 : void FlushOutputQueue();
219 0 : uint32_t AmountOfOutputBuffered() { return mOutputQueueUsed - mOutputQueueSent; }
220 :
221 0 : uint32_t GetServerInitialStreamWindow() { return mServerInitialStreamWindow; }
222 :
223 : MOZ_MUST_USE bool TryToActivate(Http2Stream *stream);
224 : void ConnectPushedStream(Http2Stream *stream);
225 : void ConnectSlowConsumer(Http2Stream *stream);
226 :
227 : MOZ_MUST_USE nsresult ConfirmTLSProfile();
228 : static MOZ_MUST_USE bool ALPNCallback(nsISupports *securityInfo);
229 :
230 0 : uint64_t Serial() { return mSerial; }
231 :
232 : void PrintDiagnostics (nsCString &log) override;
233 :
234 : // Streams need access to these
235 0 : uint32_t SendingChunkSize() { return mSendingChunkSize; }
236 0 : uint32_t PushAllowance() { return mPushAllowance; }
237 0 : Http2Compressor *Compressor() { return &mCompressor; }
238 0 : nsISocketTransport *SocketTransport() { return mSocketTransport; }
239 0 : int64_t ServerSessionWindow() { return mServerSessionWindow; }
240 0 : void DecrementServerSessionWindow (uint32_t bytes) { mServerSessionWindow -= bytes; }
241 0 : uint32_t InitialRwin() { return mInitialRwin; }
242 :
243 : void SendPing() override;
244 : MOZ_MUST_USE bool MaybeReTunnel(nsAHttpTransaction *) override;
245 0 : bool UseH2Deps() { return mUseH2Deps; }
246 :
247 : // overload of nsAHttpTransaction
248 : MOZ_MUST_USE nsresult ReadSegmentsAgain(nsAHttpSegmentReader *, uint32_t, uint32_t *, bool *) override final;
249 : MOZ_MUST_USE nsresult WriteSegmentsAgain(nsAHttpSegmentWriter *, uint32_t , uint32_t *, bool *) override final;
250 0 : MOZ_MUST_USE bool Do0RTT() override final { return true; }
251 : MOZ_MUST_USE nsresult Finish0RTT(bool aRestart, bool aAlpnChanged) override final;
252 : void SetFastOpenStatus(uint8_t aStatus) override final;
253 :
254 : // For use by an HTTP2Stream
255 : void Received421(nsHttpConnectionInfo *ci);
256 :
257 : private:
258 :
259 : // These internal states do not correspond to the states of the HTTP/2 specification
260 : enum internalStateType {
261 : BUFFERING_OPENING_SETTINGS,
262 : BUFFERING_FRAME_HEADER,
263 : BUFFERING_CONTROL_FRAME,
264 : PROCESSING_DATA_FRAME_PADDING_CONTROL,
265 : PROCESSING_DATA_FRAME,
266 : DISCARDING_DATA_FRAME_PADDING,
267 : DISCARDING_DATA_FRAME,
268 : PROCESSING_COMPLETE_HEADERS,
269 : PROCESSING_CONTROL_RST_STREAM,
270 : NOT_USING_NETWORK
271 : };
272 :
273 : static const uint8_t kMagicHello[24];
274 :
275 : MOZ_MUST_USE nsresult ResponseHeadersComplete();
276 : uint32_t GetWriteQueueSize();
277 : void ChangeDownstreamState(enum internalStateType);
278 : void ResetDownstreamState();
279 : MOZ_MUST_USE nsresult ReadyToProcessDataFrame(enum internalStateType);
280 : MOZ_MUST_USE nsresult UncompressAndDiscard(bool);
281 : void GeneratePing(bool);
282 : void GenerateSettingsAck();
283 : void GeneratePriority(uint32_t, uint8_t);
284 : void GenerateRstStream(uint32_t, uint32_t);
285 : void GenerateGoAway(uint32_t);
286 : void CleanupStream(Http2Stream *, nsresult, errorType);
287 : void CleanupStream(uint32_t, nsresult, errorType);
288 : void CloseStream(Http2Stream *, nsresult);
289 : void SendHello();
290 : void RemoveStreamFromQueues(Http2Stream *);
291 : MOZ_MUST_USE nsresult ParsePadding(uint8_t &, uint16_t &);
292 :
293 : void SetWriteCallbacks();
294 : void RealignOutputQueue();
295 :
296 : void ProcessPending();
297 : MOZ_MUST_USE nsresult ProcessConnectedPush(Http2Stream *,
298 : nsAHttpSegmentWriter *,
299 : uint32_t, uint32_t *);
300 : MOZ_MUST_USE nsresult ProcessSlowConsumer(Http2Stream *,
301 : nsAHttpSegmentWriter *,
302 : uint32_t, uint32_t *);
303 :
304 : MOZ_MUST_USE nsresult SetInputFrameDataStream(uint32_t);
305 : void CreatePriorityNode(uint32_t, uint32_t, uint8_t, const char *);
306 : bool VerifyStream(Http2Stream *, uint32_t);
307 : void SetNeedsCleanup();
308 :
309 : void UpdateLocalRwin(Http2Stream *stream, uint32_t bytes);
310 : void UpdateLocalStreamWindow(Http2Stream *stream, uint32_t bytes);
311 : void UpdateLocalSessionWindow(uint32_t bytes);
312 :
313 : void MaybeDecrementConcurrent(Http2Stream *stream);
314 : bool RoomForMoreConcurrent();
315 : void IncrementConcurrent(Http2Stream *stream);
316 : void QueueStream(Http2Stream *stream);
317 :
318 : // a wrapper for all calls to the nshttpconnection level segment writer. Used
319 : // to track network I/O for timeout purposes
320 : MOZ_MUST_USE nsresult NetworkRead(nsAHttpSegmentWriter *, char *, uint32_t, uint32_t *);
321 :
322 : void Shutdown();
323 :
324 : // This is intended to be nsHttpConnectionMgr:nsConnectionHandle taken
325 : // from the first transaction on this session. That object contains the
326 : // pointer to the real network-level nsHttpConnection object.
327 : RefPtr<nsAHttpConnection> mConnection;
328 :
329 : // The underlying socket transport object is needed to propogate some events
330 : nsISocketTransport *mSocketTransport;
331 :
332 : // These are temporary state variables to hold the argument to
333 : // Read/WriteSegments so it can be accessed by On(read/write)segment
334 : // further up the stack.
335 : nsAHttpSegmentReader *mSegmentReader;
336 : nsAHttpSegmentWriter *mSegmentWriter;
337 :
338 : uint32_t mSendingChunkSize; /* the transmission chunk size */
339 : uint32_t mNextStreamID; /* 24 bits */
340 : uint32_t mLastPushedID;
341 : uint32_t mConcurrentHighWater; /* max parallelism on session */
342 : uint32_t mPushAllowance; /* rwin for unmatched pushes */
343 :
344 : internalStateType mDownstreamState; /* in frame, between frames, etc.. */
345 :
346 : // Maintain 2 indexes - one by stream ID, one by transaction pointer.
347 : // There are also several lists of streams: ready to write, queued due to
348 : // max parallelism, streams that need to force a read for push, and the full
349 : // set of pushed streams.
350 : // The objects are not ref counted - they get destroyed
351 : // by the nsClassHashtable implementation when they are removed from
352 : // the transaction hash.
353 : nsDataHashtable<nsUint32HashKey, Http2Stream *> mStreamIDHash;
354 : nsClassHashtable<nsPtrHashKey<nsAHttpTransaction>,
355 : Http2Stream> mStreamTransactionHash;
356 :
357 : nsDeque mReadyForWrite;
358 : nsDeque mQueuedStreams;
359 : nsDeque mPushesReadyForRead;
360 : nsDeque mSlowConsumersReadyForRead;
361 : nsTArray<Http2PushedStream *> mPushedStreams;
362 :
363 : // Compression contexts for header transport.
364 : // HTTP/2 compresses only HTTP headers and does not reset the context in between
365 : // frames. Even data that is not associated with a stream (e.g invalid
366 : // stream ID) is passed through these contexts to keep the compression
367 : // context correct.
368 : Http2Compressor mCompressor;
369 : Http2Decompressor mDecompressor;
370 : nsCString mDecompressBuffer;
371 :
372 : // mInputFrameBuffer is used to store received control packets and the 8 bytes
373 : // of header on data packets
374 : uint32_t mInputFrameBufferSize; // buffer allocation
375 : uint32_t mInputFrameBufferUsed; // amt of allocation used
376 : UniquePtr<char[]> mInputFrameBuffer;
377 :
378 : // mInputFrameDataSize/Read are used for tracking the amount of data consumed
379 : // in a frame after the 8 byte header. Control frames are always fully buffered
380 : // and the fixed 8 byte leading header is at mInputFrameBuffer + 0, the first
381 : // data byte (i.e. the first settings/goaway/etc.. specific byte) is at
382 : // mInputFrameBuffer + 8
383 : // The frame size is mInputFrameDataSize + the constant 8 byte header
384 : uint32_t mInputFrameDataSize;
385 : uint32_t mInputFrameDataRead;
386 : bool mInputFrameFinal; // This frame was marked FIN
387 : uint8_t mInputFrameType;
388 : uint8_t mInputFrameFlags;
389 : uint32_t mInputFrameID;
390 : uint16_t mPaddingLength;
391 :
392 : // When a frame has been received that is addressed to a particular stream
393 : // (e.g. a data frame after the stream-id has been decoded), this points
394 : // to the stream.
395 : Http2Stream *mInputFrameDataStream;
396 :
397 : // mNeedsCleanup is a state variable to defer cleanup of a closed stream
398 : // If needed, It is set in session::OnWriteSegments() and acted on and
399 : // cleared when the stack returns to session::WriteSegments(). The stream
400 : // cannot be destroyed directly out of OnWriteSegments because
401 : // stream::writeSegments() is on the stack at that time.
402 : Http2Stream *mNeedsCleanup;
403 :
404 : // This reason code in the last processed RESET frame
405 : uint32_t mDownstreamRstReason;
406 :
407 : // When HEADERS/PROMISE are chained together, this is the expected ID of the next
408 : // recvd frame which must be the same type
409 : uint32_t mExpectedHeaderID;
410 : uint32_t mExpectedPushPromiseID;
411 : uint32_t mContinuedPromiseStream;
412 :
413 : // for the conversion of downstream http headers into http/2 formatted headers
414 : // The data here does not persist between frames
415 : nsCString mFlatHTTPResponseHeaders;
416 : uint32_t mFlatHTTPResponseHeadersOut;
417 :
418 : // when set, the session will go away when it reaches 0 streams. This flag
419 : // is set when: the stream IDs are running out (at either the client or the
420 : // server), when DontReuse() is called, a RST that is not specific to a
421 : // particular stream is received, a GOAWAY frame has been received from
422 : // the server.
423 : bool mShouldGoAway;
424 :
425 : // the session has received a nsAHttpTransaction::Close() call
426 : bool mClosed;
427 :
428 : // the session received a GoAway frame with a valid GoAwayID
429 : bool mCleanShutdown;
430 :
431 : // the session received the opening SETTINGS frame from the server
432 : bool mReceivedSettings;
433 :
434 : // The TLS comlpiance checks are not done in the ctor beacuse of bad
435 : // exception handling - so we do them at IO time and cache the result
436 : bool mTLSProfileConfirmed;
437 :
438 : // A specifc reason code for the eventual GoAway frame. If set to NO_HTTP_ERROR
439 : // only NO_HTTP_ERROR, PROTOCOL_ERROR, or INTERNAL_ERROR will be sent.
440 : errorType mGoAwayReason;
441 :
442 : // The error code sent/received on the session goaway frame. UNASSIGNED/31
443 : // if not transmitted.
444 : int32_t mClientGoAwayReason;
445 : int32_t mPeerGoAwayReason;
446 :
447 : // If a GoAway message was received this is the ID of the last valid
448 : // stream. 0 otherwise. (0 is never a valid stream id.)
449 : uint32_t mGoAwayID;
450 :
451 : // The last stream processed ID we will send in our GoAway frame.
452 : uint32_t mOutgoingGoAwayID;
453 :
454 : // The limit on number of concurrent streams for this session. Normally it
455 : // is basically unlimited, but the SETTINGS control message from the
456 : // server might bring it down.
457 : uint32_t mMaxConcurrent;
458 :
459 : // The actual number of concurrent streams at this moment. Generally below
460 : // mMaxConcurrent, but the max can be lowered in real time to a value
461 : // below the current value
462 : uint32_t mConcurrent;
463 :
464 : // The number of server initiated promises, tracked for telemetry
465 : uint32_t mServerPushedResources;
466 :
467 : // The server rwin for new streams as determined from a SETTINGS frame
468 : uint32_t mServerInitialStreamWindow;
469 :
470 : // The Local Session window is how much data the server is allowed to send
471 : // (across all streams) without getting a window update to stream 0. It is
472 : // signed because asynchronous changes via SETTINGS can drive it negative.
473 : int64_t mLocalSessionWindow;
474 :
475 : // The Remote Session Window is how much data the client is allowed to send
476 : // (across all streams) without receiving a window update to stream 0. It is
477 : // signed because asynchronous changes via SETTINGS can drive it negative.
478 : int64_t mServerSessionWindow;
479 :
480 : // The initial value of the local stream and session window
481 : uint32_t mInitialRwin;
482 :
483 : // This is a output queue of bytes ready to be written to the SSL stream.
484 : // When that streams returns WOULD_BLOCK on direct write the bytes get
485 : // coalesced together here. This results in larger writes to the SSL layer.
486 : // The buffer is not dynamically grown to accomodate stream writes, but
487 : // does expand to accept infallible session wide frames like GoAway and RST.
488 : uint32_t mOutputQueueSize;
489 : uint32_t mOutputQueueUsed;
490 : uint32_t mOutputQueueSent;
491 : UniquePtr<char[]> mOutputQueueBuffer;
492 :
493 : PRIntervalTime mPingThreshold;
494 : PRIntervalTime mLastReadEpoch; // used for ping timeouts
495 : PRIntervalTime mLastDataReadEpoch; // used for IdleTime()
496 : PRIntervalTime mPingSentEpoch;
497 :
498 : PRIntervalTime mPreviousPingThreshold; // backup for the former value
499 : bool mPreviousUsed; // true when backup is used
500 :
501 : // used as a temporary buffer while enumerating the stream hash during GoAway
502 : nsDeque mGoAwayStreamsToRestart;
503 :
504 : // Each session gets a unique serial number because the push cache is correlated
505 : // by the load group and the serial number can be used as part of the cache key
506 : // to make sure streams aren't shared across sessions.
507 : uint64_t mSerial;
508 :
509 : // Telemetry for continued headers (pushed and pulled) for quic design
510 : uint32_t mAggregatedHeaderSize;
511 :
512 : // If push is disabled, we want to be able to send PROTOCOL_ERRORs if we
513 : // receive a PUSH_PROMISE, but we have to wait for the SETTINGS ACK before
514 : // we can actually tell the other end to go away. These help us keep track
515 : // of that state so we can behave appropriately.
516 : bool mWaitingForSettingsAck;
517 : bool mGoAwayOnPush;
518 :
519 : bool mUseH2Deps;
520 :
521 : bool mAttemptingEarlyData;
522 : // The ID(s) of the stream(s) that we are getting 0RTT data from.
523 : nsTArray<WeakPtr<Http2Stream>> m0RTTStreams;
524 :
525 : bool RealJoinConnection(const nsACString &hostname, int32_t port, bool jk);
526 : bool TestOriginFrame(const nsACString &name, int32_t port);
527 : bool mOriginFrameActivated;
528 : nsDataHashtable<nsCStringHashKey, bool> mOriginFrame;
529 :
530 : nsDataHashtable<nsCStringHashKey, bool> mJoinConnectionCache;
531 :
532 : private:
533 : /// connect tunnels
534 : void DispatchOnTunnel(nsAHttpTransaction *, nsIInterfaceRequestor *);
535 : void CreateTunnel(nsHttpTransaction *, nsHttpConnectionInfo *, nsIInterfaceRequestor *);
536 : void RegisterTunnel(Http2Stream *);
537 : void UnRegisterTunnel(Http2Stream *);
538 : uint32_t FindTunnelCount(nsHttpConnectionInfo *);
539 : nsDataHashtable<nsCStringHashKey, uint32_t> mTunnelHash;
540 : };
541 :
542 : } // namespace net
543 : } // namespace mozilla
544 :
545 : #endif // mozilla_net_Http2Session_h
|