Allow print NAT64 address in IPv4 form for better debugging

This commit is contained in:
Benau 2020-01-28 15:15:20 +08:00
parent 40b0a6371e
commit 2c78625ef6
3 changed files with 39 additions and 11 deletions

View File

@ -71,6 +71,7 @@ NetworkConfig::NetworkConfig()
m_joined_server_version = 0; m_joined_server_version = 0;
m_network_ai_tester = false; m_network_ai_tester = false;
m_state_frequency = 10; m_state_frequency = 10;
m_nat64_prefix_data.fill(-1);
} // NetworkConfig } // NetworkConfig
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -188,6 +189,7 @@ bool NetworkConfig::roundValuesNow() const
*/ */
void NetworkConfig::detectIPType() void NetworkConfig::detectIPType()
{ {
m_nat64_prefix_data.fill(-1);
#ifdef ENABLE_IPV6 #ifdef ENABLE_IPV6
ENetAddress addr; ENetAddress addr;
addr.host = STKHost::HOST_ANY; addr.host = STKHost::HOST_ANY;
@ -305,6 +307,20 @@ void NetworkConfig::detectIPType()
(struct sockaddr_in6*)res->ai_addr; (struct sockaddr_in6*)res->ai_addr;
memcpy(nat64.sin6_addr.s6_addr, out->sin6_addr.s6_addr, memcpy(nat64.sin6_addr.s6_addr, out->sin6_addr.s6_addr,
12); 12);
m_nat64_prefix_data[0] =
((uint32_t)(nat64.sin6_addr.s6_addr[0]) << 8) | nat64.sin6_addr.s6_addr[1];
m_nat64_prefix_data[1] =
((uint32_t)(nat64.sin6_addr.s6_addr[2]) << 8) | nat64.sin6_addr.s6_addr[3];
m_nat64_prefix_data[2] =
((uint32_t)(nat64.sin6_addr.s6_addr[4]) << 8) | nat64.sin6_addr.s6_addr[5];
m_nat64_prefix_data[3] =
((uint32_t)(nat64.sin6_addr.s6_addr[6]) << 8) | nat64.sin6_addr.s6_addr[7];
m_nat64_prefix_data[4] =
((uint32_t)(nat64.sin6_addr.s6_addr[8]) << 8) | nat64.sin6_addr.s6_addr[9];
m_nat64_prefix_data[5] =
((uint32_t)(nat64.sin6_addr.s6_addr[10]) << 8) | nat64.sin6_addr.s6_addr[11];
m_nat64_prefix_data[6] = 0;
m_nat64_prefix_data[7] = 0;
m_nat64_prefix = getIPV6ReadableFromIn6(&nat64); m_nat64_prefix = getIPV6ReadableFromIn6(&nat64);
} }
freeaddrinfo(res); freeaddrinfo(res);

View File

@ -26,6 +26,7 @@
#include "utils/no_copy.hpp" #include "utils/no_copy.hpp"
#include "irrString.h" #include "irrString.h"
#include <array>
#include <atomic> #include <atomic>
#include <memory> #include <memory>
#include <set> #include <set>
@ -109,6 +110,7 @@ private:
* use it to connect to ipv4 only servers. STK assumes that for all ipv4 * use it to connect to ipv4 only servers. STK assumes that for all ipv4
* addresses they use the same prefix for each initIPTest. */ * addresses they use the same prefix for each initIPTest. */
std::string m_nat64_prefix; std::string m_nat64_prefix;
std::array<uint32_t, 8> m_nat64_prefix_data;
public: public:
/** Singleton get, which creates this object if necessary. */ /** Singleton get, which creates this object if necessary. */
static NetworkConfig *get() static NetworkConfig *get()
@ -264,6 +266,9 @@ public:
void setIPType(IPType ip_type) { m_ip_type.store(ip_type); } void setIPType(IPType ip_type) { m_ip_type.store(ip_type); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
const std::string& getNAT64Prefix() const { return m_nat64_prefix; } const std::string& getNAT64Prefix() const { return m_nat64_prefix; }
// ------------------------------------------------------------------------
const std::array<uint32_t, 8>& getNAT64PrefixData() const
{ return m_nat64_prefix_data; }
}; // class NetworkConfig }; // class NetworkConfig
#endif // HEADER_NETWORK_CONFIG #endif // HEADER_NETWORK_CONFIG

