Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Working on new TransportTuple.hash implementation #839

Merged
merged 14 commits into from
Jun 21, 2022
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