| File: | root/firefox-clang/dom/media/webrtc/transport/nricectx.cpp |
| Warning: | line 238, column 8 Potential memory leak |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 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 | /* | |||
| 10 | Copyright (c) 2007, Adobe Systems, Incorporated | |||
| 11 | All rights reserved. | |||
| 12 | ||||
| 13 | Redistribution and use in source and binary forms, with or without | |||
| 14 | modification, are permitted provided that the following conditions are | |||
| 15 | met: | |||
| 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 | ||||
| 28 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
| 29 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
| 30 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
| 31 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||
| 32 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
| 33 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
| 34 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |||
| 35 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |||
| 36 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
| 37 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |||
| 38 | OF 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 | ||||
| 85 | namespace mozilla { | |||
| 86 | ||||
| 87 | using std::shared_ptr; | |||
| 88 | using ParsedIceServer = IceServerParser::ParsedIceServer; | |||
| 89 | using IceTransport = IceServerParser::IceTransport; | |||
| 90 | ||||
| 91 | TimeStamp nr_socket_short_term_violation_time() { | |||
| 92 | return NrSocketBase::short_term_violation_time(); | |||
| 93 | } | |||
| 94 | ||||
| 95 | TimeStamp nr_socket_long_term_violation_time() { | |||
| 96 | return NrSocketBase::long_term_violation_time(); | |||
| 97 | } | |||
| 98 | ||||
| 99 | MOZ_MTLOG_MODULE("mtransport")static mozilla::LogModule* getLogModule() { static mozilla::LazyLogModule log("mtransport"); return static_cast<mozilla::LogModule* >(log); } | |||
| 100 | ||||
| 101 | const char kNrIceTransportUdp[] = "udp"; | |||
| 102 | const char kNrIceTransportTcp[] = "tcp"; | |||
| 103 | const char kNrIceTransportTls[] = "tls"; | |||
| 104 | static constexpr UINT4 kRegularNominationDelayMs = 20; | |||
| 105 | ||||
| 106 | static bool initialized = false; | |||
| 107 | ||||
| 108 | static int noop(void** obj) { return 0; } | |||
| 109 | ||||
| 110 | static nr_socket_factory_vtbl ctx_socket_factory_vtbl = {nr_socket_local_create, | |||
| 111 | noop}; | |||
| 112 | ||||
| 113 | // Implement NSPR-based crypto algorithms | |||
| 114 | static 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 | ||||
| 124 | static 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, ¶m); | |||
| 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 | ||||
| 160 | abort: | |||
| 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 | ||||
| 168 | static 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; | |||
| 182 | abort: | |||
| 183 | return err; | |||
| 184 | } | |||
| 185 | ||||
| 186 | static nr_ice_crypto_vtbl nr_ice_crypto_nss_vtbl = { | |||
| 187 | nr_crypto_nss_random_bytes, nr_crypto_nss_hmac, nr_crypto_nss_md5}; | |||
| 188 | ||||
| 189 | static 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 | ||||
| 234 | static 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))) { | |||
| ||||
| 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()); | |||
| 243 | if (!aResult->username) { | |||
| 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()) { | |||
| 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); | |||
| 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 | ||||
| 267 | NrIceCtx::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 */ | |||
| 282 | RefPtr<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 | ||||
| 292 | nsresult 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 | ||||
| 345 | RefPtr<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 | ||||
| 358 | void 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 | |||
| 369 | int 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 | ||||
| 392 | int 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 | ||||
| 411 | int 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 | ||||
| 440 | int 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 | ||||
| 458 | int 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 | ||||
| 473 | int 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 | ||||
| 488 | int 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 | ||||
| 503 | int 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 | ||||
| 539 | int 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 | ||||
| 545 | int 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 | ||||
| 551 | int 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 | ||||
| 557 | int 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 | ||||
| 572 | void 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 | ||||
| 610 | void 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 | ||||
| 656 | void 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 */ | |||
| 665 | nsTArray<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 | ||||
| 690 | void 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 | ||||
| 702 | bool 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 | ||||
| 798 | int 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. | |||
| 811 | void 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 | ||||
| 819 | void NrIceCtx::internal_SetTimerAccelarator(int divider) { | |||
| 820 | ctx_->test_timer_divider = divider; | |||
| 821 | } | |||
| 822 | ||||
| 823 | void 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 | ||||
| 830 | NrIceStats 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 | ||||
| 870 | NrIceCtx::~NrIceCtx() = default; | |||
| 871 | ||||
| 872 | void NrIceCtx::destroy_peer_ctx() { nr_ice_peer_ctx_destroy(&peer_); } | |||
| 873 | ||||
| 874 | nsresult 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 | ||||
| 885 | NrIceCtx::Controlling NrIceCtx::GetControlling() { | |||
| 886 | return (peer_->controlling) ? ICE_CONTROLLING : ICE_CONTROLLED; | |||
| 887 | } | |||
| 888 | ||||
| 889 | nsresult 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); | |||
| ||||
| 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
| |||
| 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, | |||
| 909 | IPPROTO_UDPIPPROTO_UDP, &parsed)) { | |||
| 910 | isFqdn = parsed.fqdn[0] != '\0'; | |||
| 911 | } | |||
| 912 | ||||
| 913 | if (isFqdn
| |||
| 914 | // Not a parseable IP address -- treat as FQDN. | |||
| 915 | // Create both IPv4 and IPv6 versions with a placeholder address | |||
| 916 | if (isTurn
| |||
| 917 | nr_ice_turn_server turnServer; | |||
| 918 | if (ToNicerTurnStruct("0.0.0.0", entry, &turnServer)) { | |||
| 919 | turnServers.push_back(turnServer); | |||
| 920 | } | |||
| 921 | if (ToNicerTurnStruct("::", entry, &turnServer)) { | |||
| 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 | ||||
| 972 | nsresult 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 | ||||
| 983 | nsresult 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 | ||||
| 998 | void 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 | ||||
| 1008 | nsresult 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 | ||||
| 1034 | RefPtr<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 | ||||
| 1044 | std::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 | ||||
| 1066 | nsresult 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 | ||||
| 1084 | bool 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 | ||||
| 1093 | nsresult 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 | ||||
| 1125 | void 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 | ||||
| 1130 | void NrIceCtx::SignalAllStreamsFailed() { | |||
| 1131 | for (auto& [id, stream] : streams_) { | |||
| 1132 | (void)id; | |||
| 1133 | stream->Failed(); | |||
| 1134 | SignalConnectionStateChange(stream, ICE_CTX_FAILED); | |||
| 1135 | } | |||
| 1136 | } | |||
| 1137 | ||||
| 1138 | void 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 | ||||
| 1148 | void 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 | |||
| 1200 | void 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 | ||||
| 1209 | int 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 | ||||
| 1238 | abort: | |||
| 1239 | return _status; | |||
| 1240 | } |