From 38a78cf795680633b05db7e694fa91e1464381fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D1=88=D0=B5=20=D0=B8=D0=BC=D1=8F=D1=8D?= Date: Fri, 8 Sep 2023 15:37:23 +0700 Subject: [PATCH] #1965 issue --- libi2pd/Config.cpp | 82 ++++++++++++++++++++++++++++++++++++++- libi2pd/Config.h | 3 ++ libi2pd/Reseed.cpp | 7 +++- libi2pd/RouterContext.cpp | 7 +++- libi2pd/Transports.cpp | 25 +++++++++--- 5 files changed, 112 insertions(+), 12 deletions(-) diff --git a/libi2pd/Config.cpp b/libi2pd/Config.cpp index 5551b010..822a5499 100644 --- a/libi2pd/Config.cpp +++ b/libi2pd/Config.cpp @@ -11,10 +11,15 @@ #include #include #include +#include +#include + #include #include #include #include +#include + #include "Identity.h" #include "Config.h" @@ -25,6 +30,7 @@ using namespace boost::program_options; namespace i2p { namespace config { + options_description m_OptionsDesc; variables_map m_Options; @@ -51,9 +57,9 @@ namespace config { ("ifname6", value()->default_value(""), "Network interface to bind to for ipv6") ("nat", bool_switch()->default_value(true), "Should we assume we are behind NAT? (default: enabled)") ("port", value()->default_value(0), "Port to listen for incoming connections (default: auto)") - ("ipv4", bool_switch()->default_value(true), "Enable communication through ipv4 (default: enabled)") ("address4", value()->default_value(""), "Local address to bind ipv4 transport sockets to") - ("ipv6", bool_switch()->default_value(false), "Enable communication through ipv6 (default: disabled)") + ("ipv4", value()->default_value("true"), "Enable communication through ipv4 (default: 'true')") + ("ipv6", value()->default_value("false"), "Enable communication through ipv6 (default: 'false')") ("address6", value()->default_value(""), "Local address to bind ipv6 transport sockets to") ("reservedrange", bool_switch()->default_value(true), "Check remote RI for being in blacklist of reserved IP ranges (default: enabled)") ("netid", value()->default_value(I2PD_NET_ID), "Specify NetID. Main I2P is 2") @@ -451,5 +457,77 @@ namespace config { return GetOptionAsAny (name.c_str (), value); } + // + bool IsTrueOrYes(std::string & val, std::function fun ) + { + if (val.find("true") != std::string::npos || val.find("yes") != std::string::npos) { + return true; + } else if (val.find("false") != std::string::npos || val.find("no") != std::string::npos) { + return false; + } else if (val.find("auto") != std::string::npos) { + return fun(); + } + throw "Invalid value"; // Added a throw statement for invalid values + } + + // To utils maybe + static bool IsIPResolveAndConnect(std::string w = "::1") + { + boost::asio::io_service io_service; + boost::asio::ip::tcp::resolver resolver(io_service); + boost::asio::ip::tcp::resolver::query query(w.c_str(), ""); + boost::asio::ip::tcp::socket socket(io_service); + + std::atomic_bool success(false); + auto handler = [&success](const boost::system::error_code& ec, boost::asio::ip::tcp::resolver::iterator it) { + success = !ec; + if (!ec) { + success = !ec; + } + }; + + boost::asio::deadline_timer timer(io_service, boost::posix_time::milliseconds(500)); + timer.async_wait([&io_service](const boost::system::error_code&) { io_service.stop(); }); + + resolver.async_resolve(query, handler); + io_service.run(); // Run the resolve. + + if (!success) { + return false; + } + try { + boost::asio::connect(socket, resolver.resolve(query)); + } catch( const std::exception&) { + return false; + } + // Done, assuming that the response from the server was successful, otherwise you could parse the HTTP + // response to verify it was a 200 OK. + return true; + } + + bool IsIPv4Works(void) + { + // TODO: + return true; // if we connect to localhost even then is give a false + } + static bool IsIPv6HadTest = false; + static bool IPv6Works = false; + bool IsIPv6Works(void) + { + if (IsIPv6HadTest) return IPv6Works;// TODO: + // TODO: if we try to get from netdb then get nullptr because this not runs. If we runs then get a recursion loop. So need a better way. + const std::vector addresses={ + "2001:4860:4860::8888", // Google Public DNS сервер1 + "2001:4860:4860::8844" // Google Public DNS сервер2 + }; + std::random_device rd; + std::mt19937 mt(rd()); + std::uniform_int_distribution dist(0, addresses.size() - 1); + std::size_t random_index = dist(mt); + std::string random_address = addresses[random_index]; + IsIPv6HadTest = true; + IPv6Works = IsIPResolveAndConnect(random_address); + return IPv6Works; + } } // namespace config } // namespace i2p diff --git a/libi2pd/Config.h b/libi2pd/Config.h index 79463e65..4a1e4785 100644 --- a/libi2pd/Config.h +++ b/libi2pd/Config.h @@ -121,6 +121,9 @@ namespace config { * @return true if value set to default, false otherwise */ bool IsDefault(const char *name); + bool IsTrueOrYes(std::string & val, std::function fun = []() {return false;} ); + bool IsIPv4Works(void); + bool IsIPv6Works(void); } } diff --git a/libi2pd/Reseed.cpp b/libi2pd/Reseed.cpp index 28e4db24..34648d3d 100644 --- a/libi2pd/Reseed.cpp +++ b/libi2pd/Reseed.cpp @@ -82,8 +82,11 @@ namespace data */ int Reseeder::ReseedFromServers () { - bool ipv6; i2p::config::GetOption("ipv6", ipv6); - bool ipv4; i2p::config::GetOption("ipv4", ipv4); + std::string ipv4_str;i2p::config::GetOption("ipv4", ipv4_str); + std::string ipv6_str;i2p::config::GetOption("ipv6", ipv6_str); + bool ipv4 = i2p::config::IsTrueOrYes(ipv4_str, i2p::config::IsIPv4Works); + bool ipv6 = i2p::config::IsTrueOrYes(ipv6_str, i2p::config::IsIPv6Works); + // bool yggdrasil; i2p::config::GetOption("meshnets.yggdrasil", yggdrasil); std::vector httpsReseedHostList; diff --git a/libi2pd/RouterContext.cpp b/libi2pd/RouterContext.cpp index fa3ba7bd..488537d0 100644 --- a/libi2pd/RouterContext.cpp +++ b/libi2pd/RouterContext.cpp @@ -93,8 +93,11 @@ namespace i2p routerInfo.SetRouterIdentity (GetIdentity ()); uint16_t port; i2p::config::GetOption("port", port); if (!port) port = SelectRandomPort (); - bool ipv4; i2p::config::GetOption("ipv4", ipv4); - bool ipv6; i2p::config::GetOption("ipv6", ipv6); + std::string ipv4_str;i2p::config::GetOption("ipv4", ipv4_str); + std::string ipv6_str;i2p::config::GetOption("ipv6", ipv6_str); + bool ipv4 = i2p::config::IsTrueOrYes(ipv4_str, i2p::config::IsIPv4Works); + bool ipv6 = i2p::config::IsTrueOrYes(ipv6_str, i2p::config::IsIPv6Works); + // bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); diff --git a/libi2pd/Transports.cpp b/libi2pd/Transports.cpp index b452c05e..f2463e1f 100644 --- a/libi2pd/Transports.cpp +++ b/libi2pd/Transports.cpp @@ -171,8 +171,16 @@ namespace transport m_UpdateBandwidthTimer = new boost::asio::deadline_timer (*m_Service); } - bool ipv4; i2p::config::GetOption("ipv4", ipv4); - bool ipv6; i2p::config::GetOption("ipv6", ipv6); + // IPv4 / IPv6 auto experemental option + + std::string ipv4_str;i2p::config::GetOption("ipv4", ipv4_str); + std::string ipv6_str;i2p::config::GetOption("ipv6", ipv6_str); + bool ipv4 = i2p::config::IsTrueOrYes(ipv4_str, i2p::config::IsIPv4Works); + bool ipv6 = i2p::config::IsTrueOrYes(ipv6_str, i2p::config::IsIPv6Works); + LogPrint (eLogDebug, "Transports: IPv6 supports is ", ipv6); + LogPrint (eLogDebug, "Transports: IPv4 supports is ", ipv4); + + // i2p::config::GetOption("nat", m_IsNAT); m_X25519KeysPairSupplier.Start (); m_IsRunning = true; @@ -1044,8 +1052,11 @@ namespace transport void InitAddressFromIface () { - bool ipv6; i2p::config::GetOption("ipv6", ipv6); - bool ipv4; i2p::config::GetOption("ipv4", ipv4); + std::string ipv4_str;i2p::config::GetOption("ipv4", ipv4_str); + std::string ipv6_str;i2p::config::GetOption("ipv6", ipv6_str); + bool ipv4 = i2p::config::IsTrueOrYes(ipv4_str, i2p::config::IsIPv4Works); + bool ipv6 = i2p::config::IsTrueOrYes(ipv6_str, i2p::config::IsIPv6Works); + // ifname -> address std::string ifname; i2p::config::GetOption("ifname", ifname); @@ -1069,8 +1080,10 @@ namespace transport void InitTransports () { - bool ipv6; i2p::config::GetOption("ipv6", ipv6); - bool ipv4; i2p::config::GetOption("ipv4", ipv4); + std::string ipv4_str;i2p::config::GetOption("ipv4", ipv4_str); + std::string ipv6_str;i2p::config::GetOption("ipv6", ipv6_str); + bool ipv4 = i2p::config::IsTrueOrYes(ipv4_str, i2p::config::IsIPv4Works); + bool ipv6 = i2p::config::IsTrueOrYes(ipv6_str, i2p::config::IsIPv6Works); bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); uint16_t port; i2p::config::GetOption("port", port);