/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <algorithm>
#include "mozilla/Assertions.h"
// nICEr includes
#include "local_addr.h"
#include "transport_addr.h"
// Local includes
#include "nricestunaddr.h"
template <typename T, size_t N>
static void StringToArray(
const nsTSubstring<T>& str, T (&array)[N]) {
const auto copied = str.View().copy(array, N -
1);
array[copied] =
'\0';
}
namespace mozilla {
NrIceStunAddr::NrIceStunAddr(
const nr_local_addr* addr)
: protocol_(protocolFromNrTransportAddr(addr->addr)),
address_(addressFromNrTransportAddr(addr->addr)),
ifname_(addr->addr.ifname),
fqdn_(addr->addr.fqdn),
is_proxied_(addr->addr.is_proxied),
tls_(addr->addr.tls),
interface_type_(static_cast<InterfaceType>(addr->interface.type)),
estimated_speed_(addr->interface.estimated_speed),
temporary_((addr->flags & NR_ADDR_FLAG_TEMPORARY) !=
0) {}
NrIceStunAddr::Protocol NrIceStunAddr::protocolFromNrTransportAddr(
const nr_transport_addr& addr) {
switch (addr.protocol) {
case 0:
return Protocol::None;
case IPPROTO_TCP:
return Protocol::TCP;
case IPPROTO_UDP:
return Protocol::UDP;
default:
MOZ_CRASH(
"invalid protocol");
}
}
decltype(NrIceStunAddr::address_) NrIceStunAddr::addressFromNrTransportAddr(
const nr_transport_addr& addr) {
switch (addr.ip_version) {
case NR_IPV4:
return AsVariant(
IPv4{addr.u.addr4.sin_addr.s_addr, addr.u.addr4.sin_port});
case NR_IPV6:
return AsVariant(IPv6{std::to_array(addr.u.addr6.sin6_addr.s6_addr),
addr.u.addr6.sin6_port, addr.u.addr6.sin6_flowinfo,
addr.u.addr6.sin6_scope_id});
default:
MOZ_CRASH(
"invalid IP version");
}
}
NrIceStunAddr::NrIceStunAddr(
const NrIceStunAddr& rhs) =
default;
NrIceStunAddr::~NrIceStunAddr() =
default;
void NrIceStunAddr::toNrLocalAddr(nr_local_addr& addr)
const {
memset(&addr,
0,
sizeof(nr_local_addr));
switch (protocol_) {
case Protocol::None:
break;
case Protocol::TCP:
addr.addr.protocol = IPPROTO_TCP;
break;
case Protocol::UDP:
addr.addr.protocol = IPPROTO_UDP;
break;
}
address_.match(
[&](
const IPv4& v4) {
addr.addr.ip_version = NR_IPV4;
auto& sockaddr = addr.addr.u.addr4;
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = v4.address;
sockaddr.sin_port = v4.port;
},
[&](
const IPv6& v6) {
addr.addr.ip_version = NR_IPV6;
auto& sockaddr = addr.addr.u.addr6;
sockaddr.sin6_family = AF_INET6;
std::copy(v6.address.begin(), v6.address.end(),
sockaddr.sin6_addr.s6_addr);
sockaddr.sin6_port = v6.port;
sockaddr.sin6_flowinfo = v6.flowinfo;
sockaddr.sin6_scope_id = v6.scope_id;
});
StringToArray(ifname_, addr.addr.ifname);
StringToArray(fqdn_, addr.addr.fqdn);
addr.addr.is_proxied = is_proxied_;
addr.addr.tls = tls_;
// generate as_string
nr_transport_addr_fmt_addr_string(&addr.addr);
addr.interface.type = static_cast<
int>(interface_type_);
addr.interface.estimated_speed = estimated_speed_;
if (temporary_) {
addr.flags |= NR_ADDR_FLAG_TEMPORARY;
}
}
}
// namespace mozilla