check if local ipv6 clearnet address is presented

This commit is contained in:
orignal 2025-09-20 16:32:16 -04:00
parent db82903bb0
commit d280190822
4 changed files with 72 additions and 47 deletions

View file

@ -177,6 +177,9 @@ namespace i2p
} }
} }
if (ipv6) if (ipv6)
{
auto ipv6addr = i2p::util::net::GetClearnetIPV6Address ();
if (!ipv6addr.is_unspecified ())
{ {
std::string host; i2p::config::GetOption("address6", host); std::string host; i2p::config::GetOption("address6", host);
if (host.empty () && !ipv4) i2p::config::GetOption("host", host); // use host for ipv6 only if ipv4 is not presented if (host.empty () && !ipv4) i2p::config::GetOption("host", host); // use host for ipv6 only if ipv4 is not presented
@ -225,6 +228,7 @@ namespace i2p
} }
} }
} }
}
if (ygg) if (ygg)
{ {
auto yggaddr = i2p::util::net::GetYggdrasilAddress (); auto yggaddr = i2p::util::net::GetYggdrasilAddress ();

View file

@ -1345,6 +1345,12 @@ namespace transport
} }
} }
if (ipv6 && i2p::util::net::GetClearnetIPV6Address ().is_unspecified ())
{
LogPrint(eLogWarning, "Transports: Clearnet ipv6 not found. Disabled");
ipv6 = false;
}
if (!i2p::config::IsDefault("port")) if (!i2p::config::IsDefault("port"))
{ {
LogPrint(eLogInfo, "Transports: Accepting incoming connections at port ", port); LogPrint(eLogInfo, "Transports: Accepting incoming connections at port ", port);

View file

@ -545,7 +545,8 @@ namespace net
return (reservedPorts.find(port) != reservedPorts.end()); return (reservedPorts.find(port) != reservedPorts.end());
} }
boost::asio::ip::address_v6 GetYggdrasilAddress () template<typename CheckAddress>
static boost::asio::ip::address_v6 GetLocalIPV6Address (CheckAddress checkAddress)
{ {
#if defined(_WIN32) #if defined(_WIN32)
ULONG outBufLen = 0; ULONG outBufLen = 0;
@ -580,7 +581,7 @@ namespace net
{ {
LPSOCKADDR lpAddr = pUnicast->Address.lpSockaddr; LPSOCKADDR lpAddr = pUnicast->Address.lpSockaddr;
sockaddr_in6 *localInterfaceAddress = (sockaddr_in6*) lpAddr; sockaddr_in6 *localInterfaceAddress = (sockaddr_in6*) lpAddr;
if (IsYggdrasilAddress(localInterfaceAddress->sin6_addr.u.Byte)) { if (checkAddress(localInterfaceAddress->sin6_addr.u.Byte)) {
boost::asio::ip::address_v6::bytes_type bytes; boost::asio::ip::address_v6::bytes_type bytes;
memcpy (bytes.data (), &localInterfaceAddress->sin6_addr.u.Byte, 16); memcpy (bytes.data (), &localInterfaceAddress->sin6_addr.u.Byte, 16);
FREE(pAddresses); FREE(pAddresses);
@ -590,7 +591,7 @@ namespace net
} }
pCurrAddresses = pCurrAddresses->Next; pCurrAddresses = pCurrAddresses->Next;
} }
LogPrint(eLogWarning, "NetIface: Interface with Yggdrasil network address not found"); LogPrint(eLogWarning, "NetIface: Interface with ipv6 network address not found");
FREE(pAddresses); FREE(pAddresses);
return boost::asio::ip::address_v6 (); return boost::asio::ip::address_v6 ();
#else #else
@ -604,7 +605,7 @@ namespace net
if (cur->ifa_addr && cur->ifa_addr->sa_family == AF_INET6) if (cur->ifa_addr && cur->ifa_addr->sa_family == AF_INET6)
{ {
sockaddr_in6* sa = (sockaddr_in6*)cur->ifa_addr; sockaddr_in6* sa = (sockaddr_in6*)cur->ifa_addr;
if (IsYggdrasilAddress(sa->sin6_addr.s6_addr)) if (checkAddress(sa->sin6_addr.s6_addr))
{ {
boost::asio::ip::address_v6::bytes_type bytes; boost::asio::ip::address_v6::bytes_type bytes;
memcpy (bytes.data (), &sa->sin6_addr, 16); memcpy (bytes.data (), &sa->sin6_addr, 16);
@ -617,14 +618,27 @@ namespace net
} }
catch (std::exception& ex) catch (std::exception& ex)
{ {
LogPrint(eLogError, "NetIface: Exception while searching Yggdrasill address using ifaddr: ", ex.what()); LogPrint(eLogError, "NetIface: Exception while searching ipv6 address using ifaddr: ", ex.what());
} }
LogPrint(eLogWarning, "NetIface: Interface with Yggdrasil network address not found"); LogPrint(eLogWarning, "NetIface: Interface with ipv6 network address not found");
if (addrs) freeifaddrs(addrs); if (addrs) freeifaddrs(addrs);
return boost::asio::ip::address_v6 (); return boost::asio::ip::address_v6 ();
#endif #endif
} }
boost::asio::ip::address_v6 GetYggdrasilAddress ()
{
return GetLocalIPV6Address ([](const uint8_t addr[16]) { return IsYggdrasilAddress (addr); });
}
boost::asio::ip::address_v6 GetClearnetIPV6Address ()
{
return GetLocalIPV6Address ([](const uint8_t addr[16])
{
return (addr[0] & 0xF0) == 0x20; // 2000::/3
});
}
bool IsLocalAddress (const boost::asio::ip::address& addr) bool IsLocalAddress (const boost::asio::ip::address& addr)
{ {
auto mtu = // TODO: implement better auto mtu = // TODO: implement better

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2024, The PurpleI2P Project * Copyright (c) 2013-2025, The PurpleI2P Project
* *
* This file is part of Purple i2pd project and licensed under BSD3 * This file is part of Purple i2pd project and licensed under BSD3
* *
@ -231,6 +231,7 @@ namespace util
int GetMaxMTU (const boost::asio::ip::address_v6& localAddress); // check tunnel broker for ipv6 address int GetMaxMTU (const boost::asio::ip::address_v6& localAddress); // check tunnel broker for ipv6 address
const boost::asio::ip::address GetInterfaceAddress (const std::string & ifname, bool ipv6=false); const boost::asio::ip::address GetInterfaceAddress (const std::string & ifname, bool ipv6=false);
boost::asio::ip::address_v6 GetYggdrasilAddress (); boost::asio::ip::address_v6 GetYggdrasilAddress ();
boost::asio::ip::address_v6 GetClearnetIPV6Address ();
bool IsLocalAddress (const boost::asio::ip::address& addr); bool IsLocalAddress (const boost::asio::ip::address& addr);
bool IsInReservedRange (const boost::asio::ip::address& host); bool IsInReservedRange (const boost::asio::ip::address& host);
bool IsYggdrasilAddress (const boost::asio::ip::address& addr); bool IsYggdrasilAddress (const boost::asio::ip::address& addr);