diff --git a/libi2pd/util.cpp b/libi2pd/util.cpp index 69fc366a..2d5617b6 100644 --- a/libi2pd/util.cpp +++ b/libi2pd/util.cpp @@ -555,7 +555,10 @@ namespace net static const std::vector< std::pair > reservedIPv6Ranges { address_pair_v6("2001:db8::", "2001:db8:ffff:ffff:ffff:ffff:ffff:ffff"), address_pair_v6("fc00::", "fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), - address_pair_v6("fe80::", "febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff") + address_pair_v6("fe80::", "febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + address_pair_v6("ff00::", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), + address_pair_v6("::", "::"), + address_pair_v6("::1", "::1") }; boost::asio::ip::address_v6::bytes_type ipv6_address = host.to_v6 ().to_bytes (); diff --git a/libi2pd_client/I2PTunnel.cpp b/libi2pd_client/I2PTunnel.cpp index 5476bfe2..e8a66228 100644 --- a/libi2pd_client/I2PTunnel.cpp +++ b/libi2pd_client/I2PTunnel.cpp @@ -605,7 +605,47 @@ namespace client { if (!ecode) { - auto addr = (*it).endpoint ().address (); + bool found = false; + boost::asio::ip::tcp::endpoint ep; + if (m_LocalAddress) + { + boost::asio::ip::tcp::resolver::iterator end; + while (it != end) + { + ep = *it; + if (!ep.address ().is_unspecified ()) + { + if (ep.address ().is_v4 ()) + { + if (m_LocalAddress->is_v4 ()) found = true; + } + else if (ep.address ().is_v6 ()) + { + if (i2p::util::net::IsYggdrasilAddress (ep.address ())) + { + if (i2p::util::net::IsYggdrasilAddress (*m_LocalAddress)) + found = true; + } + else if (m_LocalAddress->is_v6 ()) + found = true; + } + } + if (found) break; + it++; + } + } + else + { + found = true; + ep = *it; // first available + } + if (!found) + { + LogPrint (eLogError, "I2PTunnel: Unable to resolve to compatible address"); + return; + } + + auto addr = ep.address (); LogPrint (eLogInfo, "I2PTunnel: server tunnel ", (*it).host_name (), " has been resolved to ", addr); m_Endpoint.address (addr); Accept ();