diff --git a/net/http/test/client_function_test.cpp b/net/http/test/client_function_test.cpp index 29151c0d..7af2d2df 100644 --- a/net/http/test/client_function_test.cpp +++ b/net/http/test/client_function_test.cpp @@ -84,11 +84,12 @@ TEST(http_client, get) { auto op2 = client->new_operation(Verb::GET, target); DEFER(delete op2); op2->req.headers.content_length(0); - client->call(op2); + int ret = client->call(op2); + GTEST_ASSERT_EQ(0, ret); char resp_body_buf[1024]; EXPECT_EQ(sizeof(socket_buf), op2->resp.resource_size()); - auto ret = op2->resp.read(resp_body_buf, sizeof(socket_buf)); + ret = op2->resp.read(resp_body_buf, sizeof(socket_buf)); EXPECT_EQ(sizeof(socket_buf), ret); resp_body_buf[sizeof(socket_buf) - 1] = '\0'; LOG_DEBUG(resp_body_buf); diff --git a/net/utils.cpp b/net/utils.cpp index 28827d77..2e9d5c52 100644 --- a/net/utils.cpp +++ b/net/utils.cpp @@ -260,19 +260,30 @@ class DefaultResolver : public Resolver { : dnscache_(cache_ttl), resolve_timeout_(resolve_timeout) {} ~DefaultResolver() { dnscache_.clear(); } - IPAddr resolve(const char *host) override { + IPAddr resolve(const char *host, bool ipv6 = false) override { auto ctr = [&]() -> IPAddr * { - auto *ip = new IPAddr(); + std::vector addrs; photon::semaphore sem; std::thread([&]() { - *ip = gethostbyname(host); + int ret = gethostbyname(host, addrs); + if (ret < 0) { + addrs.clear(); + } sem.signal(1); }).detach(); auto ret = sem.wait(1, resolve_timeout_); if (ret < 0 && errno == ETIMEDOUT) { LOG_WARN("Domain resolution for ` timeout!", host); + return new IPAddr; // undefined addr + } else if (addrs.empty()) { + LOG_WARN("Domain resolution for ` failed", host); + return new IPAddr; // undefined addr } - return ip; + for (auto& each : addrs) { + if ((each.is_ipv4() ^ !ipv6) == 0) + return new IPAddr(each); + } + return new IPAddr; // undefined addr }; return *(dnscache_.borrow(host, ctr)); } diff --git a/net/utils.h b/net/utils.h index 9420686e..bf9eaa2c 100644 --- a/net/utils.h +++ b/net/utils.h @@ -153,9 +153,9 @@ bool zerocopy_available(); */ class Resolver : public Object { public: - // When failed, IPAddr(0) should be returned. + // When failed, return an Undefined IPAddr // Normally dns servers return multiple ips in random order, choosing the first one should suffice. - virtual IPAddr resolve(const char* host) = 0; + virtual IPAddr resolve(const char* host, bool ipv6 = false) = 0; virtual void resolve(const char* host, Delegate func) = 0; virtual void discard_cache(const char* host) = 0; // discard current cache of host:ip };