tor-browser

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

TLSTransportLayer.h (6191B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 #ifndef TLSTransportLayer_h__
      6 #define TLSTransportLayer_h__
      7 
      8 #include "nsSocketTransportService2.h"
      9 #include "nsIInterfaceRequestor.h"
     10 #include "nsISocketTransport.h"
     11 #include "nsIAsyncInputStream.h"
     12 #include "nsIAsyncOutputStream.h"
     13 #include "prio.h"
     14 
     15 namespace mozilla::net {
     16 
     17 // TLSTransportLayer will provide a secondary TLS layer. It will be added as a
     18 // layer between nsHttpConnection and nsSocketTransport.
     19 // The mSocketTransport, mSocketIn, and mSocketOut of nsHttpConnection will be
     20 // replaced by TLSTransportLayer.
     21 //
     22 // The input path of reading data from a socket is shown below.
     23 // nsHttpConnection::OnSocketReadable
     24 // nsHttpConnection::OnWriteSegment
     25 // nsHttpConnection::mSocketIn->Read
     26 // TLSTransportLayer::InputStreamWrapper::Read
     27 // TLSTransportLayer::InputInternal
     28 // TLSTransportLayer::InputStreamWrapper::ReadDirectly
     29 // nsSocketInputStream::Read
     30 //
     31 // The output path of writing data to a socket is shown below.
     32 // nsHttpConnection::OnSocketWritable
     33 // nsHttpConnection::OnReadSegment
     34 // TLSTransportLayer::OutputStreamWrapper::Write
     35 // TLSTransportLayer::OutputInternal
     36 // TLSTransportLayer::OutputStreamWrapper::WriteDirectly
     37 // nsSocketOutputStream::Write
     38 
     39 // 9d6a3bc6-1f90-41d0-9b02-33ccd169052b
     40 #define NS_TLSTRANSPORTLAYER_IID \
     41  {0x9d6a3bc6, 0x1f90, 0x41d0, {0x9b, 0x02, 0x33, 0xcc, 0xd1, 0x69, 0x05, 0x2b}}
     42 
     43 class TLSTransportLayer final : public nsISocketTransport,
     44                                public nsIInputStreamCallback,
     45                                public nsIOutputStreamCallback {
     46 public:
     47  NS_INLINE_DECL_STATIC_IID(NS_TLSTRANSPORTLAYER_IID)
     48  NS_DECL_THREADSAFE_ISUPPORTS
     49  NS_DECL_NSITRANSPORT
     50  NS_DECL_NSISOCKETTRANSPORT
     51  NS_DECL_NSIINPUTSTREAMCALLBACK
     52  NS_DECL_NSIOUTPUTSTREAMCALLBACK
     53 
     54  explicit TLSTransportLayer(nsISocketTransport* aTransport,
     55                             nsIAsyncInputStream* aInputStream,
     56                             nsIAsyncOutputStream* aOutputStream,
     57                             nsIInputStreamCallback* aOwner);
     58  bool Init(const char* aTLSHost, int32_t aTLSPort);
     59  already_AddRefed<nsIAsyncInputStream> GetInputStreamWrapper() {
     60    nsCOMPtr<nsIAsyncInputStream> stream = &mSocketInWrapper;
     61    return stream.forget();
     62  }
     63  already_AddRefed<nsIAsyncOutputStream> GetOutputStreamWrapper() {
     64    nsCOMPtr<nsIAsyncOutputStream> stream = &mSocketOutWrapper;
     65    return stream.forget();
     66  }
     67 
     68  bool HasDataToRecv();
     69 
     70  void ReleaseOwner() { mOwner = nullptr; }
     71 
     72 private:
     73  class InputStreamWrapper : public nsIAsyncInputStream {
     74   public:
     75    NS_DECL_THREADSAFE_ISUPPORTS
     76    NS_DECL_NSIINPUTSTREAM
     77    NS_DECL_NSIASYNCINPUTSTREAM
     78 
     79    explicit InputStreamWrapper(nsIAsyncInputStream* aInputStream,
     80                                TLSTransportLayer* aTransport);
     81 
     82    nsresult ReadDirectly(char* buf, uint32_t count, uint32_t* countRead);
     83    nsresult Status() { return mStatus; }
     84    void SetStatus(nsresult aStatus) { mStatus = aStatus; }
     85 
     86   private:
     87    friend class TLSTransportLayer;
     88    virtual ~InputStreamWrapper() = default;
     89    nsresult ReturnDataFromBuffer(char* buf, uint32_t count,
     90                                  uint32_t* countRead);
     91 
     92    nsCOMPtr<nsIAsyncInputStream> mSocketIn;
     93 
     94    nsresult mStatus{NS_OK};
     95    // The lifetime of InputStreamWrapper and OutputStreamWrapper are bound to
     96    // TLSTransportLayer, so using |mTransport| as a raw pointer should be safe.
     97    TLSTransportLayer* MOZ_OWNING_REF mTransport;
     98  };
     99 
    100  class OutputStreamWrapper : public nsIAsyncOutputStream {
    101   public:
    102    NS_DECL_THREADSAFE_ISUPPORTS
    103    NS_DECL_NSIOUTPUTSTREAM
    104    NS_DECL_NSIASYNCOUTPUTSTREAM
    105 
    106    explicit OutputStreamWrapper(nsIAsyncOutputStream* aOutputStream,
    107                                 TLSTransportLayer* aTransport);
    108 
    109    nsresult WriteDirectly(const char* buf, uint32_t count,
    110                           uint32_t* countWritten);
    111    nsresult Status() { return mStatus; }
    112    void SetStatus(nsresult aStatus) { mStatus = aStatus; }
    113 
    114   private:
    115    friend class TLSTransportLayer;
    116    virtual ~OutputStreamWrapper() = default;
    117    static nsresult WriteFromSegments(nsIInputStream*, void*, const char*,
    118                                      uint32_t offset, uint32_t count,
    119                                      uint32_t* countRead);
    120 
    121    nsCOMPtr<nsIAsyncOutputStream> mSocketOut;
    122 
    123    nsresult mStatus{NS_OK};
    124    TLSTransportLayer* MOZ_OWNING_REF mTransport;
    125  };
    126 
    127  virtual ~TLSTransportLayer();
    128  bool DispatchRelease();
    129 
    130  nsISocketTransport* Transport() { return mSocketTransport; }
    131 
    132  int32_t OutputInternal(const char* aBuf, int32_t aAmount);
    133  int32_t InputInternal(char* aBuf, int32_t aAmount);
    134 
    135  static PRStatus GetPeerName(PRFileDesc* fd, PRNetAddr* addr);
    136  static PRStatus GetSocketOption(PRFileDesc* fd, PRSocketOptionData* aOpt);
    137  static PRStatus SetSocketOption(PRFileDesc* fd,
    138                                  const PRSocketOptionData* data);
    139  static int32_t Write(PRFileDesc* fd, const void* buf, int32_t amount);
    140  static int32_t Read(PRFileDesc* fd, void* buf, int32_t amount);
    141  static int32_t Send(PRFileDesc* fd, const void* buf, int32_t amount,
    142                      int flags, PRIntervalTime timeout);
    143  static int32_t Recv(PRFileDesc* fd, void* buf, int32_t amount, int flags,
    144                      PRIntervalTime timeout);
    145  static PRStatus Close(PRFileDesc* fd);
    146  static int16_t Poll(PRFileDesc* fd, int16_t in_flags, int16_t* out_flags);
    147 
    148  nsCOMPtr<nsISocketTransport> mSocketTransport;
    149  InputStreamWrapper mSocketInWrapper;
    150  OutputStreamWrapper mSocketOutWrapper;
    151  nsCOMPtr<nsITLSSocketControl> mTLSSocketControl;
    152  nsCOMPtr<nsIInputStreamCallback> mInputCallback;
    153  nsCOMPtr<nsIOutputStreamCallback> mOutputCallback;
    154  PRFileDesc* mFD{nullptr};
    155  nsCOMPtr<nsIInputStreamCallback> mOwner;
    156  nsresult mOutputStatus{NS_OK};
    157  nsresult mInputStatus{NS_OK};
    158 };
    159 
    160 }  // namespace mozilla::net
    161 
    162 inline nsISupports* ToSupports(mozilla::net::TLSTransportLayer* aTransport) {
    163  return static_cast<nsISocketTransport*>(aTransport);
    164 }
    165 
    166 #endif