From 0536db0ec304c7aa238fb70bcb440f5712a7cd4e Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 20 May 2021 08:13:17 +0300 Subject: [PATCH 1/5] Fix resolving of IPv6 addresses v2: move the check from Cluster to DNSResolver --- src/Common/DNSResolver.cpp | 17 ++++++++++++++--- .../0_stateless/01880_remote_ipv6.reference | 0 tests/queries/0_stateless/01880_remote_ipv6.sql | 8 ++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 tests/queries/0_stateless/01880_remote_ipv6.reference create mode 100644 tests/queries/0_stateless/01880_remote_ipv6.sql diff --git a/src/Common/DNSResolver.cpp b/src/Common/DNSResolver.cpp index f54d3e72df5..8b006bc550d 100644 --- a/src/Common/DNSResolver.cpp +++ b/src/Common/DNSResolver.cpp @@ -87,9 +87,20 @@ static DNSResolver::IPAddresses resolveIPAddressImpl(const std::string & host) { Poco::Net::IPAddress ip; - /// NOTE: Poco::Net::DNS::resolveOne(host) doesn't work for IP addresses like 127.0.0.2 - if (Poco::Net::IPAddress::tryParse(host, ip)) - return DNSResolver::IPAddresses(1, ip); + /// NOTE: + /// - Poco::Net::DNS::resolveOne(host) doesn't work for IP addresses like 127.0.0.2 + /// - Poco::Net::IPAddress::tryParse() expect hex string for IPv6 (w/o brackets) + if (host.starts_with('[')) + { + assert(host.ends_with(']')); + if (Poco::Net::IPAddress::tryParse(host.substr(1, host.size() - 2), ip)) + return DNSResolver::IPAddresses(1, ip); + } + else + { + if (Poco::Net::IPAddress::tryParse(host, ip)) + return DNSResolver::IPAddresses(1, ip); + } /// Family: AF_UNSPEC /// AI_ALL is required for checking if client is allowed to connect from an address diff --git a/tests/queries/0_stateless/01880_remote_ipv6.reference b/tests/queries/0_stateless/01880_remote_ipv6.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/queries/0_stateless/01880_remote_ipv6.sql b/tests/queries/0_stateless/01880_remote_ipv6.sql new file mode 100644 index 00000000000..11bdf850ec0 --- /dev/null +++ b/tests/queries/0_stateless/01880_remote_ipv6.sql @@ -0,0 +1,8 @@ +SET connections_with_failover_max_tries=0; + +SELECT * FROM remote('[::1]', system.one) FORMAT Null; +SELECT * FROM remote('[::1]:9000', system.one) FORMAT Null; + +SELECT * FROM remote('[::1', system.one) FORMAT Null; -- { serverError 36 } +SELECT * FROM remote('::1]', system.one) FORMAT Null; -- { serverError 519 } +SELECT * FROM remote('::1', system.one) FORMAT Null; -- { serverError 519 } From 09020242b212f5066329cd572aae28267e45bf5f Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 20 May 2021 21:02:45 +0300 Subject: [PATCH 2/5] parseAddress: improve parsing of port (by using tryParse() over parse()) --- src/Common/parseAddress.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Common/parseAddress.cpp b/src/Common/parseAddress.cpp index 664e0ca2f59..465c424166e 100644 --- a/src/Common/parseAddress.cpp +++ b/src/Common/parseAddress.cpp @@ -35,7 +35,12 @@ std::pair parseAddress(const std::string & str, UInt16 defa if (port != end) { - UInt16 port_number = parse(port + 1); + UInt16 port_number; + if (!tryParse(port_number, port + 1)) + { + throw Exception(ErrorCodes::BAD_ARGUMENTS, + "Illegal port passed to function parseAddress: {}", port + 1); + } return { std::string(begin, port), port_number }; } else if (default_port) From 44c85edae043f136b9194845d97cb7903031e4be Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 20 May 2021 21:02:45 +0300 Subject: [PATCH 3/5] parseAddress: improve parsing of port for IPv6 --- src/Common/parseAddress.cpp | 6 +++++- tests/queries/0_stateless/01880_remote_ipv6.sql | 4 ++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Common/parseAddress.cpp b/src/Common/parseAddress.cpp index 465c424166e..b398f5cff10 100644 --- a/src/Common/parseAddress.cpp +++ b/src/Common/parseAddress.cpp @@ -28,13 +28,17 @@ std::pair parseAddress(const std::string & str, UInt16 defa throw Exception("Illegal address passed to function parseAddress: " "the address begins with opening square bracket, but no closing square bracket found", ErrorCodes::BAD_ARGUMENTS); - port = find_first_symbols<':'>(closing_square_bracket + 1, end); + port = closing_square_bracket + 1; } else port = find_first_symbols<':'>(begin, end); if (port != end) { + if (*port != ':') + throw Exception(ErrorCodes::BAD_ARGUMENTS, + "Illegal port prefix passed to function parseAddress: {}", port); + UInt16 port_number; if (!tryParse(port_number, port + 1)) { diff --git a/tests/queries/0_stateless/01880_remote_ipv6.sql b/tests/queries/0_stateless/01880_remote_ipv6.sql index 11bdf850ec0..9d9c25addbf 100644 --- a/tests/queries/0_stateless/01880_remote_ipv6.sql +++ b/tests/queries/0_stateless/01880_remote_ipv6.sql @@ -6,3 +6,7 @@ SELECT * FROM remote('[::1]:9000', system.one) FORMAT Null; SELECT * FROM remote('[::1', system.one) FORMAT Null; -- { serverError 36 } SELECT * FROM remote('::1]', system.one) FORMAT Null; -- { serverError 519 } SELECT * FROM remote('::1', system.one) FORMAT Null; -- { serverError 519 } + +SELECT * FROM remote('[::1][::1]', system.one) FORMAT Null; -- { serverError 36 } +SELECT * FROM remote('[::1][::1', system.one) FORMAT Null; -- { serverError 36 } +SELECT * FROM remote('[::1]::1]', system.one) FORMAT Null; -- { serverError 519 } From 1eceb5a8d39067c5ef1926be8bdbdc4e4450a8f8 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Thu, 20 May 2021 21:02:45 +0300 Subject: [PATCH 4/5] parseAddress: improve port parsing (verify that port is a valid int) --- src/Common/parseAddress.cpp | 9 ++++++--- tests/queries/0_stateless/01880_remote_ipv6.sql | 6 +++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Common/parseAddress.cpp b/src/Common/parseAddress.cpp index b398f5cff10..c99c08896ab 100644 --- a/src/Common/parseAddress.cpp +++ b/src/Common/parseAddress.cpp @@ -39,13 +39,16 @@ std::pair parseAddress(const std::string & str, UInt16 defa throw Exception(ErrorCodes::BAD_ARGUMENTS, "Illegal port prefix passed to function parseAddress: {}", port); + ++port; + UInt16 port_number; - if (!tryParse(port_number, port + 1)) + ReadBufferFromMemory port_buf(port, end - port); + if (!tryReadText(port_number, port_buf) || !port_buf.eof()) { throw Exception(ErrorCodes::BAD_ARGUMENTS, - "Illegal port passed to function parseAddress: {}", port + 1); + "Illegal port passed to function parseAddress: {}", port); } - return { std::string(begin, port), port_number }; + return { std::string(begin, port - 1), port_number }; } else if (default_port) { diff --git a/tests/queries/0_stateless/01880_remote_ipv6.sql b/tests/queries/0_stateless/01880_remote_ipv6.sql index 9d9c25addbf..057b3ad7ec6 100644 --- a/tests/queries/0_stateless/01880_remote_ipv6.sql +++ b/tests/queries/0_stateless/01880_remote_ipv6.sql @@ -4,9 +4,9 @@ SELECT * FROM remote('[::1]', system.one) FORMAT Null; SELECT * FROM remote('[::1]:9000', system.one) FORMAT Null; SELECT * FROM remote('[::1', system.one) FORMAT Null; -- { serverError 36 } -SELECT * FROM remote('::1]', system.one) FORMAT Null; -- { serverError 519 } -SELECT * FROM remote('::1', system.one) FORMAT Null; -- { serverError 519 } +SELECT * FROM remote('::1]', system.one) FORMAT Null; -- { serverError 36 } +SELECT * FROM remote('::1', system.one) FORMAT Null; -- { serverError 36 } SELECT * FROM remote('[::1][::1]', system.one) FORMAT Null; -- { serverError 36 } SELECT * FROM remote('[::1][::1', system.one) FORMAT Null; -- { serverError 36 } -SELECT * FROM remote('[::1]::1]', system.one) FORMAT Null; -- { serverError 519 } +SELECT * FROM remote('[::1]::1]', system.one) FORMAT Null; -- { serverError 36 } From fbe8b37ff6c44931a3da35b2593a150e9b4dd5d6 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 21 May 2021 22:47:55 +0300 Subject: [PATCH 5/5] Skip 01880_remote_ipv6 in arcadia --- tests/queries/0_stateless/arcadia_skip_list.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/queries/0_stateless/arcadia_skip_list.txt b/tests/queries/0_stateless/arcadia_skip_list.txt index 4e8ac456455..98c3a04e2ce 100644 --- a/tests/queries/0_stateless/arcadia_skip_list.txt +++ b/tests/queries/0_stateless/arcadia_skip_list.txt @@ -236,3 +236,4 @@ 01801_s3_distributed 01833_test_collation_alvarotuso 01850_dist_INSERT_preserve_error +01880_remote_ipv6