Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp
Warning:line 455, column 7
1st function call argument is an uninitialized value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name test_nr_socket.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=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dom/media/webrtc/transport/build -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dom/media/webrtc/transport/build -resource-dir /usr/lib/llvm-18/lib/clang/18 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/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 STATIC_EXPORTABLE_JS_API -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/build -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dom/media/webrtc/transport/build -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /var/lib/jenkins/workspace/firefox-scan-build/ipc/chromium/src -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/third_party -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/third_party/nICEr/src/crypto -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/third_party/nICEr/src/ice -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/third_party/nICEr/src/net -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/third_party/nICEr/src/stun -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/third_party/nICEr/src/util -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/third_party/nrappkit/src/event -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/third_party/nrappkit/src/log -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/third_party/nrappkit/src/plugin -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/third_party/nrappkit/src/port/generic/include -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/third_party/nrappkit/src/registry -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/third_party/nrappkit/src/share -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/third_party/nrappkit/src/stats -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr -I /var/lib/jenkins/workspace/firefox-scan-build/third_party/libsrtp/src/crypto/include -I /var/lib/jenkins/workspace/firefox-scan-build/third_party/libsrtp/src/include -I /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/third_party/nrappkit/src/port/linux/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/x86_64-linux-gnu/c++/13 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/backward -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-error=deprecated -Wno-error=deprecated-anon-enum-enum-conversion -Wno-error=deprecated-enum-enum-conversion -Wno-error=deprecated-pragma -Wno-error=deprecated-this-capture -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-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2023-10-10-042615-22730-1 -x c++ /var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp
1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* vim: set ts=2 et sw=2 tw=80: */
3/* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6/*
7 */
8
9/*
10Based partially on original code from nICEr and nrappkit.
11
12nICEr copyright:
13
14Copyright (c) 2007, Adobe Systems, Incorporated
15All rights reserved.
16
17Redistribution and use in source and binary forms, with or without
18modification, are permitted provided that the following conditions are
19met:
20
21* Redistributions of source code must retain the above copyright
22 notice, this list of conditions and the following disclaimer.
23
24* Redistributions in binary form must reproduce the above copyright
25 notice, this list of conditions and the following disclaimer in the
26 documentation and/or other materials provided with the distribution.
27
28* Neither the name of Adobe Systems, Network Resonance nor the names of its
29 contributors may be used to endorse or promote products derived from
30 this software without specific prior written permission.
31
32THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
35A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
37SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
38LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
39DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
40THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
42OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43
44
45nrappkit copyright:
46
47 Copyright (C) 2001-2003, Network Resonance, Inc.
48 Copyright (C) 2006, Network Resonance, Inc.
49 All Rights Reserved
50
51 Redistribution and use in source and binary forms, with or without
52 modification, are permitted provided that the following conditions
53 are met:
54
55 1. Redistributions of source code must retain the above copyright
56 notice, this list of conditions and the following disclaimer.
57 2. Redistributions in binary form must reproduce the above copyright
58 notice, this list of conditions and the following disclaimer in the
59 documentation and/or other materials provided with the distribution.
60 3. Neither the name of Network Resonance, Inc. nor the name of any
61 contributors to this software may be used to endorse or promote
62 products derived from this software without specific prior written
63 permission.
64
65 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
66 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
67 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
68 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
69 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
70 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
71 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
72 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
73 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
74 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
75 POSSIBILITY OF SUCH DAMAGE.
76
77
78 ekr@rtfm.com Thu Dec 20 20:14:49 2001
79*/
80
81// Original author: bcampen@mozilla.com [:bwc]
82
83extern "C" {
84#include "stun_msg.h" // for NR_STUN_MAX_MESSAGE_SIZE
85#include "async_wait.h"
86#include "async_timer.h"
87#include "nr_socket.h"
88#include "stun.h"
89#include "transport_addr.h"
90}
91
92#include "mozilla/RefPtr.h"
93#include "test_nr_socket.h"
94
95namespace mozilla {
96
97static int test_nat_socket_create(void* obj, nr_transport_addr* addr,
98 nr_socket** sockp) {
99 RefPtr<NrSocketBase> sock = new TestNrSocket(static_cast<TestNat*>(obj));
100
101 int r, _status;
102
103 r = sock->create(addr);
104 if (r) ABORT(r)do { int _r=r; if(!_r) _r=-1; ; _status=_r; goto abort;} while
(0)
;
105
106 r = nr_socket_create_int(static_cast<void*>(sock), sock->vtbl(), sockp);
107 if (r) ABORT(r)do { int _r=r; if(!_r) _r=-1; ; _status=_r; goto abort;} while
(0)
;
108
109 _status = 0;
110
111 {
112 // We will release this reference in destroy(), not exactly the normal
113 // ownership model, but it is what it is.
114 NrSocketBase* dummy = sock.forget().take();
115 (void)dummy;
116 }
117
118abort:
119 return _status;
120}
121
122static int test_nat_socket_factory_destroy(void** obj) {
123 TestNat* nat = static_cast<TestNat*>(*obj);
124 *obj = nullptr;
125 nat->Release();
126 return 0;
127}
128
129static nr_socket_factory_vtbl test_nat_socket_factory_vtbl = {
130 test_nat_socket_create, test_nat_socket_factory_destroy};
131
132/* static */
133TestNat::NatBehavior TestNat::ToNatBehavior(const std::string& type) {
134 if (type.empty() || !type.compare("ENDPOINT_INDEPENDENT")) {
135 return TestNat::ENDPOINT_INDEPENDENT;
136 }
137 if (!type.compare("ADDRESS_DEPENDENT")) {
138 return TestNat::ADDRESS_DEPENDENT;
139 }
140 if (!type.compare("PORT_DEPENDENT")) {
141 return TestNat::PORT_DEPENDENT;
142 }
143
144 MOZ_ASSERT(false, "Invalid NAT behavior")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "Invalid NAT behavior"
")", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 144); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"Invalid NAT behavior" ")"); do { *((volatile int*)__null) =
144; ::abort(); } while (false); } } while (false)
;
145 return TestNat::ENDPOINT_INDEPENDENT;
146}
147
148bool TestNat::has_port_mappings() const {
149 for (TestNrSocket* sock : sockets_) {
150 if (sock->has_port_mappings()) {
151 return true;
152 }
153 }
154 return false;
155}
156
157bool TestNat::is_my_external_tuple(const nr_transport_addr& addr) const {
158 for (TestNrSocket* sock : sockets_) {
159 if (sock->is_my_external_tuple(addr)) {
160 return true;
161 }
162 }
163
164 return false;
165}
166
167bool TestNat::is_an_internal_tuple(const nr_transport_addr& addr) const {
168 for (TestNrSocket* sock : sockets_) {
169 nr_transport_addr addr_behind_nat;
170 if (sock->getaddr(&addr_behind_nat)) {
171 MOZ_CRASH("TestNrSocket::getaddr failed!")do { do { } while (false); MOZ_ReportCrash("" "TestNrSocket::getaddr failed!"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 171); AnnotateMozCrashReason("MOZ_CRASH(" "TestNrSocket::getaddr failed!"
")"); do { *((volatile int*)__null) = 171; ::abort(); } while
(false); } while (false)
;
172 }
173
174 if (!nr_transport_addr_cmp(&addr, &addr_behind_nat,
175 NR_TRANSPORT_ADDR_CMP_MODE_ALL4)) {
176 return true;
177 }
178 }
179 return false;
180}
181
182int TestNat::create_socket_factory(nr_socket_factory** factorypp) {
183 int r = nr_socket_factory_create_int(this, &test_nat_socket_factory_vtbl,
184 factorypp);
185 if (!r) {
186 AddRef();
187 }
188 return r;
189}
190
191void TestNat::set_proxy_config(
192 std::shared_ptr<NrSocketProxyConfig> aProxyConfig) {
193 proxy_config_ = std::move(aProxyConfig);
194}
195
196TestNrSocket::TestNrSocket(TestNat* nat)
197 : nat_(nat), tls_(false), timer_handle_(nullptr) {
198 nat_->insert_socket(this);
199}
200
201TestNrSocket::~TestNrSocket() { nat_->erase_socket(this); }
202
203RefPtr<NrSocketBase> TestNrSocket::create_external_socket(
204 const nr_transport_addr& dest_addr) const {
205 MOZ_ASSERT(nat_->enabled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(nat_->enabled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(nat_->enabled_))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("nat_->enabled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 205); AnnotateMozCrashReason("MOZ_ASSERT" "(" "nat_->enabled_"
")"); do { *((volatile int*)__null) = 205; ::abort(); } while
(false); } } while (false)
;
206 MOZ_ASSERT(!nat_->is_an_internal_tuple(dest_addr))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!nat_->is_an_internal_tuple(dest_addr))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!nat_->is_an_internal_tuple(dest_addr)))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!nat_->is_an_internal_tuple(dest_addr)"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 206); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!nat_->is_an_internal_tuple(dest_addr)"
")"); do { *((volatile int*)__null) = 206; ::abort(); } while
(false); } } while (false)
;
207
208 int r;
209 nr_transport_addr nat_external_addr;
210
211 // Open the socket on an arbitrary port, on the same address.
212 if ((r = nr_transport_addr_copy(&nat_external_addr,
213 &internal_socket_->my_addr()))) {
214 r_log(LOG_GENERIC0, LOG_CRIT2, "%s: Failure in nr_transport_addr_copy: %d",
215 __FUNCTION__, r);
216 return nullptr;
217 }
218
219 if ((r = nr_transport_addr_set_port(&nat_external_addr, 0))) {
220 r_log(LOG_GENERIC0, LOG_CRIT2,
221 "%s: Failure in nr_transport_addr_set_port: %d", __FUNCTION__, r);
222 return nullptr;
223 }
224
225 RefPtr<NrSocketBase> external_socket;
226 r = NrSocketBase::CreateSocket(&nat_external_addr, &external_socket,
227 nat_->proxy_config_);
228
229 if (r) {
230 r_log(LOG_GENERIC0, LOG_CRIT2, "%s: Failure in NrSocket::create: %d",
231 __FUNCTION__, r);
232 return nullptr;
233 }
234
235 return external_socket;
236}
237
238int TestNrSocket::create(nr_transport_addr* addr) {
239 tls_ = addr->tls;
240
241 r_log(LOG_GENERIC0, LOG_DEBUG7, "TestNrSocket %p create %s", this,
242 addr->as_string);
243 return NrSocketBase::CreateSocket(addr, &internal_socket_, nullptr);
244}
245
246int TestNrSocket::getaddr(nr_transport_addr* addrp) {
247 return internal_socket_->getaddr(addrp);
248}
249
250void TestNrSocket::close() {
251 r_log(LOG_GENERIC0, LOG_DEBUG7, "TestNrSocket %p %s closing", this,
252 internal_socket_->my_addr().as_string);
253 if (timer_handle_) {
254 NR_async_timer_cancel(timer_handle_);
255 timer_handle_ = nullptr;
256 }
257 internal_socket_->close();
258 for (RefPtr<PortMapping>& port_mapping : port_mappings_) {
259 port_mapping->external_socket_->close();
260 }
261}
262
263int TestNrSocket::listen(int backlog) {
264 MOZ_ASSERT(internal_socket_->my_addr().protocol == IPPROTO_TCP)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(internal_socket_->my_addr().protocol == IPPROTO_TCP
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(internal_socket_->my_addr().protocol == IPPROTO_TCP
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"internal_socket_->my_addr().protocol == IPPROTO_TCP", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 264); AnnotateMozCrashReason("MOZ_ASSERT" "(" "internal_socket_->my_addr().protocol == IPPROTO_TCP"
")"); do { *((volatile int*)__null) = 264; ::abort(); } while
(false); } } while (false)
;
265 r_log(LOG_GENERIC0, LOG_DEBUG7, "TestNrSocket %p %s listening", this,
266 internal_socket_->my_addr().as_string);
267
268 return internal_socket_->listen(backlog);
269}
270
271int TestNrSocket::accept(nr_transport_addr* addrp, nr_socket** sockp) {
272 MOZ_ASSERT(internal_socket_->my_addr().protocol == IPPROTO_TCP)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(internal_socket_->my_addr().protocol == IPPROTO_TCP
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(internal_socket_->my_addr().protocol == IPPROTO_TCP
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"internal_socket_->my_addr().protocol == IPPROTO_TCP", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 272); AnnotateMozCrashReason("MOZ_ASSERT" "(" "internal_socket_->my_addr().protocol == IPPROTO_TCP"
")"); do { *((volatile int*)__null) = 272; ::abort(); } while
(false); } } while (false)
;
273 int r = internal_socket_->accept(addrp, sockp);
274 if (r) {
275 return r;
276 }
277
278 if (nat_->enabled_ && !nat_->is_an_internal_tuple(*addrp)) {
279 nr_socket_destroy(sockp);
280 return R_IO_ERROR13;
281 }
282
283 return 0;
284}
285
286void TestNrSocket::process_delayed_cb(NR_SOCKET s, int how, void* cb_arg) {
287 DeferredPacket* op = static_cast<DeferredPacket*>(cb_arg);
288 op->socket_->timer_handle_ = nullptr;
289 r_log(LOG_GENERIC0, LOG_DEBUG7, "TestNrSocket %s sending delayed STUN response",
290 op->internal_socket_->my_addr().as_string);
291 op->internal_socket_->sendto(op->buffer_.data(), op->buffer_.len(),
292 op->flags_, &op->to_);
293
294 delete op;
295}
296
297int TestNrSocket::sendto(const void* msg, size_t len, int flags,
298 const nr_transport_addr* to) {
299 MOZ_ASSERT(internal_socket_->my_addr().protocol != IPPROTO_TCP)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(internal_socket_->my_addr().protocol != IPPROTO_TCP
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(internal_socket_->my_addr().protocol != IPPROTO_TCP
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"internal_socket_->my_addr().protocol != IPPROTO_TCP", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 299); AnnotateMozCrashReason("MOZ_ASSERT" "(" "internal_socket_->my_addr().protocol != IPPROTO_TCP"
")"); do { *((volatile int*)__null) = 299; ::abort(); } while
(false); } } while (false)
;
300 r_log(LOG_GENERIC0, LOG_DEBUG7, "TestNrSocket %p %s %s", this, __FUNCTION__,
301 to->as_string);
302
303 if (nat_->nat_delegate_ &&
304 nat_->nat_delegate_->on_sendto(nat_, msg, len, flags, to)) {
305 return nat_->error_code_for_drop_;
306 }
307
308 UCHAR* buf = static_cast<UCHAR*>(const_cast<void*>(msg));
309 if (nat_->block_stun_ && nr_is_stun_message(buf, len)) {
310 return nat_->error_code_for_drop_;
311 }
312
313 if (nr_is_stun_request_message(buf, len) &&
314 maybe_send_fake_response(buf, len, to)) {
315 return 0;
316 }
317
318 /* TODO: improve the functionality of this in bug 1253657 */
319 if (!nat_->enabled_ || nat_->is_an_internal_tuple(*to)) {
320 if (nat_->delay_stun_resp_ms_ && nr_is_stun_response_message(buf, len)) {
321 NR_ASYNC_TIMER_SET(NR_async_timer_set(nat_->delay_stun_resp_ms_,process_delayed_cb
,new DeferredPacket(this, msg, len, flags, to, internal_socket_
),(char *)__FUNCTION__,324,&timer_handle_)
322 nat_->delay_stun_resp_ms_, process_delayed_cb,NR_async_timer_set(nat_->delay_stun_resp_ms_,process_delayed_cb
,new DeferredPacket(this, msg, len, flags, to, internal_socket_
),(char *)__FUNCTION__,324,&timer_handle_)
323 new DeferredPacket(this, msg, len, flags, to, internal_socket_),NR_async_timer_set(nat_->delay_stun_resp_ms_,process_delayed_cb
,new DeferredPacket(this, msg, len, flags, to, internal_socket_
),(char *)__FUNCTION__,324,&timer_handle_)
324 &timer_handle_)NR_async_timer_set(nat_->delay_stun_resp_ms_,process_delayed_cb
,new DeferredPacket(this, msg, len, flags, to, internal_socket_
),(char *)__FUNCTION__,324,&timer_handle_)
;
325 return 0;
326 }
327 return internal_socket_->sendto(msg, len, flags, to);
328 }
329
330 destroy_stale_port_mappings();
331
332 if (to->protocol == IPPROTO_UDPIPPROTO_UDP && nat_->block_udp_) {
333 return nat_->error_code_for_drop_;
334 }
335
336 // Choose our port mapping based on our most selective criteria
337 PortMapping* port_mapping = get_port_mapping(
338 *to, std::max(nat_->filtering_type_, nat_->mapping_type_));
339
340 if (!port_mapping) {
341 // See if we have already made the external socket we need to use.
342 PortMapping* similar_port_mapping =
343 get_port_mapping(*to, nat_->mapping_type_);
344 RefPtr<NrSocketBase> external_socket;
345
346 if (similar_port_mapping) {
347 external_socket = similar_port_mapping->external_socket_;
348 } else {
349 external_socket = create_external_socket(*to);
350 if (!external_socket) {
351 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 351); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { *((volatile int*)__null) = 351; ::abort(); } while (false
); } } while (false)
;
352 return R_INTERNAL3;
353 }
354 }
355
356 port_mapping = create_port_mapping(*to, external_socket);
357 port_mappings_.push_back(port_mapping);
358
359 if (poll_flags() & PR_POLL_READ0x1) {
360 // Make sure the new port mapping is ready to receive traffic if the
361 // TestNrSocket is already waiting.
362 port_mapping->async_wait(NR_ASYNC_WAIT_READ0, socket_readable_callback,
363 this, (char*)__FUNCTION__, __LINE__363);
364 }
365 }
366
367 // We probably don't want to propagate the flags, since this is a simulated
368 // external IP address.
369 return port_mapping->sendto(msg, len, *to);
370}
371
372int TestNrSocket::recvfrom(void* buf, size_t maxlen, size_t* len, int flags,
373 nr_transport_addr* from) {
374 MOZ_ASSERT(internal_socket_->my_addr().protocol != IPPROTO_TCP)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(internal_socket_->my_addr().protocol != IPPROTO_TCP
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(internal_socket_->my_addr().protocol != IPPROTO_TCP
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"internal_socket_->my_addr().protocol != IPPROTO_TCP", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 374); AnnotateMozCrashReason("MOZ_ASSERT" "(" "internal_socket_->my_addr().protocol != IPPROTO_TCP"
")"); do { *((volatile int*)__null) = 374; ::abort(); } while
(false); } } while (false)
;
1
Assuming field 'protocol' is not equal to IPPROTO_TCP
2
Taking false branch
3
Loop condition is false. Exiting loop
375
376 if (!read_buffer_.empty()) {
4
Assuming the condition is false
5
Taking false branch
377 UdpPacket& packet = read_buffer_.front();
378 *len = std::min(maxlen, packet.buffer_->len());
379 memcpy(buf, packet.buffer_->data(), *len);
380 nr_transport_addr_copy(from, &packet.remote_address_);
381 read_buffer_.pop_front();
382 return 0;
383 }
384
385 int r;
386 bool ingress_allowed = false;
387
388 if (readable_socket_) {
6
Taking true branch
389 // If any of the external sockets got data, see if it will be passed through
390 r = readable_socket_->recvfrom(buf, maxlen, len, 0, from);
391 const nr_transport_addr to = readable_socket_->my_addr();
392 readable_socket_ = nullptr;
393 if (!r) {
7
Assuming 'r' is 0
8
Taking true branch
394 PortMapping* port_mapping_used;
9
'port_mapping_used' declared without an initial value
395 ingress_allowed = allow_ingress(to, *from, &port_mapping_used);
10
Calling 'TestNrSocket::allow_ingress'
396 if (ingress_allowed) {
397 r_log(LOG_GENERIC0, LOG_DEBUG7, "TestNrSocket %s received from %s via %s",
398 internal_socket_->my_addr().as_string, from->as_string,
399 port_mapping_used->external_socket_->my_addr().as_string);
400 if (nat_->refresh_on_ingress_) {
401 port_mapping_used->last_used_ = PR_IntervalNow();
402 }
403 }
404 }
405 } else {
406 // If no external socket has data, see if there's any data that was sent
407 // directly to the TestNrSocket, and eat it if it isn't supposed to get
408 // through.
409 r = internal_socket_->recvfrom(buf, maxlen, len, flags, from);
410 if (!r) {
411 // We do not use allow_ingress() here because that only handles traffic
412 // landing on an external port.
413 ingress_allowed = (!nat_->enabled_ || nat_->is_an_internal_tuple(*from));
414 if (!ingress_allowed) {
415 r_log(LOG_GENERIC0, LOG_INFO6,
416 "TestNrSocket %s denying ingress from %s: "
417 "Not behind the same NAT",
418 internal_socket_->my_addr().as_string, from->as_string);
419 } else {
420 r_log(LOG_GENERIC0, LOG_DEBUG7, "TestNrSocket %s received from %s",
421 internal_socket_->my_addr().as_string, from->as_string);
422 }
423 }
424 }
425
426 // Kinda bad that we are forced to give the app a readable callback and then
427 // say "Oh, never mind...", but the alternative is to totally decouple the
428 // callbacks from STS and the callbacks the app sets. On the bright side, this
429 // speeds up unit tests where we are verifying that ingress is forbidden,
430 // since they'll get a readable callback and then an error, instead of having
431 // to wait for a timeout.
432 if (!ingress_allowed) {
433 *len = 0;
434 r = R_WOULDBLOCK8;
435 }
436
437 return r;
438}
439
440bool TestNrSocket::allow_ingress(const nr_transport_addr& to,
441 const nr_transport_addr& from,
442 PortMapping** port_mapping_used) const {
443 // This is only called for traffic arriving at a port mapping
444 MOZ_ASSERT(nat_->enabled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(nat_->enabled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(nat_->enabled_))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("nat_->enabled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 444); AnnotateMozCrashReason("MOZ_ASSERT" "(" "nat_->enabled_"
")"); do { *((volatile int*)__null) = 444; ::abort(); } while
(false); } } while (false)
;
11
Assuming field 'enabled_' is true
12
Taking false branch
13
Loop condition is false. Exiting loop
445 MOZ_ASSERT(!nat_->is_an_internal_tuple(from))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!nat_->is_an_internal_tuple(from))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!nat_->is_an_internal_tuple
(from)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!nat_->is_an_internal_tuple(from)", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 445); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!nat_->is_an_internal_tuple(from)"
")"); do { *((volatile int*)__null) = 445; ::abort(); } while
(false); } } while (false)
;
14
Assuming the condition is true
15
Taking false branch
16
Loop condition is false. Exiting loop
446
447 // Find the port mapping (if any) that this packet landed on
448 for (PortMapping* port_mapping : port_mappings_) {
449 if (!nr_transport_addr_cmp(&to, &port_mapping->external_socket_->my_addr(),
450 NR_TRANSPORT_ADDR_CMP_MODE_ALL4)) {
451 *port_mapping_used = port_mapping;
452 }
453 }
454
455 if (NS_WARN_IF(!(*port_mapping_used))NS_warn_if_impl(!(*port_mapping_used), "!(*port_mapping_used)"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 455)
) {
17
1st function call argument is an uninitialized value
456 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", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 456); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")");
do { *((volatile int*)__null) = 456; ::abort(); } while (false
); } } while (false)
;
457 r_log(LOG_GENERIC0, LOG_INFO6,
458 "TestNrSocket %s denying ingress from %s: "
459 "No port mapping for this local port! What?",
460 internal_socket_->my_addr().as_string, from.as_string);
461 return false;
462 }
463
464 if (!port_mapping_matches(**port_mapping_used, from, nat_->filtering_type_)) {
465 r_log(LOG_GENERIC0, LOG_INFO6,
466 "TestNrSocket %s denying ingress from %s: "
467 "Filtered (no port mapping for source)",
468 internal_socket_->my_addr().as_string, from.as_string);
469 return false;
470 }
471
472 if (is_port_mapping_stale(**port_mapping_used)) {
473 r_log(LOG_GENERIC0, LOG_INFO6,
474 "TestNrSocket %s denying ingress from %s: "
475 "Stale port mapping",
476 internal_socket_->my_addr().as_string, from.as_string);
477 return false;
478 }
479
480 if (!nat_->allow_hairpinning_ && nat_->is_my_external_tuple(from)) {
481 r_log(LOG_GENERIC0, LOG_INFO6,
482 "TestNrSocket %s denying ingress from %s: "
483 "Hairpinning disallowed",
484 internal_socket_->my_addr().as_string, from.as_string);
485 return false;
486 }
487
488 return true;
489}
490
491int TestNrSocket::connect(const nr_transport_addr* addr) {
492 r_log(LOG_GENERIC0, LOG_DEBUG7, "TestNrSocket %p %s connecting to %s", this,
493 internal_socket_->my_addr().as_string, addr->as_string);
494
495 if (connect_invoked_ || !port_mappings_.empty()) {
496 MOZ_CRASH("TestNrSocket::connect() called more than once!")do { do { } while (false); MOZ_ReportCrash("" "TestNrSocket::connect() called more than once!"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 496); AnnotateMozCrashReason("MOZ_CRASH(" "TestNrSocket::connect() called more than once!"
")"); do { *((volatile int*)__null) = 496; ::abort(); } while
(false); } while (false)
;
497 return R_INTERNAL3;
498 }
499
500 if (maybe_get_redirect_targets(addr).isSome()) {
501 // If we are simulating STUN redirects for |addr|, we need to pretend that
502 // the TCP connection worked, since |addr| probably does not actually point
503 // at something that exists.
504 connect_fake_stun_address_.reset(new nr_transport_addr);
505 nr_transport_addr_copy(connect_fake_stun_address_.get(), addr);
506
507 // We dispatch this, otherwise nICEr can trip over its shoelaces
508 GetCurrentSerialEventTarget()->Dispatch(
509 NS_NewRunnableFunction("Async writeable callback for TestNrSocket",
510 [this, self = RefPtr<TestNrSocket>(this)] {
511 if (poll_flags() & PR_POLL_WRITE0x2) {
512 fire_callback(NR_ASYNC_WAIT_WRITE1);
513 }
514 }));
515
516 return R_WOULDBLOCK8;
517 }
518
519 if (!nat_->enabled_ ||
520 addr->protocol == IPPROTO_UDPIPPROTO_UDP // Horrible hack to allow default address
521 // discovery to work. Only works because
522 // we don't normally connect on UDP.
523 || nat_->is_an_internal_tuple(*addr)) {
524 // This will set connect_invoked_
525 return internal_socket_->connect(addr);
526 }
527
528 RefPtr<NrSocketBase> external_socket(create_external_socket(*addr));
529 if (!external_socket) {
530 return R_INTERNAL3;
531 }
532
533 PortMapping* port_mapping = create_port_mapping(*addr, external_socket);
534 port_mappings_.push_back(port_mapping);
535 int r = port_mapping->external_socket_->connect(addr);
536 if (r && r != R_WOULDBLOCK8) {
537 return r;
538 }
539
540 port_mapping->last_used_ = PR_IntervalNow();
541
542 if (poll_flags() & PR_POLL_READ0x1) {
543 port_mapping->async_wait(NR_ASYNC_WAIT_READ0,
544 port_mapping_tcp_passthrough_callback, this,
545 (char*)__FUNCTION__, __LINE__545);
546 }
547
548 return r;
549}
550
551int TestNrSocket::write(const void* msg, size_t len, size_t* written) {
552 r_log(LOG_GENERIC0, LOG_DEBUG7, "TestNrSocket %p %s writing", this,
553 internal_socket_->my_addr().as_string);
554
555 UCHAR* buf = static_cast<UCHAR*>(const_cast<void*>(msg));
556
557 if (nat_->nat_delegate_ &&
558 nat_->nat_delegate_->on_write(nat_, msg, len, written)) {
559 return R_INTERNAL3;
560 }
561
562 if (nat_->block_stun_ && nr_is_stun_message(buf, len)) {
563 // Should cause this socket to be abandoned
564 r_log(LOG_GENERIC0, LOG_DEBUG7,
565 "TestNrSocket %s dropping outgoing TCP "
566 "because it is configured to drop STUN",
567 my_addr().as_string);
568 return R_INTERNAL3;
569 }
570
571 if (nr_is_stun_request_message(buf, len) && connect_fake_stun_address_ &&
572 maybe_send_fake_response(buf, len, connect_fake_stun_address_.get())) {
573 return 0;
574 }
575
576 if (nat_->block_tcp_ && !tls_) {
577 // Should cause this socket to be abandoned
578 r_log(LOG_GENERIC0, LOG_DEBUG7,
579 "TestNrSocket %s dropping outgoing TCP "
580 "because it is configured to drop TCP",
581 my_addr().as_string);
582 return R_INTERNAL3;
583 }
584
585 if (nat_->block_tls_ && tls_) {
586 // Should cause this socket to be abandoned
587 r_log(LOG_GENERIC0, LOG_DEBUG7,
588 "TestNrSocket %s dropping outgoing TLS "
589 "because it is configured to drop TLS",
590 my_addr().as_string);
591 return R_INTERNAL3;
592 }
593
594 if (port_mappings_.empty()) {
595 // The no-nat case, just pass call through.
596 r_log(LOG_GENERIC0, LOG_DEBUG7, "TestNrSocket %s writing",
597 my_addr().as_string);
598
599 return internal_socket_->write(msg, len, written);
600 }
601 destroy_stale_port_mappings();
602 if (port_mappings_.empty()) {
603 r_log(LOG_GENERIC0, LOG_DEBUG7,
604 "TestNrSocket %s dropping outgoing TCP "
605 "because the port mapping was stale",
606 my_addr().as_string);
607 return R_INTERNAL3;
608 }
609 // This is TCP only
610 MOZ_ASSERT(port_mappings_.size() == 1)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(port_mappings_.size() == 1)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(port_mappings_.size() == 1))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("port_mappings_.size() == 1"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 610); AnnotateMozCrashReason("MOZ_ASSERT" "(" "port_mappings_.size() == 1"
")"); do { *((volatile int*)__null) = 610; ::abort(); } while
(false); } } while (false)
;
611 r_log(LOG_GENERIC0, LOG_DEBUG7, "PortMapping %s -> %s writing",
612 port_mappings_.front()->external_socket_->my_addr().as_string,
613 port_mappings_.front()->remote_address_.as_string);
614 port_mappings_.front()->last_used_ = PR_IntervalNow();
615 return port_mappings_.front()->external_socket_->write(msg, len, written);
616}
617
618int TestNrSocket::read(void* buf, size_t maxlen, size_t* len) {
619 r_log(LOG_GENERIC0, LOG_DEBUG7, "TestNrSocket %p %s reading", this,
620 internal_socket_->my_addr().as_string);
621
622 if (!read_buffer_.empty()) {
623 r_log(LOG_GENERIC0, LOG_DEBUG7,
624 "TestNrSocket %p %s has stuff in read_buffer_", this,
625 internal_socket_->my_addr().as_string);
626 UdpPacket packet(std::move(read_buffer_.front()));
627 read_buffer_.pop_front();
628 *len = std::min(maxlen, packet.buffer_->len());
629 memcpy(buf, packet.buffer_->data(), *len);
630 if (*len != packet.buffer_->len()) {
631 // Put remaining bytes in new packet, at the front.
632 read_buffer_.emplace_front(packet.buffer_->data() + *len,
633 packet.buffer_->len() - *len,
634 packet.remote_address_);
635 }
636 return 0;
637 }
638
639 if (connect_fake_stun_address_) {
640 return R_WOULDBLOCK8;
641 }
642
643 int r;
644
645 if (port_mappings_.empty()) {
646 r = internal_socket_->read(buf, maxlen, len);
647 } else {
648 MOZ_ASSERT(port_mappings_.size() == 1)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(port_mappings_.size() == 1)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(port_mappings_.size() == 1))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("port_mappings_.size() == 1"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 648); AnnotateMozCrashReason("MOZ_ASSERT" "(" "port_mappings_.size() == 1"
")"); do { *((volatile int*)__null) = 648; ::abort(); } while
(false); } } while (false)
;
649 r = port_mappings_.front()->external_socket_->read(buf, maxlen, len);
650 if (!r && nat_->refresh_on_ingress_) {
651 port_mappings_.front()->last_used_ = PR_IntervalNow();
652 }
653 }
654
655 if (r) {
656 return r;
657 }
658
659 if (nat_->nat_delegate_ &&
660 nat_->nat_delegate_->on_read(nat_, buf, maxlen, len)) {
661 return R_INTERNAL3;
662 }
663
664 if (nat_->block_tcp_ && !tls_) {
665 // Should cause this socket to be abandoned
666 return R_INTERNAL3;
667 }
668
669 if (nat_->block_tls_ && tls_) {
670 // Should cause this socket to be abandoned
671 return R_INTERNAL3;
672 }
673
674 UCHAR* cbuf = static_cast<UCHAR*>(const_cast<void*>(buf));
675 if (nat_->block_stun_ && nr_is_stun_message(cbuf, *len)) {
676 // Should cause this socket to be abandoned
677 return R_INTERNAL3;
678 }
679
680 return r;
681}
682
683int TestNrSocket::async_wait(int how, NR_async_cb cb, void* cb_arg,
684 char* function, int line) {
685 r_log(LOG_GENERIC0, LOG_DEBUG7, "TestNrSocket %s waiting for %s",
686 internal_socket_->my_addr().as_string,
687 how == NR_ASYNC_WAIT_READ0 ? "read" : "write");
688
689 int r;
690
691 if (how == NR_ASYNC_WAIT_READ0) {
692 NrSocketBase::async_wait(how, cb, cb_arg, function, line);
693 if (!read_buffer_.empty()) {
694 fire_readable_callback();
695 return 0;
696 }
697
698 // Make sure we're waiting on the socket for the internal address
699 r = internal_socket_->async_wait(how, socket_readable_callback, this,
700 function, line);
701 } else {
702 if (connect_fake_stun_address_) {
703 // Fake TCP connection case; register the callback on this socket, not
704 // a real one.
705 return NrSocketBase::async_wait(how, cb, cb_arg, function, line);
706 }
707
708 // For write, just use the readiness of the internal socket, since we queue
709 // everything for the port mappings.
710 r = internal_socket_->async_wait(how, cb, cb_arg, function, line);
711 }
712
713 if (r) {
714 r_log(LOG_GENERIC0, LOG_ERR3,
715 "TestNrSocket %s failed to async_wait for "
716 "internal socket: %d\n",
717 internal_socket_->my_addr().as_string, r);
718 return r;
719 }
720
721 if (is_tcp_connection_behind_nat()) {
722 // Bypass all port-mapping related logic
723 return 0;
724 }
725
726 if (internal_socket_->my_addr().protocol == IPPROTO_TCPIPPROTO_TCP) {
727 // For a TCP connection through a simulated NAT, these signals are
728 // just passed through.
729 MOZ_ASSERT(port_mappings_.size() == 1)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(port_mappings_.size() == 1)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(port_mappings_.size() == 1))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("port_mappings_.size() == 1"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 729); AnnotateMozCrashReason("MOZ_ASSERT" "(" "port_mappings_.size() == 1"
")"); do { *((volatile int*)__null) = 729; ::abort(); } while
(false); } } while (false)
;
730
731 return port_mappings_.front()->async_wait(
732 how, port_mapping_tcp_passthrough_callback, this, function, line);
733 }
734 if (how == NR_ASYNC_WAIT_READ0) {
735 // For UDP port mappings, we decouple the writeable callbacks
736 for (PortMapping* port_mapping : port_mappings_) {
737 // Be ready to receive traffic on our port mappings
738 r = port_mapping->async_wait(how, socket_readable_callback, this,
739 function, line);
740 if (r) {
741 r_log(LOG_GENERIC0, LOG_ERR3,
742 "TestNrSocket %s failed to async_wait for "
743 "port mapping: %d\n",
744 internal_socket_->my_addr().as_string, r);
745 return r;
746 }
747 }
748 }
749
750 return 0;
751}
752
753void TestNrSocket::cancel_port_mapping_async_wait(int how) {
754 for (PortMapping* port_mapping : port_mappings_) {
755 port_mapping->cancel(how);
756 }
757}
758
759int TestNrSocket::cancel(int how) {
760 r_log(LOG_GENERIC0, LOG_DEBUG7, "TestNrSocket %s stop waiting for %s",
761 internal_socket_->my_addr().as_string,
762 how == NR_ASYNC_WAIT_READ0 ? "read" : "write");
763
764 if (connect_fake_stun_address_) {
765 return NrSocketBase::cancel(how);
766 }
767
768 // Writable callbacks are decoupled except for the TCP case
769 if (how == NR_ASYNC_WAIT_READ0 ||
770 internal_socket_->my_addr().protocol == IPPROTO_TCPIPPROTO_TCP) {
771 cancel_port_mapping_async_wait(how);
772 }
773
774 return internal_socket_->cancel(how);
775}
776
777bool TestNrSocket::has_port_mappings() const { return !port_mappings_.empty(); }
778
779bool TestNrSocket::is_my_external_tuple(const nr_transport_addr& addr) const {
780 for (PortMapping* port_mapping : port_mappings_) {
781 nr_transport_addr port_mapping_addr;
782 if (port_mapping->external_socket_->getaddr(&port_mapping_addr)) {
783 MOZ_CRASH("NrSocket::getaddr failed!")do { do { } while (false); MOZ_ReportCrash("" "NrSocket::getaddr failed!"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 783); AnnotateMozCrashReason("MOZ_CRASH(" "NrSocket::getaddr failed!"
")"); do { *((volatile int*)__null) = 783; ::abort(); } while
(false); } while (false)
;
784 }
785
786 if (!nr_transport_addr_cmp(&addr, &port_mapping_addr,
787 NR_TRANSPORT_ADDR_CMP_MODE_ALL4)) {
788 return true;
789 }
790 }
791 return false;
792}
793
794bool TestNrSocket::is_port_mapping_stale(
795 const PortMapping& port_mapping) const {
796 PRIntervalTime now = PR_IntervalNow();
797 PRIntervalTime elapsed_ticks = now - port_mapping.last_used_;
798 uint32_t idle_duration = PR_IntervalToMilliseconds(elapsed_ticks);
799 return idle_duration > nat_->mapping_timeout_;
800}
801
802void TestNrSocket::destroy_stale_port_mappings() {
803 for (auto i = port_mappings_.begin(); i != port_mappings_.end();) {
804 auto temp = i;
805 ++i;
806 if (is_port_mapping_stale(**temp)) {
807 r_log(LOG_GENERIC0, LOG_INFO6,
808 "TestNrSocket %s destroying port mapping %s -> %s",
809 internal_socket_->my_addr().as_string,
810 (*temp)->external_socket_->my_addr().as_string,
811 (*temp)->remote_address_.as_string);
812
813 port_mappings_.erase(temp);
814 }
815 }
816}
817
818void TestNrSocket::socket_readable_callback(void* real_sock_v, int how,
819 void* test_sock_v) {
820 TestNrSocket* test_socket = static_cast<TestNrSocket*>(test_sock_v);
821 NrSocketBase* real_socket = static_cast<NrSocketBase*>(real_sock_v);
822
823 test_socket->on_socket_readable(real_socket);
824}
825
826void TestNrSocket::on_socket_readable(NrSocketBase* real_socket) {
827 if (!readable_socket_ && (real_socket != internal_socket_)) {
828 readable_socket_ = real_socket;
829 }
830
831 fire_readable_callback();
832}
833
834void TestNrSocket::fire_readable_callback() {
835 MOZ_ASSERT(poll_flags() & PR_POLL_READ)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(poll_flags() & 0x1)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(poll_flags() & 0x1))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("poll_flags() & 0x1"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 835); AnnotateMozCrashReason("MOZ_ASSERT" "(" "poll_flags() & 0x1"
")"); do { *((volatile int*)__null) = 835; ::abort(); } while
(false); } } while (false)
;
836 r_log(LOG_GENERIC0, LOG_DEBUG7, "TestNrSocket %p %s ready for read", this,
837 internal_socket_->my_addr().as_string);
838 fire_callback(NR_ASYNC_WAIT_READ0);
839}
840
841void TestNrSocket::port_mapping_writeable_callback(void* ext_sock_v, int how,
842 void* test_sock_v) {
843 TestNrSocket* test_socket = static_cast<TestNrSocket*>(test_sock_v);
844 NrSocketBase* external_socket = static_cast<NrSocketBase*>(ext_sock_v);
845
846 test_socket->write_to_port_mapping(external_socket);
847}
848
849void TestNrSocket::write_to_port_mapping(NrSocketBase* external_socket) {
850 MOZ_ASSERT(internal_socket_->my_addr().protocol != IPPROTO_TCP)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(internal_socket_->my_addr().protocol != IPPROTO_TCP
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(internal_socket_->my_addr().protocol != IPPROTO_TCP
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"internal_socket_->my_addr().protocol != IPPROTO_TCP", "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 850); AnnotateMozCrashReason("MOZ_ASSERT" "(" "internal_socket_->my_addr().protocol != IPPROTO_TCP"
")"); do { *((volatile int*)__null) = 850; ::abort(); } while
(false); } } while (false)
;
851
852 int r = 0;
853 for (PortMapping* port_mapping : port_mappings_) {
854 if (port_mapping->external_socket_ == external_socket) {
855 // If the send succeeds, or if there was nothing to send, we keep going
856 r = port_mapping->send_from_queue();
857 if (r) {
858 break;
859 }
860 }
861 }
862
863 if (r == R_WOULDBLOCK8) {
864 // Re-register for writeable callbacks, since we still have stuff to send
865 NR_ASYNC_WAIT(external_socket, NR_ASYNC_WAIT_WRITE,NR_async_wait(external_socket,1,&TestNrSocket::port_mapping_writeable_callback
,this,(char *)__FUNCTION__,866)
866 &TestNrSocket::port_mapping_writeable_callback, this)NR_async_wait(external_socket,1,&TestNrSocket::port_mapping_writeable_callback
,this,(char *)__FUNCTION__,866)
;
867 }
868}
869
870void TestNrSocket::port_mapping_tcp_passthrough_callback(void* ext_sock_v,
871 int how,
872 void* test_sock_v) {
873 TestNrSocket* test_socket = static_cast<TestNrSocket*>(test_sock_v);
874 r_log(LOG_GENERIC0, LOG_DEBUG7, "TestNrSocket %s firing %s callback",
875 test_socket->internal_socket_->my_addr().as_string,
876 how == NR_ASYNC_WAIT_READ0 ? "readable" : "writeable");
877
878 test_socket->internal_socket_->fire_callback(how);
879}
880
881bool TestNrSocket::is_tcp_connection_behind_nat() const {
882 return internal_socket_->my_addr().protocol == IPPROTO_TCPIPPROTO_TCP &&
883 port_mappings_.empty();
884}
885
886TestNrSocket::PortMapping* TestNrSocket::get_port_mapping(
887 const nr_transport_addr& remote_address,
888 TestNat::NatBehavior filter) const {
889 for (PortMapping* port_mapping : port_mappings_) {
890 if (port_mapping_matches(*port_mapping, remote_address, filter)) {
891 return port_mapping;
892 }
893 }
894 return nullptr;
895}
896
897/* static */
898bool TestNrSocket::port_mapping_matches(const PortMapping& port_mapping,
899 const nr_transport_addr& remote_addr,
900 TestNat::NatBehavior filter) {
901 int compare_flags;
902 switch (filter) {
903 case TestNat::ENDPOINT_INDEPENDENT:
904 compare_flags = NR_TRANSPORT_ADDR_CMP_MODE_PROTOCOL2;
905 break;
906 case TestNat::ADDRESS_DEPENDENT:
907 compare_flags = NR_TRANSPORT_ADDR_CMP_MODE_ADDR3;
908 break;
909 case TestNat::PORT_DEPENDENT:
910 compare_flags = NR_TRANSPORT_ADDR_CMP_MODE_ALL4;
911 break;
912 }
913
914 return !nr_transport_addr_cmp(&remote_addr, &port_mapping.remote_address_,
915 compare_flags);
916}
917
918TestNrSocket::PortMapping* TestNrSocket::create_port_mapping(
919 const nr_transport_addr& remote_address,
920 const RefPtr<NrSocketBase>& external_socket) const {
921 r_log(LOG_GENERIC0, LOG_INFO6, "TestNrSocket %s creating port mapping %s -> %s",
922 internal_socket_->my_addr().as_string,
923 external_socket->my_addr().as_string, remote_address.as_string);
924
925 return new PortMapping(remote_address, external_socket);
926}
927
928TestNrSocket::PortMapping::PortMapping(
929 const nr_transport_addr& remote_address,
930 const RefPtr<NrSocketBase>& external_socket)
931 : external_socket_(external_socket) {
932 nr_transport_addr_copy(&remote_address_, &remote_address);
933}
934
935int TestNrSocket::PortMapping::send_from_queue() {
936 MOZ_ASSERT(remote_address_.protocol != IPPROTO_TCP)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(remote_address_.protocol != IPPROTO_TCP)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(remote_address_.protocol != IPPROTO_TCP))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("remote_address_.protocol != IPPROTO_TCP"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 936); AnnotateMozCrashReason("MOZ_ASSERT" "(" "remote_address_.protocol != IPPROTO_TCP"
")"); do { *((volatile int*)__null) = 936; ::abort(); } while
(false); } } while (false)
;
937 int r = 0;
938
939 while (!send_queue_.empty()) {
940 UdpPacket& packet = send_queue_.front();
941 r_log(LOG_GENERIC0, LOG_DEBUG7,
942 "PortMapping %s -> %s sending from queue to %s",
943 external_socket_->my_addr().as_string, remote_address_.as_string,
944 packet.remote_address_.as_string);
945
946 r = external_socket_->sendto(packet.buffer_->data(), packet.buffer_->len(),
947 0, &packet.remote_address_);
948
949 if (r) {
950 if (r != R_WOULDBLOCK8) {
951 r_log(LOG_GENERIC0, LOG_ERR3, "%s: Fatal error %d, stop trying",
952 __FUNCTION__, r);
953 send_queue_.clear();
954 } else {
955 r_log(LOG_GENERIC0, LOG_DEBUG7, "Would block, will retry later");
956 }
957 break;
958 }
959
960 send_queue_.pop_front();
961 }
962
963 return r;
964}
965
966int TestNrSocket::PortMapping::sendto(const void* msg, size_t len,
967 const nr_transport_addr& to) {
968 MOZ_ASSERT(remote_address_.protocol != IPPROTO_TCP)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(remote_address_.protocol != IPPROTO_TCP)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(remote_address_.protocol != IPPROTO_TCP))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("remote_address_.protocol != IPPROTO_TCP"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 968); AnnotateMozCrashReason("MOZ_ASSERT" "(" "remote_address_.protocol != IPPROTO_TCP"
")"); do { *((volatile int*)__null) = 968; ::abort(); } while
(false); } } while (false)
;
969 r_log(LOG_GENERIC0, LOG_DEBUG7, "PortMapping %s -> %s sending to %s",
970 external_socket_->my_addr().as_string, remote_address_.as_string,
971 to.as_string);
972
973 last_used_ = PR_IntervalNow();
974 int r = external_socket_->sendto(msg, len, 0, &to);
975
976 if (r == R_WOULDBLOCK8) {
977 r_log(LOG_GENERIC0, LOG_DEBUG7, "Enqueueing UDP packet to %s", to.as_string);
978 send_queue_.emplace_back(msg, len, to);
979 return 0;
980 }
981 if (r) {
982 r_log(LOG_GENERIC0, LOG_ERR3, "Error: %d", r);
983 }
984
985 return r;
986}
987
988int TestNrSocket::PortMapping::async_wait(int how, NR_async_cb cb, void* cb_arg,
989 char* function, int line) {
990 r_log(LOG_GENERIC0, LOG_DEBUG7, "PortMapping %s -> %s waiting for %s",
991 external_socket_->my_addr().as_string, remote_address_.as_string,
992 how == NR_ASYNC_WAIT_READ0 ? "read" : "write");
993
994 return external_socket_->async_wait(how, cb, cb_arg, function, line);
995}
996
997int TestNrSocket::PortMapping::cancel(int how) {
998 r_log(LOG_GENERIC0, LOG_DEBUG7, "PortMapping %s -> %s stop waiting for %s",
999 external_socket_->my_addr().as_string, remote_address_.as_string,
1000 how == NR_ASYNC_WAIT_READ0 ? "read" : "write");
1001
1002 return external_socket_->cancel(how);
1003}
1004
1005class nr_stun_message_deleter {
1006 public:
1007 nr_stun_message_deleter() = default;
1008 void operator()(nr_stun_message* msg) const { nr_stun_message_destroy(&msg); }
1009};
1010
1011bool TestNrSocket::maybe_send_fake_response(const void* msg, size_t len,
1012 const nr_transport_addr* to) {
1013 Maybe<nsTArray<nsCString>> redirect_targets = maybe_get_redirect_targets(to);
1014 if (!redirect_targets.isSome()) {
1015 return false;
1016 }
1017
1018 std::unique_ptr<nr_stun_message, nr_stun_message_deleter> request;
1019 {
1020 nr_stun_message* temp = nullptr;
1021 if (NS_WARN_IF(nr_stun_message_create2(&temp, (unsigned char*)msg, len))NS_warn_if_impl(nr_stun_message_create2(&temp, (unsigned char
*)msg, len), "nr_stun_message_create2(&temp, (unsigned char*)msg, len)"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 1021)
) {
1022 return false;
1023 }
1024 request.reset(temp);
1025 }
1026
1027 if (NS_WARN_IF(nr_stun_decode_message(request.get(), nullptr, nullptr))NS_warn_if_impl(nr_stun_decode_message(request.get(), nullptr
, nullptr), "nr_stun_decode_message(request.get(), nullptr, nullptr)"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 1027)
) {
1028 return false;
1029 }
1030
1031 std::unique_ptr<nr_stun_message, nr_stun_message_deleter> response;
1032 {
1033 nr_stun_message* temp = nullptr;
1034 if (nr_stun_message_create(&temp)) {
1035 MOZ_CRASH("nr_stun_message_create failed!")do { do { } while (false); MOZ_ReportCrash("" "nr_stun_message_create failed!"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 1035); AnnotateMozCrashReason("MOZ_CRASH(" "nr_stun_message_create failed!"
")"); do { *((volatile int*)__null) = 1035; ::abort(); } while
(false); } while (false)
;
1036 }
1037 response.reset(temp);
1038 }
1039
1040 nr_stun_form_error_response(request.get(), response.get(), 300,
1041 (char*)"Try alternate");
1042
1043 int port = 0;
1044 if (nr_transport_addr_get_port(to, &port)) {
1045 MOZ_CRASH()do { do { } while (false); MOZ_ReportCrash("" , "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 1045); AnnotateMozCrashReason("MOZ_CRASH(" ")"); do { *((volatile
int*)__null) = 1045; ::abort(); } while (false); } while (false
)
;
1046 }
1047
1048 for (const nsCString& address : *redirect_targets) {
1049 r_log(LOG_GENERIC0, LOG_DEBUG7,
1050 "TestNrSocket attempting to add alternate server %s", address.Data());
1051 nr_transport_addr addr;
1052 if (NS_WARN_IF(nr_str_port_to_transport_addr(address.Data(), port,NS_warn_if_impl(nr_str_port_to_transport_addr(address.Data(),
port, IPPROTO_UDP, &addr), "nr_str_port_to_transport_addr(address.Data(), port, IPPROTO_UDP, &addr)"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 1053)
1053 IPPROTO_UDP, &addr))NS_warn_if_impl(nr_str_port_to_transport_addr(address.Data(),
port, IPPROTO_UDP, &addr), "nr_str_port_to_transport_addr(address.Data(), port, IPPROTO_UDP, &addr)"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 1053)
) {
1054 continue;
1055 }
1056 if (nr_stun_message_add_alternate_server_attribute(response.get(), &addr)) {
1057 MOZ_CRASH("nr_stun_message_add_alternate_server_attribute failed!")do { do { } while (false); MOZ_ReportCrash("" "nr_stun_message_add_alternate_server_attribute failed!"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 1057); AnnotateMozCrashReason("MOZ_CRASH(" "nr_stun_message_add_alternate_server_attribute failed!"
")"); do { *((volatile int*)__null) = 1057; ::abort(); } while
(false); } while (false)
;
1058 }
1059 }
1060
1061 if (nr_stun_encode_message(response.get())) {
1062 MOZ_CRASH("nr_stun_encode_message failed!")do { do { } while (false); MOZ_ReportCrash("" "nr_stun_encode_message failed!"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 1062); AnnotateMozCrashReason("MOZ_CRASH(" "nr_stun_encode_message failed!"
")"); do { *((volatile int*)__null) = 1062; ::abort(); } while
(false); } while (false)
;
1063 }
1064
1065 nr_transport_addr response_from;
1066 if (nr_transport_addr_is_wildcard(to)) {
1067 // |to| points to an FQDN, and nICEr is delegating DNS lookup to us; we
1068 // aren't _actually_ going to do that though, so we select a bogus address
1069 // for the response to come from. TEST-NET is a fairly reasonable thing to
1070 // use for this.
1071 int port = 0;
1072 if (nr_transport_addr_get_port(to, &port)) {
1073 MOZ_CRASH()do { do { } while (false); MOZ_ReportCrash("" , "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 1073); AnnotateMozCrashReason("MOZ_CRASH(" ")"); do { *((volatile
int*)__null) = 1073; ::abort(); } while (false); } while (false
)
;
1074 }
1075 switch (to->ip_version) {
1076 case NR_IPV44:
1077 if (nr_str_port_to_transport_addr("198.51.100.1", port, to->protocol,
1078 &response_from)) {
1079 MOZ_CRASH()do { do { } while (false); MOZ_ReportCrash("" , "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 1079); AnnotateMozCrashReason("MOZ_CRASH(" ")"); do { *((volatile
int*)__null) = 1079; ::abort(); } while (false); } while (false
)
;
1080 }
1081 break;
1082 case NR_IPV66:
1083 if (nr_str_port_to_transport_addr("::ffff:198.51.100.1", port,
1084 to->protocol, &response_from)) {
1085 MOZ_CRASH()do { do { } while (false); MOZ_ReportCrash("" , "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 1085); AnnotateMozCrashReason("MOZ_CRASH(" ")"); do { *((volatile
int*)__null) = 1085; ::abort(); } while (false); } while (false
)
;
1086 }
1087 break;
1088 default:
1089 MOZ_CRASH()do { do { } while (false); MOZ_ReportCrash("" , "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 1089); AnnotateMozCrashReason("MOZ_CRASH(" ")"); do { *((volatile
int*)__null) = 1089; ::abort(); } while (false); } while (false
)
;
1090 }
1091 } else {
1092 nr_transport_addr_copy(&response_from, to);
1093 }
1094
1095 read_buffer_.emplace_back(response->buffer, response->length, response_from);
1096
1097 // We dispatch this, otherwise nICEr can trip over its shoelaces
1098 r_log(LOG_GENERIC0, LOG_DEBUG7,
1099 "TestNrSocket %p scheduling callback for redirect response", this);
1100 GetCurrentSerialEventTarget()->Dispatch(NS_NewRunnableFunction(
1101 "Async readable callback for TestNrSocket",
1102 [this, self = RefPtr<TestNrSocket>(this)] {
1103 if (poll_flags() & PR_POLL_READ0x1) {
1104 fire_readable_callback();
1105 } else {
1106 r_log(LOG_GENERIC0, LOG_DEBUG7,
1107 "TestNrSocket %p deferring callback for redirect response",
1108 this);
1109 }
1110 }));
1111
1112 return true;
1113}
1114
1115Maybe<nsTArray<nsCString>> TestNrSocket::maybe_get_redirect_targets(
1116 const nr_transport_addr* to) const {
1117 Maybe<nsTArray<nsCString>> result;
1118
1119 // 256 is overkill, but it hardly matters
1120 char addrstring[256];
1121 if (nr_transport_addr_get_addrstring(to, addrstring, 256)) {
1122 MOZ_CRASH("nr_transport_addr_get_addrstring failed!")do { do { } while (false); MOZ_ReportCrash("" "nr_transport_addr_get_addrstring failed!"
, "/var/lib/jenkins/workspace/firefox-scan-build/dom/media/webrtc/transport/test_nr_socket.cpp"
, 1122); AnnotateMozCrashReason("MOZ_CRASH(" "nr_transport_addr_get_addrstring failed!"
")"); do { *((volatile int*)__null) = 1122; ::abort(); } while
(false); } while (false)
;
1123 }
1124
1125 r_log(LOG_GENERIC0, LOG_DEBUG7, "TestNrSocket checking redirect rules for %s",
1126 addrstring);
1127 auto it = nat_->stun_redirect_map_.find(nsCString(addrstring));
1128 if (it != nat_->stun_redirect_map_.end()) {
1129 result = Some(it->second);
1130 }
1131
1132 return result;
1133}
1134
1135} // namespace mozilla