diff --git a/include/opendht/utils.h b/include/opendht/utils.h index a762129600ecce5dc8f71e55f95eb113da6a5d7e..eb79078d58b89d019deb4cc8fb238ad148b48922 100644 --- a/include/opendht/utils.h +++ b/include/opendht/utils.h @@ -54,6 +54,12 @@ void erase_if(std::map<Key, Item>& map, const Condition& condition) } } +/** + * Split "[host]:port" or "host:port" to pair<"host", "port">. + */ +OPENDHT_PUBLIC std::pair<std::string, std::string> +splitPort(const std::string& s); + class OPENDHT_PUBLIC DhtException : public std::runtime_error { public: DhtException(const std::string &str = "") : diff --git a/src/dht_proxy_client.cpp b/src/dht_proxy_client.cpp index e2dde088e5050d656f585108fd95281c4b5f6a98..41b2d6deba00e0b95791d9afd05b7101661e5e26 100644 --- a/src/dht_proxy_client.cpp +++ b/src/dht_proxy_client.cpp @@ -23,6 +23,7 @@ #include "dhtrunner.h" #include "op_cache.h" +#include "utils.h" #include <restbed> #include <json/json.h> @@ -452,15 +453,8 @@ DhtProxyClient::getProxyInfos() } // A node can have a Ipv4 and a Ipv6. So, we need to retrieve all public ips - std::string host, service; - auto serviceMarker = serverHost_.find(':'); - if (serviceMarker != std::string::npos) { - host = serverHost_.substr(0, serviceMarker - 1); - service = serverHost_.substr(serviceMarker + 1); - } else { - host = serverHost_; - } - auto resolved_proxies = SockAddr::resolve(host, service); + auto hostAndService = splitPort(serverHost_); + auto resolved_proxies = SockAddr::resolve(hostAndService.first, hostAndService.second); auto serverHost = serverHost_; // Try to contact the proxy and set the status to connected when done. @@ -551,10 +545,8 @@ SockAddr DhtProxyClient::parsePublicAddress(const Json::Value& val) { auto public_ip = val.asString(); - auto endIp = public_ip.find_last_of(':'); - auto marker = (public_ip.size() > 0 && public_ip[0] == '[') ? 1 : 0; - std::string address = public_ip.substr(marker, endIp - marker * 2); - auto sa = SockAddr::resolve(address); + auto hostAndService = splitPort(public_ip); + auto sa = SockAddr::resolve(hostAndService.first); if (sa.empty()) return {}; return sa.front().getMappedIPv4(); } diff --git a/src/utils.cpp b/src/utils.cpp index c9a7abfd02015fd82778bf77985e3a21a7d4a3b3..93abc1f76ddc866688a5be54a177f1f0f0a3b8bd 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -29,6 +29,26 @@ namespace dht { static constexpr std::array<uint8_t, 12> MAPPED_IPV4_PREFIX {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}}; +std::pair<std::string, std::string> +splitPort(const std::string& s) { + if (s.empty()) + return {}; + if (s[0] == '[') { + std::size_t closure = s.find_first_of(']'); + std::size_t found = s.find_last_of(':'); + if (closure == std::string::npos) + return {s, ""}; + if (found == std::string::npos or found < closure) + return {s.substr(1,closure-1), ""}; + return {s.substr(1,closure-1), s.substr(found+1)}; + } + std::size_t found = s.find_last_of(':'); + std::size_t first = s.find_first_of(':'); + if (found == std::string::npos or found != first) + return {s, ""}; + return {s.substr(0,found), s.substr(found+1)}; +} + std::vector<SockAddr> SockAddr::resolve(const std::string& host, const std::string& service) { diff --git a/tools/tools_common.h b/tools/tools_common.h index b51cb60ab12344033ad409f0afbee42168066bad..92c2af5d8ceee703d6dc6640b46fa2e4459a9e02 100644 --- a/tools/tools_common.h +++ b/tools/tools_common.h @@ -45,29 +45,6 @@ #include <sstream> #include <fstream> -/** - * Split "[host]:port" or "host:port" to pair<"host", "port">. - */ -std::pair<std::string, std::string> -splitPort(const std::string& s) { - if (s.empty()) - return {}; - if (s[0] == '[') { - std::size_t closure = s.find_first_of(']'); - std::size_t found = s.find_last_of(':'); - if (closure == std::string::npos) - return {s, ""}; - if (found == std::string::npos or found < closure) - return {s.substr(1,closure-1), ""}; - return {s.substr(1,closure-1), s.substr(found+1)}; - } - std::size_t found = s.find_last_of(':'); - std::size_t first = s.find_first_of(':'); - if (found == std::string::npos or found != first) - return {s, ""}; - return {s.substr(0,found), s.substr(found+1)}; -} - /* * The mapString shall have the following format: * @@ -181,7 +158,7 @@ parseArgs(int argc, char **argv) { params.network = strtoul(optarg, nullptr, 0); break; case 'b': - params.bootstrap = splitPort((optarg[0] == '=') ? optarg+1 : optarg); + params.bootstrap = dht::splitPort((optarg[0] == '=') ? optarg+1 : optarg); if (not params.bootstrap.first.empty() and params.bootstrap.second.empty()) { params.bootstrap.second = std::to_string(DHT_DEFAULT_PORT); }