Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #ifndef mozilla_net_SpdySession3_h |
michael@0 | 7 | #define mozilla_net_SpdySession3_h |
michael@0 | 8 | |
michael@0 | 9 | // SPDY as defined by |
michael@0 | 10 | // http://dev.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3 |
michael@0 | 11 | |
michael@0 | 12 | #include "ASpdySession.h" |
michael@0 | 13 | #include "mozilla/Attributes.h" |
michael@0 | 14 | #include "nsAHttpConnection.h" |
michael@0 | 15 | #include "nsClassHashtable.h" |
michael@0 | 16 | #include "nsDataHashtable.h" |
michael@0 | 17 | #include "nsDeque.h" |
michael@0 | 18 | #include "nsHashKeys.h" |
michael@0 | 19 | #include "zlib.h" |
michael@0 | 20 | |
michael@0 | 21 | class nsISocketTransport; |
michael@0 | 22 | |
michael@0 | 23 | namespace mozilla { namespace net { |
michael@0 | 24 | |
michael@0 | 25 | class SpdyPushedStream3; |
michael@0 | 26 | class SpdyStream3; |
michael@0 | 27 | |
michael@0 | 28 | class SpdySession3 MOZ_FINAL : public ASpdySession |
michael@0 | 29 | , public nsAHttpConnection |
michael@0 | 30 | , public nsAHttpSegmentReader |
michael@0 | 31 | , public nsAHttpSegmentWriter |
michael@0 | 32 | { |
michael@0 | 33 | public: |
michael@0 | 34 | NS_DECL_THREADSAFE_ISUPPORTS |
michael@0 | 35 | NS_DECL_NSAHTTPTRANSACTION |
michael@0 | 36 | NS_DECL_NSAHTTPCONNECTION(mConnection) |
michael@0 | 37 | NS_DECL_NSAHTTPSEGMENTREADER |
michael@0 | 38 | NS_DECL_NSAHTTPSEGMENTWRITER |
michael@0 | 39 | |
michael@0 | 40 | SpdySession3(nsAHttpTransaction *, nsISocketTransport *, int32_t); |
michael@0 | 41 | ~SpdySession3(); |
michael@0 | 42 | |
michael@0 | 43 | bool AddStream(nsAHttpTransaction *, int32_t); |
michael@0 | 44 | bool CanReuse() { return !mShouldGoAway && !mClosed; } |
michael@0 | 45 | bool RoomForMoreStreams(); |
michael@0 | 46 | |
michael@0 | 47 | // When the connection is active this is called up to once every 1 second |
michael@0 | 48 | // return the interval (in seconds) that the connection next wants to |
michael@0 | 49 | // have this invoked. It might happen sooner depending on the needs of |
michael@0 | 50 | // other connections. |
michael@0 | 51 | uint32_t ReadTimeoutTick(PRIntervalTime now); |
michael@0 | 52 | |
michael@0 | 53 | // Idle time represents time since "goodput".. e.g. a data or header frame |
michael@0 | 54 | PRIntervalTime IdleTime(); |
michael@0 | 55 | |
michael@0 | 56 | // Registering with a newID of 0 means pick the next available odd ID |
michael@0 | 57 | uint32_t RegisterStreamID(SpdyStream3 *, uint32_t aNewID = 0); |
michael@0 | 58 | |
michael@0 | 59 | const static uint8_t kVersion = 3; |
michael@0 | 60 | |
michael@0 | 61 | const static uint8_t kFlag_Control = 0x80; |
michael@0 | 62 | |
michael@0 | 63 | const static uint8_t kFlag_Data_FIN = 0x01; |
michael@0 | 64 | const static uint8_t kFlag_Data_UNI = 0x02; |
michael@0 | 65 | |
michael@0 | 66 | enum |
michael@0 | 67 | { |
michael@0 | 68 | CONTROL_TYPE_FIRST = 0, |
michael@0 | 69 | CONTROL_TYPE_SYN_STREAM = 1, |
michael@0 | 70 | CONTROL_TYPE_SYN_REPLY = 2, |
michael@0 | 71 | CONTROL_TYPE_RST_STREAM = 3, |
michael@0 | 72 | CONTROL_TYPE_SETTINGS = 4, |
michael@0 | 73 | CONTROL_TYPE_NOOP = 5, /* deprecated */ |
michael@0 | 74 | CONTROL_TYPE_PING = 6, |
michael@0 | 75 | CONTROL_TYPE_GOAWAY = 7, |
michael@0 | 76 | CONTROL_TYPE_HEADERS = 8, |
michael@0 | 77 | CONTROL_TYPE_WINDOW_UPDATE = 9, |
michael@0 | 78 | CONTROL_TYPE_CREDENTIAL = 10, |
michael@0 | 79 | CONTROL_TYPE_LAST = 11 |
michael@0 | 80 | }; |
michael@0 | 81 | |
michael@0 | 82 | enum rstReason |
michael@0 | 83 | { |
michael@0 | 84 | RST_PROTOCOL_ERROR = 1, |
michael@0 | 85 | RST_INVALID_STREAM = 2, |
michael@0 | 86 | RST_REFUSED_STREAM = 3, |
michael@0 | 87 | RST_UNSUPPORTED_VERSION = 4, |
michael@0 | 88 | RST_CANCEL = 5, |
michael@0 | 89 | RST_INTERNAL_ERROR = 6, |
michael@0 | 90 | RST_FLOW_CONTROL_ERROR = 7, |
michael@0 | 91 | RST_STREAM_IN_USE = 8, |
michael@0 | 92 | RST_STREAM_ALREADY_CLOSED = 9, |
michael@0 | 93 | RST_INVALID_CREDENTIALS = 10, |
michael@0 | 94 | RST_FRAME_TOO_LARGE = 11 |
michael@0 | 95 | }; |
michael@0 | 96 | |
michael@0 | 97 | enum goawayReason |
michael@0 | 98 | { |
michael@0 | 99 | OK = 0, |
michael@0 | 100 | PROTOCOL_ERROR = 1, |
michael@0 | 101 | INTERNAL_ERROR = 2, // sometimes misdocumented as 11 |
michael@0 | 102 | NUM_STATUS_CODES = 3 // reserved by chromium but undocumented |
michael@0 | 103 | }; |
michael@0 | 104 | |
michael@0 | 105 | enum settingsFlags |
michael@0 | 106 | { |
michael@0 | 107 | PERSIST_VALUE = 1, |
michael@0 | 108 | PERSISTED_VALUE = 2 |
michael@0 | 109 | }; |
michael@0 | 110 | |
michael@0 | 111 | enum |
michael@0 | 112 | { |
michael@0 | 113 | SETTINGS_TYPE_UPLOAD_BW = 1, // kb/s |
michael@0 | 114 | SETTINGS_TYPE_DOWNLOAD_BW = 2, // kb/s |
michael@0 | 115 | SETTINGS_TYPE_RTT = 3, // ms |
michael@0 | 116 | SETTINGS_TYPE_MAX_CONCURRENT = 4, // streams |
michael@0 | 117 | SETTINGS_TYPE_CWND = 5, // packets |
michael@0 | 118 | SETTINGS_TYPE_DOWNLOAD_RETRANS_RATE = 6, // percentage |
michael@0 | 119 | SETTINGS_TYPE_INITIAL_WINDOW = 7, // bytes for flow control |
michael@0 | 120 | SETTINGS_CLIENT_CERTIFICATE_VECTOR_SIZE = 8 |
michael@0 | 121 | }; |
michael@0 | 122 | |
michael@0 | 123 | // This should be big enough to hold all of your control packets, |
michael@0 | 124 | // but if it needs to grow for huge headers it can do so dynamically. |
michael@0 | 125 | // About 1% of responses from SPDY google services seem to be > 1000 |
michael@0 | 126 | // with all less than 2000 when compression is enabled. |
michael@0 | 127 | const static uint32_t kDefaultBufferSize = 2048; |
michael@0 | 128 | |
michael@0 | 129 | // kDefaultQueueSize must be >= other queue size constants |
michael@0 | 130 | const static uint32_t kDefaultQueueSize = 32768; |
michael@0 | 131 | const static uint32_t kQueueMinimumCleanup = 24576; |
michael@0 | 132 | const static uint32_t kQueueTailRoom = 4096; |
michael@0 | 133 | const static uint32_t kQueueReserved = 1024; |
michael@0 | 134 | |
michael@0 | 135 | const static uint32_t kDefaultMaxConcurrent = 100; |
michael@0 | 136 | const static uint32_t kMaxStreamID = 0x7800000; |
michael@0 | 137 | |
michael@0 | 138 | // This is a sentinel for a deleted stream. It is not a valid |
michael@0 | 139 | // 31 bit stream ID. |
michael@0 | 140 | const static uint32_t kDeadStreamID = 0xffffdead; |
michael@0 | 141 | |
michael@0 | 142 | // below the emergency threshold of local window we ack every received |
michael@0 | 143 | // byte. Above that we coalesce bytes into the MinimumToAck size. |
michael@0 | 144 | const static int32_t kEmergencyWindowThreshold = 1024 * 1024; |
michael@0 | 145 | const static uint32_t kMinimumToAck = 64 * 1024; |
michael@0 | 146 | |
michael@0 | 147 | // The default peer rwin is 64KB unless updated by a settings frame |
michael@0 | 148 | const static uint32_t kDefaultServerRwin = 64 * 1024; |
michael@0 | 149 | |
michael@0 | 150 | static nsresult HandleSynStream(SpdySession3 *); |
michael@0 | 151 | static nsresult HandleSynReply(SpdySession3 *); |
michael@0 | 152 | static nsresult HandleRstStream(SpdySession3 *); |
michael@0 | 153 | static nsresult HandleSettings(SpdySession3 *); |
michael@0 | 154 | static nsresult HandleNoop(SpdySession3 *); |
michael@0 | 155 | static nsresult HandlePing(SpdySession3 *); |
michael@0 | 156 | static nsresult HandleGoAway(SpdySession3 *); |
michael@0 | 157 | static nsresult HandleHeaders(SpdySession3 *); |
michael@0 | 158 | static nsresult HandleWindowUpdate(SpdySession3 *); |
michael@0 | 159 | static nsresult HandleCredential(SpdySession3 *); |
michael@0 | 160 | |
michael@0 | 161 | template<typename T> |
michael@0 | 162 | static void EnsureBuffer(nsAutoArrayPtr<T> &, |
michael@0 | 163 | uint32_t, uint32_t, uint32_t &); |
michael@0 | 164 | |
michael@0 | 165 | // For writing the SPDY data stream to LOG4 |
michael@0 | 166 | static void LogIO(SpdySession3 *, SpdyStream3 *, const char *, |
michael@0 | 167 | const char *, uint32_t); |
michael@0 | 168 | |
michael@0 | 169 | // an overload of nsAHttpConnection |
michael@0 | 170 | void TransactionHasDataToWrite(nsAHttpTransaction *); |
michael@0 | 171 | |
michael@0 | 172 | // a similar version for SpdyStream3 |
michael@0 | 173 | void TransactionHasDataToWrite(SpdyStream3 *); |
michael@0 | 174 | |
michael@0 | 175 | // an overload of nsAHttpSegementReader |
michael@0 | 176 | virtual nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment); |
michael@0 | 177 | |
michael@0 | 178 | uint32_t GetServerInitialWindow() { return mServerInitialWindow; } |
michael@0 | 179 | |
michael@0 | 180 | void ConnectPushedStream(SpdyStream3 *stream); |
michael@0 | 181 | void DecrementConcurrent(SpdyStream3 *stream); |
michael@0 | 182 | |
michael@0 | 183 | uint64_t Serial() { return mSerial; } |
michael@0 | 184 | |
michael@0 | 185 | void PrintDiagnostics (nsCString &log); |
michael@0 | 186 | |
michael@0 | 187 | // Streams need access to these |
michael@0 | 188 | uint32_t SendingChunkSize() { return mSendingChunkSize; } |
michael@0 | 189 | uint32_t PushAllowance() { return mPushAllowance; } |
michael@0 | 190 | z_stream *UpstreamZlib() { return &mUpstreamZlib; } |
michael@0 | 191 | nsISocketTransport *SocketTransport() { return mSocketTransport; } |
michael@0 | 192 | |
michael@0 | 193 | private: |
michael@0 | 194 | |
michael@0 | 195 | enum stateType { |
michael@0 | 196 | BUFFERING_FRAME_HEADER, |
michael@0 | 197 | BUFFERING_CONTROL_FRAME, |
michael@0 | 198 | PROCESSING_DATA_FRAME, |
michael@0 | 199 | DISCARDING_DATA_FRAME, |
michael@0 | 200 | PROCESSING_COMPLETE_HEADERS, |
michael@0 | 201 | PROCESSING_CONTROL_RST_STREAM |
michael@0 | 202 | }; |
michael@0 | 203 | |
michael@0 | 204 | nsresult ResponseHeadersComplete(); |
michael@0 | 205 | uint32_t GetWriteQueueSize(); |
michael@0 | 206 | void ChangeDownstreamState(enum stateType); |
michael@0 | 207 | void ResetDownstreamState(); |
michael@0 | 208 | nsresult UncompressAndDiscard(uint32_t, uint32_t); |
michael@0 | 209 | void zlibInit(); |
michael@0 | 210 | void GeneratePing(uint32_t); |
michael@0 | 211 | void GenerateRstStream(uint32_t, uint32_t); |
michael@0 | 212 | void GenerateGoAway(uint32_t); |
michael@0 | 213 | void CleanupStream(SpdyStream3 *, nsresult, rstReason); |
michael@0 | 214 | void CloseStream(SpdyStream3 *, nsresult); |
michael@0 | 215 | void GenerateSettings(); |
michael@0 | 216 | void RemoveStreamFromQueues(SpdyStream3 *); |
michael@0 | 217 | |
michael@0 | 218 | void SetWriteCallbacks(); |
michael@0 | 219 | void FlushOutputQueue(); |
michael@0 | 220 | void RealignOutputQueue(); |
michael@0 | 221 | |
michael@0 | 222 | bool RoomForMoreConcurrent(); |
michael@0 | 223 | void ActivateStream(SpdyStream3 *); |
michael@0 | 224 | void ProcessPending(); |
michael@0 | 225 | nsresult SetInputFrameDataStream(uint32_t); |
michael@0 | 226 | bool VerifyStream(SpdyStream3 *, uint32_t); |
michael@0 | 227 | void SetNeedsCleanup(); |
michael@0 | 228 | |
michael@0 | 229 | void UpdateLocalRwin(SpdyStream3 *stream, uint32_t bytes); |
michael@0 | 230 | |
michael@0 | 231 | // a wrapper for all calls to the nshttpconnection level segment writer. Used |
michael@0 | 232 | // to track network I/O for timeout purposes |
michael@0 | 233 | nsresult NetworkRead(nsAHttpSegmentWriter *, char *, uint32_t, uint32_t *); |
michael@0 | 234 | |
michael@0 | 235 | static PLDHashOperator ShutdownEnumerator(nsAHttpTransaction *, |
michael@0 | 236 | nsAutoPtr<SpdyStream3> &, |
michael@0 | 237 | void *); |
michael@0 | 238 | |
michael@0 | 239 | static PLDHashOperator GoAwayEnumerator(nsAHttpTransaction *, |
michael@0 | 240 | nsAutoPtr<SpdyStream3> &, |
michael@0 | 241 | void *); |
michael@0 | 242 | |
michael@0 | 243 | static PLDHashOperator UpdateServerRwinEnumerator(nsAHttpTransaction *, |
michael@0 | 244 | nsAutoPtr<SpdyStream3> &, |
michael@0 | 245 | void *); |
michael@0 | 246 | |
michael@0 | 247 | // This is intended to be nsHttpConnectionMgr:nsConnectionHandle taken |
michael@0 | 248 | // from the first transaction on this session. That object contains the |
michael@0 | 249 | // pointer to the real network-level nsHttpConnection object. |
michael@0 | 250 | nsRefPtr<nsAHttpConnection> mConnection; |
michael@0 | 251 | |
michael@0 | 252 | // The underlying socket transport object is needed to propogate some events |
michael@0 | 253 | nsISocketTransport *mSocketTransport; |
michael@0 | 254 | |
michael@0 | 255 | // These are temporary state variables to hold the argument to |
michael@0 | 256 | // Read/WriteSegments so it can be accessed by On(read/write)segment |
michael@0 | 257 | // further up the stack. |
michael@0 | 258 | nsAHttpSegmentReader *mSegmentReader; |
michael@0 | 259 | nsAHttpSegmentWriter *mSegmentWriter; |
michael@0 | 260 | |
michael@0 | 261 | uint32_t mSendingChunkSize; /* the transmission chunk size */ |
michael@0 | 262 | uint32_t mNextStreamID; /* 24 bits */ |
michael@0 | 263 | uint32_t mConcurrentHighWater; /* max parallelism on session */ |
michael@0 | 264 | uint32_t mPushAllowance; /* rwin for unmatched pushes */ |
michael@0 | 265 | |
michael@0 | 266 | stateType mDownstreamState; /* in frame, between frames, etc.. */ |
michael@0 | 267 | |
michael@0 | 268 | // Maintain 2 indexes - one by stream ID, one by transaction pointer. |
michael@0 | 269 | // There are also several lists of streams: ready to write, queued due to |
michael@0 | 270 | // max parallelism, streams that need to force a read for push, and the full |
michael@0 | 271 | // set of pushed streams. |
michael@0 | 272 | // The objects are not ref counted - they get destroyed |
michael@0 | 273 | // by the nsClassHashtable implementation when they are removed from |
michael@0 | 274 | // the transaction hash. |
michael@0 | 275 | nsDataHashtable<nsUint32HashKey, SpdyStream3 *> mStreamIDHash; |
michael@0 | 276 | nsClassHashtable<nsPtrHashKey<nsAHttpTransaction>, |
michael@0 | 277 | SpdyStream3> mStreamTransactionHash; |
michael@0 | 278 | |
michael@0 | 279 | nsDeque mReadyForWrite; |
michael@0 | 280 | nsDeque mQueuedStreams; |
michael@0 | 281 | nsDeque mReadyForRead; |
michael@0 | 282 | nsTArray<SpdyPushedStream3 *> mPushedStreams; |
michael@0 | 283 | |
michael@0 | 284 | // Compression contexts for header transport using deflate. |
michael@0 | 285 | // SPDY compresses only HTTP headers and does not reset zlib in between |
michael@0 | 286 | // frames. Even data that is not associated with a stream (e.g invalid |
michael@0 | 287 | // stream ID) is passed through these contexts to keep the compression |
michael@0 | 288 | // context correct. |
michael@0 | 289 | z_stream mDownstreamZlib; |
michael@0 | 290 | z_stream mUpstreamZlib; |
michael@0 | 291 | |
michael@0 | 292 | // mInputFrameBuffer is used to store received control packets and the 8 bytes |
michael@0 | 293 | // of header on data packets |
michael@0 | 294 | uint32_t mInputFrameBufferSize; |
michael@0 | 295 | uint32_t mInputFrameBufferUsed; |
michael@0 | 296 | nsAutoArrayPtr<char> mInputFrameBuffer; |
michael@0 | 297 | |
michael@0 | 298 | // mInputFrameDataSize/Read are used for tracking the amount of data consumed |
michael@0 | 299 | // in a data frame. the data itself is not buffered in spdy |
michael@0 | 300 | // The frame size is mInputFrameDataSize + the constant 8 byte header |
michael@0 | 301 | uint32_t mInputFrameDataSize; |
michael@0 | 302 | uint32_t mInputFrameDataRead; |
michael@0 | 303 | bool mInputFrameDataLast; // This frame was marked FIN |
michael@0 | 304 | |
michael@0 | 305 | // When a frame has been received that is addressed to a particular stream |
michael@0 | 306 | // (e.g. a data frame after the stream-id has been decoded), this points |
michael@0 | 307 | // to the stream. |
michael@0 | 308 | SpdyStream3 *mInputFrameDataStream; |
michael@0 | 309 | |
michael@0 | 310 | // mNeedsCleanup is a state variable to defer cleanup of a closed stream |
michael@0 | 311 | // If needed, It is set in session::OnWriteSegments() and acted on and |
michael@0 | 312 | // cleared when the stack returns to session::WriteSegments(). The stream |
michael@0 | 313 | // cannot be destroyed directly out of OnWriteSegments because |
michael@0 | 314 | // stream::writeSegments() is on the stack at that time. |
michael@0 | 315 | SpdyStream3 *mNeedsCleanup; |
michael@0 | 316 | |
michael@0 | 317 | // The CONTROL_TYPE value for a control frame |
michael@0 | 318 | uint32_t mFrameControlType; |
michael@0 | 319 | |
michael@0 | 320 | // This reason code in the last processed RESET frame |
michael@0 | 321 | uint32_t mDownstreamRstReason; |
michael@0 | 322 | |
michael@0 | 323 | // for the conversion of downstream http headers into spdy formatted headers |
michael@0 | 324 | // The data here does not persist between frames |
michael@0 | 325 | nsCString mFlatHTTPResponseHeaders; |
michael@0 | 326 | uint32_t mFlatHTTPResponseHeadersOut; |
michael@0 | 327 | |
michael@0 | 328 | // when set, the session will go away when it reaches 0 streams. This flag |
michael@0 | 329 | // is set when: the stream IDs are running out (at either the client or the |
michael@0 | 330 | // server), when DontReuse() is called, a RST that is not specific to a |
michael@0 | 331 | // particular stream is received, a GOAWAY frame has been received from |
michael@0 | 332 | // the server. |
michael@0 | 333 | bool mShouldGoAway; |
michael@0 | 334 | |
michael@0 | 335 | // the session has received a nsAHttpTransaction::Close() call |
michael@0 | 336 | bool mClosed; |
michael@0 | 337 | |
michael@0 | 338 | // the session received a GoAway frame with a valid GoAwayID |
michael@0 | 339 | bool mCleanShutdown; |
michael@0 | 340 | |
michael@0 | 341 | // indicates PROCESSING_COMPLETE_HEADERS state was pushed onto the stack |
michael@0 | 342 | // over an active PROCESSING_DATA_FRAME, which should be restored when |
michael@0 | 343 | // the processed headers are written to the stream |
michael@0 | 344 | bool mDataPending; |
michael@0 | 345 | |
michael@0 | 346 | // If a GoAway message was received this is the ID of the last valid |
michael@0 | 347 | // stream. 0 otherwise. (0 is never a valid stream id.) |
michael@0 | 348 | uint32_t mGoAwayID; |
michael@0 | 349 | |
michael@0 | 350 | // The limit on number of concurrent streams for this session. Normally it |
michael@0 | 351 | // is basically unlimited, but the SETTINGS control message from the |
michael@0 | 352 | // server might bring it down. |
michael@0 | 353 | uint32_t mMaxConcurrent; |
michael@0 | 354 | |
michael@0 | 355 | // The actual number of concurrent streams at this moment. Generally below |
michael@0 | 356 | // mMaxConcurrent, but the max can be lowered in real time to a value |
michael@0 | 357 | // below the current value |
michael@0 | 358 | uint32_t mConcurrent; |
michael@0 | 359 | |
michael@0 | 360 | // The number of server initiated SYN-STREAMS, tracked for telemetry |
michael@0 | 361 | uint32_t mServerPushedResources; |
michael@0 | 362 | |
michael@0 | 363 | // The server rwin for new streams as determined from a SETTINGS frame |
michael@0 | 364 | uint32_t mServerInitialWindow; |
michael@0 | 365 | |
michael@0 | 366 | // This is a output queue of bytes ready to be written to the SSL stream. |
michael@0 | 367 | // When that streams returns WOULD_BLOCK on direct write the bytes get |
michael@0 | 368 | // coalesced together here. This results in larger writes to the SSL layer. |
michael@0 | 369 | // The buffer is not dynamically grown to accomodate stream writes, but |
michael@0 | 370 | // does expand to accept infallible session wide frames like GoAway and RST. |
michael@0 | 371 | uint32_t mOutputQueueSize; |
michael@0 | 372 | uint32_t mOutputQueueUsed; |
michael@0 | 373 | uint32_t mOutputQueueSent; |
michael@0 | 374 | nsAutoArrayPtr<char> mOutputQueueBuffer; |
michael@0 | 375 | |
michael@0 | 376 | PRIntervalTime mPingThreshold; |
michael@0 | 377 | PRIntervalTime mLastReadEpoch; // used for ping timeouts |
michael@0 | 378 | PRIntervalTime mLastDataReadEpoch; // used for IdleTime() |
michael@0 | 379 | PRIntervalTime mPingSentEpoch; |
michael@0 | 380 | uint32_t mNextPingID; |
michael@0 | 381 | |
michael@0 | 382 | // used as a temporary buffer while enumerating the stream hash during GoAway |
michael@0 | 383 | nsDeque mGoAwayStreamsToRestart; |
michael@0 | 384 | |
michael@0 | 385 | // Each session gets a unique serial number because the push cache is correlated |
michael@0 | 386 | // by the load group and the serial number can be used as part of the cache key |
michael@0 | 387 | // to make sure streams aren't shared across sessions. |
michael@0 | 388 | uint64_t mSerial; |
michael@0 | 389 | }; |
michael@0 | 390 | |
michael@0 | 391 | }} // namespace mozilla::net |
michael@0 | 392 | |
michael@0 | 393 | #endif // mozilla_net_SpdySession3_h |