Bug 1231973 - Allow NAT simulator to be enabled with the pref system. r=drno

This commit is contained in:
Byron Campen [:bwc] 2015-12-16 14:26:02 -06:00
parent de2dab0590
commit 06024461a8
7 changed files with 111 additions and 22 deletions

View File

@ -89,6 +89,7 @@ nrappkit copyright:
#include <sys/types.h>
#include <assert.h>
#include <errno.h>
#include <string>
#include "nspr.h"
#include "prerror.h"
@ -110,6 +111,8 @@ nrappkit copyright:
#include "nsTArray.h"
#include "mozilla/dom/TCPSocketBinding.h"
#include "nsITCPSocketCallback.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#if defined(MOZILLA_INTERNAL_API) && !defined(MOZILLA_XPCOMRT_API)
// csi_platform.h deep in nrappkit defines LOG_INFO and LOG_WARNING
@ -164,6 +167,7 @@ extern "C" {
}
#include "nr_socket_prsock.h"
#include "simpletokenbucket.h"
#include "test_nr_socket.h"
// Implement the nsISupports ref counting
namespace mozilla {

View File

@ -93,6 +93,7 @@ extern "C" {
#include "nr_socket_prsock.h"
#include "nrinterfaceprioritizer.h"
#include "rlogringbuffer.h"
#include "test_nr_socket.h"
namespace mozilla {
@ -268,6 +269,25 @@ nsresult NrIceTurnServer::ToNicerTurnStruct(nr_ice_turn_server *server) const {
return NS_OK;
}
NrIceCtx::NrIceCtx(const std::string& name,
bool offerer,
Policy policy)
: connection_state_(ICE_CTX_INIT),
gathering_state_(ICE_CTX_GATHER_INIT),
name_(name),
offerer_(offerer),
streams_(),
ctx_(nullptr),
peer_(nullptr),
ice_handler_vtbl_(nullptr),
ice_handler_(nullptr),
trickle_(true),
policy_(policy),
nat_ (nullptr) {
// XXX: offerer_ will be used eventually; placate clang in the meantime.
(void)offerer_;
}
// Handler callbacks
int NrIceCtx::select_pair(void *obj,nr_ice_media_stream *stream,
int component_id, nr_ice_cand_pair **potentials,
@ -498,6 +518,42 @@ RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& name,
}
}
char* mapping_type = nullptr;
char* filtering_type = nullptr;
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",
&mapping_type);
rv = pref_branch->GetCharPref(
"media.peerconnection.nat_simulator.filtering_type",
&filtering_type);
rv = pref_branch->GetBoolPref(
"media.peerconnection.nat_simulator.block_udp",
&block_udp);
}
}
MOZ_MTLOG(ML_DEBUG, "NAT filtering type: " << filtering_type);
MOZ_MTLOG(ML_DEBUG, "NAT mapping type: " << mapping_type);
if (mapping_type && filtering_type) {
TestNat* test_nat = new TestNat;
test_nat->filtering_type_ = TestNat::ToNatBehavior(filtering_type);
test_nat->mapping_type_ = TestNat::ToNatBehavior(mapping_type);
test_nat->block_udp_ = block_udp;
test_nat->enabled_ = true;
ctx->SetNat(test_nat);
}
// Create the handler objects
ctx->ice_handler_vtbl_ = new nr_ice_handler_vtbl();
ctx->ice_handler_vtbl_->select_pair = &NrIceCtx::select_pair;
@ -522,7 +578,6 @@ RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& name,
return nullptr;
}
nsresult rv;
ctx->sts_target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
if (!NS_SUCCEEDED(rv))
@ -531,6 +586,17 @@ RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& name,
return ctx;
}
int NrIceCtx::SetNat(const RefPtr<TestNat>& aNat) {
nat_ = aNat;
nr_socket_factory *fac;
int r = nat_->create_socket_factory(&fac);
if (r) {
return r;
}
nr_ice_ctx_set_socket_factory(ctx_, fac);
return 0;
}
// ONLY USE THIS FOR TESTING. Will cause totally unpredictable and possibly very
// bad effects if ICE is still live.
void NrIceCtx::internal_DeinitializeGlobal() {

View File

@ -191,6 +191,7 @@ class NrIceProxyServer {
std::string alpn_;
};
class TestNat;
class NrIceCtx {
public:
@ -223,6 +224,8 @@ class NrIceCtx {
bool hide_non_default = false,
Policy policy = ICE_POLICY_ALL);
int SetNat(const RefPtr<TestNat>& aNat);
// Deinitialize all ICE global state. Used only for testing.
static void internal_DeinitializeGlobal();
@ -332,21 +335,7 @@ class NrIceCtx {
private:
NrIceCtx(const std::string& name,
bool offerer,
Policy policy)
: connection_state_(ICE_CTX_INIT),
gathering_state_(ICE_CTX_GATHER_INIT),
name_(name),
offerer_(offerer),
streams_(),
ctx_(nullptr),
peer_(nullptr),
ice_handler_vtbl_(nullptr),
ice_handler_(nullptr),
trickle_(true),
policy_(policy) {
// XXX: offerer_ will be used eventually; placate clang in the meantime.
(void)offerer_;
}
Policy policy);
virtual ~NrIceCtx();
@ -390,6 +379,7 @@ class NrIceCtx {
bool trickle_;
nsCOMPtr<nsIEventTarget> sts_target_; // The thread to run on
Policy policy_;
RefPtr<TestNat> nat_;
};

View File

@ -316,12 +316,9 @@ class IceTestPeer : public sigslot::has_slots<> {
this,
&IceTestPeer::ConnectionStateChange);
nr_socket_factory *fac;
int r = nat_->create_socket_factory(&fac);
int r = ice_ctx_->SetNat(nat_);
(void)r;
MOZ_ASSERT(!r);
if (!r) {
nr_ice_ctx_set_socket_factory(ice_ctx_->ctx(), fac);
}
}
~IceTestPeer() {

View File

@ -137,6 +137,21 @@ static nr_socket_factory_vtbl test_nat_socket_factory_vtbl = {
test_nat_socket_factory_destroy
};
/* static */
TestNat::NatBehavior
TestNat::ToNatBehavior(const std::string& type) {
if (!type.compare("ENDPOINT_INDEPENDENT")) {
return TestNat::ENDPOINT_INDEPENDENT;
} else if (!type.compare("ADDRESS_DEPENDENT")) {
return TestNat::ADDRESS_DEPENDENT;
} else if (!type.compare("PORT_DEPENDENT")) {
return TestNat::PORT_DEPENDENT;
}
MOZ_ASSERT(false, "Invalid NAT behavior");
return TestNat::ENDPOINT_INDEPENDENT;
}
bool TestNat::has_port_mappings() const {
for (TestNrSocket *sock : sockets_) {
if (sock->has_port_mappings()) {
@ -512,6 +527,10 @@ int TestNrSocket::async_wait(int how, NR_async_cb cb, void *cb_arg,
}
if (r) {
r_log(LOG_GENERIC, LOG_ERR, "TestNrSocket %s failed to async_wait for "
"internal socket: %d\n",
internal_socket_->my_addr().as_string,
r);
return r;
}
@ -541,6 +560,10 @@ int TestNrSocket::async_wait(int how, NR_async_cb cb, void *cb_arg,
function,
line);
if (r) {
r_log(LOG_GENERIC, LOG_ERR, "TestNrSocket %s failed to async_wait for "
"port mapping: %d\n",
internal_socket_->my_addr().as_string,
r);
return r;
}
}

View File

@ -83,6 +83,10 @@ nrappkit copyright:
#ifndef test_nr_socket__
#define test_nr_socket__
extern "C" {
#include "transport_addr.h"
}
#include "nr_socket_prsock.h"
extern "C" {
@ -93,6 +97,7 @@ extern "C" {
#include <vector>
#include <map>
#include <list>
#include <string>
#include "mozilla/UniquePtr.h"
#include "prinrval.h"
@ -152,6 +157,8 @@ class TestNat {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TestNat);
static NatBehavior ToNatBehavior(const std::string& type);
bool enabled_;
TestNat::NatBehavior filtering_type_;
TestNat::NatBehavior mapping_type_;

View File

@ -61,8 +61,10 @@ static void nr_ice_socket_readable_cb(NR_SOCKET s, int how, void *cb_arg)
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Socket ready to read",sock->ctx->label);
/* Re-arm first! */
if (sock->type != NR_ICE_SOCKET_TYPE_STREAM_TCP)
if (sock->type != NR_ICE_SOCKET_TYPE_STREAM_TCP) {
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): rearming",sock->ctx->label);
NR_ASYNC_WAIT(s,how,nr_ice_socket_readable_cb,cb_arg);
}
if(r=nr_socket_recvfrom(sock->sock,buf,sizeof(buf),&len_s,0,&addr)){
if (r != R_WOULDBLOCK && (sock->type != NR_ICE_SOCKET_TYPE_DGRAM)) {