From 725e99bb9c49fdee7866f8521f2e33bd41486c33 Mon Sep 17 00:00:00 2001 From: Lukas Werling Date: Sat, 7 Jan 2017 17:18:06 +0100 Subject: [PATCH] Convert addresses from puncher to IPv4 Addresses from the puncher would show as [::ffff:1.2.3.4] and be a bit confusing. --- src/network/C4NetIO.cpp | 16 ++++++++++++++++ src/network/C4NetIO.h | 2 ++ src/network/C4Network2IO.cpp | 9 ++++----- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/network/C4NetIO.cpp b/src/network/C4NetIO.cpp index 38675631a..953efde8a 100644 --- a/src/network/C4NetIO.cpp +++ b/src/network/C4NetIO.cpp @@ -290,11 +290,27 @@ C4NetIO::HostAddress C4NetIO::HostAddress::AsIPv6() const return nrv; } +C4NetIO::HostAddress C4NetIO::HostAddress::AsIPv4() const +{ + HostAddress nrv(*this); + if (gen.sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&v6.sin6_addr)) + { + nrv.v4.sin_family = AF_INET; + memcpy((char*) &nrv.v4.sin_addr, (char*) &v6.sin6_addr.s6_addr[12], sizeof(v4.sin_addr)); + } + return nrv; +} + C4NetIO::EndpointAddress C4NetIO::EndpointAddress::AsIPv6() const { return EndpointAddress(HostAddress::AsIPv6(), GetPort()); } +C4NetIO::EndpointAddress C4NetIO::EndpointAddress::AsIPv4() const +{ + return EndpointAddress(HostAddress::AsIPv4(), GetPort()); +} + void C4NetIO::HostAddress::SetHost(const sockaddr *addr) { // Copy all but port number diff --git a/src/network/C4NetIO.h b/src/network/C4NetIO.h index 875eb670f..ecae8fbbc 100644 --- a/src/network/C4NetIO.h +++ b/src/network/C4NetIO.h @@ -106,6 +106,7 @@ public: void SetHost(uint32_t host); C4NetIO::HostAddress AsIPv6() const; // convert an IPv4 address to an IPv6-mapped IPv4 address + C4NetIO::HostAddress AsIPv4() const; // try to convert an IPv6-mapped IPv4 address to an IPv4 address (returns unchanged address if not possible) // General categories bool IsNull() const; @@ -151,6 +152,7 @@ public: HostAddress GetHost() const { return *this; } // HostAddress copy ctor slices off port information EndpointAddress AsIPv6() const; // convert an IPv4 address to an IPv6-mapped IPv4 address + EndpointAddress AsIPv4() const; // try to convert an IPv6-mapped IPv4 address to an IPv4 address (returns unchanged address if not possible) void SetPort(uint16_t port); uint16_t GetPort() const; diff --git a/src/network/C4Network2IO.cpp b/src/network/C4Network2IO.cpp index 5a50be240..edf0a2c84 100644 --- a/src/network/C4Network2IO.cpp +++ b/src/network/C4Network2IO.cpp @@ -1268,14 +1268,13 @@ void C4Network2IO::SendConnPackets() void C4Network2IO::OnPuncherConnect(C4NetIO::addr_t addr) { - // Sanity check - if (addr.GetFamily() != C4NetIO::HostAddress::IPv4) - return; - Application.InteractiveThread.ThreadLogS("Adding address from puncher: %s", addr.ToString().getData()); + // NAT punching is only relevant for IPv4, so convert here to show a proper address. + auto maybe_v4 = addr.AsIPv4(); + Application.InteractiveThread.ThreadLogS("Adding address from puncher: %s", maybe_v4.ToString().getData()); // Add for local client C4Network2Client *pLocal = ::Network.Clients.GetLocal(); if (pLocal) - pLocal->AddAddr(C4Network2Address(addr, P_UDP), true); + pLocal->AddAddr(C4Network2Address(maybe_v4, P_UDP), true); // Do not ::Network.InvalidateReference(); yet, we're expecting an ID from the netpuncher }