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