From: Otto Moerbeek Date: Wed, 2 Sep 2020 08:08:39 +0000 (+0200) Subject: Better way to distinguish IPV6 vs IPV4L count colons, plus explicitly X-Git-Tag: auth-4.4.0-alpha2~49^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f06d11c87cb4490b707703592a5d55c4fba5a1f5;p=thirdparty%2Fpdns.git Better way to distinguish IPV6 vs IPV4L count colons, plus explicitly verify port in unit tests. --- diff --git a/pdns/iputils.cc b/pdns/iputils.cc index 19b84833e3..cb737b9426 100644 --- a/pdns/iputils.cc +++ b/pdns/iputils.cc @@ -436,7 +436,7 @@ bool isTCPSocketUsable(int sock) return false; } -/* mission in life: parse three cases +/* mission in life: parse four cases 1) 1.2.3.4 2) 1.2.3.4:5300 3) 2001::1 @@ -445,27 +445,34 @@ bool isTCPSocketUsable(int sock) ComboAddress parseIPAndPort(const std::string& input, uint16_t port) { - if (input.find(':') == string::npos || input.empty()) { // common case - return ComboAddress(input, port); + if (input[0] == '[') { // case 4 + auto both = splitField(input.substr(1), ']'); + return ComboAddress(both.first, both.second.empty() ? port : static_cast(pdns_stou(both.second.substr(1)))); } - pair both; - try { // case 2 + string::size_type count = 0; + for (char c : input) { + if (c == ':') { + count++; + } + if (count > 1) { + break; + } + } + switch (count) { + case 0: // case 1 + return ComboAddress(input, port); + case 1: { // case 2 string::size_type cpos = input.rfind(':'); + pair both; both.first = input.substr(0, cpos); both.second = input.substr(cpos + 1); uint16_t newport = static_cast(pdns_stou(both.second)); return ComboAddress(both.first, newport); } - catch(...) { - } - - if (input[0] == '[') { // case 4 - both = splitField(input.substr(1), ']'); - return ComboAddress(both.first, both.second.empty() ? port : static_cast(pdns_stou(both.second.substr(1)))); + default: // case 3 + return ComboAddress(input, port); } - - return ComboAddress(input, port); // case 3 } diff --git a/pdns/test-iputils_hh.cc b/pdns/test-iputils_hh.cc index 06fdc69d3b..36e65779c4 100644 --- a/pdns/test-iputils_hh.cc +++ b/pdns/test-iputils_hh.cc @@ -834,11 +834,12 @@ BOOST_AUTO_TEST_CASE(test_parseIPAndPort) { "1.2.3.4", 0, "1.2.3.4:0", false }, { "1.2.3.4", 999, "1.2.3.4:999", false }, { "1::", 999, "[1::]:999", false }, - { "1::33:99", 0, "[1::33]:99", false }, + { "1::33:99", 0, "[1::33:99]", false }, { "[1::33]:99", 0, "[1::33]:99", false }, { "1:33::99", 0, "1:33::99", false }, { "[1:33::]:99", 0, "[1:33::]:99", false }, { "2003:1234::f561", 53, "[2003:1234::f561]:53", false }, + { "2003:1234::f561:53", 54, "[2003:1234::f561:53]:54", false }, }; for (const auto& t : tests) { @@ -846,7 +847,7 @@ BOOST_AUTO_TEST_CASE(test_parseIPAndPort) BOOST_CHECK_THROW(parseIPAndPort(t.str, t.port), PDNSException); } else { ComboAddress a = parseIPAndPort(t.str, t.port); - BOOST_CHECK_EQUAL(a.toString(), ComboAddress(t.result).toString()); + BOOST_CHECK_EQUAL(a.toStringWithPort(), ComboAddress(t.result).toStringWithPort()); } } }