mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 797262 - IPV6 support for webrtc. r=drno
This commit is contained in:
parent
a7fb589b65
commit
4965ecc09e
@ -119,7 +119,7 @@ GetInterfaces(std::vector<NetworkInterface>* aInterfaces)
|
||||
|
||||
int
|
||||
nr_stun_get_addrs(nr_local_addr aAddrs[], int aMaxAddrs,
|
||||
int aDropLoopback, int* aCount)
|
||||
int aDropLoopback, int aDropLinkLocal, int* aCount)
|
||||
{
|
||||
nsresult rv;
|
||||
int r;
|
||||
@ -141,7 +141,6 @@ nr_stun_get_addrs(nr_local_addr aAddrs[], int aMaxAddrs,
|
||||
for (size_t i = 0; i < num_interface; ++i) {
|
||||
NetworkInterface &interface = interfaces[i];
|
||||
if (nr_sockaddr_to_transport_addr((sockaddr*)&(interface.addr),
|
||||
sizeof(struct sockaddr_in),
|
||||
IPPROTO_UDP, 0, &(aAddrs[n].addr))) {
|
||||
r_log(NR_LOG_STUN, LOG_WARNING, "Problem transforming address");
|
||||
return R_FAILED;
|
||||
@ -154,7 +153,7 @@ nr_stun_get_addrs(nr_local_addr aAddrs[], int aMaxAddrs,
|
||||
}
|
||||
|
||||
*aCount = n;
|
||||
r = nr_stun_remove_duplicate_addrs(aAddrs, aDropLoopback, aCount);
|
||||
r = nr_stun_remove_duplicate_addrs(aAddrs, aDropLoopback, aDropLinkLocal, aCount);
|
||||
if (r != 0) {
|
||||
return r;
|
||||
}
|
||||
|
@ -337,20 +337,11 @@ static int nr_transport_addr_to_praddr(nr_transport_addr *addr,
|
||||
naddr->inet.ip = addr->u.addr4.sin_addr.s_addr;
|
||||
break;
|
||||
case NR_IPV6:
|
||||
#if 0
|
||||
naddr->ipv6.family = PR_AF_INET6;
|
||||
naddr->ipv6.port = addr->u.addr6.sin6_port;
|
||||
#ifdef LINUX
|
||||
memcpy(naddr->ipv6.ip._S6_un._S6_u8,
|
||||
&addr->u.addr6.sin6_addr.__in6_u.__u6_addr8, 16);
|
||||
#else
|
||||
memcpy(naddr->ipv6.ip._S6_un._S6_u8,
|
||||
&addr->u.addr6.sin6_addr.__u6_addr.__u6_addr8, 16);
|
||||
#endif
|
||||
#else
|
||||
// TODO: make IPv6 work
|
||||
ABORT(R_INTERNAL);
|
||||
#endif
|
||||
naddr->ipv6.flowinfo = addr->u.addr6.sin6_flowinfo;
|
||||
memcpy(&naddr->ipv6.ip, &addr->u.addr6.sin6_addr, sizeof(in6_addr));
|
||||
naddr->ipv6.scope_id = addr->u.addr6.sin6_scope_id;
|
||||
break;
|
||||
default:
|
||||
ABORT(R_BAD_ARGS);
|
||||
@ -440,6 +431,7 @@ int nr_praddr_to_transport_addr(const PRNetAddr *praddr,
|
||||
int _status;
|
||||
int r;
|
||||
struct sockaddr_in ip4;
|
||||
struct sockaddr_in6 ip6;
|
||||
|
||||
switch(praddr->raw.family) {
|
||||
case PR_AF_INET:
|
||||
@ -447,18 +439,19 @@ int nr_praddr_to_transport_addr(const PRNetAddr *praddr,
|
||||
ip4.sin_addr.s_addr = praddr->inet.ip;
|
||||
ip4.sin_port = praddr->inet.port;
|
||||
if ((r = nr_sockaddr_to_transport_addr((sockaddr *)&ip4,
|
||||
sizeof(ip4),
|
||||
protocol, keep,
|
||||
addr)))
|
||||
ABORT(r);
|
||||
break;
|
||||
case PR_AF_INET6:
|
||||
#if 0
|
||||
r = nr_sockaddr_to_transport_addr((sockaddr *)&praddr->raw,
|
||||
sizeof(struct sockaddr_in6),IPPROTO_UDP,keep,addr);
|
||||
ip6.sin6_family = PF_INET6;
|
||||
ip6.sin6_port = praddr->ipv6.port;
|
||||
ip6.sin6_flowinfo = praddr->ipv6.flowinfo;
|
||||
memcpy(&ip6.sin6_addr, &praddr->ipv6.ip, sizeof(in6_addr));
|
||||
ip6.sin6_scope_id = praddr->ipv6.scope_id;
|
||||
if ((r = nr_sockaddr_to_transport_addr((sockaddr *)&ip6,protocol,keep,addr)))
|
||||
ABORT(r);
|
||||
break;
|
||||
#endif
|
||||
ABORT(R_BAD_ARGS);
|
||||
default:
|
||||
MOZ_ASSERT(false);
|
||||
ABORT(R_BAD_ARGS);
|
||||
@ -516,14 +509,16 @@ int NrSocket::create(nr_transport_addr *addr) {
|
||||
|
||||
switch (addr->protocol) {
|
||||
case IPPROTO_UDP:
|
||||
if (!(fd_ = PR_NewUDPSocket())) {
|
||||
r_log(LOG_GENERIC,LOG_CRIT,"Couldn't create socket");
|
||||
if (!(fd_ = PR_OpenUDPSocket(naddr.raw.family))) {
|
||||
r_log(LOG_GENERIC,LOG_CRIT,"Couldn't create UDP socket, "
|
||||
"family=%d, err=%d", naddr.raw.family, PR_GetError());
|
||||
ABORT(R_INTERNAL);
|
||||
}
|
||||
break;
|
||||
case IPPROTO_TCP:
|
||||
if (!(fd_ = PR_NewTCPSocket())) {
|
||||
r_log(LOG_GENERIC,LOG_CRIT,"Couldn't create socket");
|
||||
if (!(fd_ = PR_OpenTCPSocket(naddr.raw.family))) {
|
||||
r_log(LOG_GENERIC,LOG_CRIT,"Couldn't create TCP socket, "
|
||||
"family=%d, err=%d", naddr.raw.family, PR_GetError());
|
||||
ABORT(R_INTERNAL);
|
||||
}
|
||||
// Set ReuseAddr for TCP sockets to enable having several
|
||||
@ -686,7 +681,8 @@ int NrSocket::sendto(const void *msg, size_t len,
|
||||
if (PR_GetError() == PR_WOULD_BLOCK_ERROR)
|
||||
ABORT(R_WOULDBLOCK);
|
||||
|
||||
r_log(LOG_GENERIC, LOG_INFO, "Error in sendto: %s", to->as_string);
|
||||
r_log(LOG_GENERIC, LOG_INFO, "Error in sendto %s: %d",
|
||||
to->as_string, PR_GetError());
|
||||
ABORT(R_IO_ERROR);
|
||||
}
|
||||
|
||||
|
@ -380,7 +380,8 @@ RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& name,
|
||||
bool offerer,
|
||||
bool set_interface_priorities,
|
||||
bool allow_loopback,
|
||||
bool tcp_enabled) {
|
||||
bool tcp_enabled,
|
||||
bool allow_link_local) {
|
||||
|
||||
RefPtr<NrIceCtx> ctx = new NrIceCtx(name, offerer);
|
||||
|
||||
@ -472,6 +473,10 @@ RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& name,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// Create the ICE context
|
||||
|
@ -212,7 +212,8 @@ class NrIceCtx {
|
||||
bool offerer,
|
||||
bool set_interface_priorities = true,
|
||||
bool allow_loopback = false,
|
||||
bool tcp_enabled = true);
|
||||
bool tcp_enabled = true,
|
||||
bool allow_link_local = false);
|
||||
|
||||
// Deinitialize all ICE global state. Used only for testing.
|
||||
static void internal_DeinitializeGlobal();
|
||||
|
@ -150,6 +150,7 @@ int NrIceResolver::resolve(nr_resolver_resource *resource,
|
||||
MOZ_ASSERT(allocated_resolvers_ > 0);
|
||||
ASSERT_ON_THREAD(sts_thread_);
|
||||
nsRefPtr<PendingResolution> pr;
|
||||
uint32_t resolve_flags = 0;
|
||||
|
||||
if (resource->transport_protocol != IPPROTO_UDP &&
|
||||
resource->transport_protocol != IPPROTO_TCP) {
|
||||
@ -162,8 +163,20 @@ int NrIceResolver::resolve(nr_resolver_resource *resource,
|
||||
resource->transport_protocol :
|
||||
IPPROTO_UDP,
|
||||
cb, cb_arg);
|
||||
|
||||
switch(resource->address_family) {
|
||||
case AF_INET:
|
||||
resolve_flags |= nsIDNSService::RESOLVE_DISABLE_IPV6;
|
||||
break;
|
||||
case AF_INET6:
|
||||
resolve_flags |= nsIDNSService::RESOLVE_DISABLE_IPV4;
|
||||
break;
|
||||
default:
|
||||
ABORT(R_BAD_ARGS);
|
||||
}
|
||||
|
||||
if (NS_FAILED(dns_->AsyncResolve(nsAutoCString(resource->domain_name),
|
||||
nsIDNSService::RESOLVE_DISABLE_IPV6, pr,
|
||||
resolve_flags, pr,
|
||||
sts_thread_, getter_AddRefs(pr->request_)))) {
|
||||
MOZ_MTLOG(ML_ERROR, "AsyncResolve failed.");
|
||||
ABORT(R_NOT_FOUND);
|
||||
|
@ -122,6 +122,7 @@ int NrIceResolverFake::resolve(void *obj,
|
||||
resource->transport_protocol ?
|
||||
resource->transport_protocol :
|
||||
IPPROTO_UDP,
|
||||
resource->address_family,
|
||||
cb, cb_arg);
|
||||
|
||||
if ((r=NR_ASYNC_TIMER_SET(fake->delay_ms_,NrIceResolverFake::resolve_cb,
|
||||
@ -140,7 +141,8 @@ void NrIceResolverFake::resolve_cb(NR_SOCKET s, int how, void *cb_arg) {
|
||||
MOZ_ASSERT(cb_arg);
|
||||
PendingResolution *pending = static_cast<PendingResolution *>(cb_arg);
|
||||
|
||||
const PRNetAddr *addr=pending->resolver_->Resolve(pending->hostname_);
|
||||
const PRNetAddr *addr=pending->resolver_->Resolve(pending->hostname_,
|
||||
pending->address_family_);
|
||||
|
||||
if (addr) {
|
||||
nr_transport_addr transport_addr;
|
||||
|
@ -63,7 +63,16 @@ class NrIceResolverFake {
|
||||
~NrIceResolverFake();
|
||||
|
||||
void SetAddr(const std::string& hostname, const PRNetAddr& addr) {
|
||||
addrs_[hostname] = addr;
|
||||
switch (addr.raw.family) {
|
||||
case AF_INET:
|
||||
addrs_[hostname] = addr;
|
||||
break;
|
||||
case AF_INET6:
|
||||
addrs6_[hostname] = addr;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH();
|
||||
}
|
||||
}
|
||||
|
||||
nr_resolver *AllocateResolver();
|
||||
@ -83,11 +92,21 @@ private:
|
||||
static int cancel(void *obj, void *handle);
|
||||
|
||||
// Get an address.
|
||||
const PRNetAddr *Resolve(const std::string& hostname) {
|
||||
if (!addrs_.count(hostname))
|
||||
return nullptr;
|
||||
const PRNetAddr *Resolve(const std::string& hostname, int address_family) {
|
||||
switch (address_family) {
|
||||
case AF_INET:
|
||||
if (!addrs_.count(hostname))
|
||||
return nullptr;
|
||||
|
||||
return &addrs_[hostname];
|
||||
return &addrs_[hostname];
|
||||
case AF_INET6:
|
||||
if (!addrs6_.count(hostname))
|
||||
return nullptr;
|
||||
|
||||
return &addrs6_[hostname];
|
||||
default:
|
||||
MOZ_CRASH();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -96,18 +115,21 @@ private:
|
||||
const std::string& hostname,
|
||||
uint16_t port,
|
||||
int transport,
|
||||
int address_family,
|
||||
int (*cb)(void *cb_arg, nr_transport_addr *addr),
|
||||
void *cb_arg) :
|
||||
resolver_(resolver),
|
||||
hostname_(hostname),
|
||||
port_(port),
|
||||
transport_(transport),
|
||||
address_family_(address_family),
|
||||
cb_(cb), cb_arg_(cb_arg) {}
|
||||
|
||||
NrIceResolverFake *resolver_;
|
||||
std::string hostname_;
|
||||
uint16_t port_;
|
||||
int transport_;
|
||||
int address_family_;
|
||||
int (*cb_)(void *cb_arg, nr_transport_addr *addr);
|
||||
void *cb_arg_;
|
||||
void *timer_handle_;
|
||||
@ -115,6 +137,7 @@ private:
|
||||
|
||||
nr_resolver_vtbl* vtbl_;
|
||||
std::map<std::string, PRNetAddr> addrs_;
|
||||
std::map<std::string, PRNetAddr> addrs6_;
|
||||
uint32_t delay_ms_;
|
||||
int allocated_resolvers_;
|
||||
};
|
||||
|
@ -18,7 +18,8 @@ public:
|
||||
: key_(),
|
||||
is_vpn_(-1),
|
||||
estimated_speed_(-1),
|
||||
type_preference_(-1) {}
|
||||
type_preference_(-1),
|
||||
ip_version_(-1) {}
|
||||
|
||||
bool Init(const nr_local_addr& local_addr) {
|
||||
char buf[MAXIFNAME + 41];
|
||||
@ -31,6 +32,7 @@ public:
|
||||
is_vpn_ = (local_addr.interface.type & NR_INTERFACE_TYPE_VPN) != 0 ? 1 : 0;
|
||||
estimated_speed_ = local_addr.interface.estimated_speed;
|
||||
type_preference_ = GetNetworkTypePreference(local_addr.interface.type);
|
||||
ip_version_ = local_addr.addr.ip_version;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -54,6 +56,11 @@ public:
|
||||
return estimated_speed_ > rhs.estimated_speed_;
|
||||
}
|
||||
|
||||
// Prefer IPV6 over IPV4
|
||||
if (ip_version_ != rhs.ip_version_) {
|
||||
return ip_version_ > rhs.ip_version_;
|
||||
}
|
||||
|
||||
// All things above are the same, we can at least sort with key.
|
||||
return key_ < rhs.key_;
|
||||
}
|
||||
@ -82,6 +89,7 @@ private:
|
||||
int is_vpn_;
|
||||
int estimated_speed_;
|
||||
int type_preference_;
|
||||
int ip_version_;
|
||||
};
|
||||
|
||||
class InterfacePrioritizer {
|
||||
|
@ -21,42 +21,51 @@ extern "C" {
|
||||
|
||||
namespace {
|
||||
|
||||
class NetAddressAdapter {
|
||||
class NetAddrCompare {
|
||||
public:
|
||||
MOZ_IMPLICIT NetAddressAdapter(const mozilla::net::NetAddr& netaddr)
|
||||
: addr_(ntohl(netaddr.inet.ip)),
|
||||
port_(ntohs(netaddr.inet.port)) {
|
||||
MOZ_ASSERT(netaddr.raw.family == AF_INET);
|
||||
}
|
||||
bool operator()(const mozilla::net::NetAddr& lhs,
|
||||
const mozilla::net::NetAddr& rhs) const {
|
||||
if (lhs.raw.family != rhs.raw.family) {
|
||||
return lhs.raw.family < rhs.raw.family;
|
||||
}
|
||||
|
||||
bool operator<(const NetAddressAdapter& rhs) const {
|
||||
return addr_ != rhs.addr_ ? (addr_ < rhs.addr_) : (port_ < rhs.port_);
|
||||
}
|
||||
|
||||
bool operator!=(const NetAddressAdapter& rhs) const {
|
||||
return (*this < rhs) || (rhs < *this);
|
||||
}
|
||||
|
||||
private:
|
||||
const uint32_t addr_;
|
||||
const uint16_t port_;
|
||||
switch (lhs.raw.family) {
|
||||
case AF_INET:
|
||||
if (lhs.inet.port != rhs.inet.port) {
|
||||
return lhs.inet.port < rhs.inet.port;
|
||||
}
|
||||
return lhs.inet.ip < rhs.inet.ip;
|
||||
case AF_INET6:
|
||||
if (lhs.inet6.port != rhs.inet6.port) {
|
||||
return lhs.inet6.port < rhs.inet6.port;
|
||||
}
|
||||
return memcmp(&lhs.inet6.ip, &rhs.inet6.ip, sizeof(lhs.inet6.ip)) < 0;
|
||||
default:
|
||||
MOZ_ASSERT(false);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class PendingSTUNRequest {
|
||||
public:
|
||||
PendingSTUNRequest(const NetAddressAdapter& netaddr, const UINT12 &id)
|
||||
PendingSTUNRequest(const mozilla::net::NetAddr& netaddr, const UINT12 &id)
|
||||
: id_(id),
|
||||
net_addr_(netaddr),
|
||||
is_id_set_(true) {}
|
||||
|
||||
MOZ_IMPLICIT PendingSTUNRequest(const NetAddressAdapter& netaddr)
|
||||
MOZ_IMPLICIT PendingSTUNRequest(const mozilla::net::NetAddr& netaddr)
|
||||
: id_(),
|
||||
net_addr_(netaddr),
|
||||
is_id_set_(false) {}
|
||||
|
||||
bool operator<(const PendingSTUNRequest& rhs) const {
|
||||
if (net_addr_ != rhs.net_addr_) {
|
||||
return net_addr_ < rhs.net_addr_;
|
||||
if (NetAddrCompare()(net_addr_, rhs.net_addr_)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (NetAddrCompare()(rhs.net_addr_, net_addr_)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_id_set_ && !rhs.is_id_set_) {
|
||||
@ -76,7 +85,7 @@ class PendingSTUNRequest {
|
||||
|
||||
private:
|
||||
const UINT12 id_;
|
||||
const NetAddressAdapter net_addr_;
|
||||
const mozilla::net::NetAddr net_addr_;
|
||||
const bool is_id_set_;
|
||||
};
|
||||
|
||||
@ -101,7 +110,7 @@ class STUNUDPSocketFilter : public nsIUDPSocketFilter {
|
||||
const uint8_t *data,
|
||||
uint32_t len);
|
||||
|
||||
std::set<NetAddressAdapter> white_list_;
|
||||
std::set<mozilla::net::NetAddr, NetAddrCompare> white_list_;
|
||||
std::set<PendingSTUNRequest> pending_requests_;
|
||||
std::set<PendingSTUNRequest> response_allowed_;
|
||||
};
|
||||
@ -114,12 +123,6 @@ STUNUDPSocketFilter::FilterPacket(const mozilla::net::NetAddr *remote_addr,
|
||||
uint32_t len,
|
||||
int32_t direction,
|
||||
bool *result) {
|
||||
// Allowing IPv4 address only.
|
||||
if (remote_addr->raw.family != AF_INET) {
|
||||
*result = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
switch (direction) {
|
||||
case nsIUDPSocketFilter::SF_INCOMING:
|
||||
*result = filter_incoming_packet(remote_addr, data, len);
|
||||
|
@ -64,7 +64,7 @@ class BufferedStunSocketTest : public ::testing::Test {
|
||||
ASSERT_EQ(0, r);
|
||||
dummy_ = dummy.forget(); // Now owned by test_socket_.
|
||||
|
||||
r = nr_ip4_str_port_to_transport_addr(
|
||||
r = nr_str_port_to_transport_addr(
|
||||
(char *)"192.0.2.133", 3333, IPPROTO_TCP, &remote_addr_);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
@ -184,7 +184,7 @@ TEST_F(BufferedStunSocketTest, TestSendToReject) {
|
||||
TEST_F(BufferedStunSocketTest, TestSendToWrongAddr) {
|
||||
nr_transport_addr addr;
|
||||
|
||||
int r = nr_ip4_str_port_to_transport_addr(
|
||||
int r = nr_str_port_to_transport_addr(
|
||||
(char *)"192.0.2.134", 3333, IPPROTO_TCP, &addr);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
|
@ -354,8 +354,8 @@ class IceTestPeer : public sigslot::has_slots<> {
|
||||
}
|
||||
|
||||
void UseTestStunServer() {
|
||||
SetStunServer(TestStunServer::GetInstance()->addr(),
|
||||
TestStunServer::GetInstance()->port());
|
||||
SetStunServer(TestStunServer::GetInstance(AF_INET)->addr(),
|
||||
TestStunServer::GetInstance(AF_INET)->port());
|
||||
}
|
||||
|
||||
void SetTurnServer(const std::string addr, uint16_t port,
|
||||
@ -382,15 +382,15 @@ class IceTestPeer : public sigslot::has_slots<> {
|
||||
ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->SetTurnServers(servers)));
|
||||
}
|
||||
|
||||
void SetFakeResolver() {
|
||||
void SetFakeResolver(const std::string& ip = g_stun_server_address,
|
||||
const std::string& fqdn = g_stun_server_hostname) {
|
||||
ASSERT_TRUE(NS_SUCCEEDED(dns_resolver_->Init()));
|
||||
if (!g_stun_server_address.empty() && !g_stun_server_hostname.empty()) {
|
||||
if (!ip.empty() && !fqdn.empty()) {
|
||||
PRNetAddr addr;
|
||||
PRStatus status = PR_StringToNetAddr(g_stun_server_address.c_str(),
|
||||
&addr);
|
||||
PRStatus status = PR_StringToNetAddr(ip.c_str(), &addr);
|
||||
addr.inet.port = kDefaultStunServerPort;
|
||||
ASSERT_EQ(PR_SUCCESS, status);
|
||||
fake_resolver_.SetAddr(g_stun_server_hostname, addr);
|
||||
fake_resolver_.SetAddr(fqdn, addr);
|
||||
}
|
||||
ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->SetResolver(
|
||||
fake_resolver_.AllocateResolver())));
|
||||
@ -1098,9 +1098,16 @@ void SchedulableTrickleCandidate::Trickle() {
|
||||
class IceGatherTest : public ::testing::Test {
|
||||
public:
|
||||
void SetUp() {
|
||||
test_utils->sts_target()->Dispatch(WrapRunnable(TestStunServer::GetInstance(),
|
||||
&TestStunServer::Reset),
|
||||
NS_DISPATCH_SYNC);
|
||||
test_utils->sts_target()->Dispatch(
|
||||
WrapRunnable(TestStunServer::GetInstance(AF_INET),
|
||||
&TestStunServer::Reset),
|
||||
NS_DISPATCH_SYNC);
|
||||
if (TestStunServer::GetInstance(AF_INET6)) {
|
||||
test_utils->sts_target()->Dispatch(
|
||||
WrapRunnable(TestStunServer::GetInstance(AF_INET6),
|
||||
&TestStunServer::Reset),
|
||||
NS_DISPATCH_SYNC);
|
||||
}
|
||||
}
|
||||
|
||||
void TearDown() {
|
||||
@ -1135,54 +1142,90 @@ class IceGatherTest : public ::testing::Test {
|
||||
ASSERT_TRUE_WAIT(peer_->gathering_complete(), waitTime);
|
||||
}
|
||||
|
||||
void UseFakeStunUdpServerWithResponse(const std::string& fake_addr,
|
||||
uint16_t fake_port) {
|
||||
EnsurePeer();
|
||||
TestStunServer::GetInstance()->SetResponseAddr(fake_addr, fake_port);
|
||||
// Sets an additional stun server
|
||||
peer_->SetStunServer(TestStunServer::GetInstance()->addr(),
|
||||
TestStunServer::GetInstance()->port(),
|
||||
kNrIceTransportUdp);
|
||||
void AddStunServerWithResponse(
|
||||
const std::string& fake_addr,
|
||||
uint16_t fake_port,
|
||||
const std::string& fqdn,
|
||||
const std::string& proto,
|
||||
std::vector<NrIceStunServer>* stun_servers) {
|
||||
int family;
|
||||
if (fake_addr.find(':') != std::string::npos) {
|
||||
family = AF_INET6;
|
||||
} else {
|
||||
family = AF_INET;
|
||||
}
|
||||
|
||||
std::string stun_addr;
|
||||
uint16_t stun_port;
|
||||
if (proto == kNrIceTransportUdp) {
|
||||
TestStunServer::GetInstance(family)->SetResponseAddr(fake_addr,
|
||||
fake_port);
|
||||
stun_addr = TestStunServer::GetInstance(family)->addr();
|
||||
stun_port = TestStunServer::GetInstance(family)->port();
|
||||
} else if (proto == kNrIceTransportTcp) {
|
||||
TestStunTcpServer::GetInstance(family)->SetResponseAddr(fake_addr,
|
||||
fake_port);
|
||||
stun_addr = TestStunTcpServer::GetInstance(family)->addr();
|
||||
stun_port = TestStunTcpServer::GetInstance(family)->port();
|
||||
} else {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
if (!fqdn.empty()) {
|
||||
peer_->SetFakeResolver(stun_addr, fqdn);
|
||||
stun_addr = fqdn;
|
||||
}
|
||||
|
||||
stun_servers->push_back(*NrIceStunServer::Create(stun_addr,
|
||||
stun_port,
|
||||
proto.c_str()));
|
||||
}
|
||||
|
||||
void UseFakeStunTcpServerWithResponse(const std::string& fake_addr,
|
||||
uint16_t fake_port) {
|
||||
EnsurePeer();
|
||||
TestStunTcpServer::GetInstance()->SetResponseAddr(fake_addr, fake_port);
|
||||
// Sets an additional stun server
|
||||
peer_->SetStunServer(TestStunTcpServer::GetInstance()->addr(),
|
||||
TestStunTcpServer::GetInstance()->port(),
|
||||
kNrIceTransportTcp);
|
||||
}
|
||||
|
||||
void UseFakeStunUdpTcpServersWithResponse(const std::string& fake_udp_addr,
|
||||
uint16_t fake_udp_port,
|
||||
const std::string& fake_tcp_addr,
|
||||
uint16_t fake_tcp_port) {
|
||||
void UseFakeStunUdpServerWithResponse(
|
||||
const std::string& fake_addr,
|
||||
uint16_t fake_port,
|
||||
const std::string& fqdn = std::string()) {
|
||||
EnsurePeer();
|
||||
std::vector<NrIceStunServer> stun_servers;
|
||||
AddStunServerWithResponse(fake_addr, fake_port, fqdn, "udp", &stun_servers);
|
||||
peer_->SetStunServers(stun_servers);
|
||||
}
|
||||
|
||||
stun_servers.push_back(*NrIceStunServer::Create(
|
||||
TestStunServer::GetInstance()->addr(),
|
||||
TestStunServer::GetInstance()->port(),
|
||||
kNrIceTransportUdp));
|
||||
stun_servers.push_back(*NrIceStunServer::Create(
|
||||
TestStunTcpServer::GetInstance()->addr(),
|
||||
TestStunTcpServer::GetInstance()->port(),
|
||||
kNrIceTransportTcp));
|
||||
void UseFakeStunTcpServerWithResponse(
|
||||
const std::string& fake_addr,
|
||||
uint16_t fake_port,
|
||||
const std::string& fqdn = std::string()) {
|
||||
EnsurePeer();
|
||||
std::vector<NrIceStunServer> stun_servers;
|
||||
AddStunServerWithResponse(fake_addr, fake_port, fqdn, "tcp", &stun_servers);
|
||||
peer_->SetStunServers(stun_servers);
|
||||
}
|
||||
|
||||
void UseFakeStunUdpTcpServersWithResponse(
|
||||
const std::string& fake_udp_addr,
|
||||
uint16_t fake_udp_port,
|
||||
const std::string& fake_tcp_addr,
|
||||
uint16_t fake_tcp_port) {
|
||||
EnsurePeer();
|
||||
std::vector<NrIceStunServer> stun_servers;
|
||||
AddStunServerWithResponse(fake_udp_addr,
|
||||
fake_udp_port,
|
||||
"", // no fqdn
|
||||
"udp",
|
||||
&stun_servers);
|
||||
AddStunServerWithResponse(fake_tcp_addr,
|
||||
fake_tcp_port,
|
||||
"", // no fqdn
|
||||
"tcp",
|
||||
&stun_servers);
|
||||
|
||||
TestStunServer::GetInstance()->SetResponseAddr(fake_udp_addr,
|
||||
fake_udp_port);
|
||||
TestStunTcpServer::GetInstance()->SetResponseAddr(fake_tcp_addr,
|
||||
fake_tcp_port);
|
||||
// Sets an additional stun server
|
||||
peer_->SetStunServers(stun_servers);
|
||||
}
|
||||
|
||||
void UseTestStunServer() {
|
||||
TestStunServer::GetInstance()->Reset();
|
||||
peer_->SetStunServer(TestStunServer::GetInstance()->addr(),
|
||||
TestStunServer::GetInstance()->port());
|
||||
TestStunServer::GetInstance(AF_INET)->Reset();
|
||||
peer_->SetStunServer(TestStunServer::GetInstance(AF_INET)->addr(),
|
||||
TestStunServer::GetInstance(AF_INET)->port());
|
||||
}
|
||||
|
||||
// NB: Only does substring matching, watch out for stuff like "1.2.3.4"
|
||||
@ -1314,7 +1357,7 @@ class IceConnectTest : public ::testing::Test {
|
||||
}
|
||||
|
||||
void UseTestStunServer() {
|
||||
TestStunServer::GetInstance()->Reset();
|
||||
TestStunServer::GetInstance(AF_INET)->Reset();
|
||||
p1_->UseTestStunServer();
|
||||
p2_->UseTestStunServer();
|
||||
}
|
||||
@ -1482,8 +1525,8 @@ class PrioritizerTest : public ::testing::Test {
|
||||
local_addr.interface.type = type;
|
||||
local_addr.interface.estimated_speed = estimated_speed;
|
||||
|
||||
int r = nr_ip4_str_port_to_transport_addr(str_addr.c_str(), 0,
|
||||
IPPROTO_UDP, &(local_addr.addr));
|
||||
int r = nr_str_port_to_transport_addr(str_addr.c_str(), 0,
|
||||
IPPROTO_UDP, &(local_addr.addr));
|
||||
ASSERT_EQ(0, r);
|
||||
strncpy(local_addr.addr.ifname, ifname.c_str(), MAXIFNAME);
|
||||
|
||||
@ -1791,12 +1834,48 @@ TEST_F(IceGatherTest, VerifyTestStunTcpServer) {
|
||||
" tcptype "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, VerifyTestStunServerV6) {
|
||||
if (!TestStunServer::GetInstance(AF_INET6)) {
|
||||
// No V6 addresses
|
||||
return;
|
||||
}
|
||||
UseFakeStunUdpServerWithResponse("beef::", 3333);
|
||||
Gather();
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, " beef:: 3333 "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, VerifyTestStunServerFQDN) {
|
||||
UseFakeStunUdpServerWithResponse("192.0.2.133", 3333, "stun.example.com");
|
||||
Gather();
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.2.133 3333 "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, VerifyTestStunServerV6FQDN) {
|
||||
if (!TestStunServer::GetInstance(AF_INET6)) {
|
||||
// No V6 addresses
|
||||
return;
|
||||
}
|
||||
UseFakeStunUdpServerWithResponse("beef::", 3333, "stun.example.com");
|
||||
Gather();
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, " beef:: 3333 "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestStunServerReturnsWildcardAddr) {
|
||||
UseFakeStunUdpServerWithResponse("0.0.0.0", 3333);
|
||||
Gather(kDefaultTimeout * 3);
|
||||
ASSERT_FALSE(StreamHasMatchingCandidate(0, " 0.0.0.0 "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestStunServerReturnsWildcardAddrV6) {
|
||||
if (!TestStunServer::GetInstance(AF_INET6)) {
|
||||
// No V6 addresses
|
||||
return;
|
||||
}
|
||||
UseFakeStunUdpServerWithResponse("::", 3333);
|
||||
Gather(kDefaultTimeout * 3);
|
||||
ASSERT_FALSE(StreamHasMatchingCandidate(0, " :: "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestStunServerReturnsPort0) {
|
||||
UseFakeStunUdpServerWithResponse("192.0.2.133", 0);
|
||||
Gather(kDefaultTimeout * 3);
|
||||
@ -1809,35 +1888,45 @@ TEST_F(IceGatherTest, TestStunServerReturnsLoopbackAddr) {
|
||||
ASSERT_FALSE(StreamHasMatchingCandidate(0, " 127.0.0.133 "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestStunServerReturnsLoopbackAddrV6) {
|
||||
if (!TestStunServer::GetInstance(AF_INET6)) {
|
||||
// No V6 addresses
|
||||
return;
|
||||
}
|
||||
UseFakeStunUdpServerWithResponse("::1", 3333);
|
||||
Gather(kDefaultTimeout * 3);
|
||||
ASSERT_FALSE(StreamHasMatchingCandidate(0, " ::1 "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestStunServerTrickle) {
|
||||
UseFakeStunUdpServerWithResponse("192.0.2.1", 3333);
|
||||
TestStunServer::GetInstance()->SetActive(false);
|
||||
TestStunServer::GetInstance(AF_INET)->SetActive(false);
|
||||
Gather(0);
|
||||
ASSERT_FALSE(StreamHasMatchingCandidate(0, "192.0.2.1"));
|
||||
TestStunServer::GetInstance()->SetActive(true);
|
||||
TestStunServer::GetInstance(AF_INET)->SetActive(true);
|
||||
WaitForGather();
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, "192.0.2.1"));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestStunTcpServerTrickle) {
|
||||
UseFakeStunTcpServerWithResponse("192.0.3.1", 3333);
|
||||
TestStunTcpServer::GetInstance()->SetActive(false);
|
||||
TestStunTcpServer::GetInstance(AF_INET)->SetActive(false);
|
||||
Gather(0);
|
||||
ASSERT_FALSE(StreamHasMatchingCandidate(0, " 192.0.3.1 ", " tcptype "));
|
||||
TestStunTcpServer::GetInstance()->SetActive(true);
|
||||
TestStunTcpServer::GetInstance(AF_INET)->SetActive(true);
|
||||
WaitForGather();
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.3.1 ", " tcptype "));
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestStunTcpAndUdpServerTrickle) {
|
||||
UseFakeStunUdpTcpServersWithResponse("192.0.2.1", 3333, "192.0.3.1", 3333);
|
||||
TestStunServer::GetInstance()->SetActive(false);
|
||||
TestStunTcpServer::GetInstance()->SetActive(false);
|
||||
TestStunServer::GetInstance(AF_INET)->SetActive(false);
|
||||
TestStunTcpServer::GetInstance(AF_INET)->SetActive(false);
|
||||
Gather(0);
|
||||
ASSERT_FALSE(StreamHasMatchingCandidate(0, "192.0.2.1", "UDP"));
|
||||
ASSERT_FALSE(StreamHasMatchingCandidate(0, " 192.0.3.1 ", " tcptype "));
|
||||
TestStunServer::GetInstance()->SetActive(true);
|
||||
TestStunTcpServer::GetInstance()->SetActive(true);
|
||||
TestStunServer::GetInstance(AF_INET)->SetActive(true);
|
||||
TestStunTcpServer::GetInstance(AF_INET)->SetActive(true);
|
||||
WaitForGather();
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, "192.0.2.1", "UDP"));
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, " 192.0.3.1 ", " tcptype "));
|
||||
@ -2863,10 +2952,18 @@ int main(int argc, char **argv)
|
||||
|
||||
listeners.Append(new test::RingbufferDumper(test_utils));
|
||||
test_utils->sts_target()->Dispatch(
|
||||
WrapRunnableNM(&TestStunServer::GetInstance), NS_DISPATCH_SYNC);
|
||||
WrapRunnableNM(&TestStunServer::GetInstance, AF_INET),
|
||||
NS_DISPATCH_SYNC);
|
||||
test_utils->sts_target()->Dispatch(
|
||||
WrapRunnableNM(&TestStunServer::GetInstance, AF_INET6),
|
||||
NS_DISPATCH_SYNC);
|
||||
|
||||
test_utils->sts_target()->Dispatch(
|
||||
WrapRunnableNM(&TestStunTcpServer::GetInstance), NS_DISPATCH_SYNC);
|
||||
WrapRunnableNM(&TestStunTcpServer::GetInstance, AF_INET),
|
||||
NS_DISPATCH_SYNC);
|
||||
test_utils->sts_target()->Dispatch(
|
||||
WrapRunnableNM(&TestStunTcpServer::GetInstance, AF_INET6),
|
||||
NS_DISPATCH_SYNC);
|
||||
|
||||
int rv = RUN_ALL_TESTS();
|
||||
|
||||
|
@ -112,7 +112,7 @@ class MultiTcpSocketTest : public ::testing::Test {
|
||||
|
||||
r = 1;
|
||||
for (int tries=10; tries && r; --tries) {
|
||||
r = nr_ip4_str_port_to_transport_addr(
|
||||
r = nr_str_port_to_transport_addr(
|
||||
(char *)"127.0.0.1", EnsureEphemeral(port_s++), IPPROTO_TCP, &local);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
|
@ -84,7 +84,7 @@ class DummyResolver {
|
||||
void **handle) {
|
||||
nr_transport_addr addr;
|
||||
|
||||
nr_ip4_str_port_to_transport_addr(
|
||||
nr_str_port_to_transport_addr(
|
||||
(char *)kProxyAddr.c_str(), kProxyPort, IPPROTO_TCP, &addr);
|
||||
|
||||
cb(cb_arg, &addr);
|
||||
@ -120,11 +120,11 @@ class ProxyTunnelSocketTest : public ::testing::Test {
|
||||
|
||||
nr_resolver_ = resolver_impl_.get_nr_resolver();
|
||||
|
||||
int r = nr_ip4_str_port_to_transport_addr(
|
||||
int r = nr_str_port_to_transport_addr(
|
||||
(char *)kRemoteAddr.c_str(), kRemotePort, IPPROTO_TCP, &remote_addr_);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
r = nr_ip4_str_port_to_transport_addr(
|
||||
r = nr_str_port_to_transport_addr(
|
||||
(char *)kProxyAddr.c_str(), kProxyPort, IPPROTO_TCP, &proxy_addr_);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
|
@ -188,6 +188,8 @@ int nr_socket_wrapped_create(nr_socket *inner, nr_socket **outp) {
|
||||
// we have no reason to expect this will be initted to a nullptr yet.
|
||||
TestStunServer* TestStunServer::instance;
|
||||
TestStunTcpServer* TestStunTcpServer::instance;
|
||||
TestStunServer* TestStunServer::instance6;
|
||||
TestStunTcpServer* TestStunTcpServer::instance6;
|
||||
uint16_t TestStunServer::instance_port = 3478;
|
||||
uint16_t TestStunTcpServer::instance_port = 3478;
|
||||
|
||||
@ -243,12 +245,14 @@ int TestStunServer::TryOpenListenSocket(nr_local_addr* addr, uint16_t port) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TestStunServer::Initialize() {
|
||||
nr_local_addr addrs[100];
|
||||
int TestStunServer::Initialize(int address_family) {
|
||||
static const size_t max_addrs = 100;
|
||||
nr_local_addr addrs[max_addrs];
|
||||
int addr_ct;
|
||||
int r;
|
||||
int i;
|
||||
|
||||
r = nr_stun_find_local_addresses(addrs, 100, &addr_ct);
|
||||
r = nr_stun_find_local_addresses(addrs, max_addrs, &addr_ct);
|
||||
if (r) {
|
||||
MOZ_MTLOG(ML_ERROR, "Couldn't retrieve addresses");
|
||||
return R_INTERNAL;
|
||||
@ -259,10 +263,21 @@ int TestStunServer::Initialize() {
|
||||
return R_INTERNAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < addr_ct; ++i) {
|
||||
if (addrs[i].addr.addr->sa_family == address_family) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == addr_ct) {
|
||||
MOZ_MTLOG(ML_ERROR, "No local addresses of the configured IP version");
|
||||
return R_INTERNAL;
|
||||
}
|
||||
|
||||
int tries = 100;
|
||||
while (tries--) {
|
||||
// Bind to the first address (arbitrarily) on configured port (default 3478)
|
||||
r = TryOpenListenSocket(&addrs[0], instance_port);
|
||||
// Bind on configured port (default 3478)
|
||||
r = TryOpenListenSocket(&addrs[i], instance_port);
|
||||
// We interpret R_ALREADY to mean the addr is probably in use. Try another.
|
||||
// Otherwise, it either worked or it didn't, and we check below.
|
||||
if (r != R_ALREADY) {
|
||||
@ -291,7 +306,7 @@ int TestStunServer::Initialize() {
|
||||
|
||||
// Cache the address and port.
|
||||
char addr_string[INET6_ADDRSTRLEN];
|
||||
r = nr_transport_addr_get_addrstring(&addrs[0].addr, addr_string,
|
||||
r = nr_transport_addr_get_addrstring(&addrs[i].addr, addr_string,
|
||||
sizeof(addr_string));
|
||||
if (r) {
|
||||
MOZ_MTLOG(ML_ERROR, "Failed to convert listen addr to a string representation");
|
||||
@ -304,12 +319,12 @@ int TestStunServer::Initialize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TestStunServer* TestStunServer::Create() {
|
||||
TestStunServer* TestStunServer::Create(int address_family) {
|
||||
NR_reg_init(NR_REG_MODE_LOCAL);
|
||||
|
||||
ScopedDeletePtr<TestStunServer> server(new TestStunServer());
|
||||
|
||||
if (server->Initialize())
|
||||
if (server->Initialize(address_family))
|
||||
return nullptr;
|
||||
|
||||
NR_SOCKET fd;
|
||||
@ -328,18 +343,29 @@ void TestStunServer::ConfigurePort(uint16_t port) {
|
||||
instance_port = port;
|
||||
}
|
||||
|
||||
TestStunServer* TestStunServer::GetInstance() {
|
||||
if (!instance)
|
||||
instance = Create();
|
||||
TestStunServer* TestStunServer::GetInstance(int address_family) {
|
||||
switch (address_family) {
|
||||
case AF_INET:
|
||||
if (!instance)
|
||||
instance = Create(address_family);
|
||||
|
||||
MOZ_ASSERT(instance);
|
||||
return instance;
|
||||
MOZ_ASSERT(instance);
|
||||
return instance;
|
||||
case AF_INET6:
|
||||
if (!instance6)
|
||||
instance6 = Create(address_family);
|
||||
|
||||
return instance6;
|
||||
default:
|
||||
MOZ_CRASH();
|
||||
}
|
||||
}
|
||||
|
||||
void TestStunServer::ShutdownInstance() {
|
||||
delete instance;
|
||||
|
||||
instance = nullptr;
|
||||
delete instance6;
|
||||
instance6 = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -453,9 +479,9 @@ nsresult TestStunServer::SetResponseAddr(const std::string& addr,
|
||||
uint16_t port) {
|
||||
nr_transport_addr addr2;
|
||||
|
||||
int r = nr_ip4_str_port_to_transport_addr(addr.c_str(),
|
||||
port, IPPROTO_UDP,
|
||||
&addr2);
|
||||
int r = nr_str_port_to_transport_addr(addr.c_str(),
|
||||
port, IPPROTO_UDP,
|
||||
&addr2);
|
||||
if (r)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
@ -479,12 +505,22 @@ void TestStunTcpServer::ConfigurePort(uint16_t port) {
|
||||
instance_port = port;
|
||||
}
|
||||
|
||||
TestStunTcpServer* TestStunTcpServer::GetInstance() {
|
||||
if (!instance)
|
||||
instance = Create();
|
||||
TestStunTcpServer* TestStunTcpServer::GetInstance(int address_family) {
|
||||
switch (address_family) {
|
||||
case AF_INET:
|
||||
if (!instance)
|
||||
instance = Create(address_family);
|
||||
|
||||
MOZ_ASSERT(instance);
|
||||
return instance;
|
||||
MOZ_ASSERT(instance);
|
||||
return instance;
|
||||
case AF_INET6:
|
||||
if (!instance6)
|
||||
instance6 = Create(address_family);
|
||||
|
||||
return instance6;
|
||||
default:
|
||||
MOZ_CRASH();
|
||||
}
|
||||
}
|
||||
|
||||
void TestStunTcpServer::ShutdownInstance() {
|
||||
@ -523,12 +559,14 @@ int TestStunTcpServer::TryOpenListenSocket(nr_local_addr* addr, uint16_t port) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TestStunTcpServer* TestStunTcpServer::Create() {
|
||||
TestStunTcpServer* TestStunTcpServer::Create(int address_family) {
|
||||
NR_reg_init(NR_REG_MODE_LOCAL);
|
||||
|
||||
ScopedDeletePtr<TestStunTcpServer> server(new TestStunTcpServer());
|
||||
|
||||
server->Initialize();
|
||||
if (server->Initialize(address_family)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nr_socket_multi_tcp_set_readable_cb(server->listen_sock_,
|
||||
&TestStunServer::readable_cb, server.get());
|
||||
|
@ -24,12 +24,13 @@ class TestStunServer {
|
||||
public:
|
||||
// Generally, you should only call API in this class from the same thread that
|
||||
// the initial |GetInstance| call was made from.
|
||||
static TestStunServer *GetInstance();
|
||||
static TestStunServer *GetInstance(int address_family = AF_INET);
|
||||
static void ShutdownInstance();
|
||||
// |ConfigurePort| will only have an effect if called before the first call
|
||||
// to |GetInstance| (possibly following a |ShutdownInstance| call)
|
||||
static void ConfigurePort(uint16_t port);
|
||||
static TestStunServer *Create();
|
||||
// AF_INET, AF_INET6
|
||||
static TestStunServer *Create(int address_family);
|
||||
|
||||
virtual ~TestStunServer();
|
||||
|
||||
@ -59,7 +60,7 @@ class TestStunServer {
|
||||
timer_handle_(nullptr) {}
|
||||
|
||||
int SetInternalPort(nr_local_addr* addr, uint16_t port);
|
||||
int Initialize();
|
||||
int Initialize(int address_family);
|
||||
static void readable_cb(NR_SOCKET sock, int how, void *cb_arg);
|
||||
|
||||
private:
|
||||
@ -82,12 +83,13 @@ class TestStunServer {
|
||||
std::map<std::string, uint32_t> received_ct_;
|
||||
|
||||
static TestStunServer* instance;
|
||||
static TestStunServer* instance6;
|
||||
static uint16_t instance_port;
|
||||
};
|
||||
|
||||
class TestStunTcpServer: public TestStunServer {
|
||||
public:
|
||||
static TestStunTcpServer *GetInstance();
|
||||
static TestStunTcpServer *GetInstance(int address_family);
|
||||
static void ShutdownInstance();
|
||||
static void ConfigurePort(uint16_t port);
|
||||
virtual ~TestStunTcpServer();
|
||||
@ -98,9 +100,10 @@ class TestStunTcpServer: public TestStunServer {
|
||||
nsRefPtr<NrIceCtx> ice_ctx_;
|
||||
private:
|
||||
virtual int TryOpenListenSocket(nr_local_addr* addr, uint16_t port);
|
||||
static TestStunTcpServer *Create();
|
||||
static TestStunTcpServer *Create(int address_family);
|
||||
|
||||
static TestStunTcpServer* instance;
|
||||
static TestStunTcpServer* instance6;
|
||||
static uint16_t instance_port;
|
||||
};
|
||||
} // End of namespace mozilla
|
||||
|
@ -67,7 +67,7 @@ class TestNrSocketTest : public ::testing::Test {
|
||||
// is how we simulate a non-natted socket.
|
||||
nsRefPtr<TestNrSocket> sock(new TestNrSocket(nat ? nat : new TestNat));
|
||||
nr_transport_addr address;
|
||||
nr_ip4_str_port_to_transport_addr(ip_str, 0, IPPROTO_UDP, &address);
|
||||
nr_str_port_to_transport_addr(ip_str, 0, IPPROTO_UDP, &address);
|
||||
int r = sock->create(&address);
|
||||
if (r) {
|
||||
return nullptr;
|
||||
|
@ -132,7 +132,7 @@ class TurnClient : public ::testing::Test {
|
||||
net_socket_ = real_socket_;
|
||||
}
|
||||
|
||||
r = nr_ip4_str_port_to_transport_addr(turn_server_.c_str(), 3478,
|
||||
r = nr_str_port_to_transport_addr(turn_server_.c_str(), 3478,
|
||||
protocol_, &addr);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
@ -237,10 +237,10 @@ class TurnClient : public ::testing::Test {
|
||||
std::string host = target.substr(4, offset - 4);
|
||||
std::string port = target.substr(offset + 1);
|
||||
|
||||
r = nr_ip4_str_port_to_transport_addr(host.c_str(),
|
||||
atoi(port.c_str()),
|
||||
IPPROTO_UDP,
|
||||
&addr);
|
||||
r = nr_str_port_to_transport_addr(host.c_str(),
|
||||
atoi(port.c_str()),
|
||||
IPPROTO_UDP,
|
||||
&addr);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
r = nr_turn_client_ensure_perm(turn_ctx_, &addr);
|
||||
@ -324,10 +324,10 @@ class TurnClient : public ::testing::Test {
|
||||
std::string host = target.substr(4, offset - 4);
|
||||
std::string port = target.substr(offset + 1);
|
||||
|
||||
r = nr_ip4_str_port_to_transport_addr(host.c_str(),
|
||||
atoi(port.c_str()),
|
||||
IPPROTO_UDP,
|
||||
&addr);
|
||||
r = nr_str_port_to_transport_addr(host.c_str(),
|
||||
atoi(port.c_str()),
|
||||
IPPROTO_UDP,
|
||||
&addr);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
unsigned char test[100];
|
||||
@ -488,8 +488,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
{
|
||||
nr_transport_addr addr;
|
||||
if (nr_ip4_str_port_to_transport_addr(g_turn_server.c_str(), 3478,
|
||||
IPPROTO_UDP, &addr)) {
|
||||
if (nr_str_port_to_transport_addr(g_turn_server.c_str(), 3478,
|
||||
IPPROTO_UDP, &addr)) {
|
||||
printf("Invalid TURN_SERVER_ADDRESS \"%s\". Only IP numbers supported.\n",
|
||||
g_turn_server.c_str());
|
||||
return 0;
|
||||
@ -504,7 +504,7 @@ int main(int argc, char **argv)
|
||||
std::string dummy("dummy");
|
||||
RUN_ON_THREAD(test_utils->sts_target(),
|
||||
WrapRunnableNM(&NrIceCtx::Create,
|
||||
dummy, false, false, false, false),
|
||||
dummy, false, false, false, false, false),
|
||||
NS_DISPATCH_SYNC);
|
||||
|
||||
// Start the tests
|
||||
|
@ -37,6 +37,8 @@
|
||||
# STUN
|
||||
./src/stun/addrs.c
|
||||
./src/stun/addrs.h
|
||||
./src/stun/ifaddrs-android.c
|
||||
./src/stun/ifaddrs-android.h
|
||||
./src/stun/nr_socket_turn.c
|
||||
./src/stun/nr_socket_turn.h
|
||||
./src/stun/stun.h
|
||||
|
2
media/mtransport/third_party/nICEr/nicer.gyp
vendored
2
media/mtransport/third_party/nICEr/nicer.gyp
vendored
@ -88,6 +88,8 @@
|
||||
# STUN
|
||||
"./src/stun/addrs.c",
|
||||
"./src/stun/addrs.h",
|
||||
"./src/stun/ifaddrs-android.c",
|
||||
"./src/stun/ifaddrs-android.h",
|
||||
"./src/stun/nr_socket_turn.c",
|
||||
"./src/stun/nr_socket_turn.h",
|
||||
"./src/stun/nr_socket_buffered_stun.c",
|
||||
|
@ -64,7 +64,7 @@ static char *RCSSTRING __UNUSED__="$Id: ice_candidate.c,v 1.2 2008/04/28 17:59:0
|
||||
#include "nr_socket.h"
|
||||
#include "nr_socket_multi_tcp.h"
|
||||
|
||||
static int next_automatic_preference = 224;
|
||||
static int next_automatic_preference = 127;
|
||||
|
||||
static int nr_ice_candidate_initialize2(nr_ice_candidate *cand);
|
||||
static int nr_ice_get_foundation(nr_ice_ctx *ctx,nr_ice_candidate *cand);
|
||||
@ -470,8 +470,12 @@ int nr_ice_candidate_compute_priority(nr_ice_candidate *cand)
|
||||
if (r=NR_reg_set2_uchar(NR_ICE_REG_PREF_INTERFACE_PRFX,cand->base.ifname,next_automatic_preference)){
|
||||
ABORT(r);
|
||||
}
|
||||
interface_preference=next_automatic_preference;
|
||||
interface_preference=next_automatic_preference << 1;
|
||||
next_automatic_preference--;
|
||||
if (cand->base.ip_version == NR_IPV6) {
|
||||
/* Prefer IPV6 over IPV4 on the same interface. */
|
||||
interface_preference += 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ABORT(r);
|
||||
@ -550,6 +554,11 @@ int nr_ice_candidate_initialize(nr_ice_candidate *cand, NR_async_cb ready_cb, vo
|
||||
cand->state=NR_ICE_CAND_STATE_INITIALIZING;
|
||||
|
||||
if(cand->stun_server->type == NR_ICE_STUN_SERVER_TYPE_ADDR) {
|
||||
if(cand->base.ip_version != cand->stun_server->u.addr.ip_version) {
|
||||
r_log(LOG_ICE, LOG_INFO, "ICE-CANDIDATE(%s): Skipping srflx/relayed candidate with different IP version (%d) than STUN/TURN server (%d).", cand->label,cand->base.ip_version,cand->stun_server->u.addr.ip_version);
|
||||
ABORT(R_NOT_FOUND); /* Same error code when DNS lookup fails */
|
||||
}
|
||||
|
||||
/* Just copy the address */
|
||||
if (r=nr_transport_addr_copy(&cand->stun_server_addr,
|
||||
&cand->stun_server->u.addr)) {
|
||||
@ -567,6 +576,17 @@ int nr_ice_candidate_initialize(nr_ice_candidate *cand, NR_async_cb ready_cb, vo
|
||||
resource.stun_turn=protocol;
|
||||
resource.transport_protocol=cand->stun_server->transport;
|
||||
|
||||
switch (cand->base.ip_version) {
|
||||
case NR_IPV4:
|
||||
resource.address_family=AF_INET;
|
||||
break;
|
||||
case NR_IPV6:
|
||||
resource.address_family=AF_INET6;
|
||||
break;
|
||||
default:
|
||||
ABORT(R_BAD_ARGS);
|
||||
}
|
||||
|
||||
/* Try to resolve */
|
||||
if(!cand->ctx->resolver) {
|
||||
r_log(LOG_ICE, LOG_ERR, "ICE-CANDIDATE(%s): Can't use DNS names without a resolver", cand->label);
|
||||
|
@ -999,6 +999,9 @@ int nr_ice_component_pair_candidate(nr_ice_peer_ctx *pctx, nr_ice_component *pco
|
||||
continue;
|
||||
if (lcand->tcp_type == TCP_TYPE_PASSIVE)
|
||||
continue;
|
||||
if(pcand->addr.ip_version != lcand->addr.ip_version)
|
||||
continue;
|
||||
|
||||
/*
|
||||
Two modes, depending on |pair_all_remote|
|
||||
|
||||
@ -1334,3 +1337,44 @@ int nr_ice_component_insert_pair(nr_ice_component *pcomp, nr_ice_cand_pair *pair
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_component_get_default_candidate(nr_ice_component *comp, nr_ice_candidate **candp, int ip_version)
|
||||
{
|
||||
int _status;
|
||||
nr_ice_candidate *cand;
|
||||
nr_ice_candidate *best_cand = NULL;
|
||||
|
||||
/* We have the component. Now find the "best" candidate, making
|
||||
use of the fact that more "reliable" candidate types have
|
||||
higher numbers. So, we sort by type and then priority within
|
||||
type
|
||||
*/
|
||||
cand=TAILQ_FIRST(&comp->candidates);
|
||||
while(cand){
|
||||
if (cand->state == NR_ICE_CAND_STATE_INITIALIZED &&
|
||||
cand->addr.ip_version == ip_version) {
|
||||
if (!best_cand) {
|
||||
best_cand = cand;
|
||||
}
|
||||
else if (best_cand->type < cand->type) {
|
||||
best_cand = cand;
|
||||
} else if (best_cand->type == cand->type &&
|
||||
best_cand->priority < cand->priority) {
|
||||
best_cand = cand;
|
||||
}
|
||||
}
|
||||
|
||||
cand=TAILQ_NEXT(cand,entry_comp);
|
||||
}
|
||||
|
||||
/* No candidates */
|
||||
if (!best_cand)
|
||||
ABORT(R_NOT_FOUND);
|
||||
|
||||
*candp = best_cand;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,7 @@ int nr_ice_component_select_pair(nr_ice_peer_ctx *pctx, nr_ice_component *comp);
|
||||
int nr_ice_component_set_failed(nr_ice_component *comp);
|
||||
int nr_ice_component_finalize(nr_ice_component *lcomp, nr_ice_component *rcomp);
|
||||
int nr_ice_component_insert_pair(nr_ice_component *pcomp, nr_ice_cand_pair *pair);
|
||||
int nr_ice_component_get_default_candidate(nr_ice_component *comp, nr_ice_candidate **candp, int ip_version);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -223,14 +223,11 @@ int nr_ice_media_stream_get_attributes(nr_ice_media_stream *stream, char ***attr
|
||||
return(_status);
|
||||
}
|
||||
|
||||
|
||||
/* Get a default candidate per 4.1.4 */
|
||||
int nr_ice_media_stream_get_default_candidate(nr_ice_media_stream *stream, int component, nr_ice_candidate **candp)
|
||||
{
|
||||
int _status;
|
||||
int r,_status;
|
||||
nr_ice_component *comp;
|
||||
nr_ice_candidate *cand;
|
||||
nr_ice_candidate *best_cand = NULL;
|
||||
|
||||
comp=STAILQ_FIRST(&stream->components);
|
||||
while(comp){
|
||||
@ -243,36 +240,12 @@ int nr_ice_media_stream_get_default_candidate(nr_ice_media_stream *stream, int c
|
||||
if (!comp)
|
||||
ABORT(R_NOT_FOUND);
|
||||
|
||||
/* We have the component. Now find the "best" candidate, making
|
||||
use of the fact that more "reliable" candidate types have
|
||||
higher numbers. So, we sort by type and then priority within
|
||||
type
|
||||
*/
|
||||
cand=TAILQ_FIRST(&comp->candidates);
|
||||
while(cand){
|
||||
if (cand->state == NR_ICE_CAND_STATE_INITIALIZED) {
|
||||
if (!best_cand) {
|
||||
best_cand = cand;
|
||||
}
|
||||
else {
|
||||
if (best_cand->type < cand->type) {
|
||||
best_cand = cand;
|
||||
} else if (best_cand->type == cand->type) {
|
||||
if (best_cand->priority < cand->priority)
|
||||
best_cand = cand;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cand=TAILQ_NEXT(cand,entry_comp);
|
||||
/* If there aren't any IPV4 candidates, try IPV6 */
|
||||
if((r=nr_ice_component_get_default_candidate(comp, candp, NR_IPV4)) &&
|
||||
(r=nr_ice_component_get_default_candidate(comp, candp, NR_IPV6))) {
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
/* No candidates */
|
||||
if (!best_cand)
|
||||
ABORT(R_NOT_FOUND);
|
||||
|
||||
*candp = best_cand;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
|
@ -120,7 +120,6 @@ nr_ice_peer_candidate_from_attribute(nr_ice_ctx *ctx,char *orig,nr_ice_media_str
|
||||
nr_ice_candidate *cand;
|
||||
char *connection_address=0;
|
||||
unsigned int port;
|
||||
in_addr_t addr;
|
||||
int i;
|
||||
unsigned int component_id;
|
||||
char *rel_addr=0;
|
||||
@ -212,10 +211,6 @@ nr_ice_peer_candidate_from_attribute(nr_ice_ctx *ctx,char *orig,nr_ice_media_str
|
||||
if (*str == '\0')
|
||||
ABORT(R_BAD_DATA);
|
||||
|
||||
addr = inet_addr(connection_address);
|
||||
if (addr == INADDR_NONE)
|
||||
ABORT(R_BAD_DATA);
|
||||
|
||||
skip_whitespace(&str);
|
||||
if (*str == '\0')
|
||||
ABORT(R_BAD_DATA);
|
||||
@ -226,8 +221,7 @@ nr_ice_peer_candidate_from_attribute(nr_ice_ctx *ctx,char *orig,nr_ice_media_str
|
||||
if (port < 1 || port > 0x0FFFF)
|
||||
ABORT(R_BAD_DATA);
|
||||
|
||||
/* Assume v4 for now */
|
||||
if(r=nr_ip4_port_to_transport_addr(ntohl(addr),port,transport,&cand->addr))
|
||||
if ((r=nr_str_port_to_transport_addr(connection_address,port,transport,&cand->addr)))
|
||||
ABORT(r);
|
||||
|
||||
skip_to_past_space(&str);
|
||||
@ -289,10 +283,6 @@ nr_ice_peer_candidate_from_attribute(nr_ice_ctx *ctx,char *orig,nr_ice_media_str
|
||||
if (*str == '\0')
|
||||
ABORT(R_BAD_DATA);
|
||||
|
||||
addr = inet_addr(rel_addr);
|
||||
if (addr == INADDR_NONE)
|
||||
ABORT(R_BAD_DATA);
|
||||
|
||||
skip_whitespace(&str);
|
||||
if (*str == '\0')
|
||||
ABORT(R_BAD_DATA);
|
||||
@ -314,8 +304,7 @@ nr_ice_peer_candidate_from_attribute(nr_ice_ctx *ctx,char *orig,nr_ice_media_str
|
||||
if (port < 1 || port > 0x0FFFF)
|
||||
ABORT(R_BAD_DATA);
|
||||
|
||||
/* Assume v4 for now */
|
||||
if(r=nr_ip4_port_to_transport_addr(ntohl(addr),port,transport,&cand->base))
|
||||
if ((r=nr_str_port_to_transport_addr(rel_addr,port,transport,&cand->base)))
|
||||
ABORT(r);
|
||||
|
||||
skip_to_past_space(&str);
|
||||
|
@ -256,7 +256,7 @@ int nr_socket_proxy_tunnel_connect(void *obj, nr_transport_addr *addr)
|
||||
assert(config->proxy_host);
|
||||
|
||||
/* Check if the proxy_host is already an IP address */
|
||||
has_addr = !nr_ip4_str_port_to_transport_addr(config->proxy_host,
|
||||
has_addr = !nr_str_port_to_transport_addr(config->proxy_host,
|
||||
config->proxy_port, IPPROTO_TCP, &proxy_addr);
|
||||
|
||||
r_log(LOG_GENERIC,LOG_DEBUG,"nr_socket_proxy_tunnel_connect: %s", config->proxy_host);
|
||||
|
@ -46,6 +46,7 @@ typedef struct nr_resolver_resource_ {
|
||||
UINT2 port;
|
||||
int stun_turn;
|
||||
UCHAR transport_protocol;
|
||||
UCHAR address_family;
|
||||
} nr_resolver_resource;
|
||||
|
||||
typedef struct nr_resolver_vtbl_ {
|
||||
|
@ -100,44 +100,51 @@ int nr_transport_addr_fmt_ifname_addr_string(const nr_transport_addr *addr, char
|
||||
if (!inet_ntop(AF_INET, &addr->u.addr4.sin_addr,buffer,sizeof(buffer))) {
|
||||
strncpy(buffer, "[error]", len);
|
||||
}
|
||||
snprintf(buf,len,"%s:%s",addr->ifname,buffer);
|
||||
break;
|
||||
case NR_IPV6:
|
||||
if (!inet_ntop(AF_INET6, &addr->u.addr6.sin6_addr,buffer,sizeof(buffer))) {
|
||||
strncpy(buffer, "[error]", len);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ABORT(R_INTERNAL);
|
||||
}
|
||||
snprintf(buf,len,"%s:%s",addr->ifname,buffer);
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_sockaddr_to_transport_addr(struct sockaddr *saddr, int saddr_len, int protocol, int keep, nr_transport_addr *addr)
|
||||
int nr_sockaddr_to_transport_addr(struct sockaddr *saddr, int protocol, int keep, nr_transport_addr *addr)
|
||||
{
|
||||
int r,_status;
|
||||
|
||||
if(!keep) memset(addr,0,sizeof(nr_transport_addr));
|
||||
|
||||
if(saddr->sa_family==PF_INET){
|
||||
if(saddr_len != sizeof(struct sockaddr_in))
|
||||
switch(protocol){
|
||||
case IPPROTO_TCP:
|
||||
case IPPROTO_UDP:
|
||||
break;
|
||||
default:
|
||||
ABORT(R_BAD_ARGS);
|
||||
}
|
||||
|
||||
switch(protocol){
|
||||
case IPPROTO_TCP:
|
||||
case IPPROTO_UDP:
|
||||
break;
|
||||
default:
|
||||
ABORT(R_BAD_ARGS);
|
||||
}
|
||||
addr->protocol=protocol;
|
||||
|
||||
if(saddr->sa_family==AF_INET){
|
||||
addr->ip_version=NR_IPV4;
|
||||
addr->protocol=protocol;
|
||||
|
||||
memcpy(&addr->u.addr4,saddr,sizeof(struct sockaddr_in));
|
||||
addr->addr=(struct sockaddr *)&addr->u.addr4;
|
||||
addr->addr_len=saddr_len;
|
||||
addr->addr_len=sizeof(struct sockaddr_in);
|
||||
}
|
||||
else if(saddr->sa_family==PF_INET6){
|
||||
/* Not implemented */
|
||||
ABORT(R_INTERNAL);
|
||||
else if(saddr->sa_family==AF_INET6){
|
||||
addr->ip_version=NR_IPV6;
|
||||
|
||||
memcpy(&addr->u.addr6, saddr, sizeof(struct sockaddr_in6));
|
||||
addr->addr=(struct sockaddr *)&addr->u.addr6;
|
||||
addr->addr_len=sizeof(struct sockaddr_in6);
|
||||
}
|
||||
else
|
||||
ABORT(R_BAD_ARGS);
|
||||
@ -206,16 +213,42 @@ int nr_ip4_port_to_transport_addr(UINT4 ip4, UINT2 port, int protocol, nr_transp
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ip4_str_port_to_transport_addr(const char *ip4, UINT2 port, int protocol, nr_transport_addr *addr)
|
||||
int nr_str_port_to_transport_addr(const char *ip, UINT2 port, int protocol, nr_transport_addr *addr_out)
|
||||
{
|
||||
int r,_status;
|
||||
in_addr_t ip_addr;
|
||||
struct in_addr addr;
|
||||
struct in6_addr addr6;
|
||||
|
||||
ip_addr=inet_addr(ip4);
|
||||
if (ip_addr == INADDR_NONE)
|
||||
if (inet_pton(AF_INET, ip, &addr) == 1) {
|
||||
if(r=nr_ip4_port_to_transport_addr(ntohl(addr.s_addr),port,protocol,addr_out))
|
||||
ABORT(r);
|
||||
} else if (inet_pton(AF_INET6, ip, &addr6) == 1) {
|
||||
if(r=nr_ip6_port_to_transport_addr(&addr6,port,protocol,addr_out))
|
||||
ABORT(r);
|
||||
} else {
|
||||
ABORT(R_BAD_DATA);
|
||||
/* Assume v4 for now */
|
||||
if(r=nr_ip4_port_to_transport_addr(ntohl(ip_addr),port,protocol,addr))
|
||||
}
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ip6_port_to_transport_addr(struct in6_addr* addr6, UINT2 port, int protocol, nr_transport_addr *addr)
|
||||
{
|
||||
int r,_status;
|
||||
|
||||
memset(addr, 0, sizeof(nr_transport_addr));
|
||||
|
||||
addr->ip_version=NR_IPV6;
|
||||
addr->protocol=protocol;
|
||||
addr->u.addr6.sin6_family=PF_INET6;
|
||||
addr->u.addr6.sin6_port=htons(port);
|
||||
memcpy(addr->u.addr6.sin6_addr.s6_addr, addr6->s6_addr, sizeof(addr6->s6_addr));
|
||||
addr->addr=(struct sockaddr *)&addr->u.addr6;
|
||||
addr->addr_len=sizeof(struct sockaddr_in6);
|
||||
|
||||
if(r=nr_transport_addr_fmt_addr_string(addr))
|
||||
ABORT(r);
|
||||
|
||||
_status=0;
|
||||
@ -291,26 +324,6 @@ int nr_transport_addr_set_port(nr_transport_addr *addr, int port)
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_transport_addr_get_ip4(nr_transport_addr *addr, UINT4 *ip4p)
|
||||
{
|
||||
int _status;
|
||||
|
||||
switch(addr->ip_version){
|
||||
case NR_IPV4:
|
||||
*ip4p=ntohl(addr->u.addr4.sin_addr.s_addr);
|
||||
break;
|
||||
case NR_IPV6:
|
||||
ABORT(R_NOT_FOUND);
|
||||
break;
|
||||
default:
|
||||
ABORT(R_INTERNAL);
|
||||
}
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
/* memcmp() may not work if, for instance, the string or interface
|
||||
haven't been made. Hmmm.. */
|
||||
int nr_transport_addr_cmp(nr_transport_addr *addr1,nr_transport_addr *addr2,int mode)
|
||||
@ -340,7 +353,13 @@ int nr_transport_addr_cmp(nr_transport_addr *addr1,nr_transport_addr *addr2,int
|
||||
return(1);
|
||||
break;
|
||||
case NR_IPV6:
|
||||
UNIMPLEMENTED;
|
||||
if(memcmp(addr1->u.addr6.sin6_addr.s6_addr,addr2->u.addr6.sin6_addr.s6_addr,sizeof(struct in6_addr)))
|
||||
return(1);
|
||||
if(mode < NR_TRANSPORT_ADDR_CMP_MODE_ALL)
|
||||
return(0);
|
||||
if(addr1->u.addr6.sin6_port != addr2->u.addr6.sin6_port)
|
||||
return(1);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
@ -363,6 +382,10 @@ int nr_transport_addr_is_loopback(nr_transport_addr *addr)
|
||||
}
|
||||
break;
|
||||
|
||||
case NR_IPV6:
|
||||
if(!memcmp(addr->u.addr6.sin6_addr.s6_addr,in6addr_loopback.s6_addr,sizeof(struct in6_addr)))
|
||||
return(1);
|
||||
break;
|
||||
default:
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
@ -370,6 +393,18 @@ int nr_transport_addr_is_loopback(nr_transport_addr *addr)
|
||||
return(0);
|
||||
}
|
||||
|
||||
int nr_transport_addr_is_link_local(nr_transport_addr *addr)
|
||||
{
|
||||
if(addr->ip_version == NR_IPV6){
|
||||
UINT4* addrTop = (UINT4*)(addr->u.addr6.sin6_addr.s6_addr);
|
||||
return ((*addrTop & htonl(0xFFC00000)) == htonl(0xFE800000));
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int nr_transport_addr_is_wildcard(nr_transport_addr *addr)
|
||||
{
|
||||
switch(addr->ip_version){
|
||||
@ -379,6 +414,12 @@ int nr_transport_addr_is_wildcard(nr_transport_addr *addr)
|
||||
if(addr->u.addr4.sin_port==0)
|
||||
return(1);
|
||||
break;
|
||||
case NR_IPV6:
|
||||
if(!memcmp(addr->u.addr6.sin6_addr.s6_addr,in6addr_any.s6_addr,sizeof(struct in6_addr)))
|
||||
return(1);
|
||||
if(addr->u.addr6.sin6_port==0)
|
||||
return(1);
|
||||
break;
|
||||
default:
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
@ -71,15 +71,15 @@ typedef struct nr_transport_addr_ {
|
||||
char as_string[56];
|
||||
} nr_transport_addr;
|
||||
|
||||
int nr_sockaddr_to_transport_addr(struct sockaddr *saddr, int saddr_len, int protocol, int keep, nr_transport_addr *addr);
|
||||
int nr_sockaddr_to_transport_addr(struct sockaddr *saddr, int protocol, int keep, nr_transport_addr *addr);
|
||||
|
||||
// addresses, ports in local byte order
|
||||
int nr_ip4_port_to_transport_addr(UINT4 ip4, UINT2 port, int protocol, nr_transport_addr *addr);
|
||||
int nr_ip4_str_port_to_transport_addr(const char *ip4, UINT2 port, int protocol, nr_transport_addr *addr);
|
||||
int nr_str_port_to_transport_addr(const char *ip4, UINT2 port, int protocol, nr_transport_addr *addr);
|
||||
int nr_ip6_port_to_transport_addr(struct in6_addr* addr6, UINT2 port, int protocol, nr_transport_addr *addr);
|
||||
|
||||
int nr_transport_addr_get_addrstring(nr_transport_addr *addr, char *str, int maxlen);
|
||||
int nr_transport_addr_get_port(nr_transport_addr *addr, int *port);
|
||||
int nr_transport_addr_get_ip4(nr_transport_addr *addr, UINT4 *ip4p);
|
||||
int nr_transport_addr_cmp(nr_transport_addr *addr1,nr_transport_addr *addr2,int mode);
|
||||
#define NR_TRANSPORT_ADDR_CMP_MODE_VERSION 1
|
||||
#define NR_TRANSPORT_ADDR_CMP_MODE_PROTOCOL 2
|
||||
@ -88,6 +88,7 @@ int nr_transport_addr_cmp(nr_transport_addr *addr1,nr_transport_addr *addr2,int
|
||||
|
||||
int nr_transport_addr_is_wildcard(nr_transport_addr *addr);
|
||||
int nr_transport_addr_is_loopback(nr_transport_addr *addr);
|
||||
int nr_transport_addr_is_link_local(nr_transport_addr *addr);
|
||||
int nr_transport_addr_copy(nr_transport_addr *to, nr_transport_addr *from);
|
||||
int nr_transport_addr_copy_keep_ifname(nr_transport_addr *to, nr_transport_addr *from);
|
||||
int nr_transport_addr_fmt_addr_string(nr_transport_addr *addr);
|
||||
|
@ -53,6 +53,9 @@ static char *RCSSTRING __UNUSED__="$Id: transport_addr_reg.c,v 1.2 2008/04/28 17
|
||||
#include "transport_addr.h"
|
||||
#include "transport_addr_reg.h"
|
||||
|
||||
#ifndef INET6_ADDRSTRLEN
|
||||
#define INET6_ADDRSTRLEN 46 /* Value used by linux/BSD */
|
||||
#endif
|
||||
|
||||
int
|
||||
nr_reg_get_transport_addr(NR_registry prefix, int keep, nr_transport_addr *addr)
|
||||
@ -107,7 +110,7 @@ nr_reg_get_transport_addr(NR_registry prefix, int keep, nr_transport_addr *addr)
|
||||
|
||||
if (!keep) memset(addr, 0, sizeof(*addr));
|
||||
|
||||
if ((r=nr_ip4_str_port_to_transport_addr(address?address:"0.0.0.0", port, p, addr)))
|
||||
if ((r=nr_str_port_to_transport_addr(address?address:"0.0.0.0", port, p, addr)))
|
||||
ABORT(r);
|
||||
|
||||
if (ifname)
|
||||
@ -133,7 +136,7 @@ nr_reg_set_transport_addr(NR_registry prefix, int keep, nr_transport_addr *addr)
|
||||
|
||||
switch (addr->ip_version) {
|
||||
case NR_IPV4:
|
||||
if (addr->u.addr4.sin_addr.s_addr != INADDR_ANY) {
|
||||
if (!nr_transport_addr_is_wildcard(addr)) {
|
||||
if ((r=NR_reg_set2_string(prefix, "address", inet_ntoa(addr->u.addr4.sin_addr))))
|
||||
ABORT(r);
|
||||
}
|
||||
@ -142,35 +145,50 @@ nr_reg_set_transport_addr(NR_registry prefix, int keep, nr_transport_addr *addr)
|
||||
if ((r=NR_reg_set2_uint2(prefix, "port", ntohs(addr->u.addr4.sin_port))))
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
switch (addr->protocol) {
|
||||
case IPPROTO_TCP:
|
||||
if ((r=NR_reg_set2_string(prefix, "protocol", "tcp")))
|
||||
ABORT(r);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
if ((r=NR_reg_set2_string(prefix, "protocol", "udp")))
|
||||
ABORT(r);
|
||||
break;
|
||||
default:
|
||||
UNIMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (strlen(addr->ifname) > 0) {
|
||||
if ((r=NR_reg_set2_string(prefix, "ifname", addr->ifname)))
|
||||
ABORT(r);
|
||||
}
|
||||
break;
|
||||
|
||||
case NR_IPV6:
|
||||
UNIMPLEMENTED;
|
||||
if (!nr_transport_addr_is_wildcard(addr)) {
|
||||
char address[INET6_ADDRSTRLEN];
|
||||
if(!inet_ntop(AF_INET6, &addr->u.addr6.sin6_addr,address,sizeof(address))) {
|
||||
ABORT(R_BAD_DATA);
|
||||
}
|
||||
|
||||
if ((r=NR_reg_set2_string(prefix, "address", address))) {
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
|
||||
if (addr->u.addr6.sin6_port != 0) {
|
||||
if ((r=NR_reg_set2_uint2(prefix, "port", ntohs(addr->u.addr6.sin6_port))))
|
||||
ABORT(r);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ABORT(R_INTERNAL);
|
||||
break;
|
||||
}
|
||||
|
||||
/* We abort if neither NR_IPV4 or NR_IPV6 above */
|
||||
switch (addr->protocol) {
|
||||
case IPPROTO_TCP:
|
||||
if ((r=NR_reg_set2_string(prefix, "protocol", "tcp")))
|
||||
ABORT(r);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
if ((r=NR_reg_set2_string(prefix, "protocol", "udp")))
|
||||
ABORT(r);
|
||||
break;
|
||||
default:
|
||||
UNIMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (strlen(addr->ifname) > 0) {
|
||||
if ((r=NR_reg_set2_string(prefix, "ifname", addr->ifname)))
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if (_status)
|
||||
|
570
media/mtransport/third_party/nICEr/src/stun/addrs.c
vendored
570
media/mtransport/third_party/nICEr/src/stun/addrs.c
vendored
@ -41,267 +41,42 @@ static char *RCSSTRING __UNUSED__="$Id: addrs.c,v 1.2 2008/04/28 18:21:30 ekr Ex
|
||||
#include <winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <tchar.h>
|
||||
#else /* UNIX */
|
||||
#include <sys/param.h>
|
||||
#else /* !WIN32 */
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef ANDROID
|
||||
#include <sys/syslog.h>
|
||||
/* This works on linux and BSD, but not android */
|
||||
#include <sys/types.h> /* getifaddrs */
|
||||
#include <ifaddrs.h> /* getifaddrs */
|
||||
#else
|
||||
#include <syslog.h>
|
||||
#include "ifaddrs-android.h"
|
||||
#define getifaddrs android_getifaddrs
|
||||
#define freeifaddrs android_freeifaddrs
|
||||
#endif
|
||||
|
||||
#ifdef LINUX
|
||||
|
||||
#ifdef ANDROID
|
||||
/* Work around an Android NDK < r8c bug */
|
||||
#undef __unused
|
||||
#endif
|
||||
#ifndef LINUX
|
||||
#include <net/if.h>
|
||||
#if !defined(__OpenBSD__) && !defined(__NetBSD__)
|
||||
#include <net/if_var.h>
|
||||
#endif
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <sys/sockio.h>
|
||||
#else
|
||||
#include <linux/sockios.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/wireless.h>
|
||||
#ifndef ANDROID
|
||||
#include <linux/ethtool.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <net/route.h>
|
||||
#include <linux/if.h> /* struct ifreq, IFF_POINTTOPOINT */
|
||||
#include <linux/wireless.h> /* struct iwreq */
|
||||
#include <linux/ethtool.h> /* struct ethtool_cmd */
|
||||
#include <linux/sockios.h> /* SIOCETHTOOL */
|
||||
#endif /* ANDROID */
|
||||
|
||||
/* IP */
|
||||
#include <netinet/in.h>
|
||||
#ifdef LINUX
|
||||
#include "sys/ioctl.h"
|
||||
#else
|
||||
#include <netinet/in_var.h>
|
||||
#endif
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#endif /* UNIX */
|
||||
#endif /* LINUX */
|
||||
|
||||
#endif /* !WIN32 */
|
||||
|
||||
#include "stun.h"
|
||||
#include "addrs.h"
|
||||
|
||||
|
||||
|
||||
#if defined(BSD) || defined(DARWIN)
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*[3 Deleted as of 22nd July 1999; see
|
||||
* ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
|
||||
* for details]
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
static void stun_rt_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *);
|
||||
static int stun_grab_addrs(char *name, int addrcount,
|
||||
struct ifa_msghdr *ifam,
|
||||
nr_local_addr addrs[], int maxaddrs, int *count);
|
||||
static int
|
||||
nr_stun_is_duplicate_addr(nr_local_addr addrs[], int count, nr_local_addr *addr);
|
||||
|
||||
|
||||
/*
|
||||
* Expand the compacted form of addresses as returned via the
|
||||
* configuration read via sysctl().
|
||||
*/
|
||||
#define ROUNDUP(a) \
|
||||
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
|
||||
#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
|
||||
|
||||
static void
|
||||
stun_rt_xaddrs(cp, cplim, rtinfo)
|
||||
caddr_t cp, cplim;
|
||||
struct rt_addrinfo *rtinfo;
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
int i;
|
||||
|
||||
memset(rtinfo->rti_info, 0, sizeof(rtinfo->rti_info));
|
||||
for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) {
|
||||
if ((rtinfo->rti_addrs & (1 << i)) == 0)
|
||||
continue;
|
||||
rtinfo->rti_info[i] = sa = (struct sockaddr *)cp;
|
||||
ADVANCE(cp, sa);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
stun_grab_addrs(char *name, int addrcount, struct ifa_msghdr *ifam, nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
int r,_status;
|
||||
int s = -1;
|
||||
struct ifreq ifr;
|
||||
struct rt_addrinfo info;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
|
||||
|
||||
if ((s = socket(ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0) {
|
||||
r_log(NR_LOG_STUN, LOG_ERR, "unable to obtain addresses from socket");
|
||||
ABORT(R_FAILED);
|
||||
}
|
||||
|
||||
while (addrcount > 0) {
|
||||
info.rti_addrs = ifam->ifam_addrs;
|
||||
|
||||
/* Expand the compacted addresses */
|
||||
stun_rt_xaddrs((char *)(ifam + 1), ifam->ifam_msglen + (char *)ifam, &info);
|
||||
addrs[*count].interface.type = NR_INTERFACE_TYPE_UNKNOWN;
|
||||
addrs[*count].interface.estimated_speed = 0;
|
||||
/* TODO (Bug 895790) Get interface properties for Darwin */
|
||||
|
||||
switch (info.rti_info[RTAX_IFA]->sa_family) {
|
||||
case AF_INET:
|
||||
sin = (struct sockaddr_in *)info.rti_info[RTAX_IFA];
|
||||
|
||||
if ((r=nr_sockaddr_to_transport_addr((struct sockaddr*)sin, sizeof(*sin), IPPROTO_UDP, 0, &(addrs[*count].addr))))
|
||||
ABORT(r);
|
||||
|
||||
strlcpy(addrs[*count].addr.ifname, name, sizeof(addrs[*count].addr.ifname));
|
||||
|
||||
++*count;
|
||||
break;
|
||||
case AF_INET6:
|
||||
UNIMPLEMENTED;
|
||||
break;
|
||||
}
|
||||
|
||||
addrcount--;
|
||||
|
||||
if (*count >= maxaddrs) {
|
||||
r_log(NR_LOG_STUN, LOG_WARNING, "Address list truncated at %d out of %d entries", maxaddrs, maxaddrs+addrcount);
|
||||
break;
|
||||
}
|
||||
|
||||
ifam = (struct ifa_msghdr *)((char *)ifam + ifam->ifam_msglen);
|
||||
}
|
||||
|
||||
_status = 0;
|
||||
abort:
|
||||
if (s != -1) close(s);
|
||||
return _status;
|
||||
}
|
||||
|
||||
static int
|
||||
stun_get_mib_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
int _status;
|
||||
char name[32];
|
||||
int flags;
|
||||
int addrcount;
|
||||
struct if_msghdr *ifm, *nextifm;
|
||||
struct ifa_msghdr *ifam;
|
||||
struct sockaddr_dl *sdl;
|
||||
char *buf = 0;
|
||||
char *lim;
|
||||
char *next;
|
||||
size_t needed;
|
||||
int mib[6];
|
||||
|
||||
*count = 0;
|
||||
|
||||
mib[0] = CTL_NET;
|
||||
mib[1] = PF_ROUTE;
|
||||
mib[2] = 0;
|
||||
mib[3] = AF_INET;
|
||||
mib[4] = NET_RT_IFLIST;
|
||||
mib[5] = 0;
|
||||
|
||||
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
|
||||
errx(1, "iflist-sysctl-estimate");
|
||||
ABORT(R_INTERNAL);
|
||||
}
|
||||
|
||||
if ((buf = malloc(needed)) == NULL) {
|
||||
errx(1, "malloc");
|
||||
ABORT(R_NO_MEMORY);
|
||||
}
|
||||
|
||||
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
|
||||
errx(1, "actual retrieval of interface table");
|
||||
ABORT(R_INTERNAL);
|
||||
}
|
||||
|
||||
lim = buf + needed;
|
||||
|
||||
next = buf;
|
||||
while (next < lim) {
|
||||
ifm = (struct if_msghdr *)next;
|
||||
|
||||
if (ifm->ifm_type == RTM_IFINFO) {
|
||||
sdl = (struct sockaddr_dl *)(ifm + 1);
|
||||
flags = ifm->ifm_flags;
|
||||
} else {
|
||||
r_log(NR_LOG_STUN, LOG_WARNING, "out of sync parsing NET_RT_IFLIST");
|
||||
r_log(NR_LOG_STUN, LOG_DEBUG, "expected %d, got %d, msglen = %d, buf:%p, next:%p, lim:%p", RTM_IFINFO, ifm->ifm_type, ifm->ifm_msglen, buf, next, lim);
|
||||
ABORT(R_FAILED);
|
||||
}
|
||||
|
||||
next += ifm->ifm_msglen;
|
||||
ifam = NULL;
|
||||
addrcount = 0;
|
||||
while (next < lim) {
|
||||
|
||||
nextifm = (struct if_msghdr *)next;
|
||||
|
||||
if (nextifm->ifm_type != RTM_NEWADDR)
|
||||
break;
|
||||
|
||||
if (ifam == NULL)
|
||||
ifam = (struct ifa_msghdr *)nextifm;
|
||||
|
||||
addrcount++;
|
||||
next += nextifm->ifm_msglen;
|
||||
}
|
||||
|
||||
if (sdl->sdl_nlen > sizeof(name) - 1) {
|
||||
ABORT(R_INTERNAL);
|
||||
}
|
||||
|
||||
memcpy(name, sdl->sdl_data, sdl->sdl_nlen);
|
||||
name[sdl->sdl_nlen] = '\0';
|
||||
|
||||
stun_grab_addrs(name, addrcount, ifam, addrs, maxaddrs, count);
|
||||
}
|
||||
|
||||
_status = 0;
|
||||
abort:
|
||||
if (buf) free(buf);
|
||||
return _status;
|
||||
}
|
||||
|
||||
#elif defined(WIN32)
|
||||
#if defined(WIN32)
|
||||
|
||||
#define WIN32_MAX_NUM_INTERFACES 20
|
||||
|
||||
@ -368,125 +143,6 @@ abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
stun_get_win32_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
int r,_status;
|
||||
PIP_ADAPTER_INFO pAdapterInfo;
|
||||
PIP_ADAPTER_INFO pAdapter = NULL;
|
||||
PIP_ADDR_STRING pAddrString;
|
||||
ULONG out_buf_len;
|
||||
char *friendly_name=0;
|
||||
char munged_ifname[IFNAMSIZ];
|
||||
int n = 0;
|
||||
|
||||
*count = 0;
|
||||
|
||||
pAdapterInfo = (IP_ADAPTER_INFO *) RMALLOC(sizeof(IP_ADAPTER_INFO));
|
||||
out_buf_len = sizeof(IP_ADAPTER_INFO);
|
||||
|
||||
/* First call to GetAdaptersInfo is mainly to get length */
|
||||
|
||||
if (GetAdaptersInfo(pAdapterInfo, &out_buf_len) == ERROR_BUFFER_OVERFLOW) {
|
||||
RFREE(pAdapterInfo);
|
||||
pAdapterInfo = (IP_ADAPTER_INFO *) RMALLOC(out_buf_len);
|
||||
if (pAdapterInfo == NULL) {
|
||||
r_log(NR_LOG_STUN, LOG_ERR, "Error allocating memory for GetAdaptersInfo output");
|
||||
ABORT(R_NO_MEMORY);
|
||||
}
|
||||
}
|
||||
if ((r = GetAdaptersInfo(pAdapterInfo, &out_buf_len)) != NO_ERROR) {
|
||||
r_log(NR_LOG_STUN, LOG_ERR, "Got error from GetAdaptersInfo");
|
||||
ABORT(R_INTERNAL);
|
||||
}
|
||||
r_log(NR_LOG_STUN, LOG_DEBUG, "Got AdaptersInfo");
|
||||
|
||||
pAdapter = pAdapterInfo;
|
||||
|
||||
while (pAdapter) {
|
||||
char *c;
|
||||
|
||||
r_log(NR_LOG_STUN, LOG_DEBUG, "Adapter Name (GUID) = %s", pAdapter->AdapterName);
|
||||
r_log(NR_LOG_STUN, LOG_DEBUG, "Adapter Description = %s", pAdapter->Description);
|
||||
|
||||
if (nr_win32_get_adapter_friendly_name(pAdapter->AdapterName, &friendly_name)) {
|
||||
friendly_name = 0;
|
||||
}
|
||||
if (friendly_name && *friendly_name) {
|
||||
r_log(NR_LOG_STUN, LOG_INFO, "Found adapter with friendly name: %s", friendly_name);
|
||||
snprintf(munged_ifname, IFNAMSIZ, "%s%c", friendly_name, 0);
|
||||
RFREE(friendly_name);
|
||||
friendly_name = 0;
|
||||
} else {
|
||||
// Not all adapters follow the friendly name convention. Windows' PPTP
|
||||
// VPN adapter puts "VPN Connection 2" in the Description field instead.
|
||||
// Windows's renaming-logic appears to enforce uniqueness in spite of this.
|
||||
r_log(NR_LOG_STUN, LOG_INFO, "Found adapter with description: %s", pAdapter->Description);
|
||||
snprintf(munged_ifname, IFNAMSIZ, "%s%c", pAdapter->Description, 0);
|
||||
}
|
||||
/* replace spaces with underscores */
|
||||
c = strchr(munged_ifname, ' ');
|
||||
while (c != NULL) {
|
||||
*c = '_';
|
||||
c = strchr(munged_ifname, ' ');
|
||||
}
|
||||
c = strchr(munged_ifname, '.');
|
||||
while (c != NULL) {
|
||||
*c = '+';
|
||||
c = strchr(munged_ifname, '.');
|
||||
}
|
||||
|
||||
r_log(NR_LOG_STUN, LOG_INFO, "Converted ifname: %s", munged_ifname);
|
||||
|
||||
for (pAddrString = &(pAdapter->IpAddressList); pAddrString != NULL; pAddrString = pAddrString->Next) {
|
||||
unsigned long this_addr = inet_addr(pAddrString->IpAddress.String);
|
||||
nr_transport_addr *addr = &(addrs[n].addr);
|
||||
|
||||
if (this_addr == 0)
|
||||
continue;
|
||||
|
||||
r_log(NR_LOG_STUN, LOG_INFO, "Adapter %s address: %s", munged_ifname, pAddrString->IpAddress.String);
|
||||
|
||||
addr->ip_version=NR_IPV4;
|
||||
addr->protocol = IPPROTO_UDP;
|
||||
|
||||
addr->u.addr4.sin_family=PF_INET;
|
||||
addr->u.addr4.sin_port=0;
|
||||
addr->u.addr4.sin_addr.s_addr=this_addr;
|
||||
addr->addr=(struct sockaddr *)&(addr->u.addr4);
|
||||
addr->addr_len=sizeof(struct sockaddr_in);
|
||||
|
||||
strlcpy(addr->ifname, munged_ifname, sizeof(addr->ifname));
|
||||
snprintf(addr->as_string,40,"IP4:%s:%d",
|
||||
inet_ntoa(addr->u.addr4.sin_addr),
|
||||
ntohs(addr->u.addr4.sin_port));
|
||||
|
||||
/* TODO: (Bug 895793) Getting interface properties for Windows */
|
||||
addrs[n].interface.type = NR_INTERFACE_TYPE_UNKNOWN;
|
||||
addrs[n].interface.estimated_speed = 0;
|
||||
|
||||
if (++n >= maxaddrs)
|
||||
goto done;
|
||||
}
|
||||
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
|
||||
done:
|
||||
*count = n;
|
||||
_status = 0;
|
||||
|
||||
abort:
|
||||
RFREE(pAdapterInfo);
|
||||
RFREE(friendly_name);
|
||||
return _status;
|
||||
}
|
||||
|
||||
#ifdef GET_WIN32_ADDRS_NO_WIN2K
|
||||
/* Here's a nice way to get adapter addresses and names, but it
|
||||
* isn't supported on Win2000.
|
||||
*/
|
||||
static int
|
||||
stun_get_win32_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
@ -505,7 +161,7 @@ stun_get_win32_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
|
||||
buflen = 0;
|
||||
|
||||
r = GetAdaptersAddresses(AF_INET, 0, NULL, AdapterAddresses, &buflen);
|
||||
r = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, AdapterAddresses, &buflen);
|
||||
if (r != ERROR_BUFFER_OVERFLOW) {
|
||||
r_log(NR_LOG_STUN, LOG_ERR, "Error getting buf len from GetAdaptersAddresses()");
|
||||
ABORT(R_INTERNAL);
|
||||
@ -519,7 +175,7 @@ stun_get_win32_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
|
||||
/* for real, this time */
|
||||
|
||||
r = GetAdaptersAddresses(AF_INET, 0, NULL, AdapterAddresses, &buflen);
|
||||
r = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, AdapterAddresses, &buflen);
|
||||
if (r != NO_ERROR) {
|
||||
r_log(NR_LOG_STUN, LOG_ERR, "Error getting addresses from GetAdaptersAddresses()");
|
||||
ABORT(R_INTERNAL);
|
||||
@ -554,7 +210,7 @@ stun_get_win32_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
|
||||
if ((sa_addr->lpSockaddr->sa_family == AF_INET) ||
|
||||
(sa_addr->lpSockaddr->sa_family == AF_INET6)) {
|
||||
if ((r=nr_sockaddr_to_transport_addr((struct sockaddr*)sa_addr->lpSockaddr, sizeof(*sa_addr->lpSockaddr), IPPROTO_UDP, 0, &(addrs[n].addr))))
|
||||
if ((r=nr_sockaddr_to_transport_addr((struct sockaddr*)sa_addr->lpSockaddr, IPPROTO_UDP, 0, &(addrs[n].addr))))
|
||||
ABORT(r);
|
||||
}
|
||||
else {
|
||||
@ -580,131 +236,98 @@ stun_get_win32_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
RFREE(AdapterAddresses);
|
||||
return _status;
|
||||
}
|
||||
#endif /* GET_WIN32_ADDRS_NO_WIN2K */
|
||||
|
||||
#elif defined(__sparc__)
|
||||
#else /* WIN32 */
|
||||
|
||||
static int
|
||||
stun_get_sparc_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
*count = 0;
|
||||
UNIMPLEMENTED; /*TODO !nn! - sparc */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
nr_stun_is_duplicate_addr(nr_local_addr addrs[], int count, nr_local_addr *addr);
|
||||
|
||||
static int
|
||||
stun_get_siocgifconf_addrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
stun_getifaddrs(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
{
|
||||
struct ifconf ifc;
|
||||
int _status;
|
||||
int s = socket( AF_INET, SOCK_DGRAM, 0 );
|
||||
int len = 100 * sizeof(struct ifreq);
|
||||
int r;
|
||||
int e;
|
||||
char *ptr;
|
||||
int tl;
|
||||
int n;
|
||||
struct ifreq ifr2;
|
||||
int r,_status;
|
||||
struct ifaddrs* if_addrs_head=NULL;
|
||||
struct ifaddrs* if_addr;
|
||||
|
||||
char buf[ len ];
|
||||
*count=0;
|
||||
|
||||
ifc.ifc_len = len;
|
||||
ifc.ifc_buf = buf;
|
||||
if (getifaddrs(&if_addrs_head) == -1) {
|
||||
r_log(NR_LOG_STUN, LOG_ERR, "getifaddrs error e = %d", errno);
|
||||
ABORT(R_INTERNAL);
|
||||
}
|
||||
|
||||
e = ioctl(s,SIOCGIFCONF,&ifc);
|
||||
if_addr = if_addrs_head;
|
||||
|
||||
if ( e == -1 )
|
||||
{
|
||||
return(R_INTERNAL);
|
||||
}
|
||||
|
||||
ptr = buf;
|
||||
tl = ifc.ifc_len;
|
||||
n=0;
|
||||
|
||||
while ( (tl > 0) && ( n < maxaddrs) )
|
||||
{
|
||||
struct ifreq* ifr = (struct ifreq *)ptr;
|
||||
|
||||
#ifdef LINUX
|
||||
int si = sizeof(struct ifreq);
|
||||
#ifndef ANDROID
|
||||
struct ethtool_cmd ecmd;
|
||||
struct iwreq wrq;
|
||||
#endif
|
||||
#else
|
||||
int si = sizeof(ifr->ifr_name) + MAX(ifr->ifr_addr.sa_len, sizeof(ifr->ifr_addr));
|
||||
#endif
|
||||
tl -= si;
|
||||
ptr += si;
|
||||
|
||||
ifr2 = *ifr;
|
||||
|
||||
e = ioctl(s,SIOCGIFADDR,&ifr2);
|
||||
if ( e == -1 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//r_log(NR_LOG_STUN, LOG_ERR, "ioctl addr e = %d",e);
|
||||
|
||||
if ((r=nr_sockaddr_to_transport_addr(&ifr2.ifr_addr, sizeof(ifr2.ifr_addr), IPPROTO_UDP, 0, &(addrs[n].addr)))) {
|
||||
r_log(NR_LOG_STUN, LOG_WARNING, "Problem transforming address");
|
||||
}
|
||||
else {
|
||||
addrs[n].interface.type = NR_INTERFACE_TYPE_UNKNOWN;
|
||||
addrs[n].interface.estimated_speed = 0;
|
||||
while (if_addr && *count < maxaddrs) {
|
||||
switch (if_addr->ifa_addr->sa_family) {
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
if (r=nr_sockaddr_to_transport_addr(if_addr->ifa_addr, IPPROTO_UDP, 0, &(addrs[*count].addr))) {
|
||||
r_log(NR_LOG_STUN, LOG_ERR, "nr_sockaddr_to_transport_addr error r = %d", r);
|
||||
} else {
|
||||
#if defined(LINUX) && !defined(ANDROID)
|
||||
struct ethtool_cmd ecmd;
|
||||
struct ifreq ifr;
|
||||
struct iwreq wrq;
|
||||
int e;
|
||||
int s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
strncpy(ifr.ifr_name, if_addr->ifa_name, sizeof(ifr.ifr_name));
|
||||
/* TODO (Bug 896851): interface property for Android */
|
||||
/* Getting ethtool for ethernet information. */
|
||||
ecmd.cmd = ETHTOOL_GSET;
|
||||
ifr2.ifr_data = (void*)&ecmd;
|
||||
e = ioctl(s, SIOCETHTOOL, &ifr2);
|
||||
/* In/out param */
|
||||
ifr.ifr_data = (void*)&ecmd;
|
||||
|
||||
e = ioctl(s, SIOCETHTOOL, &ifr);
|
||||
if (e == 0)
|
||||
{
|
||||
/* For wireless network, we won't get ethtool, it's a wired
|
||||
connection */
|
||||
addrs[n].interface.type = NR_INTERFACE_TYPE_WIRED;
|
||||
* connection */
|
||||
addrs[*count].interface.type = NR_INTERFACE_TYPE_WIRED;
|
||||
#ifdef DONT_HAVE_ETHTOOL_SPEED_HI
|
||||
addrs[n].interface.estimated_speed = ecmd.speed;
|
||||
addrs[*count].interface.estimated_speed = ecmd.speed;
|
||||
#else
|
||||
addrs[n].interface.estimated_speed = ((ecmd.speed_hi << 16) | ecmd.speed) * 1000;
|
||||
addrs[*count].interface.estimated_speed = ((ecmd.speed_hi << 16) | ecmd.speed) * 1000;
|
||||
#endif
|
||||
}
|
||||
|
||||
strncpy(wrq.ifr_name, ifr->ifr_name, sizeof(wrq.ifr_name));
|
||||
strncpy(wrq.ifr_name, if_addr->ifa_name, sizeof(wrq.ifr_name));
|
||||
e = ioctl(s, SIOCGIWRATE, &wrq);
|
||||
if (e == 0)
|
||||
{
|
||||
addrs[n].interface.type = NR_INTERFACE_TYPE_WIFI;
|
||||
addrs[n].interface.estimated_speed = wrq.u.bitrate.value / 1000;
|
||||
addrs[*count].interface.type = NR_INTERFACE_TYPE_WIFI;
|
||||
addrs[*count].interface.estimated_speed = wrq.u.bitrate.value / 1000;
|
||||
}
|
||||
|
||||
ifr2 = *ifr;
|
||||
e = ioctl(s, SIOCGIFFLAGS, &ifr2);
|
||||
if (e == 0)
|
||||
if (if_addr->ifa_flags & IFF_POINTOPOINT)
|
||||
{
|
||||
if (ifr2.ifr_flags & IFF_POINTOPOINT)
|
||||
{
|
||||
addrs[n].interface.type = NR_INTERFACE_TYPE_UNKNOWN | NR_INTERFACE_TYPE_VPN;
|
||||
/* TODO (Bug 896913): find backend network type of this VPN */
|
||||
}
|
||||
addrs[*count].interface.type = NR_INTERFACE_TYPE_UNKNOWN | NR_INTERFACE_TYPE_VPN;
|
||||
/* TODO (Bug 896913): find backend network type of this VPN */
|
||||
}
|
||||
#else
|
||||
addrs[*count].interface.type = NR_INTERFACE_TYPE_UNKNOWN;
|
||||
addrs[*count].interface.estimated_speed = 0;
|
||||
#endif
|
||||
strlcpy(addrs[n].addr.ifname, ifr->ifr_name, sizeof(addrs[n].addr.ifname));
|
||||
++n;
|
||||
}
|
||||
}
|
||||
strlcpy(addrs[*count].addr.ifname, if_addr->ifa_name, sizeof(addrs[*count].addr.ifname));
|
||||
++(*count);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
close(s);
|
||||
if_addr = if_addr->ifa_next;
|
||||
}
|
||||
|
||||
*count = n;
|
||||
|
||||
_status = 0;
|
||||
return _status;
|
||||
_status=0;
|
||||
abort:
|
||||
if (if_addrs_head) {
|
||||
freeifaddrs(if_addrs_head);
|
||||
}
|
||||
return(_status);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int
|
||||
@ -724,7 +347,7 @@ nr_stun_is_duplicate_addr(nr_local_addr addrs[], int count, nr_local_addr *addr)
|
||||
}
|
||||
|
||||
int
|
||||
nr_stun_remove_duplicate_addrs(nr_local_addr addrs[], int remove_loopback, int *count)
|
||||
nr_stun_remove_duplicate_addrs(nr_local_addr addrs[], int remove_loopback, int remove_link_local, int *count)
|
||||
{
|
||||
int r, _status;
|
||||
nr_local_addr *tmp = 0;
|
||||
@ -743,6 +366,11 @@ nr_stun_remove_duplicate_addrs(nr_local_addr addrs[], int remove_loopback, int *
|
||||
else if (remove_loopback && nr_transport_addr_is_loopback(&addrs[i].addr)) {
|
||||
/* skip addrs[i], it's a loopback */
|
||||
}
|
||||
else if (remove_link_local &&
|
||||
addrs[i].addr.ip_version == NR_IPV6 &&
|
||||
nr_transport_addr_is_link_local(&addrs[i].addr)) {
|
||||
/* skip addrs[i], it's a link-local address */
|
||||
}
|
||||
else {
|
||||
/* otherwise, copy it to the temporary array */
|
||||
if ((r=nr_local_addr_copy(&tmp[n], &addrs[i])))
|
||||
@ -768,23 +396,19 @@ nr_stun_remove_duplicate_addrs(nr_local_addr addrs[], int remove_loopback, int *
|
||||
#ifndef USE_PLATFORM_NR_STUN_GET_ADDRS
|
||||
|
||||
int
|
||||
nr_stun_get_addrs(nr_local_addr addrs[], int maxaddrs, int drop_loopback, int *count)
|
||||
nr_stun_get_addrs(nr_local_addr addrs[], int maxaddrs, int drop_loopback, int drop_link_local, int *count)
|
||||
{
|
||||
int _status=0;
|
||||
int i;
|
||||
char typestr[100];
|
||||
|
||||
#if defined(BSD) || defined(DARWIN)
|
||||
_status = stun_get_mib_addrs(addrs, maxaddrs, count);
|
||||
#elif defined(WIN32)
|
||||
#ifdef WIN32
|
||||
_status = stun_get_win32_addrs(addrs, maxaddrs, count);
|
||||
#elif defined(__sparc__)
|
||||
_status = stun_get_sparc_addrs(addrs, maxaddrs, count);
|
||||
#else
|
||||
_status = stun_get_siocgifconf_addrs(addrs, maxaddrs, count);
|
||||
_status = stun_getifaddrs(addrs, maxaddrs, count);
|
||||
#endif
|
||||
|
||||
nr_stun_remove_duplicate_addrs(addrs, drop_loopback, count);
|
||||
nr_stun_remove_duplicate_addrs(addrs, drop_loopback, drop_link_local, count);
|
||||
|
||||
for (i = 0; i < *count; ++i) {
|
||||
nr_local_addr_fmt_info_string(addrs+i,typestr,sizeof(typestr));
|
||||
|
@ -37,7 +37,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "transport_addr.h"
|
||||
#include "local_addr.h"
|
||||
|
||||
int nr_stun_get_addrs(nr_local_addr addrs[], int maxaddrs, int remove_loopback, int *count);
|
||||
int nr_stun_remove_duplicate_addrs(nr_local_addr addrs[], int remove_loopback,int *count);
|
||||
int nr_stun_get_addrs(nr_local_addr addrs[], int maxaddrs, int remove_loopback, int remove_link_local, int *count);
|
||||
int nr_stun_remove_duplicate_addrs(nr_local_addr addrs[], int remove_loopback, int remove_link_local, int *count);
|
||||
|
||||
#endif
|
||||
|
242
media/mtransport/third_party/nICEr/src/stun/ifaddrs-android.c
vendored
Normal file
242
media/mtransport/third_party/nICEr/src/stun/ifaddrs-android.c
vendored
Normal file
@ -0,0 +1,242 @@
|
||||
/*
|
||||
Copyright (c) 2011, The WebRTC project authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of Google nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(ANDROID)
|
||||
#include "ifaddrs-android.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
struct netlinkrequest {
|
||||
struct nlmsghdr header;
|
||||
struct ifaddrmsg msg;
|
||||
};
|
||||
|
||||
static const int kMaxReadSize = 4096;
|
||||
|
||||
static int set_ifname(struct ifaddrs* ifaddr, int interface) {
|
||||
char buf[IFNAMSIZ] = {0};
|
||||
char* name = if_indextoname(interface, buf);
|
||||
if (name == NULL) {
|
||||
return -1;
|
||||
}
|
||||
ifaddr->ifa_name = malloc(strlen(name) + 1);
|
||||
strncpy(ifaddr->ifa_name, name, strlen(name) + 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_flags(struct ifaddrs* ifaddr) {
|
||||
int fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd == -1) {
|
||||
return -1;
|
||||
}
|
||||
struct ifreq ifr;
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
strncpy(ifr.ifr_name, ifaddr->ifa_name, IFNAMSIZ - 1);
|
||||
int rc = ioctl(fd, SIOCGIFFLAGS, &ifr);
|
||||
close(fd);
|
||||
if (rc == -1) {
|
||||
return -1;
|
||||
}
|
||||
ifaddr->ifa_flags = ifr.ifr_flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_addresses(struct ifaddrs* ifaddr, struct ifaddrmsg* msg, void* data,
|
||||
size_t len) {
|
||||
if (msg->ifa_family == AF_INET) {
|
||||
struct sockaddr_in* sa = malloc(sizeof(struct sockaddr_in));
|
||||
memset(sa, 0, sizeof(struct sockaddr_in));
|
||||
sa->sin_family = AF_INET;
|
||||
memcpy(&sa->sin_addr, data, len);
|
||||
ifaddr->ifa_addr = (struct sockaddr*)sa;
|
||||
} else if (msg->ifa_family == AF_INET6) {
|
||||
struct sockaddr_in6* sa = malloc(sizeof(struct sockaddr_in6));
|
||||
memset(sa, 0, sizeof(struct sockaddr_in6));
|
||||
sa->sin6_family = AF_INET6;
|
||||
sa->sin6_scope_id = msg->ifa_index;
|
||||
memcpy(&sa->sin6_addr, data, len);
|
||||
ifaddr->ifa_addr = (struct sockaddr*)sa;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int make_prefixes(struct ifaddrs* ifaddr, int family, int prefixlen) {
|
||||
char* prefix = NULL;
|
||||
if (family == AF_INET) {
|
||||
struct sockaddr_in* mask = malloc(sizeof(struct sockaddr_in));
|
||||
memset(mask, 0, sizeof(struct sockaddr_in));
|
||||
mask->sin_family = AF_INET;
|
||||
memset(&mask->sin_addr, 0, sizeof(struct in_addr));
|
||||
ifaddr->ifa_netmask = (struct sockaddr*)mask;
|
||||
if (prefixlen > 32) {
|
||||
prefixlen = 32;
|
||||
}
|
||||
prefix = (char*)&mask->sin_addr;
|
||||
} else if (family == AF_INET6) {
|
||||
struct sockaddr_in6* mask = malloc(sizeof(struct sockaddr_in6));
|
||||
memset(mask, 0, sizeof(struct sockaddr_in6));
|
||||
mask->sin6_family = AF_INET6;
|
||||
memset(&mask->sin6_addr, 0, sizeof(struct in6_addr));
|
||||
ifaddr->ifa_netmask = (struct sockaddr*)mask;
|
||||
if (prefixlen > 128) {
|
||||
prefixlen = 128;
|
||||
}
|
||||
prefix = (char*)&mask->sin6_addr;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < (prefixlen / 8); i++) {
|
||||
*prefix++ = 0xFF;
|
||||
}
|
||||
char remainder = 0xff;
|
||||
remainder <<= (8 - prefixlen % 8);
|
||||
*prefix = remainder;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int populate_ifaddrs(struct ifaddrs* ifaddr, struct ifaddrmsg* msg, void* bytes,
|
||||
size_t len) {
|
||||
if (set_ifname(ifaddr, msg->ifa_index) != 0) {
|
||||
return -1;
|
||||
}
|
||||
if (set_flags(ifaddr) != 0) {
|
||||
return -1;
|
||||
}
|
||||
if (set_addresses(ifaddr, msg, bytes, len) != 0) {
|
||||
return -1;
|
||||
}
|
||||
if (make_prefixes(ifaddr, msg->ifa_family, msg->ifa_prefixlen) != 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int android_getifaddrs(struct ifaddrs** result) {
|
||||
int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct netlinkrequest ifaddr_request;
|
||||
memset(&ifaddr_request, 0, sizeof(ifaddr_request));
|
||||
ifaddr_request.header.nlmsg_flags = NLM_F_ROOT | NLM_F_REQUEST;
|
||||
ifaddr_request.header.nlmsg_type = RTM_GETADDR;
|
||||
ifaddr_request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
|
||||
|
||||
ssize_t count = send(fd, &ifaddr_request, ifaddr_request.header.nlmsg_len, 0);
|
||||
if ((size_t)count != ifaddr_request.header.nlmsg_len) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
struct ifaddrs* start = NULL;
|
||||
struct ifaddrs* current = NULL;
|
||||
char buf[kMaxReadSize];
|
||||
ssize_t amount_read = recv(fd, &buf, kMaxReadSize, 0);
|
||||
while (amount_read > 0) {
|
||||
struct nlmsghdr* header = (struct nlmsghdr*)&buf[0];
|
||||
size_t header_size = (size_t)amount_read;
|
||||
for ( ; NLMSG_OK(header, header_size);
|
||||
header = NLMSG_NEXT(header, header_size)) {
|
||||
switch (header->nlmsg_type) {
|
||||
case NLMSG_DONE:
|
||||
/* Success. Return. */
|
||||
*result = start;
|
||||
close(fd);
|
||||
return 0;
|
||||
case NLMSG_ERROR:
|
||||
close(fd);
|
||||
android_freeifaddrs(start);
|
||||
return -1;
|
||||
case RTM_NEWADDR: {
|
||||
struct ifaddrmsg* address_msg =
|
||||
(struct ifaddrmsg*)NLMSG_DATA(header);
|
||||
struct rtattr* rta = IFA_RTA(address_msg);
|
||||
ssize_t payload_len = IFA_PAYLOAD(header);
|
||||
while (RTA_OK(rta, payload_len)) {
|
||||
if (rta->rta_type == IFA_ADDRESS) {
|
||||
int family = address_msg->ifa_family;
|
||||
if (family == AF_INET || family == AF_INET6) {
|
||||
struct ifaddrs* newest = malloc(sizeof(struct ifaddrs));
|
||||
memset(newest, 0, sizeof(struct ifaddrs));
|
||||
if (current) {
|
||||
current->ifa_next = newest;
|
||||
} else {
|
||||
start = newest;
|
||||
}
|
||||
if (populate_ifaddrs(newest, address_msg, RTA_DATA(rta),
|
||||
RTA_PAYLOAD(rta)) != 0) {
|
||||
android_freeifaddrs(start);
|
||||
*result = NULL;
|
||||
return -1;
|
||||
}
|
||||
current = newest;
|
||||
}
|
||||
}
|
||||
rta = RTA_NEXT(rta, payload_len);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
amount_read = recv(fd, &buf, kMaxReadSize, 0);
|
||||
}
|
||||
close(fd);
|
||||
android_freeifaddrs(start);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void android_freeifaddrs(struct ifaddrs* addrs) {
|
||||
struct ifaddrs* last = NULL;
|
||||
struct ifaddrs* cursor = addrs;
|
||||
while (cursor) {
|
||||
free(cursor->ifa_name);
|
||||
free(cursor->ifa_addr);
|
||||
free(cursor->ifa_netmask);
|
||||
last = cursor;
|
||||
cursor = cursor->ifa_next;
|
||||
free(last);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* defined(ANDROID) */
|
57
media/mtransport/third_party/nICEr/src/stun/ifaddrs-android.h
vendored
Normal file
57
media/mtransport/third_party/nICEr/src/stun/ifaddrs-android.h
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
Copyright (c) 2011, The WebRTC project authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of Google nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef WEBRTC_BASE_IFADDRS_ANDROID_H_
|
||||
#define WEBRTC_BASE_IFADDRS_ANDROID_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
/* Implementation of getifaddrs for Android.
|
||||
* Fills out a list of ifaddr structs (see below) which contain information
|
||||
* about every network interface available on the host.
|
||||
* See 'man getifaddrs' on Linux or OS X (nb: it is not a POSIX function). */
|
||||
struct ifaddrs {
|
||||
struct ifaddrs* ifa_next;
|
||||
char* ifa_name;
|
||||
unsigned int ifa_flags;
|
||||
struct sockaddr* ifa_addr;
|
||||
struct sockaddr* ifa_netmask;
|
||||
/* Real ifaddrs has broadcast, point to point and data members.
|
||||
* We don't need them (yet?). */
|
||||
};
|
||||
|
||||
int android_getifaddrs(struct ifaddrs** result);
|
||||
void android_freeifaddrs(struct ifaddrs* addrs);
|
||||
|
||||
#endif /* WEBRTC_BASE_IFADDRS_ANDROID_H_ */
|
||||
|
@ -446,9 +446,15 @@ nr_stun_attr_codec_addr_encode(nr_stun_attr_info *attr_info, void *data, int off
|
||||
break;
|
||||
|
||||
case NR_IPV6:
|
||||
assert(0);
|
||||
ABORT(R_INTERNAL);
|
||||
family = NR_STUN_IPV6_FAMILY;
|
||||
if (nr_stun_encode_htons(20 , buflen, buf, &offset)
|
||||
|| nr_stun_encode(&pad, 1 , buflen, buf, &offset)
|
||||
|| nr_stun_encode(&family, 1 , buflen, buf, &offset)
|
||||
|| nr_stun_encode_htons(ntohs(addr->u.addr6.sin6_port), buflen, buf, &offset)
|
||||
|| nr_stun_encode(addr->u.addr6.sin6_addr.s6_addr, 16, buflen, buf, &offset))
|
||||
ABORT(R_FAILED);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
ABORT(R_INTERNAL);
|
||||
@ -470,6 +476,7 @@ nr_stun_attr_codec_addr_decode(nr_stun_attr_info *attr_info, int attrlen, UCHAR
|
||||
UCHAR family;
|
||||
UINT2 port;
|
||||
UINT4 addr4;
|
||||
struct in6_addr addr6;
|
||||
nr_transport_addr *result = data;
|
||||
|
||||
if (nr_stun_decode(1, buf, buflen, &offset, &pad)
|
||||
@ -492,17 +499,17 @@ nr_stun_attr_codec_addr_decode(nr_stun_attr_info *attr_info, int attrlen, UCHAR
|
||||
break;
|
||||
|
||||
case NR_STUN_IPV6_FAMILY:
|
||||
if (attrlen != 16) {
|
||||
if (attrlen != 20) {
|
||||
r_log(NR_LOG_STUN, LOG_WARNING, "Illegal attribute length: %d", attrlen);
|
||||
ABORT(R_FAILED);
|
||||
}
|
||||
|
||||
r_log(NR_LOG_STUN, LOG_WARNING, "IPv6 not supported");
|
||||
#ifdef NDEBUG
|
||||
ABORT(SKIP_ATTRIBUTE_DECODE);
|
||||
#else
|
||||
UNIMPLEMENTED;
|
||||
#endif /* NDEBUG */
|
||||
if (nr_stun_decode_htons(buf, buflen, &offset, &port)
|
||||
|| nr_stun_decode(16, buf, buflen, &offset, addr6.s6_addr))
|
||||
ABORT(R_FAILED);
|
||||
|
||||
if (nr_ip6_port_to_transport_addr(&addr6, port, IPPROTO_UDP, result))
|
||||
ABORT(R_FAILED);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1094,7 +1101,7 @@ nr_stun_attr_codec_xor_mapped_address_encode(nr_stun_attr_info *attr_info, void
|
||||
* message ID for this */
|
||||
magic_cookie = ntohl(header->magic_cookie);
|
||||
|
||||
nr_stun_xor_mapped_address(magic_cookie, &xor_mapped_address->unmasked, &xor_mapped_address->masked);
|
||||
nr_stun_xor_mapped_address(magic_cookie, header->id, &xor_mapped_address->unmasked, &xor_mapped_address->masked);
|
||||
|
||||
r_log(NR_LOG_STUN, LOG_DEBUG, "Masked XOR-MAPPED-ADDRESS = %s", xor_mapped_address->masked.as_string);
|
||||
|
||||
@ -1123,7 +1130,7 @@ nr_stun_attr_codec_xor_mapped_address_decode(nr_stun_attr_info *attr_info, int a
|
||||
* message ID for this */
|
||||
magic_cookie = ntohl(header->magic_cookie);
|
||||
|
||||
nr_stun_xor_mapped_address(magic_cookie, &xor_mapped_address->masked, &xor_mapped_address->unmasked);
|
||||
nr_stun_xor_mapped_address(magic_cookie, header->id, &xor_mapped_address->masked, &xor_mapped_address->unmasked);
|
||||
|
||||
r_log(NR_LOG_STUN, LOG_DEBUG, "Unmasked XOR-MAPPED-ADDRESS = %s", xor_mapped_address->unmasked.as_string);
|
||||
|
||||
|
@ -45,6 +45,7 @@ extern "C" {
|
||||
#define NR_STUN_REG_PREF_CLNT_FINAL_RETRANSMIT_BACKOFF "stun.client.final_retransmit_backoff"
|
||||
|
||||
#define NR_STUN_REG_PREF_ALLOW_LOOPBACK_ADDRS "stun.allow_loopback"
|
||||
#define NR_STUN_REG_PREF_ALLOW_LINK_LOCAL_ADDRS "stun.allow_link_local"
|
||||
#define NR_STUN_REG_PREF_ADDRESS_PRFX "stun.address"
|
||||
#define NR_STUN_REG_PREF_SERVER_NAME "stun.server.name"
|
||||
#define NR_STUN_REG_PREF_SERVER_NONCE_SIZE "stun.server.nonce_size"
|
||||
|
@ -71,7 +71,7 @@ nr_stun_startup(void)
|
||||
}
|
||||
|
||||
int
|
||||
nr_stun_xor_mapped_address(UINT4 magicCookie, nr_transport_addr *from, nr_transport_addr *to)
|
||||
nr_stun_xor_mapped_address(UINT4 magicCookie, UINT12 transactionId, nr_transport_addr *from, nr_transport_addr *to)
|
||||
{
|
||||
int _status;
|
||||
|
||||
@ -83,8 +83,26 @@ nr_stun_xor_mapped_address(UINT4 magicCookie, nr_transport_addr *from, nr_transp
|
||||
from->protocol, to);
|
||||
break;
|
||||
case NR_IPV6:
|
||||
assert(0);
|
||||
ABORT(R_INTERNAL);
|
||||
{
|
||||
union {
|
||||
unsigned char addr[16];
|
||||
UINT4 addr32[4];
|
||||
} maskedAddr;
|
||||
|
||||
maskedAddr.addr32[0] = htonl(magicCookie); /* Passed in host byte order */
|
||||
memcpy(&maskedAddr.addr32[1], transactionId.octet, sizeof(transactionId));
|
||||
|
||||
/* We now have the mask in network byte order */
|
||||
/* Xor the address in network byte order */
|
||||
for (int i = 0; i < sizeof(maskedAddr); ++i) {
|
||||
maskedAddr.addr[i] ^= from->u.addr6.sin6_addr.s6_addr[i];
|
||||
}
|
||||
|
||||
nr_ip6_port_to_transport_addr(
|
||||
(struct in6_addr*)&maskedAddr,
|
||||
(ntohs(from->u.addr6.sin6_port) ^ (magicCookie>>16)),
|
||||
from->protocol, to);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
@ -111,6 +129,7 @@ nr_stun_find_local_addresses(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
|
||||
if (*count == 0) {
|
||||
char allow_loopback;
|
||||
char allow_link_local;
|
||||
|
||||
if ((r=NR_reg_get_char(NR_STUN_REG_PREF_ALLOW_LOOPBACK_ADDRS, &allow_loopback))) {
|
||||
if (r == R_NOT_FOUND)
|
||||
@ -119,7 +138,14 @@ nr_stun_find_local_addresses(nr_local_addr addrs[], int maxaddrs, int *count)
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
if ((r=nr_stun_get_addrs(addrs, maxaddrs, !allow_loopback, count)))
|
||||
if ((r=NR_reg_get_char(NR_STUN_REG_PREF_ALLOW_LINK_LOCAL_ADDRS, &allow_link_local))) {
|
||||
if (r == R_NOT_FOUND)
|
||||
allow_link_local = 0;
|
||||
else
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
if ((r=nr_stun_get_addrs(addrs, maxaddrs, !allow_loopback, !allow_link_local, count)))
|
||||
ABORT(r);
|
||||
|
||||
goto done;
|
||||
|
@ -42,7 +42,7 @@ extern int NR_LOG_STUN;
|
||||
|
||||
int nr_stun_startup(void);
|
||||
|
||||
int nr_stun_xor_mapped_address(UINT4 magicCookie, nr_transport_addr *from, nr_transport_addr *to);
|
||||
int nr_stun_xor_mapped_address(UINT4 magicCookie, UINT12 transactionId, nr_transport_addr *from, nr_transport_addr *to);
|
||||
|
||||
int nr_stun_find_local_addresses(nr_local_addr addrs[], int maxaddrs, int *count);
|
||||
|
||||
|
@ -724,6 +724,31 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
|
||||
}
|
||||
#endif /* INET6 */
|
||||
|
||||
#ifdef WIN32
|
||||
/* Not exactly, will forgive stuff like <addr>:<port> */
|
||||
int inet_pton(int af, const char *src, void *dst)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
int addrlen = sizeof(ss);
|
||||
|
||||
if (af != AF_INET && af != AF_INET6) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!WSAStringToAddressA(src, af, NULL, (struct sockaddr*)&ss, &addrlen)) {
|
||||
if (af == AF_INET) {
|
||||
struct sockaddr_in *in = (struct sockaddr_in*)&ss;
|
||||
memcpy(dst, &in->sin_addr, sizeof(struct in_addr));
|
||||
} else {
|
||||
struct sockaddr_in6 *in6 = (struct sockaddr_in6*)&ss;
|
||||
memcpy(dst, &in6->sin6_addr, sizeof(struct in6_addr));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* WIN32 */
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
|
@ -67,6 +67,7 @@ int nr_reg_uint8_fetch_and_check(NR_registry key, UINT8 min, UINT8 max, int log_
|
||||
#ifdef WIN32
|
||||
int snprintf(char *buffer, size_t n, const char *format, ...);
|
||||
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
|
||||
int inet_pton(int af, const char *src, void *dst);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -376,6 +376,7 @@ PeerConnectionImpl::PeerConnectionImpl(const GlobalObject* aGlobal)
|
||||
, mPrivacyRequested(false)
|
||||
, mSTSThread(nullptr)
|
||||
, mAllowIceLoopback(false)
|
||||
, mAllowIceLinkLocal(false)
|
||||
, mMedia(nullptr)
|
||||
, mUuidGen(MakeUnique<PCUuidGenerator>())
|
||||
, mNumAudioStreams(0)
|
||||
@ -397,6 +398,8 @@ PeerConnectionImpl::PeerConnectionImpl(const GlobalObject* aGlobal)
|
||||
#if !defined(MOZILLA_EXTERNAL_LINKAGE)
|
||||
mAllowIceLoopback = Preferences::GetBool(
|
||||
"media.peerconnection.ice.loopback", false);
|
||||
mAllowIceLinkLocal = Preferences::GetBool(
|
||||
"media.peerconnection.ice.link_local", false);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -732,7 +735,6 @@ PeerConnectionImpl::Initialize(PeerConnectionObserver& aObserver,
|
||||
}
|
||||
|
||||
mMedia = new PeerConnectionMedia(this);
|
||||
mMedia->SetAllowIceLoopback(mAllowIceLoopback);
|
||||
|
||||
// Connect ICE slots.
|
||||
mMedia->SignalIceGatheringStateChange.connect(
|
||||
|
@ -287,6 +287,11 @@ public:
|
||||
|
||||
// Configure the ability to use localhost.
|
||||
void SetAllowIceLoopback(bool val) { mAllowIceLoopback = val; }
|
||||
bool GetAllowIceLoopback() const { return mAllowIceLoopback; }
|
||||
|
||||
// Configure the ability to use IPV6 link-local addresses.
|
||||
void SetAllowIceLinkLocal(bool val) { mAllowIceLinkLocal = val; }
|
||||
bool GetAllowIceLinkLocal() const { return mAllowIceLinkLocal; }
|
||||
|
||||
// Handle system to allow weak references to be passed through C code
|
||||
virtual const std::string& GetHandle();
|
||||
@ -739,6 +744,7 @@ private:
|
||||
#endif
|
||||
|
||||
bool mAllowIceLoopback;
|
||||
bool mAllowIceLinkLocal;
|
||||
nsRefPtr<PeerConnectionMedia> mMedia;
|
||||
|
||||
// The JSEP negotiation session.
|
||||
|
@ -219,7 +219,6 @@ PeerConnectionMedia::PeerConnectionMedia(PeerConnectionImpl *parent)
|
||||
: mParent(parent),
|
||||
mParentHandle(parent->GetHandle()),
|
||||
mParentName(parent->GetName()),
|
||||
mAllowIceLoopback(false),
|
||||
mIceCtx(nullptr),
|
||||
mDNSResolver(new NrIceResolver()),
|
||||
mUuidGen(MakeUnique<PCUuidGenerator>()),
|
||||
@ -311,8 +310,9 @@ nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_serv
|
||||
mIceCtx = NrIceCtx::Create("PC:" + mParentName,
|
||||
true, // Offerer
|
||||
true, // Explicitly set priorities
|
||||
mAllowIceLoopback,
|
||||
ice_tcp);
|
||||
mParent->GetAllowIceLoopback(),
|
||||
ice_tcp,
|
||||
mParent->GetAllowIceLinkLocal());
|
||||
if(!mIceCtx) {
|
||||
CSFLogError(logTag, "%s: Failed to create Ice Context", __FUNCTION__);
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -232,9 +232,6 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||
// WARNING: This destroys the object!
|
||||
void SelfDestruct();
|
||||
|
||||
// Configure the ability to use localhost.
|
||||
void SetAllowIceLoopback(bool val) { mAllowIceLoopback = val; }
|
||||
|
||||
RefPtr<NrIceCtx> ice_ctx() const { return mIceCtx; }
|
||||
|
||||
RefPtr<NrIceMediaStream> ice_media_stream(size_t i) const {
|
||||
@ -491,9 +488,6 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
||||
|
||||
std::map<size_t, std::pair<bool, RefPtr<MediaSessionConduit>>> mConduits;
|
||||
|
||||
// Allow loopback for ICE.
|
||||
bool mAllowIceLoopback;
|
||||
|
||||
// ICE objects
|
||||
RefPtr<NrIceCtx> mIceCtx;
|
||||
|
||||
|
@ -286,6 +286,11 @@ public:
|
||||
SetAddress(const std::string& address)
|
||||
{
|
||||
mAddr = address;
|
||||
if (mAddr.find(':') != std::string::npos) {
|
||||
mAddrType = sdp::kIPv6;
|
||||
} else {
|
||||
mAddrType = sdp::kIPv4;
|
||||
}
|
||||
}
|
||||
uint8_t
|
||||
GetTtl() const
|
||||
|
@ -913,6 +913,7 @@ class SignalingAgent {
|
||||
PeerConnectionImpl::CreatePeerConnection();
|
||||
EXPECT_TRUE(pcImpl);
|
||||
pcImpl->SetAllowIceLoopback(true);
|
||||
pcImpl->SetAllowIceLinkLocal(true);
|
||||
pc = new PCDispatchWrapper(pcImpl);
|
||||
}
|
||||
|
||||
@ -4709,7 +4710,7 @@ int main(int argc, char **argv) {
|
||||
// Adds a listener to the end. Google Test takes the ownership.
|
||||
listeners.Append(new test::RingbufferDumper(test_utils));
|
||||
test_utils->sts_target()->Dispatch(
|
||||
WrapRunnableNM(&TestStunServer::GetInstance), NS_DISPATCH_SYNC);
|
||||
WrapRunnableNM(&TestStunServer::GetInstance, AF_INET), NS_DISPATCH_SYNC);
|
||||
|
||||
// Set the main thread global which is this thread.
|
||||
nsIThread *thread;
|
||||
|
@ -375,6 +375,7 @@ pref("media.navigator.permission.disabled", false);
|
||||
pref("media.peerconnection.default_iceservers", "[]");
|
||||
pref("media.peerconnection.ice.loopback", false); // Set only for testing in offline environments.
|
||||
pref("media.peerconnection.ice.tcp", false);
|
||||
pref("media.peerconnection.ice.link_local", false); // Set only for testing IPV6 in networks that don't assign IPV6 addresses
|
||||
pref("media.peerconnection.use_document_iceservers", true);
|
||||
pref("media.peerconnection.identity.enabled", true);
|
||||
pref("media.peerconnection.identity.timeout", 10000);
|
||||
|
Loading…
Reference in New Issue
Block a user