Merge pull request #8644
38d4811
p2p: fix exclusive node DNS resolution for certain hosts [release] (Jeffrey Ryan)
This commit is contained in:
commit
cbc5cf43f2
|
@ -38,7 +38,7 @@ namespace net
|
||||||
{
|
{
|
||||||
void get_network_address_host_and_port(const std::string& address, std::string& host, std::string& port)
|
void get_network_address_host_and_port(const std::string& address, std::string& host, std::string& port)
|
||||||
{
|
{
|
||||||
// require ipv6 address format "[addr:addr:addr:...:addr]:port"
|
// If IPv6 address format with port "[addr:addr:addr:...:addr]:port"
|
||||||
if (address.find(']') != std::string::npos)
|
if (address.find(']') != std::string::npos)
|
||||||
{
|
{
|
||||||
host = address.substr(1, address.rfind(']') - 1);
|
host = address.substr(1, address.rfind(']') - 1);
|
||||||
|
@ -47,6 +47,12 @@ namespace net
|
||||||
port = address.substr(address.rfind(':') + 1);
|
port = address.substr(address.rfind(':') + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Else if IPv6 address format without port e.g. "addr:addr:addr:...:addr"
|
||||||
|
else if (std::count(address.begin(), address.end(), ':') >= 2)
|
||||||
|
{
|
||||||
|
host = address;
|
||||||
|
}
|
||||||
|
// Else IPv4, Tor, I2P address or hostname
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
host = address.substr(0, address.rfind(':'));
|
host = address.substr(0, address.rfind(':'));
|
||||||
|
|
|
@ -38,6 +38,16 @@
|
||||||
|
|
||||||
namespace net
|
namespace net
|
||||||
{
|
{
|
||||||
|
/*!
|
||||||
|
* \brief Takes a valid address string (IP, Tor, I2P, or DNS name) and splits it into host and port
|
||||||
|
*
|
||||||
|
* The host of an IPv6 addresses in the format "[x:x:..:x]:port" will have the braces stripped.
|
||||||
|
* For example, when the address is "[ffff::2023]", host will be set to "ffff::2023".
|
||||||
|
*
|
||||||
|
* \param address The address string one wants to split
|
||||||
|
* \param[out] host The host part of the address string. Is always set.
|
||||||
|
* \param[out] port The port part of the address string. Is only set when address string contains a port.
|
||||||
|
*/
|
||||||
void get_network_address_host_and_port(const std::string& address, std::string& host, std::string& port);
|
void get_network_address_host_and_port(const std::string& address, std::string& host, std::string& port);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -645,20 +645,10 @@ namespace nodetool
|
||||||
{
|
{
|
||||||
using namespace boost::asio;
|
using namespace boost::asio;
|
||||||
|
|
||||||
std::string host = addr;
|
// Split addr string into host string and port string
|
||||||
|
std::string host;
|
||||||
std::string port = std::to_string(default_port);
|
std::string port = std::to_string(default_port);
|
||||||
size_t colon_pos = addr.find_last_of(':');
|
net::get_network_address_host_and_port(addr, host, port);
|
||||||
size_t dot_pos = addr.find_last_of('.');
|
|
||||||
size_t square_brace_pos = addr.find('[');
|
|
||||||
|
|
||||||
// IPv6 will have colons regardless. IPv6 and IPv4 address:port will have a colon but also either a . or a [
|
|
||||||
// as IPv6 addresses specified as address:port are to be specified as "[addr:addr:...:addr]:port"
|
|
||||||
// One may also specify an IPv6 address as simply "[addr:addr:...:addr]" without the port; in that case
|
|
||||||
// the square braces will be stripped here.
|
|
||||||
if ((std::string::npos != colon_pos && std::string::npos != dot_pos) || std::string::npos != square_brace_pos)
|
|
||||||
{
|
|
||||||
net::get_network_address_host_and_port(addr, host, port);
|
|
||||||
}
|
|
||||||
MINFO("Resolving node address: host=" << host << ", port=" << port);
|
MINFO("Resolving node address: host=" << host << ", port=" << port);
|
||||||
|
|
||||||
io_service io_srv;
|
io_service io_srv;
|
||||||
|
|
|
@ -936,6 +936,41 @@ TEST(get_network_address, ipv4subnet)
|
||||||
EXPECT_STREQ("12.34.0.0/16", address->str().c_str());
|
EXPECT_STREQ("12.34.0.0/16", address->str().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void na_host_and_port_test(std::string addr, std::string exp_host, std::string exp_port)
|
||||||
|
{
|
||||||
|
std::string host{"xxxxx"};
|
||||||
|
std::string port{"xxxxx"};
|
||||||
|
net::get_network_address_host_and_port(addr, host, port);
|
||||||
|
EXPECT_EQ(exp_host, host);
|
||||||
|
EXPECT_EQ(exp_port, port);
|
||||||
|
}
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
TEST(get_network_address_host_and_port, ipv4)
|
||||||
|
{
|
||||||
|
na_host_and_port_test("9.9.9.9", "9.9.9.9", "xxxxx");
|
||||||
|
na_host_and_port_test("9.9.9.9:18081", "9.9.9.9", "18081");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(get_network_address_host_and_port, ipv6)
|
||||||
|
{
|
||||||
|
na_host_and_port_test("::ffff", "::ffff", "xxxxx");
|
||||||
|
na_host_and_port_test("[::ffff]", "::ffff", "xxxxx");
|
||||||
|
na_host_and_port_test("[::ffff]:00231", "::ffff", "00231");
|
||||||
|
na_host_and_port_test("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "xxxxx");
|
||||||
|
na_host_and_port_test("[7777:7777:7777:7777:7777:7777:7777:7777]", "7777:7777:7777:7777:7777:7777:7777:7777", "xxxxx");
|
||||||
|
na_host_and_port_test("[7777:7777:7777:7777:7777:7777:7777:7777]:48080", "7777:7777:7777:7777:7777:7777:7777:7777", "48080");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(get_network_address_host_and_port, hostname)
|
||||||
|
{
|
||||||
|
na_host_and_port_test("localhost", "localhost", "xxxxx");
|
||||||
|
na_host_and_port_test("bar:29080", "bar", "29080"); // Issue https://github.com/monero-project/monero/issues/8633
|
||||||
|
na_host_and_port_test("xmrchain.net:18081", "xmrchain.net", "18081");
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
using stream_type = boost::asio::ip::tcp;
|
using stream_type = boost::asio::ip::tcp;
|
||||||
|
|
Loading…
Reference in New Issue