diff --git a/osdep/OSUtils.cpp b/osdep/OSUtils.cpp index a8639a12f..0ff7bfc46 100644 --- a/osdep/OSUtils.cpp +++ b/osdep/OSUtils.cpp @@ -38,9 +38,11 @@ #include #include #include +#include #include #include #include +#include #endif #ifdef __WINDOWS__ @@ -174,6 +176,34 @@ int64_t OSUtils::getFileSize(const char *path) return -1; } +std::vector OSUtils::resolve(const char *name) +{ + std::vector r; + std::vector::iterator i; + InetAddress tmp; + struct addrinfo *ai = (struct addrinfo *)0,*p; + if (!getaddrinfo(name,(const char *)0,(const struct addrinfo *)0,&ai)) { + try { + p = ai; + while (p) { + if ((p->ai_addr)&&((p->ai_addr->sa_family == AF_INET)||(p->ai_addr->sa_family == AF_INET6))) { + tmp = *(p->ai_addr); + for(i=r.begin();i!=r.end();++i) { + if (i->ipsEqual(tmp)) + goto skip_add_inetaddr; + } + r.push_back(tmp); + } +skip_add_inetaddr: + p = p->ai_next; + } + } catch ( ... ) {} + freeaddrinfo(ai); + } + std::sort(r.begin(),r.end()); + return r; +} + bool OSUtils::readFile(const char *path,std::string &buf) { char tmp[4096]; diff --git a/osdep/OSUtils.hpp b/osdep/OSUtils.hpp index 0cf4916b6..4422ab7d1 100644 --- a/osdep/OSUtils.hpp +++ b/osdep/OSUtils.hpp @@ -40,6 +40,7 @@ #include #include "../node/Constants.hpp" +#include "../node/InetAddress.hpp" #ifdef __WINDOWS__ #include @@ -146,6 +147,16 @@ public: */ static int64_t getFileSize(const char *path); + /** + * Get IP (v4 and/or v6) addresses for a given host + * + * This is a blocking resolver. + * + * @param name Host name + * @return IP addresses in InetAddress sort order or empty vector if not found + */ + static std::vector resolve(const char *name); + /** * @return Current time in milliseconds since epoch */ diff --git a/selftest.cpp b/selftest.cpp index 21e75924f..ea90813e5 100644 --- a/selftest.cpp +++ b/selftest.cpp @@ -758,7 +758,19 @@ static int testHttp() std::map requestHeaders,responseHeaders; std::string responseBody; - InetAddress downloadZerotierDotCom("142.4.214.72/80"); + InetAddress downloadZerotierDotCom; + std::vector rr(OSUtils::resolve("download.zerotier.com")); + if (rr.empty()) { + std::cout << "[http] Resolve of download.zerotier.com failed, skipping." << std::endl; + return 0; + } else { + for(std::vector::iterator r(rr.begin());r!=rr.end();++r) { + std::cout << "[http] download.zerotier.com: " << r->toString() << std::endl; + if (r->isV4()) + downloadZerotierDotCom = *r; + } + } + downloadZerotierDotCom.setPort(80); std::cout << "[http] GET http://download.zerotier.com/dev/1k @" << downloadZerotierDotCom.toString() << " ... "; std::cout.flush(); requestHeaders["Host"] = "download.zerotier.com";