RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& name, bool offerer, bool set_interface_priorities) { RefPtr<NrIceCtx> ctx = new NrIceCtx(name, offerer); // Initialize the crypto callbacks if (!initialized) { NR_reg_init(NR_REG_MODE_LOCAL); nr_crypto_vtbl = &nr_ice_crypto_nss_vtbl; initialized = true; // Set the priorites for candidate type preferences NR_reg_set_uchar((char *)"ice.pref.type.srv_rflx",100); NR_reg_set_uchar((char *)"ice.pref.type.peer_rflx",105); NR_reg_set_uchar((char *)"ice.pref.type.prflx",99); NR_reg_set_uchar((char *)"ice.pref.type.host",125); NR_reg_set_uchar((char *)"ice.pref.type.relayed",126); if (set_interface_priorities) { NR_reg_set_uchar((char *)"ice.pref.interface.rl0", 255); NR_reg_set_uchar((char *)"ice.pref.interface.wi0", 254); NR_reg_set_uchar((char *)"ice.pref.interface.lo0", 253); NR_reg_set_uchar((char *)"ice.pref.interface.en1", 252); NR_reg_set_uchar((char *)"ice.pref.interface.en0", 251); NR_reg_set_uchar((char *)"ice.pref.interface.eth0", 252); NR_reg_set_uchar((char *)"ice.pref.interface.eth1", 251); NR_reg_set_uchar((char *)"ice.pref.interface.eth2", 249); NR_reg_set_uchar((char *)"ice.pref.interface.ppp", 250); NR_reg_set_uchar((char *)"ice.pref.interface.ppp0", 249); NR_reg_set_uchar((char *)"ice.pref.interface.en2", 248); NR_reg_set_uchar((char *)"ice.pref.interface.en3", 247); NR_reg_set_uchar((char *)"ice.pref.interface.em0", 251); NR_reg_set_uchar((char *)"ice.pref.interface.em1", 252); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet0", 240); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet1", 241); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet3", 239); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet4", 238); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet5", 237); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet6", 236); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet7", 235); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet8", 234); NR_reg_set_uchar((char *)"ice.pref.interface.virbr0", 233); NR_reg_set_uchar((char *)"ice.pref.interface.wlan0", 232); } NR_reg_set_uint4((char *)"stun.client.maximum_transmits",4); } // Create the ICE context int r; UINT4 flags = offerer ? NR_ICE_CTX_FLAGS_OFFERER: NR_ICE_CTX_FLAGS_ANSWERER; flags |= NR_ICE_CTX_FLAGS_AGGRESSIVE_NOMINATION; r = nr_ice_ctx_create(const_cast<char *>(name.c_str()), flags, &ctx->ctx_); if (r) { MOZ_MTLOG(PR_LOG_ERROR, "Couldn't create ICE ctx for '" << name << "'"); return nullptr; } // Create the handler objects ctx->ice_handler_vtbl_ = new nr_ice_handler_vtbl(); ctx->ice_handler_vtbl_->select_pair = &NrIceCtx::select_pair; ctx->ice_handler_vtbl_->stream_ready = &NrIceCtx::stream_ready; ctx->ice_handler_vtbl_->stream_failed = &NrIceCtx::stream_failed; ctx->ice_handler_vtbl_->ice_completed = &NrIceCtx::ice_completed; ctx->ice_handler_vtbl_->msg_recvd = &NrIceCtx::msg_recvd; ctx->ice_handler_ = new nr_ice_handler(); ctx->ice_handler_->vtbl = ctx->ice_handler_vtbl_; ctx->ice_handler_->obj = ctx; // Create the peer ctx. Because we do not support parallel forking, we // only have one peer ctx. std::string peer_name = name + ":default"; r = nr_ice_peer_ctx_create(ctx->ctx_, ctx->ice_handler_, const_cast<char *>(peer_name.c_str()), &ctx->peer_); if (r) { MOZ_MTLOG(PR_LOG_ERROR, "Couldn't create ICE peer ctx for '" << name << "'"); return nullptr; } nsresult rv; ctx->sts_target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); if (!NS_SUCCEEDED(rv)) return nullptr; return ctx; }
RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& name, bool offerer, bool set_interface_priorities, bool allow_loopback) { RefPtr<NrIceCtx> ctx = new NrIceCtx(name, offerer); // Initialize the crypto callbacks and logging stuff if (!initialized) { NR_reg_init(NR_REG_MODE_LOCAL); RLogRingBuffer::CreateInstance(); nr_crypto_vtbl = &nr_ice_crypto_nss_vtbl; initialized = true; // Set the priorites for candidate type preferences. // These numbers come from RFC 5245 S. 4.1.2.2 NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_SRV_RFLX, 100); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_PEER_RFLX, 110); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_HOST, 126); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_RELAYED, 5); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_RELAYED_TCP, 0); if (set_interface_priorities) { NR_reg_set_uchar((char *)"ice.pref.interface.rl0", 255); NR_reg_set_uchar((char *)"ice.pref.interface.wi0", 254); NR_reg_set_uchar((char *)"ice.pref.interface.lo0", 253); NR_reg_set_uchar((char *)"ice.pref.interface.en1", 252); NR_reg_set_uchar((char *)"ice.pref.interface.en0", 251); NR_reg_set_uchar((char *)"ice.pref.interface.eth0", 252); NR_reg_set_uchar((char *)"ice.pref.interface.eth1", 251); NR_reg_set_uchar((char *)"ice.pref.interface.eth2", 249); NR_reg_set_uchar((char *)"ice.pref.interface.ppp", 250); NR_reg_set_uchar((char *)"ice.pref.interface.ppp0", 249); NR_reg_set_uchar((char *)"ice.pref.interface.en2", 248); NR_reg_set_uchar((char *)"ice.pref.interface.en3", 247); NR_reg_set_uchar((char *)"ice.pref.interface.em0", 251); NR_reg_set_uchar((char *)"ice.pref.interface.em1", 252); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet0", 240); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet1", 241); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet3", 239); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet4", 238); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet5", 237); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet6", 236); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet7", 235); NR_reg_set_uchar((char *)"ice.pref.interface.vmnet8", 234); NR_reg_set_uchar((char *)"ice.pref.interface.virbr0", 233); NR_reg_set_uchar((char *)"ice.pref.interface.wlan0", 232); } NR_reg_set_uint4((char *)"stun.client.maximum_transmits",7); NR_reg_set_uint4((char *)NR_ICE_REG_TRICKLE_GRACE_PERIOD, 5000); if (allow_loopback) { NR_reg_set_char((char *)NR_STUN_REG_PREF_ALLOW_LOOPBACK_ADDRS, 1); } } // Create the ICE context int r; UINT4 flags = offerer ? NR_ICE_CTX_FLAGS_OFFERER: NR_ICE_CTX_FLAGS_ANSWERER; flags |= NR_ICE_CTX_FLAGS_AGGRESSIVE_NOMINATION; r = nr_ice_ctx_create(const_cast<char *>(name.c_str()), flags, &ctx->ctx_); if (r) { MOZ_MTLOG(ML_ERROR, "Couldn't create ICE ctx for '" << name << "'"); return nullptr; } #ifdef USE_INTERFACE_PRIORITIZER nr_interface_prioritizer *prioritizer = CreateInterfacePrioritizer(); if (!prioritizer) { MOZ_MTLOG(PR_LOG_ERROR, "Couldn't create interface prioritizer."); return nullptr; } r = nr_ice_ctx_set_interface_prioritizer(ctx->ctx_, prioritizer); if (r) { MOZ_MTLOG(PR_LOG_ERROR, "Couldn't set interface prioritizer."); return nullptr; } #endif // USE_INTERFACE_PRIORITIZER if (ctx->generating_trickle()) { r = nr_ice_ctx_set_trickle_cb(ctx->ctx_, &NrIceCtx::trickle_cb, ctx); if (r) { MOZ_MTLOG(ML_ERROR, "Couldn't set trickle cb for '" << name << "'"); return nullptr; } } // Create the handler objects ctx->ice_handler_vtbl_ = new nr_ice_handler_vtbl(); ctx->ice_handler_vtbl_->select_pair = &NrIceCtx::select_pair; ctx->ice_handler_vtbl_->stream_ready = &NrIceCtx::stream_ready; ctx->ice_handler_vtbl_->stream_failed = &NrIceCtx::stream_failed; ctx->ice_handler_vtbl_->ice_completed = &NrIceCtx::ice_completed; ctx->ice_handler_vtbl_->msg_recvd = &NrIceCtx::msg_recvd; ctx->ice_handler_vtbl_->ice_checking = &NrIceCtx::ice_checking; ctx->ice_handler_ = new nr_ice_handler(); ctx->ice_handler_->vtbl = ctx->ice_handler_vtbl_; ctx->ice_handler_->obj = ctx; // Create the peer ctx. Because we do not support parallel forking, we // only have one peer ctx. std::string peer_name = name + ":default"; r = nr_ice_peer_ctx_create(ctx->ctx_, ctx->ice_handler_, const_cast<char *>(peer_name.c_str()), &ctx->peer_); if (r) { MOZ_MTLOG(ML_ERROR, "Couldn't create ICE peer ctx for '" << name << "'"); return nullptr; } nsresult rv; ctx->sts_target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); if (!NS_SUCCEEDED(rv)) return nullptr; return ctx; }
RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& name, bool offerer, bool allow_loopback, bool tcp_enabled, bool allow_link_local, bool hide_non_default, Policy policy) { RefPtr<NrIceCtx> ctx = new NrIceCtx(name, offerer, policy); // Initialize the crypto callbacks and logging stuff if (!initialized) { NR_reg_init(NR_REG_MODE_LOCAL); nr_crypto_vtbl = &nr_ice_crypto_nss_vtbl; initialized = true; // Set the priorites for candidate type preferences. // These numbers come from RFC 5245 S. 4.1.2.2 NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_SRV_RFLX, 100); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_PEER_RFLX, 110); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_HOST, 126); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_RELAYED, 5); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_SRV_RFLX_TCP, 99); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_PEER_RFLX_TCP, 109); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_HOST_TCP, 125); NR_reg_set_uchar((char *)NR_ICE_REG_PREF_TYPE_RELAYED_TCP, 0); int32_t stun_client_maximum_transmits = 7; int32_t ice_trickle_grace_period = 5000; int32_t ice_tcp_so_sock_count = 3; int32_t ice_tcp_listen_backlog = 10; nsAutoCString force_net_interface; #ifndef MOZILLA_XPCOMRT_API nsresult res; nsCOMPtr<nsIPrefService> prefs = do_GetService("@mozilla.org/preferences-service;1", &res); if (NS_SUCCEEDED(res)) { nsCOMPtr<nsIPrefBranch> branch = do_QueryInterface(prefs); if (branch) { branch->GetIntPref( "media.peerconnection.ice.stun_client_maximum_transmits", &stun_client_maximum_transmits); branch->GetIntPref( "media.peerconnection.ice.trickle_grace_period", &ice_trickle_grace_period); branch->GetIntPref( "media.peerconnection.ice.tcp_so_sock_count", &ice_tcp_so_sock_count); branch->GetIntPref( "media.peerconnection.ice.tcp_listen_backlog", &ice_tcp_listen_backlog); branch->GetCharPref( "media.peerconnection.ice.force_interface", getter_Copies(force_net_interface)); } } #endif NR_reg_set_uint4((char *)"stun.client.maximum_transmits", stun_client_maximum_transmits); NR_reg_set_uint4((char *)NR_ICE_REG_TRICKLE_GRACE_PERIOD, ice_trickle_grace_period); NR_reg_set_int4((char *)NR_ICE_REG_ICE_TCP_SO_SOCK_COUNT, ice_tcp_so_sock_count); NR_reg_set_int4((char *)NR_ICE_REG_ICE_TCP_LISTEN_BACKLOG, ice_tcp_listen_backlog); NR_reg_set_char((char *)NR_ICE_REG_ICE_TCP_DISABLE, !tcp_enabled); if (allow_loopback) { NR_reg_set_char((char *)NR_STUN_REG_PREF_ALLOW_LOOPBACK_ADDRS, 1); } if (allow_link_local) { NR_reg_set_char((char *)NR_STUN_REG_PREF_ALLOW_LINK_LOCAL_ADDRS, 1); } if (force_net_interface.Length() > 0) { // Stupid cast.... but needed const nsCString& flat = PromiseFlatCString(static_cast<nsACString&>(force_net_interface)); NR_reg_set_string((char *)NR_ICE_REG_PREF_FORCE_INTERFACE_NAME, const_cast<char*>(flat.get())); } } // Create the ICE context int r; UINT4 flags = offerer ? NR_ICE_CTX_FLAGS_OFFERER: NR_ICE_CTX_FLAGS_ANSWERER; flags |= NR_ICE_CTX_FLAGS_AGGRESSIVE_NOMINATION; if (policy == ICE_POLICY_RELAY) { flags |= NR_ICE_CTX_FLAGS_RELAY_ONLY; } if (hide_non_default) flags |= NR_ICE_CTX_FLAGS_ONLY_DEFAULT_ADDRS; r = nr_ice_ctx_create(const_cast<char *>(name.c_str()), flags, &ctx->ctx_); if (r) { MOZ_MTLOG(ML_ERROR, "Couldn't create ICE ctx for '" << name << "'"); return nullptr; } nr_interface_prioritizer *prioritizer = CreateInterfacePrioritizer(); if (!prioritizer) { MOZ_MTLOG(LogLevel::Error, "Couldn't create interface prioritizer."); return nullptr; } r = nr_ice_ctx_set_interface_prioritizer(ctx->ctx_, prioritizer); if (r) { MOZ_MTLOG(LogLevel::Error, "Couldn't set interface prioritizer."); return nullptr; } if (ctx->generating_trickle()) { r = nr_ice_ctx_set_trickle_cb(ctx->ctx_, &NrIceCtx::trickle_cb, ctx); if (r) { MOZ_MTLOG(ML_ERROR, "Couldn't set trickle cb for '" << name << "'"); return nullptr; } } // Create the handler objects ctx->ice_handler_vtbl_ = new nr_ice_handler_vtbl(); ctx->ice_handler_vtbl_->select_pair = &NrIceCtx::select_pair; ctx->ice_handler_vtbl_->stream_ready = &NrIceCtx::stream_ready; ctx->ice_handler_vtbl_->stream_failed = &NrIceCtx::stream_failed; ctx->ice_handler_vtbl_->ice_completed = &NrIceCtx::ice_completed; ctx->ice_handler_vtbl_->msg_recvd = &NrIceCtx::msg_recvd; ctx->ice_handler_vtbl_->ice_checking = &NrIceCtx::ice_checking; ctx->ice_handler_ = new nr_ice_handler(); ctx->ice_handler_->vtbl = ctx->ice_handler_vtbl_; ctx->ice_handler_->obj = ctx; // Create the peer ctx. Because we do not support parallel forking, we // only have one peer ctx. std::string peer_name = name + ":default"; r = nr_ice_peer_ctx_create(ctx->ctx_, ctx->ice_handler_, const_cast<char *>(peer_name.c_str()), &ctx->peer_); if (r) { MOZ_MTLOG(ML_ERROR, "Couldn't create ICE peer ctx for '" << name << "'"); return nullptr; } nsresult rv; ctx->sts_target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); if (!NS_SUCCEEDED(rv)) return nullptr; return ctx; }
bool NrIceCtx::Initialize(const std::string& ufrag, const std::string& pwd) { MOZ_ASSERT(!ufrag.empty()); MOZ_ASSERT(!pwd.empty()); if (ufrag.empty() || pwd.empty()) { return false; } // Create the ICE context int r; UINT4 flags = offerer_ ? NR_ICE_CTX_FLAGS_OFFERER: NR_ICE_CTX_FLAGS_ANSWERER; flags |= NR_ICE_CTX_FLAGS_AGGRESSIVE_NOMINATION; switch (policy_) { case ICE_POLICY_RELAY: flags |= NR_ICE_CTX_FLAGS_RELAY_ONLY; break; case ICE_POLICY_NO_HOST: flags |= NR_ICE_CTX_FLAGS_HIDE_HOST_CANDIDATES; break; case ICE_POLICY_ALL: break; } r = nr_ice_ctx_create_with_credentials(const_cast<char *>(name_.c_str()), flags, const_cast<char *>(ufrag.c_str()), const_cast<char *>(pwd.c_str()), &ctx_); MOZ_ASSERT(ufrag == ctx_->ufrag); MOZ_ASSERT(pwd == ctx_->pwd); if (r) { MOZ_MTLOG(ML_ERROR, "Couldn't create ICE ctx for '" << name_ << "'"); return false; } nr_interface_prioritizer *prioritizer = CreateInterfacePrioritizer(); if (!prioritizer) { MOZ_MTLOG(LogLevel::Error, "Couldn't create interface prioritizer."); return false; } r = nr_ice_ctx_set_interface_prioritizer(ctx_, prioritizer); if (r) { MOZ_MTLOG(LogLevel::Error, "Couldn't set interface prioritizer."); return false; } if (generating_trickle()) { r = nr_ice_ctx_set_trickle_cb(ctx_, &NrIceCtx::trickle_cb, this); if (r) { MOZ_MTLOG(ML_ERROR, "Couldn't set trickle cb for '" << name_ << "'"); return false; } } nsCString mapping_type; nsCString filtering_type; bool block_udp = false; nsresult rv; nsCOMPtr<nsIPrefService> pref_service = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); if (NS_SUCCEEDED(rv)) { nsCOMPtr<nsIPrefBranch> pref_branch; rv = pref_service->GetBranch(nullptr, getter_AddRefs(pref_branch)); if (NS_SUCCEEDED(rv)) { rv = pref_branch->GetCharPref( "media.peerconnection.nat_simulator.mapping_type", getter_Copies(mapping_type)); rv = pref_branch->GetCharPref( "media.peerconnection.nat_simulator.filtering_type", getter_Copies(filtering_type)); rv = pref_branch->GetBoolPref( "media.peerconnection.nat_simulator.block_udp", &block_udp); } } if (!mapping_type.IsEmpty() && !filtering_type.IsEmpty()) { MOZ_MTLOG(ML_DEBUG, "NAT filtering type: " << filtering_type.get()); MOZ_MTLOG(ML_DEBUG, "NAT mapping type: " << mapping_type.get()); TestNat* test_nat = new TestNat; test_nat->filtering_type_ = TestNat::ToNatBehavior(filtering_type.get()); test_nat->mapping_type_ = TestNat::ToNatBehavior(mapping_type.get()); test_nat->block_udp_ = block_udp; test_nat->enabled_ = true; SetNat(test_nat); } // Create the handler objects ice_handler_vtbl_ = new nr_ice_handler_vtbl(); ice_handler_vtbl_->select_pair = &NrIceCtx::select_pair; ice_handler_vtbl_->stream_ready = &NrIceCtx::stream_ready; ice_handler_vtbl_->stream_failed = &NrIceCtx::stream_failed; ice_handler_vtbl_->ice_connected = &NrIceCtx::ice_connected; ice_handler_vtbl_->msg_recvd = &NrIceCtx::msg_recvd; ice_handler_vtbl_->ice_checking = &NrIceCtx::ice_checking; ice_handler_vtbl_->ice_disconnected = &NrIceCtx::ice_disconnected; ice_handler_ = new nr_ice_handler(); ice_handler_->vtbl = ice_handler_vtbl_; ice_handler_->obj = this; // Create the peer ctx. Because we do not support parallel forking, we // only have one peer ctx. std::string peer_name = name_ + ":default"; r = nr_ice_peer_ctx_create(ctx_, ice_handler_, const_cast<char *>(peer_name.c_str()), &peer_); if (r) { MOZ_MTLOG(ML_ERROR, "Couldn't create ICE peer ctx for '" << name_ << "'"); return false; } sts_target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); if (!NS_SUCCEEDED(rv)) return false; return true; }