Bug Summary

File:root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp
Warning:line 234, column 8
Potential memory leak

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name nricectx.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media/webrtc/transport/build -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media/webrtc/transport/build -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D LINUX -D HAVE_STRDUP -D NR_SOCKET_IS_VOID_PTR -D R_DEFINED_INT2=int16_t -D R_DEFINED_UINT2=uint16_t -D R_DEFINED_INT4=int32_t -D R_DEFINED_UINT4=uint32_t -D R_DEFINED_INT8=int64_t -D R_DEFINED_UINT8=uint64_t -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/dom/media/webrtc/transport/build -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media/webrtc/transport/build -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/third_party/abseil-cpp -I /root/firefox-clang/dom/media/webrtc/transport -I /root/firefox-clang/dom/media/webrtc/transport/third_party -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/crypto -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/ice -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/net -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/stun -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/util -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/event -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/log -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/port/generic/include -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/registry -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/share -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr -I /root/firefox-clang/third_party/libsrtp/src/crypto/include -I /root/firefox-clang/third_party/libsrtp/src/include -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/port/linux/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-10-17-231001-351276-1 -x c++ /root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp
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 file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5// Original author: ekr@rtfm.com
6
7// Some of this code is cut-and-pasted from nICEr. Copyright is:
8
9/*
10Copyright (c) 2007, Adobe Systems, Incorporated
11All rights reserved.
12
13Redistribution and use in source and binary forms, with or without
14modification, are permitted provided that the following conditions are
15met:
16
17* Redistributions of source code must retain the above copyright
18 notice, this list of conditions and the following disclaimer.
19
20* Redistributions in binary form must reproduce the above copyright
21 notice, this list of conditions and the following disclaimer in the
22 documentation and/or other materials provided with the distribution.
23
24* Neither the name of Adobe Systems, Network Resonance nor the names of its
25 contributors may be used to endorse or promote products derived from
26 this software without specific prior written permission.
27
28THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39*/
40
41#include <string>
42#include <vector>
43
44#include "ScopedNSSTypes.h"
45#include "logging.h"
46#include "mozilla/Preferences.h"
47#include "nr_socket_proxy_config.h"
48#include "nsCOMPtr.h"
49#include "nsError.h"
50#include "nsIUUIDGenerator.h"
51#include "nsNetCID.h"
52#include "nsServiceManagerUtils.h"
53#include "nsXULAppAPI.h"
54#include "pk11pub.h"
55#include "runnable_utils.h"
56
57// nICEr includes
58// clang-format off
59#include "nr_api.h"
60#include "registry.h"
61#include "addrs.h"
62#include "async_timer.h"
63#include "r_crc32.h"
64#include "r_memory.h"
65#include "ice_reg.h"
66#include "transport_addr.h"
67#include "nr_crypto.h"
68#include "nr_socket.h"
69#include "nr_socket_local.h"
70#include "stun_reg.h"
71#include "ice_codeword.h"
72#include "ice_ctx.h"
73#include "ice_candidate.h"
74// clang-format on
75
76// Local includes
77#include "mozilla/Base64.h"
78#include "nr_socket_prsock.h"
79#include "nricectx.h"
80#include "nricemediastream.h"
81#include "nrinterfaceprioritizer.h"
82#include "rlogconnector.h"
83#include "test_nr_socket.h"
84
85namespace mozilla {
86
87using std::shared_ptr;
88using ParsedIceServer = IceServerParser::ParsedIceServer;
89using IceTransport = IceServerParser::IceTransport;
90
91TimeStamp nr_socket_short_term_violation_time() {
92 return NrSocketBase::short_term_violation_time();
93}
94
95TimeStamp nr_socket_long_term_violation_time() {
96 return NrSocketBase::long_term_violation_time();
97}
98
99MOZ_MTLOG_MODULE("mtransport")static mozilla::LogModule* getLogModule() { static mozilla::LazyLogModule
log("mtransport"); return static_cast<mozilla::LogModule*
>(log); }
100
101const char kNrIceTransportUdp[] = "udp";
102const char kNrIceTransportTcp[] = "tcp";
103const char kNrIceTransportTls[] = "tls";
104static constexpr UINT4 kRegularNominationDelayMs = 20;
105
106static bool initialized = false;
107
108static int noop(void** obj) { return 0; }
109
110static nr_socket_factory_vtbl ctx_socket_factory_vtbl = {nr_socket_local_create,
111 noop};
112
113// Implement NSPR-based crypto algorithms
114static int nr_crypto_nss_random_bytes(UCHAR* buf, size_t len) {
115 UniquePK11SlotInfo slot(PK11_GetInternalSlot());
116 if (!slot) return R_INTERNAL3;
117
118 SECStatus rv = PK11_GenerateRandomOnSlot(slot.get(), buf, len);
119 if (rv != SECSuccess) return R_INTERNAL3;
120
121 return 0;
122}
123
124static int nr_crypto_nss_hmac(UCHAR* key, size_t keyl, UCHAR* buf, size_t bufl,
125 UCHAR* result) {
126 CK_MECHANISM_TYPE mech = CKM_SHA_1_HMAC0x00000221UL;
127 PK11SlotInfo* slot = nullptr;
128 MOZ_ASSERT(keyl > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(keyl > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(keyl > 0))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("keyl > 0", "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 128); AnnotateMozCrashReason("MOZ_ASSERT" "(" "keyl > 0"
")"); do { MOZ_CrashSequence(__null, 128); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
129 SECItem keyi = {siBuffer, key, static_cast<unsigned int>(keyl)};
130 PK11SymKey* skey = nullptr;
131 PK11Context* hmac_ctx = nullptr;
132 SECStatus status;
133 unsigned int hmac_len;
134 SECItem param = {siBuffer, nullptr, 0};
135 int err = R_INTERNAL3;
136
137 slot = PK11_GetInternalKeySlot();
138 if (!slot) goto abort;
139
140 skey = PK11_ImportSymKey(slot, mech, PK11_OriginUnwrap, CKA_SIGN0x00000108UL, &keyi,
141 nullptr);
142 if (!skey) goto abort;
143
144 hmac_ctx = PK11_CreateContextBySymKey(mech, CKA_SIGN0x00000108UL, skey, &param);
145 if (!hmac_ctx) goto abort;
146
147 status = PK11_DigestBegin(hmac_ctx);
148 if (status != SECSuccess) goto abort;
149
150 status = PK11_DigestOp(hmac_ctx, buf, bufl);
151 if (status != SECSuccess) goto abort;
152
153 status = PK11_DigestFinal(hmac_ctx, result, &hmac_len, 20);
154 if (status != SECSuccess) goto abort;
155
156 MOZ_ASSERT(hmac_len == 20)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(hmac_len == 20)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(hmac_len == 20))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("hmac_len == 20"
, "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 156); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hmac_len == 20"
")"); do { MOZ_CrashSequence(__null, 156); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
157
158 err = 0;
159
160abort:
161 if (hmac_ctx) PK11_DestroyContext(hmac_ctx, PR_TRUE1);
162 if (skey) PK11_FreeSymKey(skey);
163 if (slot) PK11_FreeSlot(slot);
164
165 return err;
166}
167
168static int nr_crypto_nss_md5(UCHAR* buf, size_t bufl, UCHAR* result) {
169 int err = R_INTERNAL3;
170 SECStatus rv;
171
172 const SECHashObject* ho = HASH_GetHashObject(HASH_AlgMD5);
173 MOZ_ASSERT(ho)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(ho)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(ho))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("ho", "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 173); AnnotateMozCrashReason("MOZ_ASSERT" "(" "ho" ")"); do
{ MOZ_CrashSequence(__null, 173); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
174 if (!ho) goto abort;
175
176 MOZ_ASSERT(ho->length == 16)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(ho->length == 16)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(ho->length == 16))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("ho->length == 16"
, "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 176); AnnotateMozCrashReason("MOZ_ASSERT" "(" "ho->length == 16"
")"); do { MOZ_CrashSequence(__null, 176); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
177
178 rv = HASH_HashBuf(ho->type, result, buf, bufl);
179 if (rv != SECSuccess) goto abort;
180
181 err = 0;
182abort:
183 return err;
184}
185
186static nr_ice_crypto_vtbl nr_ice_crypto_nss_vtbl = {
187 nr_crypto_nss_random_bytes, nr_crypto_nss_hmac, nr_crypto_nss_md5};
188
189static bool ToNicerStunStruct(const char* aAddrForFqdn,
190 const ParsedIceServer& aEntry,
191 nr_ice_stun_server* aResult) {
192 memset(aResult, 0, sizeof(nr_ice_stun_server));
193 bool isTls = aEntry.mUri.IsTls();
194 uint8_t protocol = IPPROTO_UDPIPPROTO_UDP;
195 // TLS always uses TCP underneath
196 if (isTls || (aEntry.mUri.mTransport == IceTransport::Tcp)) {
197 protocol = IPPROTO_TCPIPPROTO_TCP;
198 }
199
200 if (isTls && !aAddrForFqdn) {
201 // Note: letsencrypt has cooked up super-short-lifetime IP address based
202 // certs. We may want to implement support for that.
203 // See https://bugzilla.mozilla.org/show_bug.cgi?id=2019255
204 MOZ_MTLOG(ML_ERROR, "TLS requires FQDN, not IP address")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "TLS requires FQDN, not IP address"; do { const
::mozilla::LogModule* moz_real_module = getLogModule(); if (
(__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
205 return false;
206 }
207
208 if (aEntry.mUri.mHost.Length() >= sizeof(aResult->addr.fqdn)) {
209 MOZ_MTLOG(ML_ERROR, "FQDN too long: " << aEntry.mUri.mHost.get())do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "FQDN too long: " << aEntry.mUri.mHost.get
(); do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
210 return false;
211 }
212
213 const char* ip = aAddrForFqdn ? aAddrForFqdn : aEntry.mUri.mHost.get();
214 const char* domainName = aAddrForFqdn ? aEntry.mUri.mHost.get() : nullptr;
215
216 if (nr_str_port_to_transport_addr(ip, domainName, aEntry.mUri.mPort, protocol,
217 &(aResult->addr))) {
218 MOZ_MTLOG(ML_ERROR, "Failed to init STUN server")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Failed to init STUN server"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
219 return false;
220 }
221
222 if (isTls) {
223 aResult->addr.tls = true;
224 }
225
226 nr_transport_addr_fmt_addr_string(&(aResult->addr));
227 return true;
228}
229
230static bool ToNicerTurnStruct(const char* aAddrForFqdn,
231 const ParsedIceServer& aEntry,
232 nr_ice_turn_server* aResult) {
233 memset(aResult, 0, sizeof(nr_ice_turn_server));
234 if (!ToNicerStunStruct(aAddrForFqdn, aEntry, &(aResult->turn_server))) {
14
Taking false branch
26
Potential memory leak
235 MOZ_MTLOG(ML_ERROR, "Failed to init STUN server")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Failed to init STUN server"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
236 return false;
237 }
238 aResult->username = strdup(aEntry.mUsername.get());
15
Memory is allocated
239 if (!aResult->username) {
16
Assuming field 'username' is non-null
17
Taking false branch
240 MOZ_MTLOG(ML_ERROR, "Couldn't allocate TURN username")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't allocate TURN username"; do { const ::
mozilla::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
241 return false;
242 }
243
244 if (aEntry.mPassword.IsEmpty()) {
18
Assuming the condition is true
19
Taking true branch
245 // TODO(https://bugzilla.mozilla.org/show_bug.cgi?id=2021075)
246 // Once we check for this in the validation code, we might consider removing
247 // this check. I'm inclined to keep it though, just in case.
248 MOZ_MTLOG(ML_ERROR, "TURN password is empty")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "TURN password is empty"; do { const ::mozilla::
LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
20
Assuming the condition is true
21
Taking false branch
22
Loop condition is false. Exiting loop
249 return false;
250 }
251
252 int r = r_data_create(&aResult->password,
253 reinterpret_cast<const UCHAR*>(aEntry.mPassword.get()),
254 aEntry.mPassword.Length());
255 if (r) {
256 free(aResult->username);
257 MOZ_MTLOG(ML_ERROR, "Couldn't allocate TURN password")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't allocate TURN password"; do { const ::
mozilla::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
258 return false;
259 }
260 return true;
261}
262
263NrIceCtx::NrIceCtx(const std::string& name)
264 : name_(name),
265 ice_controlling_set_(false),
266 ctx_(nullptr),
267 peer_(nullptr),
268 ice_handler_vtbl_(nullptr),
269 ice_handler_(nullptr),
270 ice_gather_handler_vtbl_(nullptr),
271 ice_gather_handler_(nullptr),
272 trickle_(true),
273 config_(),
274 nat_(nullptr),
275 proxy_config_(nullptr) {}
276
277/* static */
278RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& aName) {
279 RefPtr<NrIceCtx> ctx = new NrIceCtx(aName);
280
281 if (!ctx->Initialize()) {
282 return nullptr;
283 }
284
285 return ctx;
286}
287
288nsresult NrIceCtx::SetIceConfig(const Config& aConfig) {
289 config_ = aConfig;
290 switch (config_.mPolicy) {
291 case ICE_POLICY_RELAY:
292 MOZ_MTLOG(ML_DEBUG, "SetIceConfig: relay only")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "SetIceConfig: relay only"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
293 nr_ice_ctx_remove_flags(ctx_, NR_ICE_CTX_FLAGS_DISABLE_HOST_CANDIDATES(1<<3));
294 nr_ice_ctx_add_flags(ctx_, NR_ICE_CTX_FLAGS_RELAY_ONLY(1<<2));
295 break;
296 case ICE_POLICY_NO_HOST:
297 MOZ_MTLOG(ML_DEBUG, "SetIceConfig: no host")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "SetIceConfig: no host"; do { const ::mozilla::
LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
298 nr_ice_ctx_add_flags(ctx_, NR_ICE_CTX_FLAGS_DISABLE_HOST_CANDIDATES(1<<3));
299 nr_ice_ctx_remove_flags(ctx_, NR_ICE_CTX_FLAGS_RELAY_ONLY(1<<2));
300 break;
301 case ICE_POLICY_ALL:
302 MOZ_MTLOG(ML_DEBUG, "SetIceConfig: all")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "SetIceConfig: all"; do { const ::mozilla::LogModule
* moz_real_module = getLogModule(); if ((__builtin_expect(!!(
mozilla::detail::log_test(moz_real_module, mozilla::LogLevel::
Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
303 nr_ice_ctx_remove_flags(ctx_, NR_ICE_CTX_FLAGS_DISABLE_HOST_CANDIDATES(1<<3));
304 nr_ice_ctx_remove_flags(ctx_, NR_ICE_CTX_FLAGS_RELAY_ONLY(1<<2));
305 break;
306 }
307
308 if (config_.mAllowLoopback) {
309 nr_ice_ctx_add_flags(ctx_, NR_ICE_CTX_FLAGS_ALLOW_LOOPBACK(1 << 7));
310 }
311
312 if (config_.mAllowLinkLocal) {
313 nr_ice_ctx_add_flags(ctx_, NR_ICE_CTX_FLAGS_ALLOW_LINK_LOCAL(1 << 8));
314 }
315
316 // TODO: Support re-configuring the test NAT someday?
317 if (!nat_ && config_.mNatSimulatorConfig.isSome()) {
318 TestNat* test_nat = new TestNat;
319 test_nat->filtering_type_ = TestNat::ToNatBehavior(
320 config_.mNatSimulatorConfig->mFilteringType.get());
321 test_nat->mapping_type_ =
322 TestNat::ToNatBehavior(config_.mNatSimulatorConfig->mMappingType.get());
323 test_nat->block_udp_ = config_.mNatSimulatorConfig->mBlockUdp;
324 test_nat->block_tcp_ = config_.mNatSimulatorConfig->mBlockTcp;
325 test_nat->block_tls_ = config_.mNatSimulatorConfig->mBlockTls;
326 test_nat->error_code_for_drop_ =
327 config_.mNatSimulatorConfig->mErrorCodeForDrop;
328 if (config_.mNatSimulatorConfig->mRedirectAddress.Length()) {
329 test_nat
330 ->stun_redirect_map_[config_.mNatSimulatorConfig->mRedirectAddress] =
331 config_.mNatSimulatorConfig->mRedirectTargets;
332 }
333 test_nat->network_delay_ms_ = config_.mNatSimulatorConfig->mNetworkDelayMs;
334 test_nat->enabled_ = true;
335 SetNat(test_nat);
336 }
337
338 return NS_OK;
339}
340
341RefPtr<NrIceMediaStream> NrIceCtx::CreateStream(const std::string& id,
342 const std::string& name,
343 int components) {
344 if (streams_.count(id)) {
345 MOZ_ASSERT(false)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false", "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 345); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 345); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false)
;
346 return nullptr;
347 }
348
349 RefPtr stream = MakeRefPtr<NrIceMediaStream>(this, id, name, components);
350 streams_[id] = stream;
351 return stream;
352}
353
354void NrIceCtx::DestroyStream(const std::string& id) {
355 auto it = streams_.find(id);
356 if (it != streams_.end()) {
357 auto preexisting_stream = it->second;
358 SignalConnectionStateChange(preexisting_stream, ICE_CTX_CLOSED);
359 streams_.erase(it);
360 preexisting_stream->Close();
361 }
362}
363
364// Handler callbacks
365int NrIceCtx::select_pair(void* obj, nr_ice_media_stream* stream,
366 int component_id, nr_ice_cand_pair** potentials,
367 int potential_ct) {
368 MOZ_MTLOG(ML_DEBUG, "select pair called: potential_ct = " << potential_ct)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "select pair called: potential_ct = " <<
potential_ct; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Verbose)), 0))) {
mozilla::detail::log_print_fmt(moz_real_module, mozilla::LogLevel
::Verbose, "{}", str.str().c_str()); } } while (0); } } while
(0)
;
369 MOZ_ASSERT(stream->local_stream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(stream->local_stream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(stream->local_stream))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("stream->local_stream"
, "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 369); AnnotateMozCrashReason("MOZ_ASSERT" "(" "stream->local_stream"
")"); do { MOZ_CrashSequence(__null, 369); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
370 MOZ_ASSERT(!stream->local_stream->obsolete)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!stream->local_stream->obsolete)>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(!stream->local_stream->obsolete))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!stream->local_stream->obsolete"
, "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 370); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->local_stream->obsolete"
")"); do { MOZ_CrashSequence(__null, 370); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
371
372 for (int i = 0; i < potential_ct; ++i) {
373 nr_ice_cand_pair* pair = potentials[i];
374 if (pair->state != NR_ICE_PAIR_STATE_SUCCEEDED5) {
375 continue;
376 }
377
378 if (pair->restart_nominated_cb_timer) {
379 return 0;
380 }
381
382 return nr_ice_candidate_pair_nominate(pair, kRegularNominationDelayMs);
383 }
384
385 return 0;
386}
387
388int NrIceCtx::stream_ready(void* obj, nr_ice_media_stream* stream) {
389 MOZ_MTLOG(ML_DEBUG, "stream_ready called")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "stream_ready called"; do { const ::mozilla::LogModule
* moz_real_module = getLogModule(); if ((__builtin_expect(!!(
mozilla::detail::log_test(moz_real_module, mozilla::LogLevel::
Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
390 MOZ_ASSERT(!stream->local_stream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!stream->local_stream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!stream->local_stream))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("!stream->local_stream"
, "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 390); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->local_stream"
")"); do { MOZ_CrashSequence(__null, 390); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
391 MOZ_ASSERT(!stream->obsolete)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!stream->obsolete)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!stream->obsolete))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("!stream->obsolete"
, "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 391); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->obsolete"
")"); do { MOZ_CrashSequence(__null, 391); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
392
393 // Get the ICE ctx.
394 NrIceCtx* ctx = static_cast<NrIceCtx*>(obj);
395
396 RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
397
398 // Streams which do not exist should never be ready.
399 MOZ_ASSERT(s)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(s)>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(s))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("s", "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 399); AnnotateMozCrashReason("MOZ_ASSERT" "(" "s" ")"); do {
MOZ_CrashSequence(__null, 399); __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
400
401 s->Ready(stream);
402 ctx->SignalConnectionStateChange(s, ICE_CTX_CONNECTED);
403
404 return 0;
405}
406
407int NrIceCtx::stream_failed(void* obj, nr_ice_media_stream* stream) {
408 MOZ_MTLOG(ML_DEBUG, "stream_failed called")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "stream_failed called"; do { const ::mozilla::
LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
409 MOZ_ASSERT(!stream->local_stream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!stream->local_stream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!stream->local_stream))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("!stream->local_stream"
, "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 409); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->local_stream"
")"); do { MOZ_CrashSequence(__null, 409); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
410 MOZ_ASSERT(!stream->obsolete)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!stream->obsolete)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!stream->obsolete))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("!stream->obsolete"
, "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 410); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->obsolete"
")"); do { MOZ_CrashSequence(__null, 410); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
411
412 // Get the ICE ctx
413 NrIceCtx* ctx = static_cast<NrIceCtx*>(obj);
414 RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
415
416 // Streams which do not exist should never fail.
417 MOZ_ASSERT(s)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(s)>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(s))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("s", "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 417); AnnotateMozCrashReason("MOZ_ASSERT" "(" "s" ")"); do {
MOZ_CrashSequence(__null, 417); __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
418
419 if (!ctx->dumped_rlog_) {
420 // Do this at most once per ctx
421 ctx->dumped_rlog_ = true;
422 MOZ_MTLOG(ML_INFO,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Debug)), 0))) { std::stringstream str;
str << "NrIceCtx(" << ctx->name_ << "): dumping r_log ringbuffer... "
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Debug, "{}", str.str().c_str
()); } } while (0); } } while (0)
423 "NrIceCtx(" << ctx->name_ << "): dumping r_log ringbuffer... ")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Debug)), 0))) { std::stringstream str;
str << "NrIceCtx(" << ctx->name_ << "): dumping r_log ringbuffer... "
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Debug, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
424 std::deque<std::string> logs;
425 RLogConnector::GetInstance()->GetAny(0, &logs);
426 for (auto& log : logs) {
427 MOZ_MTLOG(ML_INFO, log)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Debug)), 0))) { std::stringstream str;
str << log; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Debug
, "{}", str.str().c_str()); } } while (0); } } while (0)
;
428 }
429 }
430
431 s->Failed();
432 ctx->SignalConnectionStateChange(s, ICE_CTX_FAILED);
433 return 0;
434}
435
436int NrIceCtx::stream_checking(void* obj, nr_ice_media_stream* stream) {
437 MOZ_MTLOG(ML_DEBUG, "stream_checking called")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "stream_checking called"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
438 MOZ_ASSERT(!stream->local_stream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!stream->local_stream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!stream->local_stream))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("!stream->local_stream"
, "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 438); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->local_stream"
")"); do { MOZ_CrashSequence(__null, 438); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
439 MOZ_ASSERT(!stream->obsolete)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!stream->obsolete)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!stream->obsolete))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("!stream->obsolete"
, "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 439); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->obsolete"
")"); do { MOZ_CrashSequence(__null, 439); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
440
441 // Get the ICE ctx
442 NrIceCtx* ctx = static_cast<NrIceCtx*>(obj);
443 RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
444
445 MOZ_ASSERT(s)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(s)>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(s))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("s", "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 445); AnnotateMozCrashReason("MOZ_ASSERT" "(" "s" ")"); do {
MOZ_CrashSequence(__null, 445); __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
446
447 if (!s->AnyGenerationIsConnected()) {
448 // the checking state only applies if we aren't connected
449 ctx->SignalConnectionStateChange(s, ICE_CTX_CHECKING);
450 }
451 return 0;
452}
453
454int NrIceCtx::stream_disconnected(void* obj, nr_ice_media_stream* stream) {
455 MOZ_MTLOG(ML_DEBUG, "stream_disconnected called")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "stream_disconnected called"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
456 MOZ_ASSERT(!stream->local_stream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!stream->local_stream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!stream->local_stream))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("!stream->local_stream"
, "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 456); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->local_stream"
")"); do { MOZ_CrashSequence(__null, 456); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
457 MOZ_ASSERT(!stream->obsolete)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!stream->obsolete)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!stream->obsolete))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("!stream->obsolete"
, "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 457); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->obsolete"
")"); do { MOZ_CrashSequence(__null, 457); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
458
459 // Get the ICE ctx
460 NrIceCtx* ctx = static_cast<NrIceCtx*>(obj);
461 RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
462
463 MOZ_ASSERT(s)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(s)>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(s))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("s", "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 463); AnnotateMozCrashReason("MOZ_ASSERT" "(" "s" ")"); do {
MOZ_CrashSequence(__null, 463); __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
464
465 ctx->SignalConnectionStateChange(s, ICE_CTX_DISCONNECTED);
466 return 0;
467}
468
469int NrIceCtx::stream_gathering(void* obj, nr_ice_media_stream* stream) {
470 MOZ_MTLOG(ML_DEBUG, "stream_gathering called")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "stream_gathering called"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
471 MOZ_ASSERT(!stream->local_stream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!stream->local_stream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!stream->local_stream))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("!stream->local_stream"
, "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 471); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->local_stream"
")"); do { MOZ_CrashSequence(__null, 471); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
472 MOZ_ASSERT(!stream->obsolete)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!stream->obsolete)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!stream->obsolete))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("!stream->obsolete"
, "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 472); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->obsolete"
")"); do { MOZ_CrashSequence(__null, 472); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
473
474 // Get the ICE ctx
475 NrIceCtx* ctx = static_cast<NrIceCtx*>(obj);
476 RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
477
478 MOZ_ASSERT(s)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(s)>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(s))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("s", "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 478); AnnotateMozCrashReason("MOZ_ASSERT" "(" "s" ")"); do {
MOZ_CrashSequence(__null, 478); __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
479
480 s->OnGatheringStarted(stream);
481 return 0;
482}
483
484int NrIceCtx::stream_gathered(void* obj, nr_ice_media_stream* stream) {
485 MOZ_MTLOG(ML_DEBUG, "stream_gathered called")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "stream_gathered called"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
486 MOZ_ASSERT(!stream->local_stream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!stream->local_stream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!stream->local_stream))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("!stream->local_stream"
, "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 486); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->local_stream"
")"); do { MOZ_CrashSequence(__null, 486); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
487
488 // Get the ICE ctx
489 NrIceCtx* ctx = static_cast<NrIceCtx*>(obj);
490 RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
491
492 // We get this callback for destroyed streams in some cases
493 if (s) {
494 s->OnGatheringComplete(stream);
495 }
496 return 0;
497}
498
499int NrIceCtx::candidate_error(void* obj, nr_ice_media_stream* stream,
500 nr_ice_candidate* candidate) {
501 NrIceCtx* ctx = static_cast<NrIceCtx*>(obj);
502 RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
503 if (!s) {
504 return 0;
505 }
506
507 if (!candidate->stun_server) {
508 return 0;
509 }
510
511 std::string address;
512 uint16_t port = 0;
513 if (!(ctx->ctx_->flags & NR_ICE_CTX_FLAGS_OBFUSCATE_HOST_ADDRESSES(1<<6))) {
514 nsCString host;
515 if (!nr_transport_addr_get_addrstring_and_port(&candidate->base, &host,
516 &port)) {
517 address = host.get();
518 }
519 }
520
521 char* url = nullptr;
522 int is_turn = (candidate->type == RELAYED);
523 if (nr_ice_stun_server_get_url(candidate->stun_server, is_turn, &url)) {
524 return 0;
525 }
526
527 // errorText is always empty; nICEr discards the STUN reason phrase after
528 // processing the response. See bug 2018863.
529 s->SignalCandidateError(s, address, port, url,
530 static_cast<uint16_t>(candidate->error_code), "");
531 free(url);
532 return 0;
533}
534
535int NrIceCtx::ice_checking(void* obj, nr_ice_peer_ctx* pctx) {
536 MOZ_MTLOG(ML_DEBUG, "ice_checking called")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "ice_checking called"; do { const ::mozilla::LogModule
* moz_real_module = getLogModule(); if ((__builtin_expect(!!(
mozilla::detail::log_test(moz_real_module, mozilla::LogLevel::
Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
537 // We don't use this; we react to the stream-specific callbacks instead
538 return 0;
539}
540
541int NrIceCtx::ice_connected(void* obj, nr_ice_peer_ctx* pctx) {
542 MOZ_MTLOG(ML_DEBUG, "ice_connected called")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "ice_connected called"; do { const ::mozilla::
LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
543 // We don't use this; we react to the stream-specific callbacks instead
544 return 0;
545}
546
547int NrIceCtx::ice_disconnected(void* obj, nr_ice_peer_ctx* pctx) {
548 MOZ_MTLOG(ML_DEBUG, "ice_disconnected called")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "ice_disconnected called"; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
549 // We don't use this; we react to the stream-specific callbacks instead
550 return 0;
551}
552
553int NrIceCtx::msg_recvd(void* obj, nr_ice_peer_ctx* pctx,
554 nr_ice_media_stream* stream, int component_id,
555 UCHAR* msg, int len) {
556 // Get the ICE ctx
557 NrIceCtx* ctx = static_cast<NrIceCtx*>(obj);
558 RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
559
560 // Streams which do not exist should never have packets.
561 MOZ_ASSERT(s)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(s)>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(s))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("s", "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 561); AnnotateMozCrashReason("MOZ_ASSERT" "(" "s" ")"); do {
MOZ_CrashSequence(__null, 561); __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
562
563 s->PacketReceived(stream, component_id, msg, len);
564
565 return 0;
566}
567
568void NrIceCtx::trickle_cb(void* arg, nr_ice_ctx* ice_ctx,
569 nr_ice_media_stream* stream, int component_id,
570 nr_ice_candidate* candidate) {
571 if (stream->obsolete) {
572 // Stream was probably just marked obsolete, resulting in this callback
573 return;
574 }
575 // Get the ICE ctx
576 NrIceCtx* ctx = static_cast<NrIceCtx*>(arg);
577 RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
578
579 if (!s) {
580 // This stream has been removed because it is inactive
581 return;
582 }
583
584 if (!candidate) {
585 return;
586 }
587
588 std::string actual_addr;
589 std::string mdns_addr;
590 ctx->GenerateObfuscatedAddress(candidate, &mdns_addr, &actual_addr);
591
592 // Format the candidate.
593 char candidate_str[NR_ICE_MAX_ATTRIBUTE_SIZE256];
594 int r = nr_ice_format_candidate_attribute(
595 candidate, candidate_str, sizeof(candidate_str),
596 (ctx->ctx()->flags & NR_ICE_CTX_FLAGS_OBFUSCATE_HOST_ADDRESSES(1<<6)) ? 1 : 0);
597 MOZ_ASSERT(!r)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!r)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(!r))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("!r", "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 597); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!r" ")"); do
{ MOZ_CrashSequence(__null, 597); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
598 if (r) return;
599
600 MOZ_MTLOG(ML_INFO, "NrIceCtx(" << ctx->name_ << "): trickling candidate "do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Debug)), 0))) { std::stringstream str;
str << "NrIceCtx(" << ctx->name_ << "): trickling candidate "
<< candidate_str; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Debug
, "{}", str.str().c_str()); } } while (0); } } while (0)
601 << candidate_str)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Debug)), 0))) { std::stringstream str;
str << "NrIceCtx(" << ctx->name_ << "): trickling candidate "
<< candidate_str; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Debug)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Debug
, "{}", str.str().c_str()); } } while (0); } } while (0)
;
602
603 s->SignalCandidate(s, candidate_str, stream->ufrag, mdns_addr, actual_addr);
604}
605
606void NrIceCtx::InitializeGlobals(const GlobalConfig& aConfig) {
607 RLogConnector::CreateInstance();
608 // Initialize the crypto callbacks and logging stuff
609 if (!initialized) {
610 NR_reg_init();
611 // Registers the "stun" logger for r_log.
612 (void)nr_stun_startup();
613 nr_crypto_vtbl = &nr_ice_crypto_nss_vtbl;
614 initialized = true;
615
616 // Set the priorites for candidate type preferences.
617 // These numbers come from RFC 5245 S. 4.1.2.2
618 NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_SRV_RFLX"ice.pref.type.srv_rflx", 100);
619 NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_PEER_RFLX"ice.pref.type.peer_rflx", 110);
620 NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_HOST"ice.pref.type.host", 126);
621 NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_RELAYED"ice.pref.type.relayed", 5);
622 NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_SRV_RFLX_TCP"ice.pref.type.srv_rflx_tcp", 99);
623 NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_PEER_RFLX_TCP"ice.pref.type.peer_rflx_tcp", 109);
624 NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_HOST_TCP"ice.pref.type.host_tcp", 125);
625 NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_RELAYED_TCP"ice.pref.type.relayed_tcp", 0);
626 NR_reg_set_uint4((char*)"stun.client.maximum_transmits",
627 aConfig.mStunClientMaxTransmits);
628 NR_reg_set_uint4((char*)NR_ICE_REG_TRICKLE_GRACE_PERIOD"ice.trickle_grace_period",
629 aConfig.mTrickleIceGracePeriod);
630 NR_reg_set_int4((char*)NR_ICE_REG_ICE_TCP_SO_SOCK_COUNT"ice.tcp.so_sock_count",
631 aConfig.mIceTcpSoSockCount);
632 NR_reg_set_int4((char*)NR_ICE_REG_ICE_TCP_LISTEN_BACKLOG"ice.tcp.listen_backlog",
633 aConfig.mIceTcpListenBacklog);
634
635 NR_reg_set_char((char*)NR_ICE_REG_ICE_TCP_DISABLE"ice.tcp.disable", !aConfig.mTcpEnabled);
636
637 if (!aConfig.mForceNetInterface.Length()) {
638 NR_reg_set_string((char*)NR_ICE_REG_PREF_FORCE_INTERFACE_NAME"ice.forced_interface_name",
639 const_cast<char*>(aConfig.mForceNetInterface.get()));
640 }
641
642 // For now, always use nr_resolver for UDP.
643 NR_reg_set_char((char*)NR_ICE_REG_USE_NR_RESOLVER_FOR_UDP"ice.udp.use_nr_resolver", 1);
644
645 // Use nr_resolver for TCP only when not in e10s mode (for unit-tests)
646 if (XRE_IsParentProcess()) {
647 NR_reg_set_char((char*)NR_ICE_REG_USE_NR_RESOLVER_FOR_TCP"ice.tcp.use_nr_resolver", 1);
648 }
649 }
650}
651
652void NrIceCtx::SetTargetForDefaultLocalAddressLookup(
653 const std::string& target_ip, uint16_t target_port) {
654 nr_ice_set_target_for_default_local_address_lookup(ctx_, target_ip.c_str(),
655 target_port);
656}
657
658#define MAXADDRS100 100 // mirrors setting in ice_ctx.c
659
660/* static */
661nsTArray<NrIceStunAddr> NrIceCtx::GetStunAddrs() {
662 nsTArray<NrIceStunAddr> addrs;
663
664 nr_local_addr local_addrs[MAXADDRS100];
665 int addr_ct = 0;
666
667 // most likely running on parent process and need crypto vtbl
668 // initialized on Windows (Linux and OSX don't seem to care)
669 if (!initialized) {
670 nr_crypto_vtbl = &nr_ice_crypto_nss_vtbl;
671 }
672
673 MOZ_MTLOG(ML_INFO, "NrIceCtx static call to find local stun addresses")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Debug)), 0))) { std::stringstream str;
str << "NrIceCtx static call to find local stun addresses"
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Debug, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
674 if (nr_stun_get_addrs(local_addrs, MAXADDRS100, &addr_ct)) {
675 MOZ_MTLOG(ML_INFO, "Error finding local stun addresses")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Debug)), 0))) { std::stringstream str;
str << "Error finding local stun addresses"; do { const
::mozilla::LogModule* moz_real_module = getLogModule(); if (
(__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Debug)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Debug, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
676 } else {
677 for (int i = 0; i < addr_ct; ++i) {
678 NrIceStunAddr addr(&local_addrs[i]);
679 addrs.AppendElement(addr);
680 }
681 }
682
683 return addrs;
684}
685
686void NrIceCtx::SetStunAddrs(const nsTArray<NrIceStunAddr>& addrs) {
687 nr_local_addr* local_addrs;
688 local_addrs = new nr_local_addr[addrs.Length()];
689
690 for (size_t i = 0; i < addrs.Length(); ++i) {
691 addrs[i].toNrLocalAddr(local_addrs[i]);
692 }
693 nr_ice_set_local_addresses(ctx_, local_addrs, addrs.Length());
694
695 delete[] local_addrs;
696}
697
698bool NrIceCtx::Initialize() {
699 // Create the gather handler objects
700 ice_gather_handler_vtbl_ = new nr_ice_gather_handler_vtbl();
701 ice_gather_handler_vtbl_->stream_gathering = &NrIceCtx::stream_gathering;
702 ice_gather_handler_vtbl_->stream_gathered = &NrIceCtx::stream_gathered;
703 ice_gather_handler_vtbl_->candidate_error = &NrIceCtx::candidate_error;
704 ice_gather_handler_ = new nr_ice_gather_handler();
705 ice_gather_handler_->vtbl = ice_gather_handler_vtbl_;
706 ice_gather_handler_->obj = this;
707
708 // Create the ICE context
709 int r;
710
711 UINT4 flags = NR_ICE_CTX_FLAGS_AGGRESSIVE_NOMINATION(1);
712
713 r = nr_ice_ctx_create(const_cast<char*>(name_.c_str()), flags,
714 ice_gather_handler_, &ctx_);
715
716 if (r) {
717 MOZ_MTLOG(ML_ERROR, "Couldn't create ICE ctx for '" << name_ << "'")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't create ICE ctx for '" << name_ <<
"'"; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
718 return false;
719 }
720
721 // override default factory to capture optional proxy config when creating
722 // sockets.
723 nr_socket_factory* factory;
724 r = nr_socket_factory_create_int(this, &ctx_socket_factory_vtbl, &factory);
725
726 if (r) {
727 MOZ_MTLOG(LogLevel::Error, "Couldn't create ctx socket factory.")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), LogLevel::Error)), 0))) { std::stringstream str; str <<
"Couldn't create ctx socket factory."; do { const ::mozilla::
LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, LogLevel::Error
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, LogLevel
::Error, "{}", str.str().c_str()); } } while (0); } } while (
0)
;
728 return false;
729 }
730 nr_ice_ctx_set_socket_factory(ctx_, factory);
731
732 nr_interface_prioritizer* prioritizer = CreateInterfacePrioritizer();
733 if (!prioritizer) {
734 MOZ_MTLOG(LogLevel::Error, "Couldn't create interface prioritizer.")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), LogLevel::Error)), 0))) { std::stringstream str; str <<
"Couldn't create interface prioritizer."; do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, LogLevel::Error
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, LogLevel
::Error, "{}", str.str().c_str()); } } while (0); } } while (
0)
;
735 return false;
736 }
737
738 r = nr_ice_ctx_set_interface_prioritizer(ctx_, prioritizer);
739 if (r) {
740 MOZ_MTLOG(LogLevel::Error, "Couldn't set interface prioritizer.")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), LogLevel::Error)), 0))) { std::stringstream str; str <<
"Couldn't set interface prioritizer."; do { const ::mozilla::
LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, LogLevel::Error
)), 0))) { mozilla::detail::log_print_fmt(moz_real_module, LogLevel
::Error, "{}", str.str().c_str()); } } while (0); } } while (
0)
;
741 return false;
742 }
743
744 if (generating_trickle()) {
745 r = nr_ice_ctx_set_trickle_cb(ctx_, &NrIceCtx::trickle_cb, this);
746 if (r) {
747 MOZ_MTLOG(ML_ERROR, "Couldn't set trickle cb for '" << name_ << "'")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't set trickle cb for '" << name_ <<
"'"; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
748 return false;
749 }
750 }
751
752 // Create the handler objects
753 ice_handler_vtbl_ = new nr_ice_handler_vtbl();
754 ice_handler_vtbl_->select_pair = &NrIceCtx::select_pair;
755 ice_handler_vtbl_->stream_ready = &NrIceCtx::stream_ready;
756 ice_handler_vtbl_->stream_failed = &NrIceCtx::stream_failed;
757 ice_handler_vtbl_->stream_checking = &NrIceCtx::stream_checking;
758 ice_handler_vtbl_->stream_disconnected = &NrIceCtx::stream_disconnected;
759 // stream_gathering and stream_gathered do not go here, since those are tied
760 // to the _local_ nr_ice_media_stream in nICEr. nICEr allows a local
761 // nr_ice_media_stream (which has a single set of candidates, and therefore a
762 // single gathering state) to be associated with multiple remote
763 // nr_ice_media_streams (which each have their own ICE connection state)
764 // because it allows forking. We never encounter forking, so these will be
765 // one-to-one in practice, but the architecture in nICEr means we have to set
766 // up these callbacks on the nr_ice_ctx, not the nr_ice_peer_ctx.
767 ice_handler_vtbl_->ice_connected = &NrIceCtx::ice_connected;
768 ice_handler_vtbl_->msg_recvd = &NrIceCtx::msg_recvd;
769 ice_handler_vtbl_->ice_checking = &NrIceCtx::ice_checking;
770 ice_handler_vtbl_->ice_disconnected = &NrIceCtx::ice_disconnected;
771
772 ice_handler_ = new nr_ice_handler();
773 ice_handler_->vtbl = ice_handler_vtbl_;
774 ice_handler_->obj = this;
775
776 // Create the peer ctx. Because we do not support parallel forking, we
777 // only have one peer ctx.
778 std::string peer_name = name_ + ":default";
779 r = nr_ice_peer_ctx_create(ctx_, ice_handler_,
780 const_cast<char*>(peer_name.c_str()), &peer_);
781 if (r) {
782 MOZ_MTLOG(ML_ERROR, "Couldn't create ICE peer ctx for '" << name_ << "'")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't create ICE peer ctx for '" << name_
<< "'"; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Error)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Error
, "{}", str.str().c_str()); } } while (0); } } while (0)
;
783 return false;
784 }
785
786 nsresult rv;
787 sts_target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID"@mozilla.org/network/socket-transport-service;1", &rv);
788
789 if (!NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) return false;
790
791 return true;
792}
793
794int NrIceCtx::SetNat(const RefPtr<TestNat>& aNat) {
795 nat_ = aNat;
796 nr_socket_factory* fac;
797 int r = nat_->create_socket_factory(&fac);
798 if (r) {
799 return r;
800 }
801 nr_ice_ctx_set_socket_factory(ctx_, fac);
802 return 0;
803}
804
805// ONLY USE THIS FOR TESTING. Will cause totally unpredictable and possibly very
806// bad effects if ICE is still live.
807void NrIceCtx::internal_DeinitializeGlobal() {
808 NR_reg_del((char*)"stun");
809 NR_reg_del((char*)"ice");
810 RLogConnector::DestroyInstance();
811 nr_crypto_vtbl = nullptr;
812 initialized = false;
813}
814
815void NrIceCtx::internal_SetTimerAccelarator(int divider) {
816 ctx_->test_timer_divider = divider;
817}
818
819void NrIceCtx::AccumulateStats(const NrIceStats& stats) {
820 nr_accumulate_count(&(ctx_->stats.stun_retransmits), stats.stun_retransmits);
821 nr_accumulate_count(&(ctx_->stats.turn_401s), stats.turn_401s);
822 nr_accumulate_count(&(ctx_->stats.turn_403s), stats.turn_403s);
823 nr_accumulate_count(&(ctx_->stats.turn_438s), stats.turn_438s);
824}
825
826NrIceStats NrIceCtx::Destroy() {
827 // designed to be called more than once so if stats are desired, this can be
828 // called just prior to the destructor
829 MOZ_MTLOG(ML_NOTICE, "NrIceCtx(" << name_ << "): " << __func__)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "NrIceCtx(" << name_ << "): " << __func__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
830
831 for (auto& idAndStream : streams_) {
832 idAndStream.second->Close();
833 }
834
835 NrIceStats stats;
836 if (ctx_) {
837 stats.stun_retransmits = ctx_->stats.stun_retransmits;
838 stats.turn_401s = ctx_->stats.turn_401s;
839 stats.turn_403s = ctx_->stats.turn_403s;
840 stats.turn_438s = ctx_->stats.turn_438s;
841 }
842
843 if (peer_) {
844 nr_ice_peer_ctx_destroy(&peer_);
845 }
846 if (ctx_) {
847 nr_ice_ctx_destroy(&ctx_);
848 }
849
850 delete ice_handler_vtbl_;
851 delete ice_handler_;
852
853 delete ice_gather_handler_vtbl_;
854 delete ice_gather_handler_;
855
856 ice_handler_vtbl_ = nullptr;
857 ice_handler_ = nullptr;
858 ice_gather_handler_vtbl_ = nullptr;
859 ice_gather_handler_ = nullptr;
860 proxy_config_ = nullptr;
861 streams_.clear();
862
863 return stats;
864}
865
866NrIceCtx::~NrIceCtx() = default;
867
868void NrIceCtx::destroy_peer_ctx() { nr_ice_peer_ctx_destroy(&peer_); }
869
870nsresult NrIceCtx::SetControlling(Controlling controlling) {
871 if (!ice_controlling_set_) {
872 peer_->controlling = (controlling == ICE_CONTROLLING) ? 1 : 0;
873 ice_controlling_set_ = true;
874
875 MOZ_MTLOG(ML_DEBUG,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "ICE ctx " << name_ << " setting controlling to"
<< controlling; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Verbose)), 0))) {
mozilla::detail::log_print_fmt(moz_real_module, mozilla::LogLevel
::Verbose, "{}", str.str().c_str()); } } while (0); } } while
(0)
876 "ICE ctx " << name_ << " setting controlling to" << controlling)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "ICE ctx " << name_ << " setting controlling to"
<< controlling; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Verbose)), 0))) {
mozilla::detail::log_print_fmt(moz_real_module, mozilla::LogLevel
::Verbose, "{}", str.str().c_str()); } } while (0); } } while
(0)
;
877 }
878 return NS_OK;
879}
880
881NrIceCtx::Controlling NrIceCtx::GetControlling() {
882 return (peer_->controlling) ? ICE_CONTROLLING : ICE_CONTROLLED;
883}
884
885nsresult NrIceCtx::SetIceServers(const nsTArray<ParsedIceServer>& aServers,
886 bool aTurnDisabled) {
887 MOZ_MTLOG(ML_NOTICE, "NrIceCtx(" << name_ << "): " << __func__)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "NrIceCtx(" << name_ << "): " << __func__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
1
Assuming the condition is false
2
Taking true branch
3
Assuming the condition is false
4
Taking true branch
5
Loop condition is false. Exiting loop
6
Loop condition is false. Exiting loop
888
889 std::vector<nr_ice_stun_server> stunServers;
890 std::vector<nr_ice_turn_server> turnServers;
891
892 for (const auto& entry : aServers) {
893 bool isTurn = entry.mUri.IsTurn();
894
895 if (isTurn
6.1
'isTurn' is true
&& aTurnDisabled) {
7
Assuming 'aTurnDisabled' is false
8
Taking false branch
896 continue;
897 }
898
899 // Test whether this uses an IP addr, or is an FQDN.
900 // We could use PR_StringToNetAddr instead, but that pulls in an extra
901 // dependency.
902 nr_transport_addr parsed;
903 bool isFqdn = false;
904 if (nr_str_port_to_transport_addr(entry.mUri.mHost.get(), nullptr,
9
Assuming the condition is true
10
Taking true branch
905 entry.mUri.mPort, IPPROTO_UDPIPPROTO_UDP, &parsed)) {
906 // Failed to parse, uri's host must be a domain name
907 isFqdn = true;
908 }
909
910 if (isFqdn
10.1
'isFqdn' is true
) {
11
Taking true branch
911 // Not a parseable IP address -- treat as FQDN.
912 // Create both IPv4 and IPv6 versions with a placeholder address
913 if (isTurn
11.1
'isTurn' is true
) {
12
Taking true branch
914 nr_ice_turn_server turnServer;
915 if (ToNicerTurnStruct("0.0.0.0", entry, &turnServer)) {
13
Calling 'ToNicerTurnStruct'
23
Returned allocated memory
24
Taking false branch
916 turnServers.push_back(turnServer);
917 }
918 if (ToNicerTurnStruct("::", entry, &turnServer)) {
25
Calling 'ToNicerTurnStruct'
919 turnServers.push_back(turnServer);
920 }
921 } else {
922 nr_ice_stun_server stunServer;
923 if (ToNicerStunStruct("0.0.0.0", entry, &stunServer)) {
924 stunServers.push_back(stunServer);
925 }
926 if (ToNicerStunStruct("::", entry, &stunServer)) {
927 stunServers.push_back(stunServer);
928 }
929 }
930 } else {
931 // Parsed as IP address.
932 if (isTurn) {
933 nr_ice_turn_server turnServer;
934 if (ToNicerTurnStruct(nullptr, entry, &turnServer)) {
935 turnServers.push_back(turnServer);
936 }
937 } else {
938 nr_ice_stun_server stunServer;
939 if (ToNicerStunStruct(nullptr, entry, &stunServer)) {
940 stunServers.push_back(stunServer);
941 }
942 }
943 }
944 }
945
946 int r = nr_ice_ctx_set_stun_servers(ctx_, stunServers.data(),
947 static_cast<int>(stunServers.size()));
948 if (!r) {
949 r = nr_ice_ctx_set_turn_servers(ctx_, turnServers.data(),
950 static_cast<int>(turnServers.size()));
951 if (!r) {
952 // nICEr has taken ownership of the username/credential in these.
953 turnServers.clear();
954 } else {
955 MOZ_MTLOG(ML_ERROR, "Couldn't set TURN servers for '" << name_ << "'")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't set TURN servers for '" << name_
<< "'"; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Error)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Error
, "{}", str.str().c_str()); } } while (0); } } while (0)
;
956 }
957 } else {
958 MOZ_MTLOG(ML_ERROR, "Couldn't set STUN servers for '" << name_ << "'")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't set STUN servers for '" << name_
<< "'"; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Error)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Error
, "{}", str.str().c_str()); } } while (0); } } while (0)
;
959 }
960
961 for (auto& turn : turnServers) {
962 free(turn.username);
963 r_data_destroy(&turn.password);
964 }
965
966 return r ? NS_ERROR_FAILURE : NS_OK;
967}
968
969nsresult NrIceCtx::SetResolver(nr_resolver* resolver) {
970 int r = nr_ice_ctx_set_resolver(ctx_, resolver);
971
972 if (r) {
973 MOZ_MTLOG(ML_ERROR, "Couldn't set resolver for '" << name_ << "'")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't set resolver for '" << name_ <<
"'"; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
974 return NS_ERROR_FAILURE;
975 }
976
977 return NS_OK;
978}
979
980nsresult NrIceCtx::SetProxyConfig(NrSocketProxyConfig&& config) {
981 proxy_config_.reset(new NrSocketProxyConfig(std::move(config)));
982 if (nat_) {
983 nat_->set_proxy_config(proxy_config_);
984 }
985
986 if (proxy_config_->GetForceProxy()) {
987 nr_ice_ctx_add_flags(ctx_, NR_ICE_CTX_FLAGS_ONLY_PROXY(1<<5));
988 } else {
989 nr_ice_ctx_remove_flags(ctx_, NR_ICE_CTX_FLAGS_ONLY_PROXY(1<<5));
990 }
991
992 return NS_OK;
993}
994
995void NrIceCtx::SetCtxFlags(bool default_route_only) {
996 ASSERT_ON_THREAD(sts_target_)do { if (sts_target_) { bool on; nsresult rv; rv = sts_target_
->IsOnCurrentThread(&on); do { static_assert( mozilla::
detail::AssertionConditionType<decltype(((bool)(__builtin_expect
(!!(!NS_FAILED_impl(rv)), 1))))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(((bool)(__builtin_expect(!!(
!NS_FAILED_impl(rv)), 1)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 996); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 996); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(on)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(on))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("on", "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 996); AnnotateMozCrashReason("MOZ_ASSERT" "(" "on" ")"); do
{ MOZ_CrashSequence(__null, 996); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); } } while (0)
;
997
998 if (default_route_only) {
999 nr_ice_ctx_add_flags(ctx_, NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS(1<<4));
1000 } else {
1001 nr_ice_ctx_remove_flags(ctx_, NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS(1<<4));
1002 }
1003}
1004
1005nsresult NrIceCtx::StartGathering(bool default_route_only,
1006 bool obfuscate_host_addresses) {
1007 ASSERT_ON_THREAD(sts_target_)do { if (sts_target_) { bool on; nsresult rv; rv = sts_target_
->IsOnCurrentThread(&on); do { static_assert( mozilla::
detail::AssertionConditionType<decltype(((bool)(__builtin_expect
(!!(!NS_FAILED_impl(rv)), 1))))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(((bool)(__builtin_expect(!!(
!NS_FAILED_impl(rv)), 1)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 1007); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 1007); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(on)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(on))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("on", "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 1007); AnnotateMozCrashReason("MOZ_ASSERT" "(" "on" ")"); do
{ MOZ_CrashSequence(__null, 1007); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); } } while (0)
;
1008 MOZ_MTLOG(ML_NOTICE, "NrIceCtx(" << name_ << "): " << __func__)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "NrIceCtx(" << name_ << "): " << __func__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
1009
1010 if (obfuscate_host_addresses) {
1011 nr_ice_ctx_add_flags(ctx_, NR_ICE_CTX_FLAGS_OBFUSCATE_HOST_ADDRESSES(1<<6));
1012 }
1013
1014 SetCtxFlags(default_route_only);
1015
1016 // This might start gathering for the first time, or again after
1017 // renegotiation, or might do nothing at all if gathering has already
1018 // finished.
1019 int r = nr_ice_gather(ctx_, &NrIceCtx::gather_cb, this);
1020
1021 if (r && r != R_WOULDBLOCK8) {
1022 MOZ_MTLOG(ML_ERROR, "ICE FAILED: Couldn't gather ICE candidates for '"do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "ICE FAILED: Couldn't gather ICE candidates for '"
<< name_ << "', error=" << r; do { const ::
mozilla::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
1023 << name_ << "', error=" << r)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "ICE FAILED: Couldn't gather ICE candidates for '"
<< name_ << "', error=" << r; do { const ::
mozilla::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Error)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Error, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
1024 SignalAllStreamsFailed();
1025 return NS_ERROR_FAILURE;
1026 }
1027
1028 return NS_OK;
1029}
1030
1031RefPtr<NrIceMediaStream> NrIceCtx::FindStream(nr_ice_media_stream* stream) {
1032 for (auto& idAndStream : streams_) {
1033 if (idAndStream.second->HasStream(stream)) {
1034 return idAndStream.second;
1035 }
1036 }
1037
1038 return nullptr;
1039}
1040
1041std::vector<std::string> NrIceCtx::GetGlobalAttributes() {
1042 char** attrs = nullptr;
1043 int attrct;
1044 int r;
1045 std::vector<std::string> ret;
1046
1047 r = nr_ice_get_global_attributes(ctx_, &attrs, &attrct);
1048 if (r) {
1049 MOZ_MTLOG(ML_ERROR,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't get ufrag and password for '" <<
name_ << "'"; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Error)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Error
, "{}", str.str().c_str()); } } while (0); } } while (0)
1050 "Couldn't get ufrag and password for '" << name_ << "'")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't get ufrag and password for '" <<
name_ << "'"; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Error)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Error
, "{}", str.str().c_str()); } } while (0); } } while (0)
;
1051 return ret;
1052 }
1053
1054 for (int i = 0; i < attrct; i++) {
1055 ret.push_back(std::string(attrs[i]));
1056 free(attrs[i]);
1057 }
1058 free(attrs);
1059
1060 return ret;
1061}
1062
1063nsresult NrIceCtx::ParseGlobalAttributes(std::vector<std::string> attrs) {
1064 std::vector<char*> attrs_in;
1065 attrs_in.reserve(attrs.size());
1066 for (auto& attr : attrs) {
1067 attrs_in.push_back(const_cast<char*>(attr.c_str()));
1068 }
1069
1070 int r = nr_ice_peer_ctx_parse_global_attributes(
1071 peer_, attrs_in.empty() ? nullptr : &attrs_in[0], attrs_in.size());
1072 if (r) {
1073 MOZ_MTLOG(ML_ERROR,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't parse global attributes for " <<
name_ << "'"; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Error)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Error
, "{}", str.str().c_str()); } } while (0); } } while (0)
1074 "Couldn't parse global attributes for " << name_ << "'")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "Couldn't parse global attributes for " <<
name_ << "'"; do { const ::mozilla::LogModule* moz_real_module
= getLogModule(); if ((__builtin_expect(!!(mozilla::detail::
log_test(moz_real_module, mozilla::LogLevel::Error)), 0))) { mozilla
::detail::log_print_fmt(moz_real_module, mozilla::LogLevel::Error
, "{}", str.str().c_str()); } } while (0); } } while (0)
;
1075 return NS_ERROR_FAILURE;
1076 }
1077
1078 return NS_OK;
1079}
1080
1081bool NrIceCtx::HasStreamsToConnect() const {
1082 for (auto& idAndStream : streams_) {
1083 if (idAndStream.second->state() != NrIceMediaStream::ICE_CLOSED) {
1084 return true;
1085 }
1086 }
1087 return false;
1088}
1089
1090nsresult NrIceCtx::StartChecks() {
1091 int r;
1092 MOZ_MTLOG(ML_NOTICE, "NrIceCtx(" << name_ << "): " << __func__)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "NrIceCtx(" << name_ << "): " << __func__
; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
1093
1094 if (!HasStreamsToConnect()) {
1095 MOZ_MTLOG(ML_NOTICE, "In StartChecks, nothing to do on " << name_)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "In StartChecks, nothing to do on " << name_;
do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Info)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Info, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
1096 return NS_OK;
1097 }
1098
1099 r = nr_ice_peer_ctx_pair_candidates(peer_);
1100 if (r) {
1101 MOZ_MTLOG(ML_ERROR, "ICE FAILED: Couldn't pair candidates on " << name_)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "ICE FAILED: Couldn't pair candidates on " <<
name_; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
1102 SignalAllStreamsFailed();
1103 return NS_ERROR_FAILURE;
1104 }
1105
1106 r = nr_ice_peer_ctx_start_checks(peer_);
1107 if (r) {
1108 if (r == R_NOT_FOUND2) {
1109 MOZ_MTLOG(ML_INFO, "Couldn't start peer checks on "do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Debug)), 0))) { std::stringstream str;
str << "Couldn't start peer checks on " << name_
<< ", assuming trickle ICE"; do { const ::mozilla::LogModule
* moz_real_module = getLogModule(); if ((__builtin_expect(!!(
mozilla::detail::log_test(moz_real_module, mozilla::LogLevel::
Debug)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Debug, "{}", str.str().c_str()); } } while
(0); } } while (0)
1110 << name_ << ", assuming trickle ICE")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Debug)), 0))) { std::stringstream str;
str << "Couldn't start peer checks on " << name_
<< ", assuming trickle ICE"; do { const ::mozilla::LogModule
* moz_real_module = getLogModule(); if ((__builtin_expect(!!(
mozilla::detail::log_test(moz_real_module, mozilla::LogLevel::
Debug)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Debug, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
1111 } else {
1112 MOZ_MTLOG(ML_ERROR,do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "ICE FAILED: Couldn't start peer checks on " <<
name_; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
1113 "ICE FAILED: Couldn't start peer checks on " << name_)do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Error)), 0))) { std::stringstream str;
str << "ICE FAILED: Couldn't start peer checks on " <<
name_; do { const ::mozilla::LogModule* moz_real_module = getLogModule
(); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, mozilla::LogLevel::Error)), 0))) { mozilla::detail::log_print_fmt
(moz_real_module, mozilla::LogLevel::Error, "{}", str.str().c_str
()); } } while (0); } } while (0)
;
1114 SignalAllStreamsFailed();
1115 return NS_ERROR_FAILURE;
1116 }
1117 }
1118
1119 return NS_OK;
1120}
1121
1122void NrIceCtx::gather_cb(NR_SOCKET s, int h, void* arg) {
1123 MOZ_MTLOG(ML_DEBUG, "gather_cb called")do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Verbose)), 0))) { std::stringstream str
; str << "gather_cb called"; do { const ::mozilla::LogModule
* moz_real_module = getLogModule(); if ((__builtin_expect(!!(
mozilla::detail::log_test(moz_real_module, mozilla::LogLevel::
Verbose)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Verbose, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
1124 // We don't use this; we react to the stream-specific callbacks instead
1125}
1126
1127void NrIceCtx::SignalAllStreamsFailed() {
1128 for (auto& [id, stream] : streams_) {
1129 (void)id;
1130 stream->Failed();
1131 SignalConnectionStateChange(stream, ICE_CTX_FAILED);
1132 }
1133}
1134
1135void NrIceCtx::UpdateNetworkState(bool online) {
1136 MOZ_MTLOG(ML_NOTICE, "NrIceCtx(" << name_ << "): updating network state to "do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "NrIceCtx(" << name_ << "): updating network state to "
<< (online ? "online" : "offline"); do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Info)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Info, "{}", str.str().c_str()); } } while
(0); } } while (0)
1137 << (online ? "online" : "offline"))do { if ((__builtin_expect(!!(mozilla::detail::log_test(getLogModule
(), mozilla::LogLevel::Info)), 0))) { std::stringstream str; str
<< "NrIceCtx(" << name_ << "): updating network state to "
<< (online ? "online" : "offline"); do { const ::mozilla
::LogModule* moz_real_module = getLogModule(); if ((__builtin_expect
(!!(mozilla::detail::log_test(moz_real_module, mozilla::LogLevel
::Info)), 0))) { mozilla::detail::log_print_fmt(moz_real_module
, mozilla::LogLevel::Info, "{}", str.str().c_str()); } } while
(0); } } while (0)
;
1138 if (online) {
1139 nr_ice_peer_ctx_refresh_consent_all_streams(peer_);
1140 } else {
1141 nr_ice_peer_ctx_disconnect_all_streams(peer_);
1142 }
1143}
1144
1145void NrIceCtx::GenerateObfuscatedAddress(nr_ice_candidate* candidate,
1146 std::string* mdns_address,
1147 std::string* actual_address) {
1148 if (candidate->type == HOST &&
1149 (ctx_->flags & NR_ICE_CTX_FLAGS_OBFUSCATE_HOST_ADDRESSES(1<<6))) {
1150 char addr[64];
1151 if (nr_transport_addr_get_addrstring(&candidate->addr, addr,
1152 sizeof(addr))) {
1153 return;
1154 }
1155
1156 *actual_address = addr;
1157
1158 const auto& iter = obfuscated_host_addresses_.find(*actual_address);
1159 if (iter != obfuscated_host_addresses_.end()) {
1160 *mdns_address = iter->second;
1161 } else {
1162 nsresult rv;
1163 nsCOMPtr<nsIUUIDGenerator> uuidgen =
1164 do_GetService("@mozilla.org/uuid-generator;1", &rv);
1165 // If this fails, we'll return a zero UUID rather than something
1166 // unexpected.
1167 nsID id = {};
1168 id.Clear();
1169 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
1170 rv = uuidgen->GenerateUUIDInPlace(&id);
1171 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1172 id.Clear();
1173 }
1174 }
1175
1176 char chars[NSID_LENGTH39];
1177 id.ToProvidedString(chars);
1178 // The string will look like {64888863-a253-424a-9b30-1ed285d20142},
1179 // we want to trim off the braces.
1180 const char* ptr_to_id = chars;
1181 ++ptr_to_id;
1182 chars[NSID_LENGTH39 - 2] = 0;
1183
1184 std::ostringstream o;
1185 o << ptr_to_id << ".local";
1186 *mdns_address = o.str();
1187
1188 obfuscated_host_addresses_[*actual_address] = *mdns_address;
1189 }
1190 strncpy(candidate->addr.fqdn, mdns_address->c_str(),
1191 sizeof(candidate->addr.fqdn));
1192 candidate->addr.fqdn[sizeof(candidate->addr.fqdn) - 1] = '\0';
1193 }
1194}
1195
1196} // namespace mozilla
1197
1198// Reimplement nr_ice_compute_codeword to avoid copyright issues
1199void nr_ice_compute_codeword(char* buf, int len, char* codeword) {
1200 UINT4 c;
1201
1202 r_crc32(buf, len, &c);
1203 [[maybe_unused]] nsresult nr = mozilla::Base64Encode(
1204 reinterpret_cast<char*>(&c), 3, mozilla::Span(codeword, 5));
1205 MOZ_ASSERT(NS_SUCCEEDED(nr))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(nr)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(nr)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(nr)), 1)))", "/root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp"
, 1205); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(nr)), 1)))"
")"); do { MOZ_CrashSequence(__null, 1205); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1206}
1207
1208int nr_socket_local_create(void* obj, nr_transport_addr* addr,
1209 nr_socket** sockp) {
1210 using namespace mozilla;
1211
1212 RefPtr<NrSocketBase> sock;
1213 int r, _status;
1214 shared_ptr<NrSocketProxyConfig> config = nullptr;
1215
1216 if (obj) {
1217 config = static_cast<NrIceCtx*>(obj)->GetProxyConfig();
1218 }
1219
1220 r = NrSocketBase::CreateSocket(addr, &sock, config);
1221 if (r) {
1222 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
1223 }
1224
1225 r = nr_socket_create_int(static_cast<void*>(sock), sock->vtbl(), sockp);
1226 if (r) ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
1227
1228 _status = 0;
1229
1230 {
1231 // We will release this reference in destroy(), not exactly the normal
1232 // ownership model, but it is what it is.
1233 NrSocketBase* dummy = sock.forget().take();
1234 (void)dummy;
1235 }
1236
1237abort:
1238 return _status;
1239}