LCOV - code coverage report
Current view: top level - netwerk/protocol/websocket - WebSocketChannel.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 10 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 4 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set sw=2 ts=8 et tw=80 : */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef mozilla_net_WebSocketChannel_h
       8             : #define mozilla_net_WebSocketChannel_h
       9             : 
      10             : #include "nsISupports.h"
      11             : #include "nsIInterfaceRequestor.h"
      12             : #include "nsIStreamListener.h"
      13             : #include "nsIAsyncInputStream.h"
      14             : #include "nsIAsyncOutputStream.h"
      15             : #include "nsITimer.h"
      16             : #include "nsIDNSListener.h"
      17             : #include "nsIObserver.h"
      18             : #include "nsIProtocolProxyCallback.h"
      19             : #include "nsIChannelEventSink.h"
      20             : #include "nsIHttpChannelInternal.h"
      21             : #include "nsIStringStream.h"
      22             : #include "BaseWebSocketChannel.h"
      23             : 
      24             : #include "nsCOMPtr.h"
      25             : #include "nsString.h"
      26             : #include "nsDeque.h"
      27             : #include "mozilla/Atomics.h"
      28             : 
      29             : class nsIAsyncVerifyRedirectCallback;
      30             : class nsIDashboardEventNotifier;
      31             : class nsIEventTarget;
      32             : class nsIHttpChannel;
      33             : class nsIRandomGenerator;
      34             : class nsISocketTransport;
      35             : class nsIURI;
      36             : 
      37             : namespace mozilla {
      38             : namespace net {
      39             : 
      40             : class OutboundMessage;
      41             : class OutboundEnqueuer;
      42             : class nsWSAdmissionManager;
      43             : class PMCECompression;
      44             : class CallOnMessageAvailable;
      45             : class CallOnStop;
      46             : class CallOnServerClose;
      47             : class CallAcknowledge;
      48             : class WebSocketEventService;
      49             : 
      50             : extern MOZ_MUST_USE nsresult
      51             : CalculateWebSocketHashedSecret(const nsACString& aKey, nsACString& aHash);
      52             : extern void
      53             : ProcessServerWebSocketExtensions(const nsACString& aExtensions,
      54             :                                  nsACString& aNegotiatedExtensions);
      55             : 
      56             : // Used to enforce "1 connecting websocket per host" rule, and reconnect delays
      57             : enum wsConnectingState {
      58             :   NOT_CONNECTING = 0,     // Not yet (or no longer) trying to open connection
      59             :   CONNECTING_QUEUED,      // Waiting for other ws to same host to finish opening
      60             :   CONNECTING_DELAYED,     // Delayed by "reconnect after failure" algorithm
      61             :   CONNECTING_IN_PROGRESS  // Started connection: waiting for result
      62             : };
      63             : 
      64             : class WebSocketChannel : public BaseWebSocketChannel,
      65             :                          public nsIHttpUpgradeListener,
      66             :                          public nsIStreamListener,
      67             :                          public nsIInputStreamCallback,
      68             :                          public nsIOutputStreamCallback,
      69             :                          public nsITimerCallback,
      70             :                          public nsIDNSListener,
      71             :                          public nsIObserver,
      72             :                          public nsIProtocolProxyCallback,
      73             :                          public nsIInterfaceRequestor,
      74             :                          public nsIChannelEventSink
      75             : {
      76             :   friend class WebSocketFrame;
      77             : 
      78             : public:
      79             :   NS_DECL_THREADSAFE_ISUPPORTS
      80             :   NS_DECL_NSIHTTPUPGRADELISTENER
      81             :   NS_DECL_NSIREQUESTOBSERVER
      82             :   NS_DECL_NSISTREAMLISTENER
      83             :   NS_DECL_NSIINPUTSTREAMCALLBACK
      84             :   NS_DECL_NSIOUTPUTSTREAMCALLBACK
      85             :   NS_DECL_NSITIMERCALLBACK
      86             :   NS_DECL_NSIDNSLISTENER
      87             :   NS_DECL_NSIPROTOCOLPROXYCALLBACK
      88             :   NS_DECL_NSIINTERFACEREQUESTOR
      89             :   NS_DECL_NSICHANNELEVENTSINK
      90             :   NS_DECL_NSIOBSERVER
      91             : 
      92             :   // nsIWebSocketChannel methods BaseWebSocketChannel didn't implement for us
      93             :   //
      94             :   NS_IMETHOD AsyncOpen(nsIURI *aURI,
      95             :                        const nsACString &aOrigin,
      96             :                        uint64_t aWindowID,
      97             :                        nsIWebSocketListener *aListener,
      98             :                        nsISupports *aContext) override;
      99             :   NS_IMETHOD Close(uint16_t aCode, const nsACString & aReason) override;
     100             :   NS_IMETHOD SendMsg(const nsACString &aMsg) override;
     101             :   NS_IMETHOD SendBinaryMsg(const nsACString &aMsg) override;
     102             :   NS_IMETHOD SendBinaryStream(nsIInputStream *aStream, uint32_t length) override;
     103             :   NS_IMETHOD GetSecurityInfo(nsISupports **aSecurityInfo) override;
     104             : 
     105             :   WebSocketChannel();
     106             :   static void Shutdown();
     107             :   bool IsOnTargetThread();
     108             : 
     109             :   // Off main thread URI access.
     110             :   void GetEffectiveURL(nsAString& aEffectiveURL) const override;
     111             :   bool IsEncrypted() const override;
     112             : 
     113             :   const static uint32_t kControlFrameMask   = 0x8;
     114             : 
     115             :   // First byte of the header
     116             :   const static uint8_t kFinalFragBit        = 0x80;
     117             :   const static uint8_t kRsvBitsMask         = 0x70;
     118             :   const static uint8_t kRsv1Bit             = 0x40;
     119             :   const static uint8_t kRsv2Bit             = 0x20;
     120             :   const static uint8_t kRsv3Bit             = 0x10;
     121             :   const static uint8_t kOpcodeBitsMask      = 0x0F;
     122             : 
     123             :   // Second byte of the header
     124             :   const static uint8_t kMaskBit             = 0x80;
     125             :   const static uint8_t kPayloadLengthBitsMask = 0x7F;
     126             : 
     127             : protected:
     128             :   virtual ~WebSocketChannel();
     129             : 
     130             : private:
     131             :   friend class OutboundEnqueuer;
     132             :   friend class nsWSAdmissionManager;
     133             :   friend class FailDelayManager;
     134             :   friend class CallOnMessageAvailable;
     135             :   friend class CallOnStop;
     136             :   friend class CallOnServerClose;
     137             :   friend class CallAcknowledge;
     138             : 
     139             :   // Common send code for binary + text msgs
     140             :   MOZ_MUST_USE nsresult SendMsgCommon(const nsACString *aMsg, bool isBinary,
     141             :                                       uint32_t length,
     142             :                                       nsIInputStream *aStream = nullptr);
     143             : 
     144             :   void EnqueueOutgoingMessage(nsDeque &aQueue, OutboundMessage *aMsg);
     145             : 
     146             :   void PrimeNewOutgoingMessage();
     147             :   void DeleteCurrentOutGoingMessage();
     148             :   void GeneratePong(uint8_t *payload, uint32_t len);
     149             :   void GeneratePing();
     150             : 
     151             :   MOZ_MUST_USE nsresult OnNetworkChanged();
     152             :   MOZ_MUST_USE nsresult StartPinging();
     153             : 
     154             :   void     BeginOpen(bool aCalledFromAdmissionManager);
     155             :   void     BeginOpenInternal();
     156             :   MOZ_MUST_USE nsresult HandleExtensions();
     157             :   MOZ_MUST_USE nsresult SetupRequest();
     158             :   MOZ_MUST_USE nsresult ApplyForAdmission();
     159             :   MOZ_MUST_USE nsresult DoAdmissionDNS();
     160             :   MOZ_MUST_USE nsresult StartWebsocketData();
     161             :   uint16_t ResultToCloseCode(nsresult resultCode);
     162             :   void     ReportConnectionTelemetry();
     163             : 
     164             :   void StopSession(nsresult reason);
     165             :   void AbortSession(nsresult reason);
     166             :   void ReleaseSession();
     167             :   void CleanupConnection();
     168             :   void IncrementSessionCount();
     169             :   void DecrementSessionCount();
     170             : 
     171             :   void EnsureHdrOut(uint32_t size);
     172             : 
     173             :   static void ApplyMask(uint32_t mask, uint8_t *data, uint64_t len);
     174             : 
     175             :   bool     IsPersistentFramePtr();
     176             :   MOZ_MUST_USE nsresult ProcessInput(uint8_t *buffer, uint32_t count);
     177             :   MOZ_MUST_USE bool UpdateReadBuffer(uint8_t *buffer, uint32_t count,
     178             :                                      uint32_t accumulatedFragments,
     179             :                                      uint32_t *available);
     180             : 
     181           0 :   inline void ResetPingTimer()
     182             :   {
     183           0 :     mPingOutstanding = 0;
     184           0 :     if (mPingTimer) {
     185           0 :       if (!mPingInterval) {
     186             :         // The timer was created by forced ping and regular pinging is disabled,
     187             :         // so cancel and null out mPingTimer.
     188           0 :         mPingTimer->Cancel();
     189           0 :         mPingTimer = nullptr;
     190             :       } else {
     191           0 :         mPingTimer->SetDelay(mPingInterval);
     192             :       }
     193             :     }
     194           0 :   }
     195             : 
     196             :   nsCOMPtr<nsIEventTarget>                 mSocketThread;
     197             :   nsCOMPtr<nsIHttpChannelInternal>         mChannel;
     198             :   nsCOMPtr<nsIHttpChannel>                 mHttpChannel;
     199             :   nsCOMPtr<nsICancelable>                  mCancelable;
     200             :   nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
     201             :   nsCOMPtr<nsIRandomGenerator>             mRandomGenerator;
     202             : 
     203             :   nsCString                       mHashedSecret;
     204             : 
     205             :   // Used as key for connection managment: Initially set to hostname from URI,
     206             :   // then to IP address (unless we're leaving DNS resolution to a proxy server)
     207             :   nsCString                       mAddress;
     208             :   int32_t                         mPort;          // WS server port
     209             : 
     210             :   // Used for off main thread access to the URI string.
     211             :   nsCString                       mHost;
     212             :   nsString                        mEffectiveURL;
     213             : 
     214             :   nsCOMPtr<nsISocketTransport>    mTransport;
     215             :   nsCOMPtr<nsIAsyncInputStream>   mSocketIn;
     216             :   nsCOMPtr<nsIAsyncOutputStream>  mSocketOut;
     217             : 
     218             :   nsCOMPtr<nsITimer>              mCloseTimer;
     219             :   uint32_t                        mCloseTimeout;  /* milliseconds */
     220             : 
     221             :   nsCOMPtr<nsITimer>              mOpenTimer;
     222             :   uint32_t                        mOpenTimeout;  /* milliseconds */
     223             :   wsConnectingState               mConnecting;   /* 0 if not connecting */
     224             :   nsCOMPtr<nsITimer>              mReconnectDelayTimer;
     225             : 
     226             :   nsCOMPtr<nsITimer>              mPingTimer;
     227             : 
     228             :   nsCOMPtr<nsITimer>              mLingeringCloseTimer;
     229             :   const static int32_t            kLingeringCloseTimeout =   1000;
     230             :   const static int32_t            kLingeringCloseThreshold = 50;
     231             : 
     232             :   RefPtr<WebSocketEventService>   mService;
     233             : 
     234             :   int32_t                         mMaxConcurrentConnections;
     235             : 
     236             :   uint64_t                        mInnerWindowID;
     237             : 
     238             :   // following members are accessed only on the main thread
     239             :   uint32_t                        mGotUpgradeOK              : 1;
     240             :   uint32_t                        mRecvdHttpUpgradeTransport : 1;
     241             :   uint32_t                        mAutoFollowRedirects       : 1;
     242             :   uint32_t                        mAllowPMCE                 : 1;
     243             :   uint32_t                                                   : 0;
     244             : 
     245             :   // following members are accessed only on the socket thread
     246             :   uint32_t                        mPingOutstanding           : 1;
     247             :   uint32_t                        mReleaseOnTransmit         : 1;
     248             :   uint32_t                                                   : 0;
     249             : 
     250             :   Atomic<bool>                    mDataStarted;
     251             :   Atomic<bool>                    mRequestedClose;
     252             :   Atomic<bool>                    mClientClosed;
     253             :   Atomic<bool>                    mServerClosed;
     254             :   Atomic<bool>                    mStopped;
     255             :   Atomic<bool>                    mCalledOnStop;
     256             :   Atomic<bool>                    mTCPClosed;
     257             :   Atomic<bool>                    mOpenedHttpChannel;
     258             :   Atomic<bool>                    mIncrementedSessionCount;
     259             :   Atomic<bool>                    mDecrementedSessionCount;
     260             : 
     261             :   int32_t                         mMaxMessageSize;
     262             :   nsresult                        mStopOnClose;
     263             :   uint16_t                        mServerCloseCode;
     264             :   nsCString                       mServerCloseReason;
     265             :   uint16_t                        mScriptCloseCode;
     266             :   nsCString                       mScriptCloseReason;
     267             : 
     268             :   // These are for the read buffers
     269             :   const static uint32_t kIncomingBufferInitialSize = 16 * 1024;
     270             :   // We're ok with keeping a buffer this size or smaller around for the life of
     271             :   // the websocket.  If a particular message needs bigger than this we'll
     272             :   // increase the buffer temporarily, then drop back down to this size.
     273             :   const static uint32_t kIncomingBufferStableSize = 128 * 1024;
     274             : 
     275             :   uint8_t                        *mFramePtr;
     276             :   uint8_t                        *mBuffer;
     277             :   uint8_t                         mFragmentOpcode;
     278             :   uint32_t                        mFragmentAccumulator;
     279             :   uint32_t                        mBuffered;
     280             :   uint32_t                        mBufferSize;
     281             : 
     282             :   // These are for the send buffers
     283             :   const static int32_t kCopyBreak = 1000;
     284             : 
     285             :   OutboundMessage                *mCurrentOut;
     286             :   uint32_t                        mCurrentOutSent;
     287             :   nsDeque                         mOutgoingMessages;
     288             :   nsDeque                         mOutgoingPingMessages;
     289             :   nsDeque                         mOutgoingPongMessages;
     290             :   uint32_t                        mHdrOutToSend;
     291             :   uint8_t                        *mHdrOut;
     292             :   uint8_t                         mOutHeader[kCopyBreak + 16];
     293             :   nsAutoPtr<PMCECompression>      mPMCECompressor;
     294             :   uint32_t                        mDynamicOutputSize;
     295             :   uint8_t                        *mDynamicOutput;
     296             :   bool                            mPrivateBrowsing;
     297             : 
     298             :   nsCOMPtr<nsIDashboardEventNotifier> mConnectionLogService;
     299             : };
     300             : 
     301             : class WebSocketSSLChannel : public WebSocketChannel
     302             : {
     303             : public:
     304           0 :     WebSocketSSLChannel() { BaseWebSocketChannel::mEncrypted = true; }
     305             : protected:
     306           0 :     virtual ~WebSocketSSLChannel() {}
     307             : };
     308             : 
     309             : } // namespace net
     310             : } // namespace mozilla
     311             : 
     312             : #endif // mozilla_net_WebSocketChannel_h

Generated by: LCOV version 1.13