WebrtcTCPSocketWrapper.cpp (4599B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set sw=2 ts=8 et tw=80 ft=cpp : */ 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 #include "WebrtcTCPSocketWrapper.h" 8 9 #include "mozilla/net/WebrtcTCPSocketChild.h" 10 #include "nr_socket_proxy_config.h" 11 #include "nsNetCID.h" 12 #include "nsProxyRelease.h" 13 #include "nsServiceManagerUtils.h" 14 15 namespace mozilla::net { 16 17 using std::shared_ptr; 18 19 WebrtcTCPSocketWrapper::WebrtcTCPSocketWrapper( 20 WebrtcTCPSocketCallback* aCallbacks) 21 : mProxyCallbacks(aCallbacks), 22 mWebrtcTCPSocket(nullptr), 23 mMainThread(nullptr), 24 mSocketThread(nullptr) { 25 mMainThread = GetMainThreadSerialEventTarget(); 26 mSocketThread = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID); 27 MOZ_RELEASE_ASSERT(mMainThread, "no main thread"); 28 MOZ_RELEASE_ASSERT(mSocketThread, "no socket thread"); 29 } 30 31 WebrtcTCPSocketWrapper::~WebrtcTCPSocketWrapper() { 32 MOZ_ASSERT(!mWebrtcTCPSocket, "webrtc TCP socket non-null"); 33 34 // If we're never opened then we never get an OnClose from our parent process. 35 // We need to release our callbacks here safely. 36 NS_ProxyRelease("WebrtcTCPSocketWrapper::CleanUpCallbacks", mSocketThread, 37 mProxyCallbacks.forget()); 38 } 39 40 void WebrtcTCPSocketWrapper::AsyncOpen( 41 const nsCString& aHost, const int& aPort, const nsCString& aLocalAddress, 42 const int& aLocalPort, bool aUseTls, 43 const shared_ptr<NrSocketProxyConfig>& aConfig) { 44 if (!NS_IsMainThread()) { 45 MOZ_ALWAYS_SUCCEEDS(mMainThread->Dispatch( 46 NewRunnableMethod<const nsCString, const int, const nsCString, 47 const int, bool, 48 const shared_ptr<NrSocketProxyConfig>>( 49 "WebrtcTCPSocketWrapper::AsyncOpen", this, 50 &WebrtcTCPSocketWrapper::AsyncOpen, aHost, aPort, aLocalAddress, 51 aLocalPort, aUseTls, aConfig))); 52 return; 53 } 54 55 MOZ_ASSERT(!mWebrtcTCPSocket, "wrapper already open"); 56 mWebrtcTCPSocket = new WebrtcTCPSocketChild(this); 57 mWebrtcTCPSocket->AsyncOpen(aHost, aPort, aLocalAddress, aLocalPort, aUseTls, 58 aConfig); 59 } 60 61 void WebrtcTCPSocketWrapper::SendWrite(nsTArray<uint8_t>&& aReadData) { 62 if (!NS_IsMainThread()) { 63 MOZ_ALWAYS_SUCCEEDS( 64 mMainThread->Dispatch(NewRunnableMethod<nsTArray<uint8_t>&&>( 65 "WebrtcTCPSocketWrapper::SendWrite", this, 66 &WebrtcTCPSocketWrapper::SendWrite, std::move(aReadData)))); 67 return; 68 } 69 70 MOZ_ASSERT(mWebrtcTCPSocket, "webrtc TCP socket should be non-null"); 71 mWebrtcTCPSocket->SendWrite(aReadData); 72 } 73 74 void WebrtcTCPSocketWrapper::Close() { 75 if (!NS_IsMainThread()) { 76 MOZ_ALWAYS_SUCCEEDS(mMainThread->Dispatch( 77 NewRunnableMethod("WebrtcTCPSocketWrapper::Close", this, 78 &WebrtcTCPSocketWrapper::Close))); 79 return; 80 } 81 82 // We're only open if we have a channel. Also Close() should be idempotent. 83 if (mWebrtcTCPSocket) { 84 RefPtr<WebrtcTCPSocketChild> child = mWebrtcTCPSocket; 85 mWebrtcTCPSocket = nullptr; 86 child->SendClose(); 87 } 88 } 89 90 void WebrtcTCPSocketWrapper::OnClose(nsresult aReason) { 91 MOZ_ASSERT(NS_IsMainThread(), "not on main thread"); 92 MOZ_ASSERT(mProxyCallbacks, "webrtc TCP callbacks should be non-null"); 93 94 MOZ_ALWAYS_SUCCEEDS(mSocketThread->Dispatch(NewRunnableMethod<nsresult>( 95 "WebrtcTCPSocketWrapper::OnClose", mProxyCallbacks, 96 &WebrtcTCPSocketCallback::OnClose, aReason))); 97 98 NS_ProxyRelease("WebrtcTCPSocketWrapper::CleanUpCallbacks", mSocketThread, 99 mProxyCallbacks.forget()); 100 } 101 102 void WebrtcTCPSocketWrapper::OnRead(nsTArray<uint8_t>&& aReadData) { 103 MOZ_ASSERT(NS_IsMainThread(), "not on main thread"); 104 MOZ_ASSERT(mProxyCallbacks, "webrtc TCP callbacks should be non-null"); 105 106 MOZ_ALWAYS_SUCCEEDS( 107 mSocketThread->Dispatch(NewRunnableMethod<nsTArray<uint8_t>&&>( 108 "WebrtcTCPSocketWrapper::OnRead", mProxyCallbacks, 109 &WebrtcTCPSocketCallback::OnRead, std::move(aReadData)))); 110 } 111 112 void WebrtcTCPSocketWrapper::OnConnected(const nsACString& aProxyType) { 113 MOZ_ASSERT(NS_IsMainThread(), "not on main thread"); 114 MOZ_ASSERT(mProxyCallbacks, "webrtc TCP callbacks should be non-null"); 115 116 MOZ_ALWAYS_SUCCEEDS(mSocketThread->Dispatch(NewRunnableMethod<nsCString>( 117 "WebrtcTCPSocketWrapper::OnConnected", mProxyCallbacks, 118 &WebrtcTCPSocketCallback::OnConnected, aProxyType))); 119 } 120 121 } // namespace mozilla::net