Bug Summary

File:root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp
Warning:line 238, 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/toolkit/components/telemetry -I /root/firefox-clang/xpcom/base -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-09-01-224014-2642839-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* host = aAddrForFqdn ? aAddrForFqdn : aEntry.mUri.mHost.get();
214
215 if (nr_str_port_to_transport_addr(host, aEntry.mUri.mPort, protocol,
216 &(aResult->addr))) {
217 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)
;
218 return false;
219 }
220
221 if (aAddrForFqdn) {
222 std::strncpy(aResult->addr.fqdn, aEntry.mUri.mHost.get(),
223 sizeof(aResult->addr.fqdn) - 1); // Don't stomp trailing null
224 }
225
226 if (isTls) {
227 aResult->addr.tls = true;
228 }
229
230 nr_transport_addr_fmt_addr_string(&(aResult->addr));
231 return true;
232}
233
234static bool ToNicerTurnStruct(const char* aAddrForFqdn,
235 const ParsedIceServer& aEntry,
236 nr_ice_turn_server* aResult) {
237 memset(aResult, 0, sizeof(nr_ice_turn_server));
238 if (!ToNicerStunStruct(aAddrForFqdn, aEntry, &(aResult->turn_server))) {
15
Taking false branch
27
Potential memory leak
239 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)
;
240 return false;
241 }
242 aResult->username = strdup(aEntry.mUsername.get());
16
Memory is allocated
243 if (!aResult->username) {
17
Assuming field 'username' is non-null
18
Taking false branch
244 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)
;
245 return false;
246 }
247
248 if (aEntry.mPassword.IsEmpty()) {
19
Assuming the condition is true
20
Taking true branch
249 // TODO(https://bugzilla.mozilla.org/show_bug.cgi?id=2021075)
250 // Once we check for this in the validation code, we might consider removing
251 // this check. I'm inclined to keep it though, just in case.
252 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)
;
21
Assuming the condition is true
22
Taking false branch
23
Loop condition is false. Exiting loop
253 return false;
254 }
255
256 int r = r_data_create(&aResult->password,
257 reinterpret_cast<const UCHAR*>(aEntry.mPassword.get()),
258 aEntry.mPassword.Length());
259 if (r) {
260 free(aResult->username);
261 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)
;
262 return false;
263 }
264 return true;
265}
266
267NrIceCtx::NrIceCtx(const std::string& name)
268 : name_(name),
269 ice_controlling_set_(false),
270 ctx_(nullptr),
271 peer_(nullptr),
272 ice_handler_vtbl_(nullptr),
273 ice_handler_(nullptr),
274 ice_gather_handler_vtbl_(nullptr),
275 ice_gather_handler_(nullptr),
276 trickle_(true),
277 config_(),
278 nat_(nullptr),
279 proxy_config_(nullptr) {}
280
281/* static */
282RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& aName) {
283 RefPtr<NrIceCtx> ctx = new NrIceCtx(aName);
284
285 if (!ctx->Initialize()) {
286 return nullptr;
287 }
288
289 return ctx;
290}
291
292nsresult NrIceCtx::SetIceConfig(const Config& aConfig) {
293 config_ = aConfig;
294 switch (config_.mPolicy) {
295 case ICE_POLICY_RELAY:
296 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)
;
297 nr_ice_ctx_remove_flags(ctx_, NR_ICE_CTX_FLAGS_DISABLE_HOST_CANDIDATES(1<<3));
298 nr_ice_ctx_add_flags(ctx_, NR_ICE_CTX_FLAGS_RELAY_ONLY(1<<2));
299 break;
300 case ICE_POLICY_NO_HOST:
301 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)
;
302 nr_ice_ctx_add_flags(ctx_, NR_ICE_CTX_FLAGS_DISABLE_HOST_CANDIDATES(1<<3));
303 nr_ice_ctx_remove_flags(ctx_, NR_ICE_CTX_FLAGS_RELAY_ONLY(1<<2));
304 break;
305 case ICE_POLICY_ALL:
306 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)
;
307 nr_ice_ctx_remove_flags(ctx_, NR_ICE_CTX_FLAGS_DISABLE_HOST_CANDIDATES(1<<3));
308 nr_ice_ctx_remove_flags(ctx_, NR_ICE_CTX_FLAGS_RELAY_ONLY(1<<2));
309 break;
310 }
311
312 if (config_.mAllowLoopback) {
313 nr_ice_ctx_add_flags(ctx_, NR_ICE_CTX_FLAGS_ALLOW_LOOPBACK(1 << 7));
314 }
315
316 if (config_.mAllowLinkLocal) {
317 nr_ice_ctx_add_flags(ctx_, NR_ICE_CTX_FLAGS_ALLOW_LINK_LOCAL(1 << 8));
318 }
319
320 // TODO: Support re-configuring the test NAT someday?
321 if (!nat_ && config_.mNatSimulatorConfig.isSome()) {
322 TestNat* test_nat = new TestNat;
323 test_nat->filtering_type_ = TestNat::ToNatBehavior(
324 config_.mNatSimulatorConfig->mFilteringType.get());
325 test_nat->mapping_type_ =
326 TestNat::ToNatBehavior(config_.mNatSimulatorConfig->mMappingType.get());
327 test_nat->block_udp_ = config_.mNatSimulatorConfig->mBlockUdp;
328 test_nat->block_tcp_ = config_.mNatSimulatorConfig->mBlockTcp;
329 test_nat->block_tls_ = config_.mNatSimulatorConfig->mBlockTls;
330 test_nat->error_code_for_drop_ =
331 config_.mNatSimulatorConfig->mErrorCodeForDrop;
332 if (config_.mNatSimulatorConfig->mRedirectAddress.Length()) {
333 test_nat
334 ->stun_redirect_map_[config_.mNatSimulatorConfig->mRedirectAddress] =
335 config_.mNatSimulatorConfig->mRedirectTargets;
336 }
337 test_nat->network_delay_ms_ = config_.mNatSimulatorConfig->mNetworkDelayMs;
338 test_nat->enabled_ = true;
339 SetNat(test_nat);
340 }
341
342 return NS_OK;
343}
344
345RefPtr<NrIceMediaStream> NrIceCtx::CreateStream(const std::string& id,
346 const std::string& name,
347 int components) {
348 if (streams_.count(id)) {
349 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"
, 349); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { MOZ_CrashSequence(__null, 349); __attribute__((nomerge)
) ::abort(); } while (false); } } while (false)
;
350 return nullptr;
351 }
352
353 RefPtr stream = MakeRefPtr<NrIceMediaStream>(this, id, name, components);
354 streams_[id] = stream;
355 return stream;
356}
357
358void NrIceCtx::DestroyStream(const std::string& id) {
359 auto it = streams_.find(id);
360 if (it != streams_.end()) {
361 auto preexisting_stream = it->second;
362 SignalConnectionStateChange(preexisting_stream, ICE_CTX_CLOSED);
363 streams_.erase(it);
364 preexisting_stream->Close();
365 }
366}
367
368// Handler callbacks
369int NrIceCtx::select_pair(void* obj, nr_ice_media_stream* stream,
370 int component_id, nr_ice_cand_pair** potentials,
371 int potential_ct) {
372 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)
;
373 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"
, 373); AnnotateMozCrashReason("MOZ_ASSERT" "(" "stream->local_stream"
")"); do { MOZ_CrashSequence(__null, 373); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
374 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"
, 374); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->local_stream->obsolete"
")"); do { MOZ_CrashSequence(__null, 374); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
375
376 for (int i = 0; i < potential_ct; ++i) {
377 nr_ice_cand_pair* pair = potentials[i];
378 if (pair->state != NR_ICE_PAIR_STATE_SUCCEEDED5) {
379 continue;
380 }
381
382 if (pair->restart_nominated_cb_timer) {
383 return 0;
384 }
385
386 return nr_ice_candidate_pair_nominate(pair, kRegularNominationDelayMs);
387 }
388
389 return 0;
390}
391
392int NrIceCtx::stream_ready(void* obj, nr_ice_media_stream* stream) {
393 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)
;
394 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"
, 394); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->local_stream"
")"); do { MOZ_CrashSequence(__null, 394); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
395 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"
, 395); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->obsolete"
")"); do { MOZ_CrashSequence(__null, 395); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
396
397 // Get the ICE ctx.
398 NrIceCtx* ctx = static_cast<NrIceCtx*>(obj);
399
400 RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
401
402 // Streams which do not exist should never be ready.
403 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"
, 403); AnnotateMozCrashReason("MOZ_ASSERT" "(" "s" ")"); do {
MOZ_CrashSequence(__null, 403); __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
404
405 s->Ready(stream);
406 ctx->SignalConnectionStateChange(s, ICE_CTX_CONNECTED);
407
408 return 0;
409}
410
411int NrIceCtx::stream_failed(void* obj, nr_ice_media_stream* stream) {
412 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)
;
413 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"
, 413); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->local_stream"
")"); do { MOZ_CrashSequence(__null, 413); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
414 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"
, 414); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->obsolete"
")"); do { MOZ_CrashSequence(__null, 414); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
415
416 // Get the ICE ctx
417 NrIceCtx* ctx = static_cast<NrIceCtx*>(obj);
418 RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
419
420 // Streams which do not exist should never fail.
421 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"
, 421); AnnotateMozCrashReason("MOZ_ASSERT" "(" "s" ")"); do {
MOZ_CrashSequence(__null, 421); __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
422
423 if (!ctx->dumped_rlog_) {
424 // Do this at most once per ctx
425 ctx->dumped_rlog_ = true;
426 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)
427 "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)
;
428 std::deque<std::string> logs;
429 RLogConnector::GetInstance()->GetAny(0, &logs);
430 for (auto& log : logs) {
431 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)
;
432 }
433 }
434
435 s->Failed();
436 ctx->SignalConnectionStateChange(s, ICE_CTX_FAILED);
437 return 0;
438}
439
440int NrIceCtx::stream_checking(void* obj, nr_ice_media_stream* stream) {
441 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)
;
442 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"
, 442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->local_stream"
")"); do { MOZ_CrashSequence(__null, 442); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
443 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"
, 443); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->obsolete"
")"); do { MOZ_CrashSequence(__null, 443); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
444
445 // Get the ICE ctx
446 NrIceCtx* ctx = static_cast<NrIceCtx*>(obj);
447 RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
448
449 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"
, 449); AnnotateMozCrashReason("MOZ_ASSERT" "(" "s" ")"); do {
MOZ_CrashSequence(__null, 449); __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
450
451 if (!s->AnyGenerationIsConnected()) {
452 // the checking state only applies if we aren't connected
453 ctx->SignalConnectionStateChange(s, ICE_CTX_CHECKING);
454 }
455 return 0;
456}
457
458int NrIceCtx::stream_disconnected(void* obj, nr_ice_media_stream* stream) {
459 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)
;
460 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"
, 460); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->local_stream"
")"); do { MOZ_CrashSequence(__null, 460); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
461 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"
, 461); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->obsolete"
")"); do { MOZ_CrashSequence(__null, 461); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
462
463 // Get the ICE ctx
464 NrIceCtx* ctx = static_cast<NrIceCtx*>(obj);
465 RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
466
467 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"
, 467); AnnotateMozCrashReason("MOZ_ASSERT" "(" "s" ")"); do {
MOZ_CrashSequence(__null, 467); __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
468
469 ctx->SignalConnectionStateChange(s, ICE_CTX_DISCONNECTED);
470 return 0;
471}
472
473int NrIceCtx::stream_gathering(void* obj, nr_ice_media_stream* stream) {
474 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)
;
475 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"
, 475); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->local_stream"
")"); do { MOZ_CrashSequence(__null, 475); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
476 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"
, 476); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->obsolete"
")"); do { MOZ_CrashSequence(__null, 476); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
477
478 // Get the ICE ctx
479 NrIceCtx* ctx = static_cast<NrIceCtx*>(obj);
480 RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
481
482 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"
, 482); AnnotateMozCrashReason("MOZ_ASSERT" "(" "s" ")"); do {
MOZ_CrashSequence(__null, 482); __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
483
484 s->OnGatheringStarted(stream);
485 return 0;
486}
487
488int NrIceCtx::stream_gathered(void* obj, nr_ice_media_stream* stream) {
489 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)
;
490 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"
, 490); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!stream->local_stream"
")"); do { MOZ_CrashSequence(__null, 490); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
491
492 // Get the ICE ctx
493 NrIceCtx* ctx = static_cast<NrIceCtx*>(obj);
494 RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
495
496 // We get this callback for destroyed streams in some cases
497 if (s) {
498 s->OnGatheringComplete(stream);
499 }
500 return 0;
501}
502
503int NrIceCtx::candidate_error(void* obj, nr_ice_media_stream* stream,
504 nr_ice_candidate* candidate) {
505 NrIceCtx* ctx = static_cast<NrIceCtx*>(obj);
506 RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
507 if (!s) {
508 return 0;
509 }
510
511 if (!candidate->stun_server) {
512 return 0;
513 }
514
515 std::string address;
516 uint16_t port = 0;
517 if (!(ctx->ctx_->flags & NR_ICE_CTX_FLAGS_OBFUSCATE_HOST_ADDRESSES(1<<6))) {
518 nsCString host;
519 if (!nr_transport_addr_get_addrstring_and_port(&candidate->base, &host,
520 &port)) {
521 address = host.get();
522 }
523 }
524
525 char* url = nullptr;
526 int is_turn = (candidate->type == RELAYED);
527 if (nr_ice_stun_server_get_url(candidate->stun_server, is_turn, &url)) {
528 return 0;
529 }
530
531 // errorText is always empty; nICEr discards the STUN reason phrase after
532 // processing the response. See bug 2018863.
533 s->SignalCandidateError(s, address, port, url,
534 static_cast<uint16_t>(candidate->error_code), "");
535 free(url);
536 return 0;
537}
538
539int NrIceCtx::ice_checking(void* obj, nr_ice_peer_ctx* pctx) {
540 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)
;
541 // We don't use this; we react to the stream-specific callbacks instead
542 return 0;
543}
544
545int NrIceCtx::ice_connected(void* obj, nr_ice_peer_ctx* pctx) {
546 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)
;
547 // We don't use this; we react to the stream-specific callbacks instead
548 return 0;
549}
550
551int NrIceCtx::ice_disconnected(void* obj, nr_ice_peer_ctx* pctx) {
552 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)
;
553 // We don't use this; we react to the stream-specific callbacks instead
554 return 0;
555}
556
557int NrIceCtx::msg_recvd(void* obj, nr_ice_peer_ctx* pctx,
558 nr_ice_media_stream* stream, int component_id,
559 UCHAR* msg, int len) {
560 // Get the ICE ctx
561 NrIceCtx* ctx = static_cast<NrIceCtx*>(obj);
562 RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
563
564 // Streams which do not exist should never have packets.
565 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"
, 565); AnnotateMozCrashReason("MOZ_ASSERT" "(" "s" ")"); do {
MOZ_CrashSequence(__null, 565); __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
566
567 s->SignalPacketReceived(s, component_id, msg, len);
568
569 return 0;
570}
571
572void NrIceCtx::trickle_cb(void* arg, nr_ice_ctx* ice_ctx,
573 nr_ice_media_stream* stream, int component_id,
574 nr_ice_candidate* candidate) {
575 if (stream->obsolete) {
576 // Stream was probably just marked obsolete, resulting in this callback
577 return;
578 }
579 // Get the ICE ctx
580 NrIceCtx* ctx = static_cast<NrIceCtx*>(arg);
581 RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
582
583 if (!s) {
584 // This stream has been removed because it is inactive
585 return;
586 }
587
588 if (!candidate) {
589 return;
590 }
591
592 std::string actual_addr;
593 std::string mdns_addr;
594 ctx->GenerateObfuscatedAddress(candidate, &mdns_addr, &actual_addr);
595
596 // Format the candidate.
597 char candidate_str[NR_ICE_MAX_ATTRIBUTE_SIZE256];
598 int r = nr_ice_format_candidate_attribute(
599 candidate, candidate_str, sizeof(candidate_str),
600 (ctx->ctx()->flags & NR_ICE_CTX_FLAGS_OBFUSCATE_HOST_ADDRESSES(1<<6)) ? 1 : 0);
601 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"
, 601); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!r" ")"); do
{ MOZ_CrashSequence(__null, 601); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
602 if (r) return;
603
604 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)
605 << 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)
;
606
607 s->SignalCandidate(s, candidate_str, stream->ufrag, mdns_addr, actual_addr);
608}
609
610void NrIceCtx::InitializeGlobals(const GlobalConfig& aConfig) {
611 RLogConnector::CreateInstance();
612 // Initialize the crypto callbacks and logging stuff
613 if (!initialized) {
614 NR_reg_init();
615 // Registers the "stun" logger for r_log.
616 (void)nr_stun_startup();
617 nr_crypto_vtbl = &nr_ice_crypto_nss_vtbl;
618 initialized = true;
619
620 // Set the priorites for candidate type preferences.
621 // These numbers come from RFC 5245 S. 4.1.2.2
622 NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_SRV_RFLX"ice.pref.type.srv_rflx", 100);
623 NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_PEER_RFLX"ice.pref.type.peer_rflx", 110);
624 NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_HOST"ice.pref.type.host", 126);
625 NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_RELAYED"ice.pref.type.relayed", 5);
626 NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_SRV_RFLX_TCP"ice.pref.type.srv_rflx_tcp", 99);
627 NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_PEER_RFLX_TCP"ice.pref.type.peer_rflx_tcp", 109);
628 NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_HOST_TCP"ice.pref.type.host_tcp", 125);
629 NR_reg_set_uchar((char*)NR_ICE_REG_PREF_TYPE_RELAYED_TCP"ice.pref.type.relayed_tcp", 0);
630 NR_reg_set_uint4((char*)"stun.client.maximum_transmits",
631 aConfig.mStunClientMaxTransmits);
632 NR_reg_set_uint4((char*)NR_ICE_REG_TRICKLE_GRACE_PERIOD"ice.trickle_grace_period",
633 aConfig.mTrickleIceGracePeriod);
634 NR_reg_set_int4((char*)NR_ICE_REG_ICE_TCP_SO_SOCK_COUNT"ice.tcp.so_sock_count",
635 aConfig.mIceTcpSoSockCount);
636 NR_reg_set_int4((char*)NR_ICE_REG_ICE_TCP_LISTEN_BACKLOG"ice.tcp.listen_backlog",
637 aConfig.mIceTcpListenBacklog);
638
639 NR_reg_set_char((char*)NR_ICE_REG_ICE_TCP_DISABLE"ice.tcp.disable", !aConfig.mTcpEnabled);
640
641 if (!aConfig.mForceNetInterface.Length()) {
642 NR_reg_set_string((char*)NR_ICE_REG_PREF_FORCE_INTERFACE_NAME"ice.forced_interface_name",
643 const_cast<char*>(aConfig.mForceNetInterface.get()));
644 }
645
646 // For now, always use nr_resolver for UDP.
647 NR_reg_set_char((char*)NR_ICE_REG_USE_NR_RESOLVER_FOR_UDP"ice.udp.use_nr_resolver", 1);
648
649 // Use nr_resolver for TCP only when not in e10s mode (for unit-tests)
650 if (XRE_IsParentProcess()) {
651 NR_reg_set_char((char*)NR_ICE_REG_USE_NR_RESOLVER_FOR_TCP"ice.tcp.use_nr_resolver", 1);
652 }
653 }
654}
655
656void NrIceCtx::SetTargetForDefaultLocalAddressLookup(
657 const std::string& target_ip, uint16_t target_port) {
658 nr_ice_set_target_for_default_local_address_lookup(ctx_, target_ip.c_str(),
659 target_port);
660}
661
662#define MAXADDRS100 100 // mirrors setting in ice_ctx.c
663
664/* static */
665nsTArray<NrIceStunAddr> NrIceCtx::GetStunAddrs() {
666 nsTArray<NrIceStunAddr> addrs;
667
668 nr_local_addr local_addrs[MAXADDRS100];
669 int addr_ct = 0;
670
671 // most likely running on parent process and need crypto vtbl
672 // initialized on Windows (Linux and OSX don't seem to care)
673 if (!initialized) {
674 nr_crypto_vtbl = &nr_ice_crypto_nss_vtbl;
675 }
676
677 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)
;
678 if (nr_stun_get_addrs(local_addrs, MAXADDRS100, &addr_ct)) {
679 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)
;
680 } else {
681 for (int i = 0; i < addr_ct; ++i) {
682 NrIceStunAddr addr(&local_addrs[i]);
683 addrs.AppendElement(addr);
684 }
685 }
686
687 return addrs;
688}
689
690void NrIceCtx::SetStunAddrs(const nsTArray<NrIceStunAddr>& addrs) {
691 nr_local_addr* local_addrs;
692 local_addrs = new nr_local_addr[addrs.Length()];
693
694 for (size_t i = 0; i < addrs.Length(); ++i) {
695 addrs[i].toNrLocalAddr(local_addrs[i]);
696 }
697 nr_ice_set_local_addresses(ctx_, local_addrs, addrs.Length());
698
699 delete[] local_addrs;
700}
701
702bool NrIceCtx::Initialize() {
703 // Create the gather handler objects
704 ice_gather_handler_vtbl_ = new nr_ice_gather_handler_vtbl();
705 ice_gather_handler_vtbl_->stream_gathering = &NrIceCtx::stream_gathering;
706 ice_gather_handler_vtbl_->stream_gathered = &NrIceCtx::stream_gathered;
707 ice_gather_handler_vtbl_->candidate_error = &NrIceCtx::candidate_error;
708 ice_gather_handler_ = new nr_ice_gather_handler();
709 ice_gather_handler_->vtbl = ice_gather_handler_vtbl_;
710 ice_gather_handler_->obj = this;
711
712 // Create the ICE context
713 int r;
714
715 UINT4 flags = NR_ICE_CTX_FLAGS_AGGRESSIVE_NOMINATION(1);
716
717 r = nr_ice_ctx_create(const_cast<char*>(name_.c_str()), flags,
718 ice_gather_handler_, &ctx_);
719
720 if (r) {
721 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)
;
722 return false;
723 }
724
725 // override default factory to capture optional proxy config when creating
726 // sockets.
727 nr_socket_factory* factory;
728 r = nr_socket_factory_create_int(this, &ctx_socket_factory_vtbl, &factory);
729
730 if (r) {
731 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)
;
732 return false;
733 }
734 nr_ice_ctx_set_socket_factory(ctx_, factory);
735
736 nr_interface_prioritizer* prioritizer = CreateInterfacePrioritizer();
737 if (!prioritizer) {
738 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)
;
739 return false;
740 }
741
742 r = nr_ice_ctx_set_interface_prioritizer(ctx_, prioritizer);
743 if (r) {
744 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)
;
745 return false;
746 }
747
748 if (generating_trickle()) {
749 r = nr_ice_ctx_set_trickle_cb(ctx_, &NrIceCtx::trickle_cb, this);
750 if (r) {
751 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)
;
752 return false;
753 }
754 }
755
756 // Create the handler objects
757 ice_handler_vtbl_ = new nr_ice_handler_vtbl();
758 ice_handler_vtbl_->select_pair = &NrIceCtx::select_pair;
759 ice_handler_vtbl_->stream_ready = &NrIceCtx::stream_ready;
760 ice_handler_vtbl_->stream_failed = &NrIceCtx::stream_failed;
761 ice_handler_vtbl_->stream_checking = &NrIceCtx::stream_checking;
762 ice_handler_vtbl_->stream_disconnected = &NrIceCtx::stream_disconnected;
763 // stream_gathering and stream_gathered do not go here, since those are tied
764 // to the _local_ nr_ice_media_stream in nICEr. nICEr allows a local
765 // nr_ice_media_stream (which has a single set of candidates, and therefore a
766 // single gathering state) to be associated with multiple remote
767 // nr_ice_media_streams (which each have their own ICE connection state)
768 // because it allows forking. We never encounter forking, so these will be
769 // one-to-one in practice, but the architecture in nICEr means we have to set
770 // up these callbacks on the nr_ice_ctx, not the nr_ice_peer_ctx.
771 ice_handler_vtbl_->ice_connected = &NrIceCtx::ice_connected;
772 ice_handler_vtbl_->msg_recvd = &NrIceCtx::msg_recvd;
773 ice_handler_vtbl_->ice_checking = &NrIceCtx::ice_checking;
774 ice_handler_vtbl_->ice_disconnected = &NrIceCtx::ice_disconnected;
775
776 ice_handler_ = new nr_ice_handler();
777 ice_handler_->vtbl = ice_handler_vtbl_;
778 ice_handler_->obj = this;
779
780 // Create the peer ctx. Because we do not support parallel forking, we
781 // only have one peer ctx.
782 std::string peer_name = name_ + ":default";
783 r = nr_ice_peer_ctx_create(ctx_, ice_handler_,
784 const_cast<char*>(peer_name.c_str()), &peer_);
785 if (r) {
786 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)
;
787 return false;
788 }
789
790 nsresult rv;
791 sts_target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID"@mozilla.org/network/socket-transport-service;1", &rv);
792
793 if (!NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) return false;
794
795 return true;
796}
797
798int NrIceCtx::SetNat(const RefPtr<TestNat>& aNat) {
799 nat_ = aNat;
800 nr_socket_factory* fac;
801 int r = nat_->create_socket_factory(&fac);
802 if (r) {
803 return r;
804 }
805 nr_ice_ctx_set_socket_factory(ctx_, fac);
806 return 0;
807}
808
809// ONLY USE THIS FOR TESTING. Will cause totally unpredictable and possibly very
810// bad effects if ICE is still live.
811void NrIceCtx::internal_DeinitializeGlobal() {
812 NR_reg_del((char*)"stun");
813 NR_reg_del((char*)"ice");
814 RLogConnector::DestroyInstance();
815 nr_crypto_vtbl = nullptr;
816 initialized = false;
817}
818
819void NrIceCtx::internal_SetTimerAccelarator(int divider) {
820 ctx_->test_timer_divider = divider;
821}
822
823void NrIceCtx::AccumulateStats(const NrIceStats& stats) {
824 nr_accumulate_count(&(ctx_->stats.stun_retransmits), stats.stun_retransmits);
825 nr_accumulate_count(&(ctx_->stats.turn_401s), stats.turn_401s);
826 nr_accumulate_count(&(ctx_->stats.turn_403s), stats.turn_403s);
827 nr_accumulate_count(&(ctx_->stats.turn_438s), stats.turn_438s);
828}
829
830NrIceStats NrIceCtx::Destroy() {
831 // designed to be called more than once so if stats are desired, this can be
832 // called just prior to the destructor
833 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)
;
834
835 for (auto& idAndStream : streams_) {
836 idAndStream.second->Close();
837 }
838
839 NrIceStats stats;
840 if (ctx_) {
841 stats.stun_retransmits = ctx_->stats.stun_retransmits;
842 stats.turn_401s = ctx_->stats.turn_401s;
843 stats.turn_403s = ctx_->stats.turn_403s;
844 stats.turn_438s = ctx_->stats.turn_438s;
845 }
846
847 if (peer_) {
848 nr_ice_peer_ctx_destroy(&peer_);
849 }
850 if (ctx_) {
851 nr_ice_ctx_destroy(&ctx_);
852 }
853
854 delete ice_handler_vtbl_;
855 delete ice_handler_;
856
857 delete ice_gather_handler_vtbl_;
858 delete ice_gather_handler_;
859
860 ice_handler_vtbl_ = nullptr;
861 ice_handler_ = nullptr;
862 ice_gather_handler_vtbl_ = nullptr;
863 ice_gather_handler_ = nullptr;
864 proxy_config_ = nullptr;
865 streams_.clear();
866
867 return stats;
868}
869
870NrIceCtx::~NrIceCtx() = default;
871
872void NrIceCtx::destroy_peer_ctx() { nr_ice_peer_ctx_destroy(&peer_); }
873
874nsresult NrIceCtx::SetControlling(Controlling controlling) {
875 if (!ice_controlling_set_) {
876 peer_->controlling = (controlling == ICE_CONTROLLING) ? 1 : 0;
877 ice_controlling_set_ = true;
878
879 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)
880 "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)
;
881 }
882 return NS_OK;
883}
884
885NrIceCtx::Controlling NrIceCtx::GetControlling() {
886 return (peer_->controlling) ? ICE_CONTROLLING : ICE_CONTROLLED;
887}
888
889nsresult NrIceCtx::SetIceServers(const nsTArray<ParsedIceServer>& aServers,
890 bool aTurnDisabled) {
891 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
892
893 std::vector<nr_ice_stun_server> stunServers;
894 std::vector<nr_ice_turn_server> turnServers;
895
896 for (const auto& entry : aServers) {
897 bool isTurn = entry.mUri.IsTurn();
898
899 if (isTurn
6.1
'isTurn' is true
&& aTurnDisabled) {
7
Assuming 'aTurnDisabled' is false
8
Taking false branch
900 continue;
901 }
902
903 // Test whether this uses an IP addr, or is an FQDN.
904 // We could use PR_StringToNetAddr instead, but that pulls in an extra
905 // dependency.
906 nr_transport_addr parsed;
907 bool isFqdn = false;
908 if (!nr_str_port_to_transport_addr(entry.mUri.mHost.get(), entry.mUri.mPort,
9
Assuming the condition is true
10
Taking true branch
909 IPPROTO_UDPIPPROTO_UDP, &parsed)) {
910 isFqdn = parsed.fqdn[0] != '\0';
11
Assuming the condition is true
911 }
912
913 if (isFqdn
11.1
'isFqdn' is true
) {
12
Taking true branch
914 // Not a parseable IP address -- treat as FQDN.
915 // Create both IPv4 and IPv6 versions with a placeholder address
916 if (isTurn
12.1
'isTurn' is true
) {
13
Taking true branch
917 nr_ice_turn_server turnServer;
918 if (ToNicerTurnStruct("0.0.0.0", entry, &turnServer)) {
14
Calling 'ToNicerTurnStruct'
24
Returned allocated memory
25
Taking false branch
919 turnServers.push_back(turnServer);
920 }
921 if (ToNicerTurnStruct("::", entry, &turnServer)) {
26
Calling 'ToNicerTurnStruct'
922 turnServers.push_back(turnServer);
923 }
924 } else {
925 nr_ice_stun_server stunServer;
926 if (ToNicerStunStruct("0.0.0.0", entry, &stunServer)) {
927 stunServers.push_back(stunServer);
928 }
929 if (ToNicerStunStruct("::", entry, &stunServer)) {
930 stunServers.push_back(stunServer);
931 }
932 }
933 } else {
934 // Parsed as IP address.
935 if (isTurn) {
936 nr_ice_turn_server turnServer;
937 if (ToNicerTurnStruct(nullptr, entry, &turnServer)) {
938 turnServers.push_back(turnServer);
939 }
940 } else {
941 nr_ice_stun_server stunServer;
942 if (ToNicerStunStruct(nullptr, entry, &stunServer)) {
943 stunServers.push_back(stunServer);
944 }
945 }
946 }
947 }
948
949 int r = nr_ice_ctx_set_stun_servers(ctx_, stunServers.data(),
950 static_cast<int>(stunServers.size()));
951 if (!r) {
952 r = nr_ice_ctx_set_turn_servers(ctx_, turnServers.data(),
953 static_cast<int>(turnServers.size()));
954 if (!r) {
955 // nICEr has taken ownership of the username/credential in these.
956 turnServers.clear();
957 } else {
958 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)
;
959 }
960 } else {
961 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)
;
962 }
963
964 for (auto& turn : turnServers) {
965 free(turn.username);
966 r_data_destroy(&turn.password);
967 }
968
969 return r ? NS_ERROR_FAILURE : NS_OK;
970}
971
972nsresult NrIceCtx::SetResolver(nr_resolver* resolver) {
973 int r = nr_ice_ctx_set_resolver(ctx_, resolver);
974
975 if (r) {
976 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)
;
977 return NS_ERROR_FAILURE;
978 }
979
980 return NS_OK;
981}
982
983nsresult NrIceCtx::SetProxyConfig(NrSocketProxyConfig&& config) {
984 proxy_config_.reset(new NrSocketProxyConfig(std::move(config)));
985 if (nat_) {
986 nat_->set_proxy_config(proxy_config_);
987 }
988
989 if (proxy_config_->GetForceProxy()) {
990 nr_ice_ctx_add_flags(ctx_, NR_ICE_CTX_FLAGS_ONLY_PROXY(1<<5));
991 } else {
992 nr_ice_ctx_remove_flags(ctx_, NR_ICE_CTX_FLAGS_ONLY_PROXY(1<<5));
993 }
994
995 return NS_OK;
996}
997
998void NrIceCtx::SetCtxFlags(bool default_route_only) {
999 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"
, 999); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 999); __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"
, 999); AnnotateMozCrashReason("MOZ_ASSERT" "(" "on" ")"); do
{ MOZ_CrashSequence(__null, 999); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); } } while (0)
;
1000
1001 if (default_route_only) {
1002 nr_ice_ctx_add_flags(ctx_, NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS(1<<4));
1003 } else {
1004 nr_ice_ctx_remove_flags(ctx_, NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS(1<<4));
1005 }
1006}
1007
1008nsresult NrIceCtx::StartGathering(bool default_route_only,
1009 bool obfuscate_host_addresses) {
1010 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"
, 1010); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { MOZ_CrashSequence(__null, 1010); __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"
, 1010); AnnotateMozCrashReason("MOZ_ASSERT" "(" "on" ")"); do
{ MOZ_CrashSequence(__null, 1010); __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); } } while (0)
;
1011 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)
;
1012
1013 if (obfuscate_host_addresses) {
1014 nr_ice_ctx_add_flags(ctx_, NR_ICE_CTX_FLAGS_OBFUSCATE_HOST_ADDRESSES(1<<6));
1015 }
1016
1017 SetCtxFlags(default_route_only);
1018
1019 // This might start gathering for the first time, or again after
1020 // renegotiation, or might do nothing at all if gathering has already
1021 // finished.
1022 int r = nr_ice_gather(ctx_, &NrIceCtx::gather_cb, this);
1023
1024 if (r && r != R_WOULDBLOCK8) {
1025 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)
1026 << 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)
;
1027 SignalAllStreamsFailed();
1028 return NS_ERROR_FAILURE;
1029 }
1030
1031 return NS_OK;
1032}
1033
1034RefPtr<NrIceMediaStream> NrIceCtx::FindStream(nr_ice_media_stream* stream) {
1035 for (auto& idAndStream : streams_) {
1036 if (idAndStream.second->HasStream(stream)) {
1037 return idAndStream.second;
1038 }
1039 }
1040
1041 return nullptr;
1042}
1043
1044std::vector<std::string> NrIceCtx::GetGlobalAttributes() {
1045 char** attrs = nullptr;
1046 int attrct;
1047 int r;
1048 std::vector<std::string> ret;
1049
1050 r = nr_ice_get_global_attributes(ctx_, &attrs, &attrct);
1051 if (r) {
1052 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)
1053 "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)
;
1054 return ret;
1055 }
1056
1057 for (int i = 0; i < attrct; i++) {
1058 ret.push_back(std::string(attrs[i]));
1059 free(attrs[i]);
1060 }
1061 free(attrs);
1062
1063 return ret;
1064}
1065
1066nsresult NrIceCtx::ParseGlobalAttributes(std::vector<std::string> attrs) {
1067 std::vector<char*> attrs_in;
1068 attrs_in.reserve(attrs.size());
1069 for (auto& attr : attrs) {
1070 attrs_in.push_back(const_cast<char*>(attr.c_str()));
1071 }
1072
1073 int r = nr_ice_peer_ctx_parse_global_attributes(
1074 peer_, attrs_in.empty() ? nullptr : &attrs_in[0], attrs_in.size());
1075 if (r) {
1076 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)
1077 "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)
;
1078 return NS_ERROR_FAILURE;
1079 }
1080
1081 return NS_OK;
1082}
1083
1084bool NrIceCtx::HasStreamsToConnect() const {
1085 for (auto& idAndStream : streams_) {
1086 if (idAndStream.second->state() != NrIceMediaStream::ICE_CLOSED) {
1087 return true;
1088 }
1089 }
1090 return false;
1091}
1092
1093nsresult NrIceCtx::StartChecks() {
1094 int r;
1095 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)
;
1096
1097 if (!HasStreamsToConnect()) {
1098 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)
;
1099 return NS_OK;
1100 }
1101
1102 r = nr_ice_peer_ctx_pair_candidates(peer_);
1103 if (r) {
1104 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)
;
1105 SignalAllStreamsFailed();
1106 return NS_ERROR_FAILURE;
1107 }
1108
1109 r = nr_ice_peer_ctx_start_checks2(peer_, 1);
1110 if (r) {
1111 if (r == R_NOT_FOUND2) {
1112 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)
1113 << 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)
;
1114 } else {
1115 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)
1116 "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)
;
1117 SignalAllStreamsFailed();
1118 return NS_ERROR_FAILURE;
1119 }
1120 }
1121
1122 return NS_OK;
1123}
1124
1125void NrIceCtx::gather_cb(NR_SOCKET s, int h, void* arg) {
1126 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)
;
1127 // We don't use this; we react to the stream-specific callbacks instead
1128}
1129
1130void NrIceCtx::SignalAllStreamsFailed() {
1131 for (auto& [id, stream] : streams_) {
1132 (void)id;
1133 stream->Failed();
1134 SignalConnectionStateChange(stream, ICE_CTX_FAILED);
1135 }
1136}
1137
1138void NrIceCtx::UpdateNetworkState(bool online) {
1139 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)
1140 << (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)
;
1141 if (online) {
1142 nr_ice_peer_ctx_refresh_consent_all_streams(peer_);
1143 } else {
1144 nr_ice_peer_ctx_disconnect_all_streams(peer_);
1145 }
1146}
1147
1148void NrIceCtx::GenerateObfuscatedAddress(nr_ice_candidate* candidate,
1149 std::string* mdns_address,
1150 std::string* actual_address) {
1151 if (candidate->type == HOST &&
1152 (ctx_->flags & NR_ICE_CTX_FLAGS_OBFUSCATE_HOST_ADDRESSES(1<<6))) {
1153 char addr[64];
1154 if (nr_transport_addr_get_addrstring(&candidate->addr, addr,
1155 sizeof(addr))) {
1156 return;
1157 }
1158
1159 *actual_address = addr;
1160
1161 const auto& iter = obfuscated_host_addresses_.find(*actual_address);
1162 if (iter != obfuscated_host_addresses_.end()) {
1163 *mdns_address = iter->second;
1164 } else {
1165 nsresult rv;
1166 nsCOMPtr<nsIUUIDGenerator> uuidgen =
1167 do_GetService("@mozilla.org/uuid-generator;1", &rv);
1168 // If this fails, we'll return a zero UUID rather than something
1169 // unexpected.
1170 nsID id = {};
1171 id.Clear();
1172 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
1173 rv = uuidgen->GenerateUUIDInPlace(&id);
1174 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1175 id.Clear();
1176 }
1177 }
1178
1179 char chars[NSID_LENGTH39];
1180 id.ToProvidedString(chars);
1181 // The string will look like {64888863-a253-424a-9b30-1ed285d20142},
1182 // we want to trim off the braces.
1183 const char* ptr_to_id = chars;
1184 ++ptr_to_id;
1185 chars[NSID_LENGTH39 - 2] = 0;
1186
1187 std::ostringstream o;
1188 o << ptr_to_id << ".local";
1189 *mdns_address = o.str();
1190
1191 obfuscated_host_addresses_[*actual_address] = *mdns_address;
1192 }
1193 candidate->mdns_addr = strdup(mdns_address->c_str());
1194 }
1195}
1196
1197} // namespace mozilla
1198
1199// Reimplement nr_ice_compute_codeword to avoid copyright issues
1200void nr_ice_compute_codeword(char* buf, int len, char* codeword) {
1201 UINT4 c;
1202
1203 r_crc32(buf, len, &c);
1204 [[maybe_unused]] nsresult nr = mozilla::Base64Encode(
1205 reinterpret_cast<char*>(&c), 3, mozilla::Span(codeword, 5));
1206 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"
, 1206); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(nr)), 1)))"
")"); do { MOZ_CrashSequence(__null, 1206); __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1207}
1208
1209int nr_socket_local_create(void* obj, nr_transport_addr* addr,
1210 nr_socket** sockp) {
1211 using namespace mozilla;
1212
1213 RefPtr<NrSocketBase> sock;
1214 int r, _status;
1215 shared_ptr<NrSocketProxyConfig> config = nullptr;
1216
1217 if (obj) {
1218 config = static_cast<NrIceCtx*>(obj)->GetProxyConfig();
1219 }
1220
1221 r = NrSocketBase::CreateSocket(addr, &sock, config);
1222 if (r) {
1223 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
1224 }
1225
1226 r = nr_socket_create_int(static_cast<void*>(sock), sock->vtbl(), sockp);
1227 if (r) ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
1228
1229 _status = 0;
1230
1231 {
1232 // We will release this reference in destroy(), not exactly the normal
1233 // ownership model, but it is what it is.
1234 NrSocketBase* dummy = sock.forget().take();
1235 (void)dummy;
1236 }
1237
1238abort:
1239 return _status;
1240}