Skip to content
76 changes: 64 additions & 12 deletions worker/include/RTC/TransportTuple.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,26 +131,78 @@ namespace RTC
}

private:
/*
* Hash for IPv4
*
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| PORT | IP |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| IP | |F|P|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* Hash for IPv6
*
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| PORT | IP[0] ^ IP[1] ^ IP[2] ^ IP[3]|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|IP[0] ^ IP[1] ^ IP[2] ^ IP[3] | IP[0] >> 16 |F|P|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
void SetHash()
{
const std::string protocol = this->protocol == Protocol::UDP ? "udp" : "tcp";
int family;
std::string localIp;
uint16_t localPort;
std::string remoteIp;
uint16_t remotePort;
const struct sockaddr* remoteSockAddr = GetRemoteAddress();

Utils::IP::GetAddressInfo(GetLocalAddress(), family, localIp, localPort);
Utils::IP::GetAddressInfo(GetRemoteAddress(), family, remoteIp, remotePort);
switch (remoteSockAddr->sa_family)
{
case AF_INET:
{
auto* remoteSockAddrIn = reinterpret_cast<const struct sockaddr_in*>(remoteSockAddr);

std::string id = remoteIp + std::to_string(remotePort) + localIp + std::to_string(localPort) +
std::to_string(family) + protocol;
const uint64_t address = ntohl(remoteSockAddrIn->sin_addr.s_addr);
const uint64_t port = (ntohs(remoteSockAddrIn->sin_port));

this->hash = std::hash<std::string>{}(id);
this->hash = port << 48;
this->hash |= address << 16;
this->hash |= 0x0000; // AF_INET.

break;
}

case AF_INET6:
{
auto* remoteSockAddrIn6 = reinterpret_cast<const struct sockaddr_in6*>(remoteSockAddr);
auto* a = reinterpret_cast<const uint32_t*>(std::addressof(remoteSockAddrIn6->sin6_addr));

const auto address1 = a[0] ^ a[1] ^ a[2] ^ a[3];
const auto address2 = a[0];
const uint64_t port = ntohs(remoteSockAddrIn6->sin6_port);

this->hash = port << 48;
this->hash |= static_cast<uint64_t>(address1) << 16;
this->hash |= address2 >> 16 & 0xFFFC;
this->hash |= 0x0002; // AF_INET6.

break;
}
}

// Override least significant bit with protocol information:
// - If UDP, start with 0.
// - If TCP, start with 1.
if (this->protocol == Protocol::UDP)
{
this->hash |= 0x0000;
}
else
{
this->hash |= 0x0001;
}
}

public:
size_t hash;
uint64_t hash{ 0u };

private:
// Passed by argument.
Expand Down
2 changes: 1 addition & 1 deletion worker/include/RTC/WebRtcServer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ namespace RTC
// Map of WebRtcTransports indexed by local ICE usernameFragment.
absl::flat_hash_map<std::string, RTC::WebRtcTransport*> mapLocalIceUsernameFragmentWebRtcTransport;
// Map of WebRtcTransports indexed by TransportTuple.hash.
absl::flat_hash_map<size_t, RTC::WebRtcTransport*> mapTupleWebRtcTransport;
absl::flat_hash_map<uint64_t, RTC::WebRtcTransport*> mapTupleWebRtcTransport;
};
} // namespace RTC

Expand Down