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_network_ai_tester = false;
m_state_frequency = 10;
m_nat64_prefix_data.fill(-1);
} // NetworkConfig
// ----------------------------------------------------------------------------
@ -188,6 +189,7 @@ bool NetworkConfig::roundValuesNow() const
*/
void NetworkConfig::detectIPType()
{
m_nat64_prefix_data.fill(-1);
#ifdef ENABLE_IPV6
ENetAddress addr;
addr.host = STKHost::HOST_ANY;
@ -305,6 +307,20 @@ void NetworkConfig::detectIPType()
(struct sockaddr_in6*)res->ai_addr;
memcpy(nat64.sin6_addr.s6_addr, out->sin6_addr.s6_addr,
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);
}
freeaddrinfo(res);

View File

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

View File

@ -45,12 +45,12 @@ extern "C"
#include <stdlib.h>
#endif
#include "network/network_config.hpp"
#include <array>
#include <string>
// ============================================================================
// 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 *
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;
struct { int base, len; } best, cur;
uint32_t words[NS_IN6ADDRSZ / NS_INT16SZ];
std::array<uint32_t, 8> words;
int i;
/*
* Preprocess:
* Copy the input (bytewise) array into a wordwise array.
* Find the longest run of 0x00's in src[] for :: shorthanding.
*/
memset(words, '\0', sizeof words);
for (i = 0; i < NS_IN6ADDRSZ; i += 2)
words[i / 2] = (src[i] << 8) | src[i + 1];
words.fill(0);
for (i = 0; i < 16; i += 2)
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;
cur.base = -1;
best.len = 0;
cur.len = 0;
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++)
for (i = 0; i < 8; i++)
{
if (words[i] == 0)
{
@ -120,7 +125,7 @@ stk_inet_ntop6(const uint8_t *src, char *dst, socklen_t size)
* Format the result.
*/
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? */
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)
*tp++ = ':';
/* Is this address an encapsulated IPv4? */
if (i == 6 && best.base == 0 &&
(best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
if (i == 6 &&
((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)))
return (NULL);
@ -144,7 +151,7 @@ stk_inet_ntop6(const uint8_t *src, char *dst, socklen_t size)
tp += sprintf(tp, "%x", words[i]);
}
/* 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++ = '\0';
/*