From: Otto Moerbeek Date: Tue, 1 Sep 2020 10:01:09 +0000 (+0200) Subject: Move parseIPAndPort() to iputils and add unit test X-Git-Tag: auth-4.4.0-alpha2~49^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7234d9fc294a78d8f257e981a4a6e7dc92a42ed5;p=thirdparty%2Fpdns.git Move parseIPAndPort() to iputils and add unit test --- diff --git a/pdns/iputils.cc b/pdns/iputils.cc index 624746db80..19b84833e3 100644 --- a/pdns/iputils.cc +++ b/pdns/iputils.cc @@ -436,3 +436,36 @@ bool isTCPSocketUsable(int sock) return false; } +/* mission in life: parse three cases + 1) 1.2.3.4 + 2) 1.2.3.4:5300 + 3) 2001::1 + 4) [2002::1]:53 +*/ + +ComboAddress parseIPAndPort(const std::string& input, uint16_t port) +{ + if (input.find(':') == string::npos || input.empty()) { // common case + return ComboAddress(input, port); + } + + pair both; + try { // case 2 + string::size_type cpos = input.rfind(':'); + 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)))); + } + + return ComboAddress(input, port); // case 3 +} + diff --git a/pdns/iputils.hh b/pdns/iputils.hh index 06ce5f2c5e..355f61b672 100644 --- a/pdns/iputils.hh +++ b/pdns/iputils.hh @@ -1440,3 +1440,5 @@ size_t sendMsgWithOptions(int fd, const char* buffer, size_t len, const ComboAdd bool isTCPSocketUsable(int sock); extern template class NetmaskTree; +ComboAddress parseIPAndPort(const std::string& input, uint16_t port); + diff --git a/pdns/reczones.cc b/pdns/reczones.cc index 487781b289..5c049b1c3a 100644 --- a/pdns/reczones.cc +++ b/pdns/reczones.cc @@ -250,42 +250,6 @@ static void makeIPToNamesZone(std::shared_ptr newMap, cons } } - - -/* mission in life: parse three cases - 1) 1.2.3.4 - 2) 1.2.3.4:5300 - 3) 2001::1 - 4) [2002::1]:53 -*/ - -ComboAddress parseIPAndPort(const std::string& input, uint16_t port) -{ - if (input.find(':') == string::npos || input.empty()) { // common case - return ComboAddress(input, port); - } - - pair both; - try { // case 2 - string::size_type cpos = input.rfind(':'); - 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)))); - } - - return ComboAddress(input, port); // case 3 -} - - static void convertServersForAD(const std::string& input, SyncRes::AuthDomain& ad, const char* sepa, bool verbose=true) { vector servers; diff --git a/pdns/syncres.hh b/pdns/syncres.hh index 616ebd0a84..69d2896606 100644 --- a/pdns/syncres.hh +++ b/pdns/syncres.hh @@ -1080,7 +1080,6 @@ extern bool g_lowercaseOutgoing; std::string reloadAuthAndForwards(); -ComboAddress parseIPAndPort(const std::string& input, uint16_t port); typedef boost::function pipefunc_t; void broadcastFunction(const pipefunc_t& func); void distributeAsyncFunction(const std::string& question, const pipefunc_t& func); diff --git a/pdns/test-iputils_hh.cc b/pdns/test-iputils_hh.cc index cc54392953..06fdc69d3b 100644 --- a/pdns/test-iputils_hh.cc +++ b/pdns/test-iputils_hh.cc @@ -820,4 +820,35 @@ BOOST_AUTO_TEST_CASE(test_ComboAddress_caContainerToString) { BOOST_CHECK_EQUAL(caVectorStr, "192.0.2.1:53,192.0.2.2:5300,[2001:db8:53::3]:53,[2001:db8:53::4]:5300"); } +BOOST_AUTO_TEST_CASE(test_parseIPAndPort) +{ + struct { + std::string str; + uint16_t port; + std::string result; + bool ex; + } tests[] = { + { "", 0, "", true }, + { "1.2.3.a", 53, "", true }, + { "1::g3", 99, "", true }, + { "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 }, + { "2003:1234::f561", 53, "[2003:1234::f561]:53", false }, + }; + + for (const auto& t : tests) { + if (t.ex) { + 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_AUTO_TEST_SUITE_END()