tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TCPSocket.h (9124B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 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 file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_dom_TCPSocket_h
      8 #define mozilla_dom_TCPSocket_h
      9 
     10 #include "js/RootingAPI.h"
     11 #include "mozilla/DOMEventTargetHelper.h"
     12 #include "mozilla/dom/TCPSocketBinding.h"
     13 #include "mozilla/dom/TypedArray.h"
     14 #include "nsIAsyncInputStream.h"
     15 #include "nsIObserver.h"
     16 #include "nsIProtocolProxyCallback.h"
     17 #include "nsIProxyInfo.h"
     18 #include "nsIStreamListener.h"
     19 #include "nsISupportsImpl.h"
     20 #include "nsITCPSocketCallback.h"
     21 #include "nsITransport.h"
     22 #include "nsWeakReference.h"
     23 
     24 class nsISocketTransport;
     25 class nsIInputStreamPump;
     26 class nsIScriptableInputStream;
     27 class nsIBinaryInputStream;
     28 class nsIMultiplexInputStream;
     29 class nsIAsyncStreamCopier;
     30 class nsIInputStream;
     31 class nsINetworkInfo;
     32 
     33 namespace mozilla {
     34 class ErrorResult;
     35 namespace dom {
     36 
     37 struct ServerSocketOptions;
     38 class TCPServerSocket;
     39 class TCPSocketChild;
     40 class TCPSocketParent;
     41 
     42 // This interface is only used for legacy navigator.mozTCPSocket API
     43 // compatibility.
     44 class LegacyMozTCPSocket : public nsISupports {
     45 public:
     46  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     47  NS_DECL_CYCLE_COLLECTION_CLASS(LegacyMozTCPSocket)
     48 
     49  explicit LegacyMozTCPSocket(nsPIDOMWindowInner* aWindow);
     50 
     51  already_AddRefed<TCPServerSocket> Listen(uint16_t aPort,
     52                                           const ServerSocketOptions& aOptions,
     53                                           uint16_t aBacklog, ErrorResult& aRv);
     54 
     55  already_AddRefed<TCPSocket> Open(const nsAString& aHost, uint16_t aPort,
     56                                   const SocketOptions& aOptions,
     57                                   ErrorResult& aRv);
     58 
     59  bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto,
     60                  JS::MutableHandle<JSObject*> aReflector);
     61 
     62 private:
     63  virtual ~LegacyMozTCPSocket();
     64 
     65  nsCOMPtr<nsIGlobalObject> mGlobal;
     66 };
     67 
     68 class TCPSocket final : public DOMEventTargetHelper,
     69                        public nsIStreamListener,
     70                        public nsITransportEventSink,
     71                        public nsIInputStreamCallback,
     72                        public nsIObserver,
     73                        public nsSupportsWeakReference,
     74                        public nsITCPSocketCallback,
     75                        public nsIProtocolProxyCallback {
     76 public:
     77  TCPSocket(nsIGlobalObject* aGlobal, const nsAString& aHost, uint16_t aPort,
     78            bool aSsl, bool aUseArrayBuffers);
     79 
     80  NS_DECL_ISUPPORTS_INHERITED
     81  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(TCPSocket,
     82                                                         DOMEventTargetHelper)
     83  NS_DECL_NSIREQUESTOBSERVER
     84  NS_DECL_NSISTREAMLISTENER
     85  NS_DECL_NSITRANSPORTEVENTSINK
     86  NS_DECL_NSIINPUTSTREAMCALLBACK
     87  NS_DECL_NSIOBSERVER
     88  NS_DECL_NSITCPSOCKETCALLBACK
     89  NS_DECL_NSIPROTOCOLPROXYCALLBACK
     90 
     91  virtual JSObject* WrapObject(JSContext* aCx,
     92                               JS::Handle<JSObject*> aGivenProto) override;
     93 
     94  static bool ShouldTCPSocketExist(JSContext* aCx, JSObject* aGlobal);
     95 
     96  nsISocketTransport* GetTransport() const { return mTransport.get(); }
     97 
     98  void GetHost(nsAString& aHost);
     99  uint32_t Port() const;
    100  bool Ssl() const;
    101  uint64_t BufferedAmount() const { return mBufferedAmount; }
    102  void Suspend();
    103  void Resume(ErrorResult& aRv);
    104  void Close();
    105  void CloseImmediately();
    106  bool Send(const nsACString& aData, ErrorResult& aRv);
    107  bool Send(const ArrayBuffer& aData, uint32_t aByteOffset,
    108            const Optional<uint32_t>& aByteLength, ErrorResult& aRv);
    109  TCPReadyState ReadyState();
    110  TCPSocketBinaryType BinaryType() const;
    111  void UpgradeToSecure(ErrorResult& aRv);
    112 
    113  static already_AddRefed<TCPSocket> Constructor(const GlobalObject& aGlobal,
    114                                                 const nsAString& aHost,
    115                                                 uint16_t aPort,
    116                                                 const SocketOptions& aOptions,
    117                                                 ErrorResult& aRv);
    118 
    119  // Create a TCPSocket object from an existing low-level socket connection.
    120  // Used by the TCPServerSocket implementation when a new connection is
    121  // accepted.
    122  static already_AddRefed<TCPSocket> CreateAcceptedSocket(
    123      nsIGlobalObject* aGlobal, nsISocketTransport* aTransport,
    124      bool aUseArrayBuffers);
    125  // Create a TCPSocket object from an existing child-side IPC actor.
    126  // Used by the TCPServerSocketChild implementation when a new connection is
    127  // accepted.
    128  static already_AddRefed<TCPSocket> CreateAcceptedSocket(
    129      nsIGlobalObject* aGlobal, TCPSocketChild* aBridge, bool aUseArrayBuffers);
    130 
    131  // Initialize this socket's associated IPC actor in the parent process.
    132  void SetSocketBridgeParent(TCPSocketParent* aBridgeParent);
    133 
    134  static bool SocketEnabled();
    135 
    136  IMPL_EVENT_HANDLER(open);
    137  IMPL_EVENT_HANDLER(drain);
    138  IMPL_EVENT_HANDLER(data);
    139  IMPL_EVENT_HANDLER(error);
    140  IMPL_EVENT_HANDLER(close);
    141 
    142  nsresult Init(nsIProxyInfo* aProxyInfo);
    143 
    144  // Inform this socket that a buffered send() has completed sending.
    145  void NotifyCopyComplete(nsresult aStatus);
    146 
    147  // Initialize this socket from a low-level connection that hasn't connected
    148  // yet (called from RecvOpenBind() in TCPSocketParent).
    149  nsresult InitWithUnconnectedTransport(nsISocketTransport* aTransport);
    150 
    151 private:
    152  ~TCPSocket();
    153 
    154  // Initialize this socket with an existing IPC actor.
    155  void InitWithSocketChild(TCPSocketChild* aSocketBridge);
    156  // Initialize this socket from an existing low-level connection.
    157  nsresult InitWithTransport(nsISocketTransport* aTransport);
    158  // Initialize the input/output streams for this socket object.
    159  nsresult CreateStream();
    160  // Initialize the asynchronous read operation from this socket's input stream.
    161  nsresult CreateInputStreamPump();
    162  // Send the contents of the provided input stream, which is assumed to be the
    163  // given length for reporting and buffering purposes.
    164  bool Send(nsIInputStream* aStream, uint32_t aByteLength);
    165  // Begin an asynchronous copy operation if one is not already in progress.
    166  nsresult EnsureCopying();
    167  // Re-calculate buffered amount.
    168  void CalculateBufferedAmount();
    169  // Helper function, should be called by ActivateTLS(), only.
    170  void ActivateTLSHelper();
    171  // Enable TLS on this socket, dispatch to STSThread if necessary.
    172  void ActivateTLS();
    173  // Dispatch an error event if necessary, then dispatch a "close" event.
    174  nsresult MaybeReportErrorAndCloseIfOpen(nsresult status);
    175 
    176  // Helper for FireDataStringEvent/FireDataArrayEvent.
    177  nsresult FireDataEvent(JSContext* aCx, const nsAString& aType,
    178                         JS::Handle<JS::Value> aData);
    179  // Helper for Close/CloseImmediately
    180  void CloseHelper(bool waitForUnsentData);
    181 
    182  nsresult ResolveProxy();
    183 
    184  TCPReadyState mReadyState;
    185  // Whether to use strings or array buffers for the "data" event.
    186  bool mUseArrayBuffers;
    187  nsString mHost;
    188  uint16_t mPort;
    189  // Whether this socket is using a secure transport.
    190  bool mSsl;
    191 
    192  // The associated IPC actor in a child process.
    193  RefPtr<TCPSocketChild> mSocketBridgeChild;
    194  // The associated IPC actor in a parent process.
    195  RefPtr<TCPSocketParent> mSocketBridgeParent;
    196 
    197  // Raw socket streams
    198  nsCOMPtr<nsISocketTransport> mTransport;
    199  nsCOMPtr<nsIInputStream> mSocketInputStream;
    200  nsCOMPtr<nsIOutputStream> mSocketOutputStream;
    201 
    202  nsCOMPtr<nsICancelable> mProxyRequest;
    203 
    204  // Input stream machinery
    205  nsCOMPtr<nsIInputStreamPump> mInputStreamPump;
    206  nsCOMPtr<nsIScriptableInputStream> mInputStreamScriptable;
    207  nsCOMPtr<nsIBinaryInputStream> mInputStreamBinary;
    208 
    209  // Is there an async copy operation in progress?
    210  bool mAsyncCopierActive;
    211  // True if the buffer is full and a "drain" event is expected by the client.
    212  bool mWaitingForDrain;
    213 
    214  // The id of the window that created this socket.
    215  uint64_t mInnerWindowID;
    216 
    217  // The current number of buffered bytes. Only used in content processes when
    218  // IPC is enabled.
    219  uint64_t mBufferedAmount;
    220 
    221  // The number of times this socket has had `Suspend` called without a
    222  // corresponding `Resume`.
    223  uint32_t mSuspendCount;
    224 
    225  // The current sequence number (ie. number of send operations) that have been
    226  // processed. This is used in the IPC scenario by the child process to filter
    227  // out outdated notifications about the amount of buffered data present in the
    228  // parent process.
    229  uint32_t mTrackingNumber;
    230 
    231  // True if this socket has been upgraded to secure after the initial
    232  // connection, but the actual upgrade is waiting for an in-progress copy
    233  // operation to complete.
    234  bool mWaitingForStartTLS;
    235  // The buffered data awaiting the TLS upgrade to finish.
    236  nsTArray<nsCOMPtr<nsIInputStream>> mPendingDataAfterStartTLS;
    237 
    238  // The data to be sent.
    239  nsTArray<nsCOMPtr<nsIInputStream>> mPendingData;
    240 
    241  bool mObserversActive;
    242 };
    243 
    244 }  // namespace dom
    245 }  // namespace mozilla
    246 
    247 #endif  // mozilla_dom_TCPSocket_h