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