View File

@ -45,12 +45,12 @@ extern "C"
#include <stdlib.h> #include <stdlib.h>
#endif #endif
#include "network/network_config.hpp"
#include <array>
#include <string> #include <string>
// ============================================================================ // ============================================================================
// Android STK seems to crash when using inet_ntop so we copy it from linux // Android STK seems to crash when using inet_ntop so we copy it from linux
#define NS_IN6ADDRSZ 16
#define NS_INT16SZ 2
static const char * static const char *
stk_inet_ntop4(const u_char *src, char *dst, socklen_t size) stk_inet_ntop4(const u_char *src, char *dst, socklen_t size)
{ {
@ -76,21 +76,26 @@ stk_inet_ntop6(const uint8_t *src, char *dst, socklen_t size)
*/ */
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
struct { int base, len; } best, cur; struct { int base, len; } best, cur;
uint32_t words[NS_IN6ADDRSZ / NS_INT16SZ]; std::array<uint32_t, 8> words;
int i; int i;
/* /*
* Preprocess: * Preprocess:
* Copy the input (bytewise) array into a wordwise array. * Copy the input (bytewise) array into a wordwise array.
* Find the longest run of 0x00's in src[] for :: shorthanding. * Find the longest run of 0x00's in src[] for :: shorthanding.
*/ */
memset(words, '\0', sizeof words); words.fill(0);
for (i = 0; i < NS_IN6ADDRSZ; i += 2) for (i = 0; i < 16; i += 2)
words[i / 2] = (src[i] << 8) | src[i + 1]; words[i / 2] = ((uint32_t)src[i] << 8) | src[i + 1];
// Test for nat64 prefix (remove the possible IPv4 in the last 32bit)
std::array<uint32_t, 8> test_nat64 = words;
test_nat64[6] = 0;
test_nat64[7] = 0;
best.base = -1; best.base = -1;
cur.base = -1; cur.base = -1;
best.len = 0; best.len = 0;
cur.len = 0; cur.len = 0;
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) for (i = 0; i < 8; i++)
{ {
if (words[i] == 0) if (words[i] == 0)
{ {
@ -120,7 +125,7 @@ stk_inet_ntop6(const uint8_t *src, char *dst, socklen_t size)
* Format the result. * Format the result.
*/ */
tp = tmp; tp = tmp;
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) for (i = 0; i < 8; i++)
{ {
/* Are we inside the best run of 0x00's? */ /* Are we inside the best run of 0x00's? */
if (best.base != -1 && i >= best.base && i < (best.base + best.len)) if (best.base != -1 && i >= best.base && i < (best.base + best.len))
@ -133,8 +138,10 @@ stk_inet_ntop6(const uint8_t *src, char *dst, socklen_t size)
if (i != 0) if (i != 0)
*tp++ = ':'; *tp++ = ':';
/* Is this address an encapsulated IPv4? */ /* Is this address an encapsulated IPv4? */
if (i == 6 && best.base == 0 && if (i == 6 &&
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) ((best.base == 0 &&
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) ||
test_nat64 == NetworkConfig::get()->getNAT64PrefixData()))
{ {
if (!stk_inet_ntop4(src + 12, tp, sizeof tmp - (tp - tmp))) if (!stk_inet_ntop4(src + 12, tp, sizeof tmp - (tp - tmp)))
return (NULL); return (NULL);
@ -144,7 +151,7 @@ stk_inet_ntop6(const uint8_t *src, char *dst, socklen_t size)
tp += sprintf(tp, "%x", words[i]); tp += sprintf(tp, "%x", words[i]);
} }
/* Was it a trailing run of 0x00's? */ /* Was it a trailing run of 0x00's? */
if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ)) if (best.base != -1 && (best.base + best.len) == 8)
*tp++ = ':'; *tp++ = ':';
*tp++ = '\0'; *tp++ = '\0';
/* /*