tor-browser

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

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