Line data Source code
1 : /* vim:set ts=4 sw=4 sts=4 et cin: */
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 nsHttpConnectionMgr_h__
7 : #define nsHttpConnectionMgr_h__
8 :
9 : #include "nsHttpConnection.h"
10 : #include "nsHttpTransaction.h"
11 : #include "nsTArray.h"
12 : #include "nsThreadUtils.h"
13 : #include "nsClassHashtable.h"
14 : #include "nsDataHashtable.h"
15 : #include "nsAutoPtr.h"
16 : #include "mozilla/ReentrantMonitor.h"
17 : #include "mozilla/TimeStamp.h"
18 : #include "mozilla/Attributes.h"
19 : #include "AlternateServices.h"
20 : #include "ARefBase.h"
21 : #include "nsWeakReference.h"
22 : #include "TCPFastOpen.h"
23 :
24 : #include "nsIObserver.h"
25 : #include "nsITimer.h"
26 :
27 : class nsIHttpUpgradeListener;
28 :
29 : namespace mozilla {
30 : namespace net {
31 : class EventTokenBucket;
32 : class NullHttpTransaction;
33 : struct HttpRetParams;
34 :
35 : // 8d411b53-54bc-4a99-8b78-ff125eab1564
36 : #define NS_HALFOPENSOCKET_IID \
37 : { 0x8d411b53, 0x54bc, 0x4a99, {0x8b, 0x78, 0xff, 0x12, 0x5e, 0xab, 0x15, 0x64 }}
38 :
39 : //-----------------------------------------------------------------------------
40 :
41 : // message handlers have this signature
42 : class nsHttpConnectionMgr;
43 : typedef void (nsHttpConnectionMgr:: *nsConnEventHandler)(int32_t, ARefBase *);
44 :
45 : class nsHttpConnectionMgr final : public nsIObserver
46 : , public AltSvcCache
47 : {
48 : public:
49 : NS_DECL_THREADSAFE_ISUPPORTS
50 : NS_DECL_NSIOBSERVER
51 :
52 : // parameter names
53 : enum nsParamName {
54 : MAX_URGENT_START_Q,
55 : MAX_CONNECTIONS,
56 : MAX_PERSISTENT_CONNECTIONS_PER_HOST,
57 : MAX_PERSISTENT_CONNECTIONS_PER_PROXY,
58 : MAX_REQUEST_DELAY,
59 : THROTTLING_ENABLED,
60 : THROTTLING_SUSPEND_FOR,
61 : THROTTLING_RESUME_FOR,
62 : THROTTLING_RESUME_IN
63 : };
64 :
65 : //-------------------------------------------------------------------------
66 : // NOTE: functions below may only be called on the main thread.
67 : //-------------------------------------------------------------------------
68 :
69 : nsHttpConnectionMgr();
70 :
71 : MOZ_MUST_USE nsresult Init(uint16_t maxUrgentExcessiveConns,
72 : uint16_t maxConnections,
73 : uint16_t maxPersistentConnectionsPerHost,
74 : uint16_t maxPersistentConnectionsPerProxy,
75 : uint16_t maxRequestDelay,
76 : bool throttleEnabled,
77 : uint32_t throttleSuspendFor,
78 : uint32_t throttleResumeFor,
79 : uint32_t throttleResumeIn);
80 : MOZ_MUST_USE nsresult Shutdown();
81 :
82 : //-------------------------------------------------------------------------
83 : // NOTE: functions below may be called on any thread.
84 : //-------------------------------------------------------------------------
85 :
86 : // Schedules next pruning of dead connection to happen after
87 : // given time.
88 : void PruneDeadConnectionsAfter(uint32_t time);
89 :
90 : // Stops timer scheduled for next pruning of dead connections if
91 : // there are no more idle connections or active spdy ones
92 : void ConditionallyStopPruneDeadConnectionsTimer();
93 :
94 : // Stops timer used for the read timeout tick if there are no currently
95 : // active connections.
96 : void ConditionallyStopTimeoutTick();
97 :
98 : // adds a transaction to the list of managed transactions.
99 : MOZ_MUST_USE nsresult AddTransaction(nsHttpTransaction *, int32_t priority);
100 :
101 : // called to reschedule the given transaction. it must already have been
102 : // added to the connection manager via AddTransaction.
103 : MOZ_MUST_USE nsresult RescheduleTransaction(nsHttpTransaction *,
104 : int32_t priority);
105 :
106 : // TOOD
107 : void UpdateClassOfServiceOnTransaction(nsHttpTransaction *,
108 : uint32_t classOfService);
109 :
110 : // cancels a transaction w/ the given reason.
111 : MOZ_MUST_USE nsresult CancelTransaction(nsHttpTransaction *,
112 : nsresult reason);
113 : MOZ_MUST_USE nsresult CancelTransactions(nsHttpConnectionInfo *,
114 : nsresult reason);
115 :
116 : // called to force the connection manager to prune its list of idle
117 : // connections.
118 : MOZ_MUST_USE nsresult PruneDeadConnections();
119 :
120 : // called to close active connections with no registered "traffic"
121 : MOZ_MUST_USE nsresult PruneNoTraffic();
122 :
123 : // "VerifyTraffic" means marking connections now, and then check again in
124 : // N seconds to see if there's been any traffic and if not, kill
125 : // that connection.
126 : MOZ_MUST_USE nsresult VerifyTraffic();
127 :
128 : // Close all idle persistent connections and prevent any active connections
129 : // from being reused. Optional connection info resets CI specific
130 : // information such as Happy Eyeballs history.
131 : MOZ_MUST_USE nsresult DoShiftReloadConnectionCleanup(nsHttpConnectionInfo *);
132 :
133 : // called to get a reference to the socket transport service. the socket
134 : // transport service is not available when the connection manager is down.
135 : MOZ_MUST_USE nsresult GetSocketThreadTarget(nsIEventTarget **);
136 :
137 : // called to indicate a transaction for the connectionInfo is likely coming
138 : // soon. The connection manager may use this information to start a TCP
139 : // and/or SSL level handshake for that resource immediately so that it is
140 : // ready when the transaction is submitted. No obligation is taken on by the
141 : // connection manager, nor is the submitter obligated to actually submit a
142 : // real transaction for this connectionInfo.
143 : MOZ_MUST_USE nsresult SpeculativeConnect(nsHttpConnectionInfo *,
144 : nsIInterfaceRequestor *,
145 : uint32_t caps = 0,
146 : NullHttpTransaction * = nullptr);
147 :
148 : // called when a connection is done processing a transaction. if the
149 : // connection can be reused then it will be added to the idle list, else
150 : // it will be closed.
151 : MOZ_MUST_USE nsresult ReclaimConnection(nsHttpConnection *conn);
152 :
153 : // called by the main thread to execute the taketransport() logic on the
154 : // socket thread after a 101 response has been received and the socket
155 : // needs to be transferred to an expectant upgrade listener such as
156 : // websockets.
157 : MOZ_MUST_USE nsresult
158 : CompleteUpgrade(nsAHttpConnection *aConn,
159 : nsIHttpUpgradeListener *aUpgradeListener);
160 :
161 : // called to update a parameter after the connection manager has already
162 : // been initialized.
163 : MOZ_MUST_USE nsresult UpdateParam(nsParamName name, uint16_t value);
164 :
165 : // called from main thread to post a new request token bucket
166 : // to the socket thread
167 : MOZ_MUST_USE nsresult UpdateRequestTokenBucket(EventTokenBucket *aBucket);
168 :
169 : // clears the connection history mCT
170 : MOZ_MUST_USE nsresult ClearConnectionHistory();
171 :
172 : void ReportFailedToProcess(nsIURI *uri);
173 :
174 : // Causes a large amount of connection diagnostic information to be
175 : // printed to the javascript console
176 : void PrintDiagnostics();
177 :
178 : //-------------------------------------------------------------------------
179 : // NOTE: functions below may be called only on the socket thread.
180 : //-------------------------------------------------------------------------
181 :
182 : // called to change the connection entry associated with conn from specific into
183 : // a wildcard (i.e. http2 proxy friendy) mapping
184 : void MoveToWildCardConnEntry(nsHttpConnectionInfo *specificCI,
185 : nsHttpConnectionInfo *wildcardCI,
186 : nsHttpConnection *conn);
187 :
188 : // called to force the transaction queue to be processed once more, giving
189 : // preference to the specified connection.
190 : MOZ_MUST_USE nsresult ProcessPendingQ(nsHttpConnectionInfo *);
191 : MOZ_MUST_USE bool ProcessPendingQForEntry(nsHttpConnectionInfo *);
192 :
193 : // Try and process all pending transactions
194 : MOZ_MUST_USE nsresult ProcessPendingQ();
195 :
196 : // This is used to force an idle connection to be closed and removed from
197 : // the idle connection list. It is called when the idle connection detects
198 : // that the network peer has closed the transport.
199 : MOZ_MUST_USE nsresult CloseIdleConnection(nsHttpConnection *);
200 : MOZ_MUST_USE nsresult RemoveIdleConnection(nsHttpConnection *);
201 :
202 : // The connection manager needs to know when a normal HTTP connection has been
203 : // upgraded to SPDY because the dispatch and idle semantics are a little
204 : // bit different.
205 : void ReportSpdyConnection(nsHttpConnection *, bool usingSpdy);
206 :
207 : bool GetConnectionData(nsTArray<HttpRetParams> *);
208 :
209 : void ResetIPFamilyPreference(nsHttpConnectionInfo *);
210 :
211 0 : uint16_t MaxRequestDelay() { return mMaxRequestDelay; }
212 :
213 : // public, so that the SPDY/http2 seesions can activate
214 : void ActivateTimeoutTick();
215 :
216 : nsresult UpdateCurrentTopLevelOuterContentWindowId(uint64_t aWindowId);
217 :
218 : // tracks and untracks active transactions according their throttle status
219 : void AddActiveTransaction(nsHttpTransaction* aTrans, bool aThrottled);
220 : void RemoveActiveTransaction(nsHttpTransaction* aTrans, bool aThrottled);
221 : void MoveActiveTransaction(nsHttpTransaction* aTrans, bool aThrottled);
222 :
223 : // called by nsHttpTransaction::WriteSegments. decides whether the transaction
224 : // should stop reading data based on: the throttling ticker status, overall
225 : // status of all active transactions regarding active tab and respective
226 : // throttling state.
227 : bool ShouldStopReading(nsHttpTransaction* aTrans, bool aThrottled);
228 :
229 : // return true iff the connection has pending transactions for the active tab.
230 : // it's mainly used to disallow throttling (stop reading) of a response
231 : // belonging to the same conn info to free up a connection ASAP.
232 : // NOTE: relatively expensive to call, there are two hashtable lookups.
233 : bool IsConnEntryUnderPressure(nsHttpConnectionInfo*);
234 :
235 : private:
236 : virtual ~nsHttpConnectionMgr();
237 :
238 : class nsHalfOpenSocket;
239 : class PendingTransactionInfo;
240 :
241 : // nsConnectionEntry
242 : //
243 : // mCT maps connection info hash key to nsConnectionEntry object, which
244 : // contains list of active and idle connections as well as the list of
245 : // pending transactions.
246 : //
247 : class nsConnectionEntry : public SupportsWeakPtr<nsConnectionEntry>
248 : {
249 : public:
250 16 : MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsConnectionEntry)
251 : explicit nsConnectionEntry(nsHttpConnectionInfo *ci);
252 : ~nsConnectionEntry();
253 :
254 : RefPtr<nsHttpConnectionInfo> mConnInfo;
255 : nsTArray<RefPtr<PendingTransactionInfo> > mUrgentStartQ;// the urgent start transaction queue
256 :
257 : // This table provides a mapping from top level outer content window id
258 : // to a queue of pending transaction information.
259 : // The transaction's order in pending queue is decided by whether it's a
260 : // blocking transaction and its priority.
261 : // Note that the window id could be 0 if the http request
262 : // is initialized without a window.
263 : nsClassHashtable<nsUint64HashKey,
264 : nsTArray<RefPtr<PendingTransactionInfo>>> mPendingTransactionTable;
265 : nsTArray<RefPtr<nsHttpConnection> > mActiveConns; // active connections
266 : nsTArray<RefPtr<nsHttpConnection> > mIdleConns; // idle persistent connections
267 : nsTArray<nsHalfOpenSocket*> mHalfOpens; // half open connections
268 : nsTArray<RefPtr<nsHalfOpenSocket> > mHalfOpenFastOpenBackups; // backup half open connections for connection in fast open phase
269 :
270 : bool AvailableForDispatchNow();
271 :
272 : // calculate the number of half open sockets that have not had at least 1
273 : // connection complete
274 : uint32_t UnconnectedHalfOpens();
275 :
276 : // Remove a particular half open socket from the mHalfOpens array
277 : void RemoveHalfOpen(nsHalfOpenSocket *);
278 :
279 : // Spdy sometimes resolves the address in the socket manager in order
280 : // to re-coalesce sharded HTTP hosts. The dotted decimal address is
281 : // combined with the Anonymous flag and OA from the connection information
282 : // to build the hash key for hosts in the same ip pool.
283 : //
284 : nsTArray<nsCString> mCoalescingKeys;
285 :
286 : // To have the UsingSpdy flag means some host with the same connection
287 : // entry has done NPN=spdy/* at some point. It does not mean every
288 : // connection is currently using spdy.
289 : bool mUsingSpdy : 1;
290 :
291 : // Flags to remember our happy-eyeballs decision.
292 : // Reset only by Ctrl-F5 reload.
293 : // True when we've first connected an IPv4 server for this host,
294 : // initially false.
295 : bool mPreferIPv4 : 1;
296 : // True when we've first connected an IPv6 server for this host,
297 : // initially false.
298 : bool mPreferIPv6 : 1;
299 :
300 : // True if this connection entry has initiated a socket
301 : bool mUsedForConnection : 1;
302 :
303 : // Try using TCP Fast Open.
304 : bool mUseFastOpen : 1;
305 :
306 : bool mDoNotDestroy : 1;
307 :
308 : // Set the IP family preference flags according the connected family
309 : void RecordIPFamilyPreference(uint16_t family);
310 : // Resets all flags to their default values
311 : void ResetIPFamilyPreference();
312 :
313 : // Return the count of pending transactions for all window ids.
314 : size_t PendingQLength() const;
315 :
316 : // Add a transaction information into the pending queue in
317 : // |mPendingTransactionTable| according to the transaction's
318 : // top level outer content window id.
319 : void InsertTransaction(PendingTransactionInfo *info,
320 : bool aInsertAsFirstForTheSamePriority = false);
321 :
322 : // Append transactions to the |result| whose window id
323 : // is equal to |windowId|.
324 : // NOTE: maxCount == 0 will get all transactions in the queue.
325 : void AppendPendingQForFocusedWindow(
326 : uint64_t windowId,
327 : nsTArray<RefPtr<PendingTransactionInfo>> &result,
328 : uint32_t maxCount = 0);
329 :
330 : // Append transactions whose window id isn't equal to |windowId|.
331 : // NOTE: windowId == 0 will get all transactions for both
332 : // focused and non-focused windows.
333 : void AppendPendingQForNonFocusedWindows(
334 : uint64_t windowId,
335 : nsTArray<RefPtr<PendingTransactionInfo>> &result,
336 : uint32_t maxCount = 0);
337 :
338 : // Remove the empty pendingQ in |mPendingTransactionTable|.
339 : void RemoveEmptyPendingQ();
340 : };
341 :
342 : public:
343 : static nsAHttpConnection *MakeConnectionHandle(nsHttpConnection *aWrapped);
344 : void RegisterOriginCoalescingKey(nsHttpConnection *, const nsACString &host, int32_t port);
345 :
346 : private:
347 :
348 : // nsHalfOpenSocket is used to hold the state of an opening TCP socket
349 : // while we wait for it to establish and bind it to a connection
350 :
351 : class nsHalfOpenSocket final : public nsIOutputStreamCallback,
352 : public nsITransportEventSink,
353 : public nsIInterfaceRequestor,
354 : public nsITimerCallback,
355 : public nsSupportsWeakReference,
356 : public TCPFastOpen
357 : {
358 : ~nsHalfOpenSocket();
359 :
360 : public:
361 : NS_DECLARE_STATIC_IID_ACCESSOR(NS_HALFOPENSOCKET_IID)
362 : NS_DECL_THREADSAFE_ISUPPORTS
363 : NS_DECL_NSIOUTPUTSTREAMCALLBACK
364 : NS_DECL_NSITRANSPORTEVENTSINK
365 : NS_DECL_NSIINTERFACEREQUESTOR
366 : NS_DECL_NSITIMERCALLBACK
367 :
368 : nsHalfOpenSocket(nsConnectionEntry *ent,
369 : nsAHttpTransaction *trans,
370 : uint32_t caps,
371 : bool speculative,
372 : bool isFromPredictor);
373 :
374 : MOZ_MUST_USE nsresult SetupStreams(nsISocketTransport **,
375 : nsIAsyncInputStream **,
376 : nsIAsyncOutputStream **,
377 : bool isBackup);
378 : MOZ_MUST_USE nsresult SetupPrimaryStreams();
379 : MOZ_MUST_USE nsresult SetupBackupStreams();
380 : void SetupBackupTimer();
381 : void CancelBackupTimer();
382 : void Abandon();
383 : double Duration(TimeStamp epoch);
384 0 : nsISocketTransport *SocketTransport() { return mSocketTransport; }
385 0 : nsISocketTransport *BackupTransport() { return mBackupTransport; }
386 :
387 : nsAHttpTransaction *Transaction() { return mTransaction; }
388 :
389 1 : bool IsSpeculative() { return mSpeculative; }
390 :
391 0 : bool IsFromPredictor() { return mIsFromPredictor; }
392 :
393 3 : bool Allow1918() { return mAllow1918; }
394 0 : void SetAllow1918(bool val) { mAllow1918 = val; }
395 :
396 0 : bool HasConnected() { return mHasConnected; }
397 :
398 : void PrintDiagnostics(nsCString &log);
399 :
400 : bool Claim();
401 : void Unclaim();
402 :
403 : bool FastOpenEnabled() override;
404 : nsresult StartFastOpen() override;
405 : void SetFastOpenConnected(nsresult, bool aWillRetry) override;
406 : void FastOpenNotSupported() override;
407 : void SetFastOpenStatus(uint8_t tfoStatus) override;
408 : void CancelFastOpenConnection();
409 : private:
410 : nsresult SetupConn(nsIAsyncOutputStream *out,
411 : bool aFastOpen);
412 :
413 : // To find out whether |mTransaction| is still in the connection entry's
414 : // pending queue. If the transaction is found and |removeWhenFound| is
415 : // true, the transaction will be removed from the pending queue.
416 : already_AddRefed<PendingTransactionInfo>
417 : FindTransactionHelper(bool removeWhenFound);
418 :
419 : WeakPtr<nsConnectionEntry> mEnt;
420 : RefPtr<nsAHttpTransaction> mTransaction;
421 : bool mDispatchedMTransaction;
422 : nsCOMPtr<nsISocketTransport> mSocketTransport;
423 : nsCOMPtr<nsIAsyncOutputStream> mStreamOut;
424 : nsCOMPtr<nsIAsyncInputStream> mStreamIn;
425 : uint32_t mCaps;
426 :
427 : // mSpeculative is set if the socket was created from
428 : // SpeculativeConnect(). It is cleared when a transaction would normally
429 : // start a new connection from scratch but instead finds this one in
430 : // the half open list and claims it for its own use. (which due to
431 : // the vagaries of scheduling from the pending queue might not actually
432 : // match up - but it prevents a speculative connection from opening
433 : // more connections that are needed.)
434 : bool mSpeculative;
435 :
436 : // mIsFromPredictor is set if the socket originated from the network
437 : // Predictor. It is used to gather telemetry data on used speculative
438 : // connections from the predictor.
439 : bool mIsFromPredictor;
440 :
441 : bool mAllow1918;
442 :
443 : TimeStamp mPrimarySynStarted;
444 : TimeStamp mBackupSynStarted;
445 :
446 : // for syn retry
447 : nsCOMPtr<nsITimer> mSynTimer;
448 : nsCOMPtr<nsISocketTransport> mBackupTransport;
449 : nsCOMPtr<nsIAsyncOutputStream> mBackupStreamOut;
450 : nsCOMPtr<nsIAsyncInputStream> mBackupStreamIn;
451 :
452 : // mHasConnected tracks whether one of the sockets has completed the
453 : // connection process. It may have completed unsuccessfully.
454 : bool mHasConnected;
455 :
456 : bool mPrimaryConnectedOK;
457 : bool mBackupConnectedOK;
458 :
459 : // A nsHalfOpenSocket can be made for a concrete non-null transaction,
460 : // but the transaction can be dispatch to another connection. In that
461 : // case we can free this transaction to be claimed by other
462 : // transactions.
463 : bool mFreeToUse;
464 : nsresult mPrimaryStreamStatus;
465 :
466 : bool mFastOpenInProgress;
467 : RefPtr<nsHttpConnection> mConnectionNegotiatingFastOpen;
468 : };
469 : friend class nsHalfOpenSocket;
470 :
471 : class PendingTransactionInfo : public ARefBase
472 : {
473 : public:
474 3 : explicit PendingTransactionInfo(nsHttpTransaction * trans)
475 3 : : mTransaction(trans)
476 3 : {}
477 :
478 44 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(PendingTransactionInfo)
479 :
480 : void PrintDiagnostics(nsCString &log);
481 : public: // meant to be public.
482 : RefPtr<nsHttpTransaction> mTransaction;
483 : nsWeakPtr mHalfOpen;
484 : nsWeakPtr mActiveConn;
485 :
486 : private:
487 9 : virtual ~PendingTransactionInfo() {}
488 : };
489 : friend class PendingTransactionInfo;
490 :
491 : class PendingComparator
492 : {
493 : public:
494 16 : bool Equals(const PendingTransactionInfo *aPendingTrans,
495 : const nsAHttpTransaction *aTrans) const {
496 16 : return aPendingTrans->mTransaction.get() == aTrans;
497 : }
498 : };
499 :
500 : //-------------------------------------------------------------------------
501 : // NOTE: these members may be accessed from any thread (use mReentrantMonitor)
502 : //-------------------------------------------------------------------------
503 :
504 : ReentrantMonitor mReentrantMonitor;
505 : nsCOMPtr<nsIEventTarget> mSocketThreadTarget;
506 :
507 : // connection limits
508 : uint16_t mMaxUrgentExcessiveConns;
509 : uint16_t mMaxConns;
510 : uint16_t mMaxPersistConnsPerHost;
511 : uint16_t mMaxPersistConnsPerProxy;
512 : uint16_t mMaxRequestDelay; // in seconds
513 : bool mThrottleEnabled;
514 : uint32_t mThrottleSuspendFor;
515 : uint32_t mThrottleResumeFor;
516 : uint32_t mThrottleResumeIn;
517 : Atomic<bool, mozilla::Relaxed> mIsShuttingDown;
518 :
519 : //-------------------------------------------------------------------------
520 : // NOTE: these members are only accessed on the socket transport thread
521 : //-------------------------------------------------------------------------
522 :
523 : MOZ_MUST_USE bool ProcessPendingQForEntry(nsConnectionEntry *,
524 : bool considerAll);
525 : bool DispatchPendingQ(nsTArray<RefPtr<PendingTransactionInfo>> &pendingQ,
526 : nsConnectionEntry *ent,
527 : bool considerAll);
528 :
529 : // Return total active connection count, which is the sum of
530 : // active connections and unconnected half open connections.
531 : uint32_t TotalActiveConnections(nsConnectionEntry *ent) const;
532 :
533 : // Return |mMaxPersistConnsPerProxy| or |mMaxPersistConnsPerHost|,
534 : // depending whether the proxy is used.
535 : uint32_t MaxPersistConnections(nsConnectionEntry *ent) const;
536 :
537 : bool AtActiveConnectionLimit(nsConnectionEntry *, uint32_t caps);
538 : MOZ_MUST_USE nsresult TryDispatchTransaction(nsConnectionEntry *ent,
539 : bool onlyReusedConnection,
540 : PendingTransactionInfo *pendingTransInfo);
541 : MOZ_MUST_USE nsresult DispatchTransaction(nsConnectionEntry *,
542 : nsHttpTransaction *,
543 : nsHttpConnection *);
544 : MOZ_MUST_USE nsresult DispatchAbstractTransaction(nsConnectionEntry *,
545 : nsAHttpTransaction *,
546 : uint32_t,
547 : nsHttpConnection *,
548 : int32_t);
549 : bool RestrictConnections(nsConnectionEntry *);
550 : MOZ_MUST_USE nsresult ProcessNewTransaction(nsHttpTransaction *);
551 : MOZ_MUST_USE nsresult EnsureSocketThreadTarget();
552 : void ClosePersistentConnections(nsConnectionEntry *ent);
553 : void ReportProxyTelemetry(nsConnectionEntry *ent);
554 : MOZ_MUST_USE nsresult CreateTransport(nsConnectionEntry *,
555 : nsAHttpTransaction *, uint32_t, bool,
556 : bool, bool,
557 : PendingTransactionInfo *pendingTransInfo);
558 : void AddActiveConn(nsHttpConnection *, nsConnectionEntry *);
559 : void DecrementActiveConnCount(nsHttpConnection *);
560 : void StartedConnect();
561 : void RecvdConnect();
562 :
563 : // This function will unclaim the claimed connection or set a halfOpen
564 : // socket to the speculative state if the transaction claiming them ends up
565 : // using another connection.
566 : void ReleaseClaimedSockets(nsConnectionEntry *ent,
567 : PendingTransactionInfo * pendingTransInfo);
568 :
569 : void InsertTransactionSorted(nsTArray<RefPtr<PendingTransactionInfo> > &pendingQ,
570 : PendingTransactionInfo *pendingTransInfo,
571 : bool aInsertAsFirstForTheSamePriority = false);
572 :
573 : nsConnectionEntry *GetOrCreateConnectionEntry(nsHttpConnectionInfo *,
574 : bool allowWildCard);
575 :
576 : MOZ_MUST_USE nsresult MakeNewConnection(nsConnectionEntry *ent,
577 : PendingTransactionInfo *pendingTransInfo);
578 :
579 : // Manage h2 connection coalescing
580 : // The hashtable contains arrays of weak pointers to nsHttpConnections
581 : nsClassHashtable<nsCStringHashKey, nsTArray<nsWeakPtr> > mCoalescingHash;
582 :
583 : nsHttpConnection *FindCoalescableConnection(nsConnectionEntry *ent, bool justKidding);
584 : nsHttpConnection *FindCoalescableConnectionByHashKey(nsConnectionEntry *ent, const nsCString &key, bool justKidding);
585 : void UpdateCoalescingForNewConn(nsHttpConnection *conn, nsConnectionEntry *ent);
586 : nsHttpConnection *GetSpdyActiveConn(nsConnectionEntry *ent);
587 :
588 : void ProcessSpdyPendingQ(nsConnectionEntry *ent);
589 : void DispatchSpdyPendingQ(nsTArray<RefPtr<PendingTransactionInfo>> &pendingQ,
590 : nsConnectionEntry *ent,
591 : nsHttpConnection *conn);
592 : // used to marshall events to the socket transport thread.
593 : MOZ_MUST_USE nsresult PostEvent(nsConnEventHandler handler,
594 : int32_t iparam = 0,
595 : ARefBase *vparam = nullptr);
596 :
597 : // Used to close all transactions in the |pendingQ| with the given |reason|.
598 : // Note that the |pendingQ| will be also cleared.
599 : void CancelTransactionsHelper(
600 : nsTArray<RefPtr<PendingTransactionInfo>> &pendingQ,
601 : const nsHttpConnectionInfo *ci,
602 : const nsConnectionEntry *ent,
603 : nsresult reason);
604 :
605 : // message handlers
606 : void OnMsgShutdown (int32_t, ARefBase *);
607 : void OnMsgShutdownConfirm (int32_t, ARefBase *);
608 : void OnMsgNewTransaction (int32_t, ARefBase *);
609 : void OnMsgReschedTransaction (int32_t, ARefBase *);
610 : void OnMsgUpdateClassOfServiceOnTransaction (int32_t, ARefBase *);
611 : void OnMsgCancelTransaction (int32_t, ARefBase *);
612 : void OnMsgCancelTransactions (int32_t, ARefBase *);
613 : void OnMsgProcessPendingQ (int32_t, ARefBase *);
614 : void OnMsgPruneDeadConnections (int32_t, ARefBase *);
615 : void OnMsgSpeculativeConnect (int32_t, ARefBase *);
616 : void OnMsgReclaimConnection (int32_t, ARefBase *);
617 : void OnMsgCompleteUpgrade (int32_t, ARefBase *);
618 : void OnMsgUpdateParam (int32_t, ARefBase *);
619 : void OnMsgDoShiftReloadConnectionCleanup (int32_t, ARefBase *);
620 : void OnMsgProcessFeedback (int32_t, ARefBase *);
621 : void OnMsgProcessAllSpdyPendingQ (int32_t, ARefBase *);
622 : void OnMsgUpdateRequestTokenBucket (int32_t, ARefBase *);
623 : void OnMsgVerifyTraffic (int32_t, ARefBase *);
624 : void OnMsgPruneNoTraffic (int32_t, ARefBase *);
625 : void OnMsgUpdateCurrentTopLevelOuterContentWindowId (int32_t, ARefBase *);
626 :
627 : // Total number of active connections in all of the ConnectionEntry objects
628 : // that are accessed from mCT connection table.
629 : uint16_t mNumActiveConns;
630 : // Total number of idle connections in all of the ConnectionEntry objects
631 : // that are accessed from mCT connection table.
632 : uint16_t mNumIdleConns;
633 : // Total number of spdy connections which are a subset of the active conns
634 : uint16_t mNumSpdyActiveConns;
635 : // Total number of connections in mHalfOpens ConnectionEntry objects
636 : // that are accessed from mCT connection table
637 : uint32_t mNumHalfOpenConns;
638 :
639 : // Holds time in seconds for next wake-up to prune dead connections.
640 : uint64_t mTimeOfNextWakeUp;
641 : // Timer for next pruning of dead connections.
642 : nsCOMPtr<nsITimer> mTimer;
643 : // Timer for pruning stalled connections after changed network.
644 : nsCOMPtr<nsITimer> mTrafficTimer;
645 : bool mPruningNoTraffic;
646 :
647 : // A 1s tick to call nsHttpConnection::ReadTimeoutTick on
648 : // active http/1 connections and check for orphaned half opens.
649 : // Disabled when there are no active or half open connections.
650 : nsCOMPtr<nsITimer> mTimeoutTick;
651 : bool mTimeoutTickArmed;
652 : uint32_t mTimeoutTickNext;
653 :
654 : //
655 : // the connection table
656 : //
657 : // this table is indexed by connection key. each entry is a
658 : // nsConnectionEntry object. It is unlocked and therefore must only
659 : // be accessed from the socket thread.
660 : //
661 : nsClassHashtable<nsCStringHashKey, nsConnectionEntry> mCT;
662 :
663 : // Read Timeout Tick handlers
664 : void TimeoutTick();
665 :
666 : // For diagnostics
667 : void OnMsgPrintDiagnostics(int32_t, ARefBase *);
668 :
669 : nsCString mLogData;
670 : uint64_t mCurrentTopLevelOuterContentWindowId;
671 :
672 : // Called on a pref change
673 : void SetThrottlingEnabled(bool aEnable);
674 :
675 : // Two hashtalbes keeping track of active transactions regarding window id and throttling.
676 : // Used by the throttling algorithm to obtain number of transactions for the active tab
677 : // and for inactive tabs according their throttle status.
678 : // mActiveTransactions[0] are all unthrottled transactions, mActiveTransactions[1] throttled.
679 : nsClassHashtable<nsUint64HashKey, nsTArray<RefPtr<nsHttpTransaction>>> mActiveTransactions[2];
680 :
681 : // Whether we are inside the "stop reading" interval, altered by the throttle ticker
682 : bool mThrottlingInhibitsReading;
683 :
684 : // ticker for the 'stop reading'/'resume reading' signal
685 : nsCOMPtr<nsITimer> mThrottleTicker;
686 : // Checks if the combination of active transactions requires the ticker.
687 : bool IsThrottleTickerNeeded();
688 : // The method also unschedules the delayed resume of background tabs timer
689 : // if the ticker was about to be scheduled.
690 : void EnsureThrottleTickerIfNeeded();
691 : // Drops also the mThrottlingInhibitsReading flag. Immediate or delayed resume
692 : // of currently throttled transactions is not affected by this method.
693 : void DestroyThrottleTicker();
694 : // Handler for the ticker: alters the mThrottlingInhibitsReading flag.
695 : void ThrottlerTick();
696 :
697 : // mechanism to delay immediate resume of background tabs and chrome initiated
698 : // throttled transactions after the last transaction blocking their unthrottle
699 : // has been removed. Needs to be delayed because during a page load there is
700 : // a number of intervals when there is no transaction that would cause throttling.
701 : // Hence, throttling of long standing responses, like downloads, would be mostly
702 : // ineffective if resumed during every such interval.
703 : nsCOMPtr<nsITimer> mDelayedResumeReadTimer;
704 : // Schedule the resume
705 : void DelayedResumeBackgroundThrottledTransactions();
706 : // Simply destroys the timer
707 : void CancelDelayedResumeBackgroundThrottledTransactions();
708 : // Handler for the timer: resumes all background throttled transactions
709 : void ResumeBackgroundThrottledTransactions();
710 :
711 : // Simple helpers, iterates the given hash/array and resume.
712 : // @param excludeActive: skip active tabid transactions.
713 : void ResumeReadOf(nsClassHashtable<nsUint64HashKey, nsTArray<RefPtr<nsHttpTransaction>>>&,
714 : bool excludeActive = false);
715 : void ResumeReadOf(nsTArray<RefPtr<nsHttpTransaction>>*);
716 :
717 : // Cached status of the active tab active transactions existence,
718 : // saves a lot of hashtable lookups
719 : bool mActiveTabTransactionsExist;
720 : bool mActiveTabUnthrottledTransactionsExist;
721 :
722 : void LogActiveTransactions(char);
723 : };
724 :
725 : NS_DEFINE_STATIC_IID_ACCESSOR(nsHttpConnectionMgr::nsHalfOpenSocket, NS_HALFOPENSOCKET_IID)
726 :
727 : } // namespace net
728 : } // namespace mozilla
729 :
730 : #endif // !nsHttpConnectionMgr_h__
|