diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:30 +0300 |
commit | 2598ef1d0aee359b4b6d5fdd1758916d5907d04f (patch) | |
tree | 012bb94d777798f1f56ac1cec429509766d05181 /contrib/libs/c-ares/test | |
parent | 6751af0b0c1b952fede40b19b71da8025b5d8bcf (diff) | |
download | ydb-2598ef1d0aee359b4b6d5fdd1758916d5907d04f.tar.gz |
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/c-ares/test')
-rw-r--r-- | contrib/libs/c-ares/test/ares-test-ai.h | 114 | ||||
-rw-r--r-- | contrib/libs/c-ares/test/ares-test-init.cc | 36 | ||||
-rw-r--r-- | contrib/libs/c-ares/test/ares-test-internal.cc | 210 | ||||
-rw-r--r-- | contrib/libs/c-ares/test/ares-test-live.cc | 242 | ||||
-rw-r--r-- | contrib/libs/c-ares/test/ares-test-misc.cc | 18 | ||||
-rw-r--r-- | contrib/libs/c-ares/test/ares-test-mock-ai.cc | 1446 | ||||
-rw-r--r-- | contrib/libs/c-ares/test/ares-test-mock.cc | 32 | ||||
-rw-r--r-- | contrib/libs/c-ares/test/ares-test-parse-a.cc | 42 | ||||
-rw-r--r-- | contrib/libs/c-ares/test/ares-test-parse-aaaa.cc | 4 | ||||
-rw-r--r-- | contrib/libs/c-ares/test/ares-test-parse-soa-any.cc | 222 | ||||
-rw-r--r-- | contrib/libs/c-ares/test/ares-test-parse-soa.cc | 2 | ||||
-rw-r--r-- | contrib/libs/c-ares/test/ares-test.cc | 148 | ||||
-rw-r--r-- | contrib/libs/c-ares/test/ares-test.h | 120 | ||||
-rw-r--r-- | contrib/libs/c-ares/test/ya.make | 4 |
14 files changed, 1320 insertions, 1320 deletions
diff --git a/contrib/libs/c-ares/test/ares-test-ai.h b/contrib/libs/c-ares/test/ares-test-ai.h index 7cf27e3306..22555d4e8c 100644 --- a/contrib/libs/c-ares/test/ares-test-ai.h +++ b/contrib/libs/c-ares/test/ares-test-ai.h @@ -1,57 +1,57 @@ -#ifndef ARES_TEST_AI_H -#define ARES_TEST_AI_H - -#include <utility> -#include "gtest/gtest.h" -#include "gmock/gmock.h" -#include "ares-test.h" - -namespace ares { -namespace test { - -class MockChannelTestAI - : public MockChannelOptsTest, - public ::testing::WithParamInterface< std::pair<int, bool> > { - public: - MockChannelTestAI() : MockChannelOptsTest(1, GetParam().first, GetParam().second, nullptr, 0) {} -}; - -class MockUDPChannelTestAI - : public MockChannelOptsTest, - public ::testing::WithParamInterface<int> { - public: - MockUDPChannelTestAI() : MockChannelOptsTest(1, GetParam(), false, nullptr, 0) {} -}; - -class MockTCPChannelTestAI - : public MockChannelOptsTest, - public ::testing::WithParamInterface<int> { - public: - MockTCPChannelTestAI() : MockChannelOptsTest(1, GetParam(), true, nullptr, 0) {} -}; - - -// Test fixture that uses a default channel. -class DefaultChannelTestAI : public LibraryTest { - public: - DefaultChannelTestAI() : channel_(nullptr) { - EXPECT_EQ(ARES_SUCCESS, ares_init(&channel_)); - EXPECT_NE(nullptr, channel_); - } - - ~DefaultChannelTestAI() { - ares_destroy(channel_); - channel_ = nullptr; - } - - // Process all pending work on ares-owned file descriptors. - void Process(); - - protected: - ares_channel channel_; -}; - -} -} - -#endif +#ifndef ARES_TEST_AI_H +#define ARES_TEST_AI_H + +#include <utility> +#include "gtest/gtest.h" +#include "gmock/gmock.h" +#include "ares-test.h" + +namespace ares { +namespace test { + +class MockChannelTestAI + : public MockChannelOptsTest, + public ::testing::WithParamInterface< std::pair<int, bool> > { + public: + MockChannelTestAI() : MockChannelOptsTest(1, GetParam().first, GetParam().second, nullptr, 0) {} +}; + +class MockUDPChannelTestAI + : public MockChannelOptsTest, + public ::testing::WithParamInterface<int> { + public: + MockUDPChannelTestAI() : MockChannelOptsTest(1, GetParam(), false, nullptr, 0) {} +}; + +class MockTCPChannelTestAI + : public MockChannelOptsTest, + public ::testing::WithParamInterface<int> { + public: + MockTCPChannelTestAI() : MockChannelOptsTest(1, GetParam(), true, nullptr, 0) {} +}; + + +// Test fixture that uses a default channel. +class DefaultChannelTestAI : public LibraryTest { + public: + DefaultChannelTestAI() : channel_(nullptr) { + EXPECT_EQ(ARES_SUCCESS, ares_init(&channel_)); + EXPECT_NE(nullptr, channel_); + } + + ~DefaultChannelTestAI() { + ares_destroy(channel_); + channel_ = nullptr; + } + + // Process all pending work on ares-owned file descriptors. + void Process(); + + protected: + ares_channel channel_; +}; + +} +} + +#endif diff --git a/contrib/libs/c-ares/test/ares-test-init.cc b/contrib/libs/c-ares/test/ares-test-init.cc index 842b0e15ac..58fa02d48c 100644 --- a/contrib/libs/c-ares/test/ares-test-init.cc +++ b/contrib/libs/c-ares/test/ares-test-init.cc @@ -495,24 +495,24 @@ CONTAINED_TEST_F(LibraryTest, ContainerSvcConfInit, return HasFailure(); } -NameContentList malformedresolvconflookup = { - {"/etc/resolv.conf", "nameserver 1.2.3.4\n" - "lookup garbage\n"}}; // malformed line -CONTAINED_TEST_F(LibraryTest, ContainerMalformedResolvConfLookup, - "myhostname", "mydomainname.org", malformedresolvconflookup) { - ares_channel channel = nullptr; - EXPECT_EQ(ARES_SUCCESS, ares_init(&channel)); - - struct ares_options opts; - int optmask = 0; - ares_save_options(channel, &opts, &optmask); - EXPECT_EQ(std::string("fb"), std::string(opts.lookups)); - ares_destroy_options(&opts); - - ares_destroy(channel); - return HasFailure(); -} - +NameContentList malformedresolvconflookup = { + {"/etc/resolv.conf", "nameserver 1.2.3.4\n" + "lookup garbage\n"}}; // malformed line +CONTAINED_TEST_F(LibraryTest, ContainerMalformedResolvConfLookup, + "myhostname", "mydomainname.org", malformedresolvconflookup) { + ares_channel channel = nullptr; + EXPECT_EQ(ARES_SUCCESS, ares_init(&channel)); + + struct ares_options opts; + int optmask = 0; + ares_save_options(channel, &opts, &optmask); + EXPECT_EQ(std::string("fb"), std::string(opts.lookups)); + ares_destroy_options(&opts); + + ares_destroy(channel); + return HasFailure(); +} + // Failures when expected config filenames are inaccessible. class MakeUnreadable { public: diff --git a/contrib/libs/c-ares/test/ares-test-internal.cc b/contrib/libs/c-ares/test/ares-test-internal.cc index 96d4edece5..cda8d96356 100644 --- a/contrib/libs/c-ares/test/ares-test-internal.cc +++ b/contrib/libs/c-ares/test/ares-test-internal.cc @@ -356,107 +356,107 @@ TEST_F(LibraryTest, GetHostentAllocFail) { fclose(fp); } -TEST_F(DefaultChannelTest, GetAddrInfoHostsPositive) { - TempFile hostsfile("1.2.3.4 example.com \n" - " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n" - "#comment\n" - "4.5.6.7\n" - "1.3.5.7 \n" - "::1 ipv6.com"); - EnvValue with_env("CARES_HOSTS", hostsfile.filename()); - struct ares_addrinfo_hints hints = {}; - AddrInfoResult result = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "example.com", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - std::stringstream ss; - ss << result.ai_; - EXPECT_EQ("{example.com addr=[1.2.3.4]}", ss.str()); -} - -TEST_F(DefaultChannelTest, GetAddrInfoHostsSpaces) { - TempFile hostsfile("1.2.3.4 example.com \n" - " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n" - "#comment\n" - "4.5.6.7\n" - "1.3.5.7 \n" - "::1 ipv6.com"); - EnvValue with_env("CARES_HOSTS", hostsfile.filename()); - struct ares_addrinfo_hints hints = {}; - AddrInfoResult result = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "google.com", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - std::stringstream ss; - ss << result.ai_; - EXPECT_EQ("{www.google.com->google.com, www2.google.com->google.com addr=[2.3.4.5]}", ss.str()); -} - -TEST_F(DefaultChannelTest, GetAddrInfoHostsByALias) { - TempFile hostsfile("1.2.3.4 example.com \n" - " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n" - "#comment\n" - "4.5.6.7\n" - "1.3.5.7 \n" - "::1 ipv6.com"); - EnvValue with_env("CARES_HOSTS", hostsfile.filename()); - struct ares_addrinfo_hints hints = {}; - AddrInfoResult result = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "www2.google.com", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - std::stringstream ss; - ss << result.ai_; - EXPECT_EQ("{www.google.com->google.com, www2.google.com->google.com addr=[2.3.4.5]}", ss.str()); -} - -TEST_F(DefaultChannelTest, GetAddrInfoHostsIPV6) { - TempFile hostsfile("1.2.3.4 example.com \n" - " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n" - "#comment\n" - "4.5.6.7\n" - "1.3.5.7 \n" - "::1 ipv6.com"); - EnvValue with_env("CARES_HOSTS", hostsfile.filename()); - struct ares_addrinfo_hints hints = {}; - AddrInfoResult result = {}; - hints.ai_family = AF_INET6; - hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "ipv6.com", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - std::stringstream ss; - ss << result.ai_; - EXPECT_EQ("{ipv6.com addr=[[0000:0000:0000:0000:0000:0000:0000:0001]]}", ss.str()); -} - -TEST_F(LibraryTest, GetAddrInfoAllocFail) { - TempFile hostsfile("1.2.3.4 example.com alias1 alias2\n"); - struct ares_addrinfo_hints hints; - unsigned short port = 80; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; - - FILE *fp = fopen(hostsfile.filename(), "r"); - ASSERT_NE(nullptr, fp); - - for (int ii = 1; ii <= 3; ii++) { - rewind(fp); - ClearFails(); - SetAllocFail(ii); - struct ares_addrinfo ai; - EXPECT_EQ(ARES_ENOMEM, ares__readaddrinfo(fp, "example.com", port, &hints, &ai)) << ii; - } - fclose(fp); -} - +TEST_F(DefaultChannelTest, GetAddrInfoHostsPositive) { + TempFile hostsfile("1.2.3.4 example.com \n" + " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n" + "#comment\n" + "4.5.6.7\n" + "1.3.5.7 \n" + "::1 ipv6.com"); + EnvValue with_env("CARES_HOSTS", hostsfile.filename()); + struct ares_addrinfo_hints hints = {}; + AddrInfoResult result = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "example.com", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + std::stringstream ss; + ss << result.ai_; + EXPECT_EQ("{example.com addr=[1.2.3.4]}", ss.str()); +} + +TEST_F(DefaultChannelTest, GetAddrInfoHostsSpaces) { + TempFile hostsfile("1.2.3.4 example.com \n" + " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n" + "#comment\n" + "4.5.6.7\n" + "1.3.5.7 \n" + "::1 ipv6.com"); + EnvValue with_env("CARES_HOSTS", hostsfile.filename()); + struct ares_addrinfo_hints hints = {}; + AddrInfoResult result = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "google.com", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + std::stringstream ss; + ss << result.ai_; + EXPECT_EQ("{www.google.com->google.com, www2.google.com->google.com addr=[2.3.4.5]}", ss.str()); +} + +TEST_F(DefaultChannelTest, GetAddrInfoHostsByALias) { + TempFile hostsfile("1.2.3.4 example.com \n" + " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n" + "#comment\n" + "4.5.6.7\n" + "1.3.5.7 \n" + "::1 ipv6.com"); + EnvValue with_env("CARES_HOSTS", hostsfile.filename()); + struct ares_addrinfo_hints hints = {}; + AddrInfoResult result = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www2.google.com", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + std::stringstream ss; + ss << result.ai_; + EXPECT_EQ("{www.google.com->google.com, www2.google.com->google.com addr=[2.3.4.5]}", ss.str()); +} + +TEST_F(DefaultChannelTest, GetAddrInfoHostsIPV6) { + TempFile hostsfile("1.2.3.4 example.com \n" + " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n" + "#comment\n" + "4.5.6.7\n" + "1.3.5.7 \n" + "::1 ipv6.com"); + EnvValue with_env("CARES_HOSTS", hostsfile.filename()); + struct ares_addrinfo_hints hints = {}; + AddrInfoResult result = {}; + hints.ai_family = AF_INET6; + hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "ipv6.com", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + std::stringstream ss; + ss << result.ai_; + EXPECT_EQ("{ipv6.com addr=[[0000:0000:0000:0000:0000:0000:0000:0001]]}", ss.str()); +} + +TEST_F(LibraryTest, GetAddrInfoAllocFail) { + TempFile hostsfile("1.2.3.4 example.com alias1 alias2\n"); + struct ares_addrinfo_hints hints; + unsigned short port = 80; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + + FILE *fp = fopen(hostsfile.filename(), "r"); + ASSERT_NE(nullptr, fp); + + for (int ii = 1; ii <= 3; ii++) { + rewind(fp); + ClearFails(); + SetAllocFail(ii); + struct ares_addrinfo ai; + EXPECT_EQ(ARES_ENOMEM, ares__readaddrinfo(fp, "example.com", port, &hints, &ai)) << ii; + } + fclose(fp); +} + TEST(Misc, OnionDomain) { EXPECT_EQ(0, ares__is_onion_domain("onion.no")); EXPECT_EQ(0, ares__is_onion_domain(".onion.no")); @@ -484,23 +484,23 @@ TEST_F(LibraryTest, Striendstr) { const char *str = "plugh"; EXPECT_NE(nullptr, ares_striendstr(str, str)); } -extern "C" int ares__single_domain(ares_channel, const char*, char**); +extern "C" int ares__single_domain(ares_channel, const char*, char**); TEST_F(DefaultChannelTest, SingleDomain) { TempFile aliases("www www.google.com\n"); EnvValue with_env("HOSTALIASES", aliases.filename()); SetAllocSizeFail(128); char *ptr = nullptr; - EXPECT_EQ(ARES_ENOMEM, ares__single_domain(channel_, "www", &ptr)); + EXPECT_EQ(ARES_ENOMEM, ares__single_domain(channel_, "www", &ptr)); channel_->flags |= ARES_FLAG_NOSEARCH|ARES_FLAG_NOALIASES; - EXPECT_EQ(ARES_SUCCESS, ares__single_domain(channel_, "www", &ptr)); + EXPECT_EQ(ARES_SUCCESS, ares__single_domain(channel_, "www", &ptr)); EXPECT_EQ("www", std::string(ptr)); ares_free(ptr); ptr = nullptr; SetAllocFail(1); - EXPECT_EQ(ARES_ENOMEM, ares__single_domain(channel_, "www", &ptr)); + EXPECT_EQ(ARES_ENOMEM, ares__single_domain(channel_, "www", &ptr)); EXPECT_EQ(nullptr, ptr); } #endif diff --git a/contrib/libs/c-ares/test/ares-test-live.cc b/contrib/libs/c-ares/test/ares-test-live.cc index 5510163e95..7d27cbc9d4 100644 --- a/contrib/libs/c-ares/test/ares-test-live.cc +++ b/contrib/libs/c-ares/test/ares-test-live.cc @@ -18,70 +18,70 @@ unsigned char gdns_addr4[4] = {0x08, 0x08, 0x08, 0x08}; unsigned char gdns_addr6[16] = {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88}; -MATCHER_P(IncludesAtLeastNumAddresses, n, "") { - if(!arg) - return false; - int cnt = 0; - for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) - cnt++; - return cnt >= n; -} - -MATCHER_P(OnlyIncludesAddrType, addrtype, "") { - if(!arg) - return false; - for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) - if (ai->ai_family != addrtype) - return false; - return true; -} - -MATCHER_P(IncludesAddrType, addrtype, "") { - if(!arg) - return false; - for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) - if (ai->ai_family == addrtype) - return true; - return false; -} - -//VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetAddrInfoV4) { - //struct ares_addrinfo_hints hints = {}; - //hints.ai_family = AF_INET; - //AddrInfoResult result; - //ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); - //Process(); - //EXPECT_TRUE(result.done_); - //EXPECT_EQ(ARES_SUCCESS, result.status_); - //EXPECT_THAT(result.ai_, IncludesAtLeastNumAddresses(1)); - //EXPECT_THAT(result.ai_, OnlyIncludesAddrType(AF_INET)); -//} - -//VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetAddrInfoV6) { - //struct ares_addrinfo_hints hints = {}; - //hints.ai_family = AF_INET6; - //AddrInfoResult result; - //ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); - //Process(); - //EXPECT_TRUE(result.done_); - //EXPECT_EQ(ARES_SUCCESS, result.status_); - //EXPECT_THAT(result.ai_, IncludesAtLeastNumAddresses(1)); - //EXPECT_THAT(result.ai_, OnlyIncludesAddrType(AF_INET6)); -//} - -//VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetAddrInfoUnspec) { - //struct ares_addrinfo_hints hints = {}; - //hints.ai_family = AF_UNSPEC; - //AddrInfoResult result; - //ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); - //Process(); - //EXPECT_TRUE(result.done_); - //EXPECT_EQ(ARES_SUCCESS, result.status_); - //EXPECT_THAT(result.ai_, IncludesAtLeastNumAddresses(2)); - //EXPECT_THAT(result.ai_, IncludesAddrType(AF_INET6)); - //EXPECT_THAT(result.ai_, IncludesAddrType(AF_INET)); -//} - +MATCHER_P(IncludesAtLeastNumAddresses, n, "") { + if(!arg) + return false; + int cnt = 0; + for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) + cnt++; + return cnt >= n; +} + +MATCHER_P(OnlyIncludesAddrType, addrtype, "") { + if(!arg) + return false; + for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) + if (ai->ai_family != addrtype) + return false; + return true; +} + +MATCHER_P(IncludesAddrType, addrtype, "") { + if(!arg) + return false; + for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) + if (ai->ai_family == addrtype) + return true; + return false; +} + +//VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetAddrInfoV4) { + //struct ares_addrinfo_hints hints = {}; + //hints.ai_family = AF_INET; + //AddrInfoResult result; + //ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + //Process(); + //EXPECT_TRUE(result.done_); + //EXPECT_EQ(ARES_SUCCESS, result.status_); + //EXPECT_THAT(result.ai_, IncludesAtLeastNumAddresses(1)); + //EXPECT_THAT(result.ai_, OnlyIncludesAddrType(AF_INET)); +//} + +//VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetAddrInfoV6) { + //struct ares_addrinfo_hints hints = {}; + //hints.ai_family = AF_INET6; + //AddrInfoResult result; + //ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + //Process(); + //EXPECT_TRUE(result.done_); + //EXPECT_EQ(ARES_SUCCESS, result.status_); + //EXPECT_THAT(result.ai_, IncludesAtLeastNumAddresses(1)); + //EXPECT_THAT(result.ai_, OnlyIncludesAddrType(AF_INET6)); +//} + +//VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetAddrInfoUnspec) { + //struct ares_addrinfo_hints hints = {}; + //hints.ai_family = AF_UNSPEC; + //AddrInfoResult result; + //ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + //Process(); + //EXPECT_TRUE(result.done_); + //EXPECT_EQ(ARES_SUCCESS, result.status_); + //EXPECT_THAT(result.ai_, IncludesAtLeastNumAddresses(2)); + //EXPECT_THAT(result.ai_, IncludesAddrType(AF_INET6)); + //EXPECT_THAT(result.ai_, IncludesAddrType(AF_INET)); +//} + VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveGetHostByNameV4) { HostResult result; ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result); @@ -214,11 +214,11 @@ TEST_P(DefaultChannelModeTest, LiveGetLocalhostByAddrV4) { EXPECT_EQ(ARES_SUCCESS, result.status_); EXPECT_LT(0, (int)result.host_.addrs_.size()); EXPECT_EQ(AF_INET, result.host_.addrtype_); - // oddly, travis does not resolve to localhost, but a random hostname starting with travis-job - if (result.host_.name_.find("travis-job") == std::string::npos) { - EXPECT_NE(std::string::npos, - result.host_.name_.find("localhost")); - } + // oddly, travis does not resolve to localhost, but a random hostname starting with travis-job + if (result.host_.name_.find("travis-job") == std::string::npos) { + EXPECT_NE(std::string::npos, + result.host_.name_.find("localhost")); + } } } @@ -234,9 +234,9 @@ TEST_P(DefaultChannelModeTest, LiveGetLocalhostByAddrV6) { EXPECT_EQ(ARES_SUCCESS, result.status_); EXPECT_LT(0, (int)result.host_.addrs_.size()); EXPECT_EQ(AF_INET6, result.host_.addrtype_); - const std::string& name = result.host_.name_; - EXPECT_TRUE(std::string::npos != name.find("localhost") || - std::string::npos != name.find("ip6-loopback")); + const std::string& name = result.host_.name_; + EXPECT_TRUE(std::string::npos != name.find("localhost") || + std::string::npos != name.find("ip6-loopback")); } } @@ -696,54 +696,54 @@ TEST_F(DefaultChannelTest, VerifySocketFunctionCallback) { } -TEST_F(DefaultChannelTest, LiveSetServers) { - struct ares_addr_node server1; - struct ares_addr_node server2; - server1.next = &server2; - server1.family = AF_INET; - server1.addr.addr4.s_addr = htonl(0x01020304); - server2.next = nullptr; - server2.family = AF_INET; - server2.addr.addr4.s_addr = htonl(0x02030405); - - // Change not allowed while request is pending - HostResult result; - ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result); - EXPECT_EQ(ARES_ENOTIMP, ares_set_servers(channel_, &server1)); - ares_cancel(channel_); -} - -TEST_F(DefaultChannelTest, LiveSetServersPorts) { - struct ares_addr_port_node server1; - struct ares_addr_port_node server2; - server1.next = &server2; - server1.family = AF_INET; - server1.addr.addr4.s_addr = htonl(0x01020304); - server1.udp_port = 111; - server1.tcp_port = 111; - server2.next = nullptr; - server2.family = AF_INET; - server2.addr.addr4.s_addr = htonl(0x02030405); - server2.udp_port = 0; - server2.tcp_port = 0;; - EXPECT_EQ(ARES_ENODATA, ares_set_servers_ports(nullptr, &server1)); - - // Change not allowed while request is pending - HostResult result; - ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result); - EXPECT_EQ(ARES_ENOTIMP, ares_set_servers_ports(channel_, &server1)); - ares_cancel(channel_); -} - -TEST_F(DefaultChannelTest, LiveSetServersCSV) { - // Change not allowed while request is pending - HostResult result; - ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result); - EXPECT_EQ(ARES_ENOTIMP, ares_set_servers_csv(channel_, "1.2.3.4,2.3.4.5")); - EXPECT_EQ(ARES_ENOTIMP, ares_set_servers_ports_csv(channel_, "1.2.3.4:56,2.3.4.5:67")); - ares_cancel(channel_); -} - - +TEST_F(DefaultChannelTest, LiveSetServers) { + struct ares_addr_node server1; + struct ares_addr_node server2; + server1.next = &server2; + server1.family = AF_INET; + server1.addr.addr4.s_addr = htonl(0x01020304); + server2.next = nullptr; + server2.family = AF_INET; + server2.addr.addr4.s_addr = htonl(0x02030405); + + // Change not allowed while request is pending + HostResult result; + ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result); + EXPECT_EQ(ARES_ENOTIMP, ares_set_servers(channel_, &server1)); + ares_cancel(channel_); +} + +TEST_F(DefaultChannelTest, LiveSetServersPorts) { + struct ares_addr_port_node server1; + struct ares_addr_port_node server2; + server1.next = &server2; + server1.family = AF_INET; + server1.addr.addr4.s_addr = htonl(0x01020304); + server1.udp_port = 111; + server1.tcp_port = 111; + server2.next = nullptr; + server2.family = AF_INET; + server2.addr.addr4.s_addr = htonl(0x02030405); + server2.udp_port = 0; + server2.tcp_port = 0;; + EXPECT_EQ(ARES_ENODATA, ares_set_servers_ports(nullptr, &server1)); + + // Change not allowed while request is pending + HostResult result; + ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result); + EXPECT_EQ(ARES_ENOTIMP, ares_set_servers_ports(channel_, &server1)); + ares_cancel(channel_); +} + +TEST_F(DefaultChannelTest, LiveSetServersCSV) { + // Change not allowed while request is pending + HostResult result; + ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result); + EXPECT_EQ(ARES_ENOTIMP, ares_set_servers_csv(channel_, "1.2.3.4,2.3.4.5")); + EXPECT_EQ(ARES_ENOTIMP, ares_set_servers_ports_csv(channel_, "1.2.3.4:56,2.3.4.5:67")); + ares_cancel(channel_); +} + + } // namespace test } // namespace ares diff --git a/contrib/libs/c-ares/test/ares-test-misc.cc b/contrib/libs/c-ares/test/ares-test-misc.cc index 6fc28a8f97..c79f67ba1f 100644 --- a/contrib/libs/c-ares/test/ares-test-misc.cc +++ b/contrib/libs/c-ares/test/ares-test-misc.cc @@ -277,15 +277,15 @@ TEST_F(DefaultChannelTest, HostByNameFileOnionDomain) { ares_gethostbyname_file(channel_, "dontleak.onion", AF_INET, &h)); } -TEST_F(DefaultChannelTest, GetAddrinfoOnionDomain) { - AddrInfoResult result; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_UNSPEC; - ares_getaddrinfo(channel_, "dontleak.onion", NULL, &hints, AddrInfoCallback, &result); - EXPECT_TRUE(result.done_); - EXPECT_EQ(ARES_ENOTFOUND, result.status_); -} - +TEST_F(DefaultChannelTest, GetAddrinfoOnionDomain) { + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_UNSPEC; + ares_getaddrinfo(channel_, "dontleak.onion", NULL, &hints, AddrInfoCallback, &result); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_ENOTFOUND, result.status_); +} + // Interesting question: should tacking on a search domain let the query // through? It seems safer to reject it because "supersecret.onion.search" // still leaks information about the query to malicious resolvers. diff --git a/contrib/libs/c-ares/test/ares-test-mock-ai.cc b/contrib/libs/c-ares/test/ares-test-mock-ai.cc index d0df867fef..700333b826 100644 --- a/contrib/libs/c-ares/test/ares-test-mock-ai.cc +++ b/contrib/libs/c-ares/test/ares-test-mock-ai.cc @@ -1,723 +1,723 @@ -#include "ares-test-ai.h" -#include "dns-proto.h" - -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif - -#include <sstream> -#include <vector> - -using testing::InvokeWithoutArgs; -using testing::DoAll; - -namespace ares { -namespace test { - -MATCHER_P(IncludesNumAddresses, n, "") { - if(!arg) - return false; - int cnt = 0; - for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) - cnt++; - return n == cnt; -} - -MATCHER_P(IncludesV4Address, address, "") { - if(!arg) - return false; - in_addr addressnum = {}; - if (!ares_inet_pton(AF_INET, address, &addressnum)) - return false; // wrong number format? - for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) { - if (ai->ai_family != AF_INET) - continue; - if (reinterpret_cast<sockaddr_in*>(ai->ai_addr)->sin_addr.s_addr == - addressnum.s_addr) - return true; // found - } - return false; -} - -MATCHER_P(IncludesV6Address, address, "") { - if(!arg) - return false; - in6_addr addressnum = {}; - if (!ares_inet_pton(AF_INET6, address, &addressnum)) { - return false; // wrong number format? - } - for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) { - if (ai->ai_family != AF_INET6) - continue; - if (!memcmp( - reinterpret_cast<sockaddr_in6*>(ai->ai_addr)->sin6_addr.s6_addr, - addressnum.s6_addr, sizeof(addressnum.s6_addr))) - return true; // found - } - return false; -} - -// UDP only so mock server doesn't get confused by concatenated requests -TEST_P(MockUDPChannelTestAI, GetAddrInfoParallelLookups) { - DNSPacket rsp1; - rsp1.set_response().set_aa() - .add_question(new DNSQuestion("www.google.com", ns_t_a)) - .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5})); - ON_CALL(server_, OnRequest("www.google.com", ns_t_a)) - .WillByDefault(SetReply(&server_, &rsp1)); - DNSPacket rsp2; - rsp2.set_response().set_aa() - .add_question(new DNSQuestion("www.example.com", ns_t_a)) - .add_answer(new DNSARR("www.example.com", 100, {1, 2, 3, 4})); - ON_CALL(server_, OnRequest("www.example.com", ns_t_a)) - .WillByDefault(SetReply(&server_, &rsp2)); - - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_NOSORT; - AddrInfoResult result1; - ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result1); - AddrInfoResult result2; - ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result2); - AddrInfoResult result3; - ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result3); - Process(); - - EXPECT_TRUE(result1.done_); - EXPECT_EQ(result1.status_, ARES_SUCCESS); - EXPECT_THAT(result1.ai_, IncludesNumAddresses(1)); - EXPECT_THAT(result1.ai_, IncludesV4Address("2.3.4.5")); - - EXPECT_TRUE(result2.done_); - EXPECT_EQ(result2.status_, ARES_SUCCESS); - EXPECT_THAT(result2.ai_, IncludesNumAddresses(1)); - EXPECT_THAT(result2.ai_, IncludesV4Address("1.2.3.4")); - - EXPECT_TRUE(result3.done_); - EXPECT_EQ(result3.status_, ARES_SUCCESS); - EXPECT_THAT(result3.ai_, IncludesNumAddresses(1)); - EXPECT_THAT(result3.ai_, IncludesV4Address("2.3.4.5")); -} - -// UDP to TCP specific test -TEST_P(MockUDPChannelTestAI, TruncationRetry) { - DNSPacket rsptruncated; - rsptruncated.set_response().set_aa().set_tc() - .add_question(new DNSQuestion("www.google.com", ns_t_a)); - DNSPacket rspok; - rspok.set_response() - .add_question(new DNSQuestion("www.google.com", ns_t_a)) - .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4})); - EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) - .WillOnce(SetReply(&server_, &rsptruncated)) - .WillOnce(SetReply(&server_, &rspok)); - - AddrInfoResult result; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - EXPECT_EQ(result.status_, ARES_SUCCESS); - EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); - EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4")); -} - -// TCP only to prevent retries -TEST_P(MockTCPChannelTestAI, MalformedResponse) { - std::vector<byte> one = {0x01}; - EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) - .WillOnce(SetReplyData(&server_, one)); - - AddrInfoResult result; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - EXPECT_EQ(ARES_ETIMEOUT, result.status_); -} - -TEST_P(MockTCPChannelTestAI, FormErrResponse) { - DNSPacket rsp; - rsp.set_response().set_aa() - .add_question(new DNSQuestion("www.google.com", ns_t_a)); - rsp.set_rcode(ns_r_formerr); - EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) - .WillOnce(SetReply(&server_, &rsp)); - - AddrInfoResult result; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - EXPECT_EQ(ARES_EFORMERR, result.status_); -} - -TEST_P(MockTCPChannelTestAI, ServFailResponse) { - DNSPacket rsp; - rsp.set_response().set_aa() - .add_question(new DNSQuestion("www.google.com", ns_t_a)); - rsp.set_rcode(ns_r_servfail); - EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) - .WillOnce(SetReply(&server_, &rsp)); - - AddrInfoResult result; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - // ARES_FLAG_NOCHECKRESP not set, so SERVFAIL consumed - EXPECT_EQ(ARES_ECONNREFUSED, result.status_); -} - -TEST_P(MockTCPChannelTestAI, NotImplResponse) { - DNSPacket rsp; - rsp.set_response().set_aa() - .add_question(new DNSQuestion("www.google.com", ns_t_a)); - rsp.set_rcode(ns_r_notimpl); - EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) - .WillOnce(SetReply(&server_, &rsp)); - - AddrInfoResult result; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - // ARES_FLAG_NOCHECKRESP not set, so NOTIMPL consumed - EXPECT_EQ(ARES_ECONNREFUSED, result.status_); -} - -TEST_P(MockTCPChannelTestAI, RefusedResponse) { - DNSPacket rsp; - rsp.set_response().set_aa() - .add_question(new DNSQuestion("www.google.com", ns_t_a)); - rsp.set_rcode(ns_r_refused); - EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) - .WillOnce(SetReply(&server_, &rsp)); - - AddrInfoResult result; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - // ARES_FLAG_NOCHECKRESP not set, so REFUSED consumed - EXPECT_EQ(ARES_ECONNREFUSED, result.status_); -} - -TEST_P(MockTCPChannelTestAI, YXDomainResponse) { - DNSPacket rsp; - rsp.set_response().set_aa() - .add_question(new DNSQuestion("www.google.com", ns_t_a)); - rsp.set_rcode(ns_r_yxdomain); - EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) - .WillOnce(SetReply(&server_, &rsp)); - - AddrInfoResult result; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - EXPECT_EQ(ARES_ENODATA, result.status_); -} - -class MockExtraOptsTestAI - : public MockChannelOptsTest, - public ::testing::WithParamInterface< std::pair<int, bool> > { - public: - MockExtraOptsTestAI() - : MockChannelOptsTest(1, GetParam().first, GetParam().second, - FillOptions(&opts_), - ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF) {} - static struct ares_options* FillOptions(struct ares_options * opts) { - memset(opts, 0, sizeof(struct ares_options)); - // Set a few options that affect socket communications - opts->socket_send_buffer_size = 514; - opts->socket_receive_buffer_size = 514; - return opts; - } - private: - struct ares_options opts_; -}; - -TEST_P(MockExtraOptsTestAI, SimpleQuery) { - ares_set_local_ip4(channel_, 0x7F000001); - byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; - ares_set_local_ip6(channel_, addr6); - ares_set_local_dev(channel_, "dummy"); - - DNSPacket rsp; - rsp.set_response().set_aa() - .add_question(new DNSQuestion("www.google.com", ns_t_a)) - .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5})); - ON_CALL(server_, OnRequest("www.google.com", ns_t_a)) - .WillByDefault(SetReply(&server_, &rsp)); - - AddrInfoResult result; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - EXPECT_EQ(ARES_SUCCESS, result.status_); - EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); - EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5")); -} - -class MockFlagsChannelOptsTestAI - : public MockChannelOptsTest, - public ::testing::WithParamInterface< std::pair<int, bool> > { - public: - MockFlagsChannelOptsTestAI(int flags) - : MockChannelOptsTest(1, GetParam().first, GetParam().second, - FillOptions(&opts_, flags), ARES_OPT_FLAGS) {} - static struct ares_options* FillOptions(struct ares_options * opts, int flags) { - memset(opts, 0, sizeof(struct ares_options)); - opts->flags = flags; - return opts; - } - private: - struct ares_options opts_; -}; - -class MockNoCheckRespChannelTestAI : public MockFlagsChannelOptsTestAI { - public: - MockNoCheckRespChannelTestAI() : MockFlagsChannelOptsTestAI(ARES_FLAG_NOCHECKRESP) {} -}; - -TEST_P(MockNoCheckRespChannelTestAI, ServFailResponse) { - DNSPacket rsp; - rsp.set_response().set_aa() - .add_question(new DNSQuestion("www.google.com", ns_t_a)); - rsp.set_rcode(ns_r_servfail); - ON_CALL(server_, OnRequest("www.google.com", ns_t_a)) - .WillByDefault(SetReply(&server_, &rsp)); - - AddrInfoResult result; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - EXPECT_EQ(ARES_ESERVFAIL, result.status_); -} - -TEST_P(MockNoCheckRespChannelTestAI, NotImplResponse) { - DNSPacket rsp; - rsp.set_response().set_aa() - .add_question(new DNSQuestion("www.google.com", ns_t_a)); - rsp.set_rcode(ns_r_notimpl); - ON_CALL(server_, OnRequest("www.google.com", ns_t_a)) - .WillByDefault(SetReply(&server_, &rsp)); - - AddrInfoResult result; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - EXPECT_EQ(ARES_ENOTIMP, result.status_); -} - -TEST_P(MockNoCheckRespChannelTestAI, RefusedResponse) { - DNSPacket rsp; - rsp.set_response().set_aa() - .add_question(new DNSQuestion("www.google.com", ns_t_a)); - rsp.set_rcode(ns_r_refused); - ON_CALL(server_, OnRequest("www.google.com", ns_t_a)) - .WillByDefault(SetReply(&server_, &rsp)); - - AddrInfoResult result; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - EXPECT_EQ(ARES_EREFUSED, result.status_); -} - -TEST_P(MockChannelTestAI, FamilyV6) { - DNSPacket rsp6; - rsp6.set_response().set_aa() - .add_question(new DNSQuestion("example.com", ns_t_aaaa)) - .add_answer(new DNSAaaaRR("example.com", 100, - {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03})); - ON_CALL(server_, OnRequest("example.com", ns_t_aaaa)) - .WillByDefault(SetReply(&server_, &rsp6)); - AddrInfoResult result; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET6; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "example.com.", NULL, &hints, - AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); - EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303")); -} - -TEST_P(MockChannelTestAI, FamilyV4) { - DNSPacket rsp4; - rsp4.set_response().set_aa() - .add_question(new DNSQuestion("example.com", ns_t_a)) - .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5})); - ON_CALL(server_, OnRequest("example.com", ns_t_a)) - .WillByDefault(SetReply(&server_, &rsp4)); - AddrInfoResult result = {}; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "example.com.", NULL, &hints, - AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); - EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5")); -} - -TEST_P(MockChannelTestAI, FamilyV4_MultipleAddresses) { - DNSPacket rsp4; - rsp4.set_response().set_aa() - .add_question(new DNSQuestion("example.com", ns_t_a)) - .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5})) - .add_answer(new DNSARR("example.com", 100, {7, 8, 9, 0})); - ON_CALL(server_, OnRequest("example.com", ns_t_a)) - .WillByDefault(SetReply(&server_, &rsp4)); - AddrInfoResult result = {}; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "example.com.", NULL, &hints, - AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - std::stringstream ss; - ss << result.ai_; - EXPECT_EQ("{addr=[2.3.4.5], addr=[7.8.9.0]}", ss.str()); -} - -TEST_P(MockChannelTestAI, FamilyUnspecified) { - DNSPacket rsp6; - rsp6.set_response().set_aa() - .add_question(new DNSQuestion("example.com", ns_t_aaaa)) - .add_answer(new DNSAaaaRR("example.com", 100, - {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03})); - ON_CALL(server_, OnRequest("example.com", ns_t_aaaa)) - .WillByDefault(SetReply(&server_, &rsp6)); - DNSPacket rsp4; - rsp4.set_response().set_aa() - .add_question(new DNSQuestion("example.com", ns_t_a)) - .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5})); - ON_CALL(server_, OnRequest("example.com", ns_t_a)) - .WillByDefault(SetReply(&server_, &rsp4)); - AddrInfoResult result; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_UNSPEC; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "example.com.", NULL, &hints, - AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - EXPECT_THAT(result.ai_, IncludesNumAddresses(2)); - EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5")); - EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303")); -} - -class MockEDNSChannelTestAI : public MockFlagsChannelOptsTestAI { - public: - MockEDNSChannelTestAI() : MockFlagsChannelOptsTestAI(ARES_FLAG_EDNS) {} -}; - -TEST_P(MockEDNSChannelTestAI, RetryWithoutEDNS) { - DNSPacket rspfail; - rspfail.set_response().set_aa().set_rcode(ns_r_servfail) - .add_question(new DNSQuestion("www.google.com", ns_t_a)); - DNSPacket rspok; - rspok.set_response() - .add_question(new DNSQuestion("www.google.com", ns_t_a)) - .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4})); - EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) - .WillOnce(SetReply(&server_, &rspfail)) - .WillOnce(SetReply(&server_, &rspok)); - - AddrInfoResult result; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); - EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4")); -} - -TEST_P(MockChannelTestAI, SearchDomains) { - DNSPacket nofirst; - nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain) - .add_question(new DNSQuestion("www.first.com", ns_t_a)); - ON_CALL(server_, OnRequest("www.first.com", ns_t_a)) - .WillByDefault(SetReply(&server_, &nofirst)); - DNSPacket nosecond; - nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain) - .add_question(new DNSQuestion("www.second.org", ns_t_a)); - ON_CALL(server_, OnRequest("www.second.org", ns_t_a)) - .WillByDefault(SetReply(&server_, &nosecond)); - DNSPacket yesthird; - yesthird.set_response().set_aa() - .add_question(new DNSQuestion("www.third.gov", ns_t_a)) - .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5})); - ON_CALL(server_, OnRequest("www.third.gov", ns_t_a)) - .WillByDefault(SetReply(&server_, &yesthird)); - - AddrInfoResult result; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "www", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); - EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5")); -} - -TEST_P(MockChannelTestAI, SearchDomainsServFailOnAAAA) { - DNSPacket nofirst; - nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain) - .add_question(new DNSQuestion("www.first.com", ns_t_aaaa)); - ON_CALL(server_, OnRequest("www.first.com", ns_t_aaaa)) - .WillByDefault(SetReply(&server_, &nofirst)); - DNSPacket nofirst4; - nofirst4.set_response().set_aa().set_rcode(ns_r_nxdomain) - .add_question(new DNSQuestion("www.first.com", ns_t_a)); - ON_CALL(server_, OnRequest("www.first.com", ns_t_a)) - .WillByDefault(SetReply(&server_, &nofirst4)); - - DNSPacket nosecond; - nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain) - .add_question(new DNSQuestion("www.second.org", ns_t_aaaa)); - ON_CALL(server_, OnRequest("www.second.org", ns_t_aaaa)) - .WillByDefault(SetReply(&server_, &nosecond)); - DNSPacket yessecond4; - yessecond4.set_response().set_aa() - .add_question(new DNSQuestion("www.second.org", ns_t_a)) - .add_answer(new DNSARR("www.second.org", 0x0200, {2, 3, 4, 5})); - ON_CALL(server_, OnRequest("www.second.org", ns_t_a)) - .WillByDefault(SetReply(&server_, &yessecond4)); - - DNSPacket failthird; - failthird.set_response().set_aa().set_rcode(ns_r_servfail) - .add_question(new DNSQuestion("www.third.gov", ns_t_aaaa)); - ON_CALL(server_, OnRequest("www.third.gov", ns_t_aaaa)) - .WillByDefault(SetReply(&server_, &failthird)); - DNSPacket failthird4; - failthird4.set_response().set_aa().set_rcode(ns_r_servfail) - .add_question(new DNSQuestion("www.third.gov", ns_t_a)); - ON_CALL(server_, OnRequest("www.third.gov", ns_t_a)) - .WillByDefault(SetReply(&server_, &failthird4)); - - AddrInfoResult result; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_UNSPEC; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "www", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); - EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5")); -} - -class MockMultiServerChannelTestAI - : public MockChannelOptsTest, - public ::testing::WithParamInterface< std::pair<int, bool> > { - public: - MockMultiServerChannelTestAI(bool rotate) - : MockChannelOptsTest(3, GetParam().first, GetParam().second, nullptr, rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE) {} - void CheckExample() { - AddrInfoResult result; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - EXPECT_EQ(result.status_, ARES_SUCCESS); - EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); - EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5")); - } -}; - -class RotateMultiMockTestAI : public MockMultiServerChannelTestAI { - public: - RotateMultiMockTestAI() : MockMultiServerChannelTestAI(true) {} -}; - -class NoRotateMultiMockTestAI : public MockMultiServerChannelTestAI { - public: - NoRotateMultiMockTestAI() : MockMultiServerChannelTestAI(false) {} -}; - - -TEST_P(RotateMultiMockTestAI, ThirdServer) { - struct ares_options opts = {0}; - int optmask = 0; - EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask)); - EXPECT_EQ(0, (optmask & ARES_OPT_NOROTATE)); - ares_destroy_options(&opts); - - DNSPacket servfailrsp; - servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail) - .add_question(new DNSQuestion("www.example.com", ns_t_a)); - DNSPacket notimplrsp; - notimplrsp.set_response().set_aa().set_rcode(ns_r_notimpl) - .add_question(new DNSQuestion("www.example.com", ns_t_a)); - DNSPacket okrsp; - okrsp.set_response().set_aa() - .add_question(new DNSQuestion("www.example.com", ns_t_a)) - .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5})); - - EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a)) - .WillOnce(SetReply(servers_[0].get(), &servfailrsp)); - EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a)) - .WillOnce(SetReply(servers_[1].get(), ¬implrsp)); - EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a)) - .WillOnce(SetReply(servers_[2].get(), &okrsp)); - CheckExample(); - - // Second time around, starts from server [1]. - EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a)) - .WillOnce(SetReply(servers_[1].get(), &servfailrsp)); - EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a)) - .WillOnce(SetReply(servers_[2].get(), ¬implrsp)); - EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a)) - .WillOnce(SetReply(servers_[0].get(), &okrsp)); - CheckExample(); - - // Third time around, starts from server [2]. - EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a)) - .WillOnce(SetReply(servers_[2].get(), &servfailrsp)); - EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a)) - .WillOnce(SetReply(servers_[0].get(), ¬implrsp)); - EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a)) - .WillOnce(SetReply(servers_[1].get(), &okrsp)); - CheckExample(); -} - -TEST_P(NoRotateMultiMockTestAI, ThirdServer) { - struct ares_options opts = {0}; - int optmask = 0; - EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask)); - EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE)); - ares_destroy_options(&opts); - - DNSPacket servfailrsp; - servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail) - .add_question(new DNSQuestion("www.example.com", ns_t_a)); - DNSPacket notimplrsp; - notimplrsp.set_response().set_aa().set_rcode(ns_r_notimpl) - .add_question(new DNSQuestion("www.example.com", ns_t_a)); - DNSPacket okrsp; - okrsp.set_response().set_aa() - .add_question(new DNSQuestion("www.example.com", ns_t_a)) - .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5})); - - EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a)) - .WillOnce(SetReply(servers_[0].get(), &servfailrsp)); - EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a)) - .WillOnce(SetReply(servers_[1].get(), ¬implrsp)); - EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a)) - .WillOnce(SetReply(servers_[2].get(), &okrsp)); - CheckExample(); - - // Second time around, still starts from server [0]. - EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a)) - .WillOnce(SetReply(servers_[0].get(), &servfailrsp)); - EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a)) - .WillOnce(SetReply(servers_[1].get(), ¬implrsp)); - EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a)) - .WillOnce(SetReply(servers_[2].get(), &okrsp)); - CheckExample(); - - // Third time around, still starts from server [0]. - EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a)) - .WillOnce(SetReply(servers_[0].get(), &servfailrsp)); - EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a)) - .WillOnce(SetReply(servers_[1].get(), ¬implrsp)); - EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a)) - .WillOnce(SetReply(servers_[2].get(), &okrsp)); - CheckExample(); -} - -TEST_P(MockChannelTestAI, FamilyV4ServiceName) { - DNSPacket rsp4; - rsp4.set_response().set_aa() - .add_question(new DNSQuestion("example.com", ns_t_a)) - .add_answer(new DNSARR("example.com", 100, {1, 1, 1, 1})) - .add_answer(new DNSARR("example.com", 100, {2, 2, 2, 2})); - ON_CALL(server_, OnRequest("example.com", ns_t_a)) - .WillByDefault(SetReply(&server_, &rsp4)); - AddrInfoResult result = {}; - struct ares_addrinfo_hints hints = {}; - hints.ai_family = AF_INET; - hints.ai_flags = ARES_AI_NOSORT; - ares_getaddrinfo(channel_, "example.com", "http", &hints, AddrInfoCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - std::stringstream ss; - ss << result.ai_; - EXPECT_EQ("{addr=[1.1.1.1:80], addr=[2.2.2.2:80]}", ss.str()); -} - -// force-tcp does currently not work, possibly test DNS server swallows -// bytes from second query -//INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockChannelTestAI, -// ::testing::ValuesIn(ares::test::families_modes)); -//const std::vector<std::pair<int, bool>> both_families_udponly = { -// std::make_pair<int, bool>(AF_INET, false), -// std::make_pair<int, bool>(AF_INET6, false) -//}; -INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockChannelTestAI, - ::testing::Values(std::make_pair<int, bool>(AF_INET, false))); - -INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockUDPChannelTestAI, - ::testing::ValuesIn(ares::test::families)); - -INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockTCPChannelTestAI, - ::testing::ValuesIn(ares::test::families)); - -INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockExtraOptsTestAI, - ::testing::ValuesIn(ares::test::families_modes)); - -INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockNoCheckRespChannelTestAI, - ::testing::ValuesIn(ares::test::families_modes)); - -INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockEDNSChannelTestAI, - ::testing::ValuesIn(ares::test::families_modes)); - -INSTANTIATE_TEST_CASE_P(TransportModesAI, RotateMultiMockTestAI, - ::testing::ValuesIn(ares::test::families_modes)); - -INSTANTIATE_TEST_CASE_P(TransportModesAI, NoRotateMultiMockTestAI, - ::testing::ValuesIn(ares::test::families_modes)); - - -} // namespace test -} // namespace ares +#include "ares-test-ai.h" +#include "dns-proto.h" + +#ifdef HAVE_NETINET_IN_H +#include <netinet/in.h> +#endif + +#include <sstream> +#include <vector> + +using testing::InvokeWithoutArgs; +using testing::DoAll; + +namespace ares { +namespace test { + +MATCHER_P(IncludesNumAddresses, n, "") { + if(!arg) + return false; + int cnt = 0; + for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) + cnt++; + return n == cnt; +} + +MATCHER_P(IncludesV4Address, address, "") { + if(!arg) + return false; + in_addr addressnum = {}; + if (!ares_inet_pton(AF_INET, address, &addressnum)) + return false; // wrong number format? + for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) { + if (ai->ai_family != AF_INET) + continue; + if (reinterpret_cast<sockaddr_in*>(ai->ai_addr)->sin_addr.s_addr == + addressnum.s_addr) + return true; // found + } + return false; +} + +MATCHER_P(IncludesV6Address, address, "") { + if(!arg) + return false; + in6_addr addressnum = {}; + if (!ares_inet_pton(AF_INET6, address, &addressnum)) { + return false; // wrong number format? + } + for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) { + if (ai->ai_family != AF_INET6) + continue; + if (!memcmp( + reinterpret_cast<sockaddr_in6*>(ai->ai_addr)->sin6_addr.s6_addr, + addressnum.s6_addr, sizeof(addressnum.s6_addr))) + return true; // found + } + return false; +} + +// UDP only so mock server doesn't get confused by concatenated requests +TEST_P(MockUDPChannelTestAI, GetAddrInfoParallelLookups) { + DNSPacket rsp1; + rsp1.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)) + .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5})); + ON_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp1)); + DNSPacket rsp2; + rsp2.set_response().set_aa() + .add_question(new DNSQuestion("www.example.com", ns_t_a)) + .add_answer(new DNSARR("www.example.com", 100, {1, 2, 3, 4})); + ON_CALL(server_, OnRequest("www.example.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp2)); + + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + AddrInfoResult result1; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result1); + AddrInfoResult result2; + ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result2); + AddrInfoResult result3; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result3); + Process(); + + EXPECT_TRUE(result1.done_); + EXPECT_EQ(result1.status_, ARES_SUCCESS); + EXPECT_THAT(result1.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result1.ai_, IncludesV4Address("2.3.4.5")); + + EXPECT_TRUE(result2.done_); + EXPECT_EQ(result2.status_, ARES_SUCCESS); + EXPECT_THAT(result2.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result2.ai_, IncludesV4Address("1.2.3.4")); + + EXPECT_TRUE(result3.done_); + EXPECT_EQ(result3.status_, ARES_SUCCESS); + EXPECT_THAT(result3.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result3.ai_, IncludesV4Address("2.3.4.5")); +} + +// UDP to TCP specific test +TEST_P(MockUDPChannelTestAI, TruncationRetry) { + DNSPacket rsptruncated; + rsptruncated.set_response().set_aa().set_tc() + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + DNSPacket rspok; + rspok.set_response() + .add_question(new DNSQuestion("www.google.com", ns_t_a)) + .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4})); + EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillOnce(SetReply(&server_, &rsptruncated)) + .WillOnce(SetReply(&server_, &rspok)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(result.status_, ARES_SUCCESS); + EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4")); +} + +// TCP only to prevent retries +TEST_P(MockTCPChannelTestAI, MalformedResponse) { + std::vector<byte> one = {0x01}; + EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillOnce(SetReplyData(&server_, one)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_ETIMEOUT, result.status_); +} + +TEST_P(MockTCPChannelTestAI, FormErrResponse) { + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + rsp.set_rcode(ns_r_formerr); + EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillOnce(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_EFORMERR, result.status_); +} + +TEST_P(MockTCPChannelTestAI, ServFailResponse) { + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + rsp.set_rcode(ns_r_servfail); + EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillOnce(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + // ARES_FLAG_NOCHECKRESP not set, so SERVFAIL consumed + EXPECT_EQ(ARES_ECONNREFUSED, result.status_); +} + +TEST_P(MockTCPChannelTestAI, NotImplResponse) { + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + rsp.set_rcode(ns_r_notimpl); + EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillOnce(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + // ARES_FLAG_NOCHECKRESP not set, so NOTIMPL consumed + EXPECT_EQ(ARES_ECONNREFUSED, result.status_); +} + +TEST_P(MockTCPChannelTestAI, RefusedResponse) { + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + rsp.set_rcode(ns_r_refused); + EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillOnce(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + // ARES_FLAG_NOCHECKRESP not set, so REFUSED consumed + EXPECT_EQ(ARES_ECONNREFUSED, result.status_); +} + +TEST_P(MockTCPChannelTestAI, YXDomainResponse) { + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + rsp.set_rcode(ns_r_yxdomain); + EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillOnce(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_ENODATA, result.status_); +} + +class MockExtraOptsTestAI + : public MockChannelOptsTest, + public ::testing::WithParamInterface< std::pair<int, bool> > { + public: + MockExtraOptsTestAI() + : MockChannelOptsTest(1, GetParam().first, GetParam().second, + FillOptions(&opts_), + ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF) {} + static struct ares_options* FillOptions(struct ares_options * opts) { + memset(opts, 0, sizeof(struct ares_options)); + // Set a few options that affect socket communications + opts->socket_send_buffer_size = 514; + opts->socket_receive_buffer_size = 514; + return opts; + } + private: + struct ares_options opts_; +}; + +TEST_P(MockExtraOptsTestAI, SimpleQuery) { + ares_set_local_ip4(channel_, 0x7F000001); + byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; + ares_set_local_ip6(channel_, addr6); + ares_set_local_dev(channel_, "dummy"); + + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)) + .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5})); + ON_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_SUCCESS, result.status_); + EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5")); +} + +class MockFlagsChannelOptsTestAI + : public MockChannelOptsTest, + public ::testing::WithParamInterface< std::pair<int, bool> > { + public: + MockFlagsChannelOptsTestAI(int flags) + : MockChannelOptsTest(1, GetParam().first, GetParam().second, + FillOptions(&opts_, flags), ARES_OPT_FLAGS) {} + static struct ares_options* FillOptions(struct ares_options * opts, int flags) { + memset(opts, 0, sizeof(struct ares_options)); + opts->flags = flags; + return opts; + } + private: + struct ares_options opts_; +}; + +class MockNoCheckRespChannelTestAI : public MockFlagsChannelOptsTestAI { + public: + MockNoCheckRespChannelTestAI() : MockFlagsChannelOptsTestAI(ARES_FLAG_NOCHECKRESP) {} +}; + +TEST_P(MockNoCheckRespChannelTestAI, ServFailResponse) { + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + rsp.set_rcode(ns_r_servfail); + ON_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_ESERVFAIL, result.status_); +} + +TEST_P(MockNoCheckRespChannelTestAI, NotImplResponse) { + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + rsp.set_rcode(ns_r_notimpl); + ON_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_ENOTIMP, result.status_); +} + +TEST_P(MockNoCheckRespChannelTestAI, RefusedResponse) { + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + rsp.set_rcode(ns_r_refused); + ON_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_EREFUSED, result.status_); +} + +TEST_P(MockChannelTestAI, FamilyV6) { + DNSPacket rsp6; + rsp6.set_response().set_aa() + .add_question(new DNSQuestion("example.com", ns_t_aaaa)) + .add_answer(new DNSAaaaRR("example.com", 100, + {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03})); + ON_CALL(server_, OnRequest("example.com", ns_t_aaaa)) + .WillByDefault(SetReply(&server_, &rsp6)); + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET6; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "example.com.", NULL, &hints, + AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303")); +} + +TEST_P(MockChannelTestAI, FamilyV4) { + DNSPacket rsp4; + rsp4.set_response().set_aa() + .add_question(new DNSQuestion("example.com", ns_t_a)) + .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5})); + ON_CALL(server_, OnRequest("example.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp4)); + AddrInfoResult result = {}; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "example.com.", NULL, &hints, + AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5")); +} + +TEST_P(MockChannelTestAI, FamilyV4_MultipleAddresses) { + DNSPacket rsp4; + rsp4.set_response().set_aa() + .add_question(new DNSQuestion("example.com", ns_t_a)) + .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5})) + .add_answer(new DNSARR("example.com", 100, {7, 8, 9, 0})); + ON_CALL(server_, OnRequest("example.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp4)); + AddrInfoResult result = {}; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "example.com.", NULL, &hints, + AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + std::stringstream ss; + ss << result.ai_; + EXPECT_EQ("{addr=[2.3.4.5], addr=[7.8.9.0]}", ss.str()); +} + +TEST_P(MockChannelTestAI, FamilyUnspecified) { + DNSPacket rsp6; + rsp6.set_response().set_aa() + .add_question(new DNSQuestion("example.com", ns_t_aaaa)) + .add_answer(new DNSAaaaRR("example.com", 100, + {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03})); + ON_CALL(server_, OnRequest("example.com", ns_t_aaaa)) + .WillByDefault(SetReply(&server_, &rsp6)); + DNSPacket rsp4; + rsp4.set_response().set_aa() + .add_question(new DNSQuestion("example.com", ns_t_a)) + .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5})); + ON_CALL(server_, OnRequest("example.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp4)); + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_UNSPEC; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "example.com.", NULL, &hints, + AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_THAT(result.ai_, IncludesNumAddresses(2)); + EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5")); + EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303")); +} + +class MockEDNSChannelTestAI : public MockFlagsChannelOptsTestAI { + public: + MockEDNSChannelTestAI() : MockFlagsChannelOptsTestAI(ARES_FLAG_EDNS) {} +}; + +TEST_P(MockEDNSChannelTestAI, RetryWithoutEDNS) { + DNSPacket rspfail; + rspfail.set_response().set_aa().set_rcode(ns_r_servfail) + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + DNSPacket rspok; + rspok.set_response() + .add_question(new DNSQuestion("www.google.com", ns_t_a)) + .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4})); + EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillOnce(SetReply(&server_, &rspfail)) + .WillOnce(SetReply(&server_, &rspok)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4")); +} + +TEST_P(MockChannelTestAI, SearchDomains) { + DNSPacket nofirst; + nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain) + .add_question(new DNSQuestion("www.first.com", ns_t_a)); + ON_CALL(server_, OnRequest("www.first.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &nofirst)); + DNSPacket nosecond; + nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain) + .add_question(new DNSQuestion("www.second.org", ns_t_a)); + ON_CALL(server_, OnRequest("www.second.org", ns_t_a)) + .WillByDefault(SetReply(&server_, &nosecond)); + DNSPacket yesthird; + yesthird.set_response().set_aa() + .add_question(new DNSQuestion("www.third.gov", ns_t_a)) + .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5})); + ON_CALL(server_, OnRequest("www.third.gov", ns_t_a)) + .WillByDefault(SetReply(&server_, &yesthird)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5")); +} + +TEST_P(MockChannelTestAI, SearchDomainsServFailOnAAAA) { + DNSPacket nofirst; + nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain) + .add_question(new DNSQuestion("www.first.com", ns_t_aaaa)); + ON_CALL(server_, OnRequest("www.first.com", ns_t_aaaa)) + .WillByDefault(SetReply(&server_, &nofirst)); + DNSPacket nofirst4; + nofirst4.set_response().set_aa().set_rcode(ns_r_nxdomain) + .add_question(new DNSQuestion("www.first.com", ns_t_a)); + ON_CALL(server_, OnRequest("www.first.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &nofirst4)); + + DNSPacket nosecond; + nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain) + .add_question(new DNSQuestion("www.second.org", ns_t_aaaa)); + ON_CALL(server_, OnRequest("www.second.org", ns_t_aaaa)) + .WillByDefault(SetReply(&server_, &nosecond)); + DNSPacket yessecond4; + yessecond4.set_response().set_aa() + .add_question(new DNSQuestion("www.second.org", ns_t_a)) + .add_answer(new DNSARR("www.second.org", 0x0200, {2, 3, 4, 5})); + ON_CALL(server_, OnRequest("www.second.org", ns_t_a)) + .WillByDefault(SetReply(&server_, &yessecond4)); + + DNSPacket failthird; + failthird.set_response().set_aa().set_rcode(ns_r_servfail) + .add_question(new DNSQuestion("www.third.gov", ns_t_aaaa)); + ON_CALL(server_, OnRequest("www.third.gov", ns_t_aaaa)) + .WillByDefault(SetReply(&server_, &failthird)); + DNSPacket failthird4; + failthird4.set_response().set_aa().set_rcode(ns_r_servfail) + .add_question(new DNSQuestion("www.third.gov", ns_t_a)); + ON_CALL(server_, OnRequest("www.third.gov", ns_t_a)) + .WillByDefault(SetReply(&server_, &failthird4)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_UNSPEC; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5")); +} + +class MockMultiServerChannelTestAI + : public MockChannelOptsTest, + public ::testing::WithParamInterface< std::pair<int, bool> > { + public: + MockMultiServerChannelTestAI(bool rotate) + : MockChannelOptsTest(3, GetParam().first, GetParam().second, nullptr, rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE) {} + void CheckExample() { + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(result.status_, ARES_SUCCESS); + EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5")); + } +}; + +class RotateMultiMockTestAI : public MockMultiServerChannelTestAI { + public: + RotateMultiMockTestAI() : MockMultiServerChannelTestAI(true) {} +}; + +class NoRotateMultiMockTestAI : public MockMultiServerChannelTestAI { + public: + NoRotateMultiMockTestAI() : MockMultiServerChannelTestAI(false) {} +}; + + +TEST_P(RotateMultiMockTestAI, ThirdServer) { + struct ares_options opts = {0}; + int optmask = 0; + EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask)); + EXPECT_EQ(0, (optmask & ARES_OPT_NOROTATE)); + ares_destroy_options(&opts); + + DNSPacket servfailrsp; + servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail) + .add_question(new DNSQuestion("www.example.com", ns_t_a)); + DNSPacket notimplrsp; + notimplrsp.set_response().set_aa().set_rcode(ns_r_notimpl) + .add_question(new DNSQuestion("www.example.com", ns_t_a)); + DNSPacket okrsp; + okrsp.set_response().set_aa() + .add_question(new DNSQuestion("www.example.com", ns_t_a)) + .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5})); + + EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[0].get(), &servfailrsp)); + EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[1].get(), ¬implrsp)); + EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[2].get(), &okrsp)); + CheckExample(); + + // Second time around, starts from server [1]. + EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[1].get(), &servfailrsp)); + EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[2].get(), ¬implrsp)); + EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[0].get(), &okrsp)); + CheckExample(); + + // Third time around, starts from server [2]. + EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[2].get(), &servfailrsp)); + EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[0].get(), ¬implrsp)); + EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[1].get(), &okrsp)); + CheckExample(); +} + +TEST_P(NoRotateMultiMockTestAI, ThirdServer) { + struct ares_options opts = {0}; + int optmask = 0; + EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask)); + EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE)); + ares_destroy_options(&opts); + + DNSPacket servfailrsp; + servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail) + .add_question(new DNSQuestion("www.example.com", ns_t_a)); + DNSPacket notimplrsp; + notimplrsp.set_response().set_aa().set_rcode(ns_r_notimpl) + .add_question(new DNSQuestion("www.example.com", ns_t_a)); + DNSPacket okrsp; + okrsp.set_response().set_aa() + .add_question(new DNSQuestion("www.example.com", ns_t_a)) + .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5})); + + EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[0].get(), &servfailrsp)); + EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[1].get(), ¬implrsp)); + EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[2].get(), &okrsp)); + CheckExample(); + + // Second time around, still starts from server [0]. + EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[0].get(), &servfailrsp)); + EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[1].get(), ¬implrsp)); + EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[2].get(), &okrsp)); + CheckExample(); + + // Third time around, still starts from server [0]. + EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[0].get(), &servfailrsp)); + EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[1].get(), ¬implrsp)); + EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[2].get(), &okrsp)); + CheckExample(); +} + +TEST_P(MockChannelTestAI, FamilyV4ServiceName) { + DNSPacket rsp4; + rsp4.set_response().set_aa() + .add_question(new DNSQuestion("example.com", ns_t_a)) + .add_answer(new DNSARR("example.com", 100, {1, 1, 1, 1})) + .add_answer(new DNSARR("example.com", 100, {2, 2, 2, 2})); + ON_CALL(server_, OnRequest("example.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp4)); + AddrInfoResult result = {}; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "example.com", "http", &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + std::stringstream ss; + ss << result.ai_; + EXPECT_EQ("{addr=[1.1.1.1:80], addr=[2.2.2.2:80]}", ss.str()); +} + +// force-tcp does currently not work, possibly test DNS server swallows +// bytes from second query +//INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockChannelTestAI, +// ::testing::ValuesIn(ares::test::families_modes)); +//const std::vector<std::pair<int, bool>> both_families_udponly = { +// std::make_pair<int, bool>(AF_INET, false), +// std::make_pair<int, bool>(AF_INET6, false) +//}; +INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockChannelTestAI, + ::testing::Values(std::make_pair<int, bool>(AF_INET, false))); + +INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockUDPChannelTestAI, + ::testing::ValuesIn(ares::test::families)); + +INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockTCPChannelTestAI, + ::testing::ValuesIn(ares::test::families)); + +INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockExtraOptsTestAI, + ::testing::ValuesIn(ares::test::families_modes)); + +INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockNoCheckRespChannelTestAI, + ::testing::ValuesIn(ares::test::families_modes)); + +INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockEDNSChannelTestAI, + ::testing::ValuesIn(ares::test::families_modes)); + +INSTANTIATE_TEST_CASE_P(TransportModesAI, RotateMultiMockTestAI, + ::testing::ValuesIn(ares::test::families_modes)); + +INSTANTIATE_TEST_CASE_P(TransportModesAI, NoRotateMultiMockTestAI, + ::testing::ValuesIn(ares::test::families_modes)); + + +} // namespace test +} // namespace ares diff --git a/contrib/libs/c-ares/test/ares-test-mock.cc b/contrib/libs/c-ares/test/ares-test-mock.cc index 80e9fc02b0..99a3c6a2bf 100644 --- a/contrib/libs/c-ares/test/ares-test-mock.cc +++ b/contrib/libs/c-ares/test/ares-test-mock.cc @@ -51,7 +51,7 @@ TEST_P(MockChannelTest, Basic) { } // UDP only so mock server doesn't get confused by concatenated requests -TEST_P(MockUDPChannelTest, GetHostByNameParallelLookups) { +TEST_P(MockUDPChannelTest, GetHostByNameParallelLookups) { DNSPacket rsp1; rsp1.set_response().set_aa() .add_question(new DNSQuestion("www.google.com", ns_t_a)) @@ -936,21 +936,21 @@ TEST_P(MockChannelTest, GetHostByNameDestroyRelative) { EXPECT_EQ(0, result.timeouts_); } -TEST_P(MockChannelTest, GetHostByNameCNAMENoData) { - DNSPacket response; - response.set_response().set_aa() - .add_question(new DNSQuestion("cname.first.com", ns_t_a)) - .add_answer(new DNSCnameRR("cname.first.com", 100, "a.first.com")); - ON_CALL(server_, OnRequest("cname.first.com", ns_t_a)) - .WillByDefault(SetReply(&server_, &response)); - - HostResult result; - ares_gethostbyname(channel_, "cname.first.com", AF_INET, HostCallback, &result); - Process(); - EXPECT_TRUE(result.done_); - EXPECT_EQ(ARES_ENODATA, result.status_); -} - +TEST_P(MockChannelTest, GetHostByNameCNAMENoData) { + DNSPacket response; + response.set_response().set_aa() + .add_question(new DNSQuestion("cname.first.com", ns_t_a)) + .add_answer(new DNSCnameRR("cname.first.com", 100, "a.first.com")); + ON_CALL(server_, OnRequest("cname.first.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &response)); + + HostResult result; + ares_gethostbyname(channel_, "cname.first.com", AF_INET, HostCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_ENODATA, result.status_); +} + TEST_P(MockChannelTest, GetHostByAddrDestroy) { unsigned char gdns_addr4[4] = {0x08, 0x08, 0x08, 0x08}; HostResult result; diff --git a/contrib/libs/c-ares/test/ares-test-parse-a.cc b/contrib/libs/c-ares/test/ares-test-parse-a.cc index 7f6a987c13..6cdaba58ac 100644 --- a/contrib/libs/c-ares/test/ares-test-parse-a.cc +++ b/contrib/libs/c-ares/test/ares-test-parse-a.cc @@ -11,14 +11,14 @@ TEST_F(LibraryTest, ParseAReplyOK) { DNSPacket pkt; pkt.set_qid(0x1234).set_response().set_aa() .add_question(new DNSQuestion("example.com", ns_t_a)) - .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5})) - .add_answer(new DNSAaaaRR("example.com", 0x01020304, {0,0,0,0,0,0,0,0,0,0,0,0,2,3,4,5})); + .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5})) + .add_answer(new DNSAaaaRR("example.com", 0x01020304, {0,0,0,0,0,0,0,0,0,0,0,0,2,3,4,5})); std::vector<byte> data = { 0x12, 0x34, // qid 0x84, // response + query + AA + not-TC + not-RD 0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError 0x00, 0x01, // num questions - 0x00, 0x02, // num answer RRs + 0x00, 0x02, // num answer RRs 0x00, 0x00, // num authority RRs 0x00, 0x00, // num additional RRs // Question @@ -36,15 +36,15 @@ TEST_F(LibraryTest, ParseAReplyOK) { 0x01, 0x02, 0x03, 0x04, // TTL 0x00, 0x04, // rdata length 0x02, 0x03, 0x04, 0x05, - // Answer 2 - 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', - 0x03, 'c', 'o', 'm', - 0x00, - 0x00, 0x1c, // RR type - 0x00, 0x01, // class IN - 0x01, 0x02, 0x03, 0x04, // TTL - 0x00, 0x10, // rdata length - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x04, 0x05, + // Answer 2 + 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', + 0x03, 'c', 'o', 'm', + 0x00, + 0x00, 0x1c, // RR type + 0x00, 0x01, // class IN + 0x01, 0x02, 0x03, 0x04, // TTL + 0x00, 0x10, // rdata length + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x04, 0x05, }; EXPECT_EQ(data, pkt.data()); struct hostent *host = nullptr; @@ -78,7 +78,7 @@ TEST_F(LibraryTest, ParseMalformedAReply) { 0x84, // [2] response + query + AA + not-TC + not-RD 0x00, // [3] not-RA + not-Z + not-AD + not-CD + rc=NoError 0x00, 0x01, // [4:6) num questions - 0x00, 0x02, // [6:8) num answer RRs + 0x00, 0x02, // [6:8) num answer RRs 0x00, 0x00, // [8:10) num authority RRs 0x00, 0x00, // [10:12) num additional RRs // Question @@ -131,16 +131,16 @@ TEST_F(LibraryTest, ParseAReplyNoData) { // Again but with a CNAME. pkt.add_answer(new DNSCnameRR("example.com", 200, "c.example.com")); - data = pkt.data(); - // Expect success as per https://github.com/c-ares/c-ares/commit/2c63440127feed70ccefb148b8f938a2df6c15f8 - EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(), + data = pkt.data(); + // Expect success as per https://github.com/c-ares/c-ares/commit/2c63440127feed70ccefb148b8f938a2df6c15f8 + EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(), &host, info, &count)); EXPECT_EQ(0, count); - EXPECT_NE(nullptr, host); - std::stringstream ss; - ss << HostEnt(host); - EXPECT_EQ("{'c.example.com' aliases=[example.com] addrs=[]}", ss.str()); - ares_free_hostent(host); + EXPECT_NE(nullptr, host); + std::stringstream ss; + ss << HostEnt(host); + EXPECT_EQ("{'c.example.com' aliases=[example.com] addrs=[]}", ss.str()); + ares_free_hostent(host); } TEST_F(LibraryTest, ParseAReplyVariantA) { diff --git a/contrib/libs/c-ares/test/ares-test-parse-aaaa.cc b/contrib/libs/c-ares/test/ares-test-parse-aaaa.cc index 1314c837a6..371438fca3 100644 --- a/contrib/libs/c-ares/test/ares-test-parse-aaaa.cc +++ b/contrib/libs/c-ares/test/ares-test-parse-aaaa.cc @@ -13,8 +13,8 @@ TEST_F(LibraryTest, ParseAaaaReplyOK) { .add_question(new DNSQuestion("example.com", ns_t_aaaa)) .add_answer(new DNSAaaaRR("example.com", 100, {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, - 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04})) - .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5})); + 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04})) + .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5})); std::vector<byte> data = pkt.data(); struct hostent *host = nullptr; struct ares_addr6ttl info[5]; diff --git a/contrib/libs/c-ares/test/ares-test-parse-soa-any.cc b/contrib/libs/c-ares/test/ares-test-parse-soa-any.cc index 804c6a0060..2e2c3f9db4 100644 --- a/contrib/libs/c-ares/test/ares-test-parse-soa-any.cc +++ b/contrib/libs/c-ares/test/ares-test-parse-soa-any.cc @@ -1,111 +1,111 @@ -#include "ares-test.h" -#include "dns-proto.h" - -#include <sstream> -#include <vector> - -namespace ares { -namespace test { - -TEST_F(LibraryTest, ParseSoaAnyReplyOK) { - DNSPacket pkt; - pkt.set_qid(0x1234).set_response().set_aa() - .add_question(new DNSQuestion("example.com", ns_t_any))\ - .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5})) - .add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com")) - .add_answer(new DNSMxRR("example.com", 100, 200, "mx2.example.com")) - .add_answer(new DNSSoaRR("example.com", 100, - "soa1.example.com", "fred.example.com", - 1, 2, 3, 4, 5)); - std::vector<byte> data = pkt.data(); - - struct ares_soa_reply* soa = nullptr; - EXPECT_EQ(ARES_SUCCESS, ares_parse_soa_reply(data.data(), data.size(), &soa)); - ASSERT_NE(nullptr, soa); - EXPECT_EQ("soa1.example.com", std::string(soa->nsname)); - EXPECT_EQ("fred.example.com", std::string(soa->hostmaster)); - EXPECT_EQ(1, soa->serial); - EXPECT_EQ(2, soa->refresh); - EXPECT_EQ(3, soa->retry); - EXPECT_EQ(4, soa->expire); - EXPECT_EQ(5, soa->minttl); - ares_free_data(soa); -} - -TEST_F(LibraryTest, ParseSoaAnyReplyErrors) { - DNSPacket pkt; - pkt.set_qid(0x1234).set_response().set_aa() - .add_question(new DNSQuestion("example.com", ns_t_any)) - .add_answer(new DNSSoaRR("example.com", 100, - "soa1.example.com", "fred.example.com", - 1, 2, 3, 4, 5)); - std::vector<byte> data; - struct ares_soa_reply* soa = nullptr; - - // No question. - pkt.questions_.clear(); - data = pkt.data(); - EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa)); - pkt.add_question(new DNSQuestion("example.com", ns_t_any)); - -#ifdef DISABLED - // Question != answer - pkt.questions_.clear(); - pkt.add_question(new DNSQuestion("Axample.com", ns_t_any)); - data = pkt.data(); - EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa)); - pkt.questions_.clear(); - pkt.add_question(new DNSQuestion("example.com", ns_t_any)); -#endif - - // Two questions - pkt.add_question(new DNSQuestion("example.com", ns_t_any)); - data = pkt.data(); - EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa)); - pkt.questions_.clear(); - pkt.add_question(new DNSQuestion("example.com", ns_t_any)); - - // Wrong sort of answer. - pkt.answers_.clear(); - pkt.add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com")); - data = pkt.data(); - EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa)); - pkt.answers_.clear(); - pkt.add_answer(new DNSSoaRR("example.com", 100, - "soa1.example.com", "fred.example.com", - 1, 2, 3, 4, 5)); - - // No answer. - pkt.answers_.clear(); - data = pkt.data(); - EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa)); - pkt.add_answer(new DNSSoaRR("example.com", 100, - "soa1.example.com", "fred.example.com", - 1, 2, 3, 4, 5)); - - // Truncated packets. - data = pkt.data(); - for (size_t len = 1; len < data.size(); len++) { - EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), len, &soa)); - } -} - -TEST_F(LibraryTest, ParseSoaAnyReplyAllocFail) { - DNSPacket pkt; - pkt.set_qid(0x1234).set_response().set_aa() - .add_question(new DNSQuestion("example.com", ns_t_any)) - .add_answer(new DNSSoaRR("example.com", 100, - "soa1.example.com", "fred.example.com", - 1, 2, 3, 4, 5)); - std::vector<byte> data = pkt.data(); - struct ares_soa_reply* soa = nullptr; - - for (int ii = 1; ii <= 5; ii++) { - ClearFails(); - SetAllocFail(ii); - EXPECT_EQ(ARES_ENOMEM, ares_parse_soa_reply(data.data(), data.size(), &soa)) << ii; - } -} - -} // namespace test -} // namespace ares +#include "ares-test.h" +#include "dns-proto.h" + +#include <sstream> +#include <vector> + +namespace ares { +namespace test { + +TEST_F(LibraryTest, ParseSoaAnyReplyOK) { + DNSPacket pkt; + pkt.set_qid(0x1234).set_response().set_aa() + .add_question(new DNSQuestion("example.com", ns_t_any))\ + .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5})) + .add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com")) + .add_answer(new DNSMxRR("example.com", 100, 200, "mx2.example.com")) + .add_answer(new DNSSoaRR("example.com", 100, + "soa1.example.com", "fred.example.com", + 1, 2, 3, 4, 5)); + std::vector<byte> data = pkt.data(); + + struct ares_soa_reply* soa = nullptr; + EXPECT_EQ(ARES_SUCCESS, ares_parse_soa_reply(data.data(), data.size(), &soa)); + ASSERT_NE(nullptr, soa); + EXPECT_EQ("soa1.example.com", std::string(soa->nsname)); + EXPECT_EQ("fred.example.com", std::string(soa->hostmaster)); + EXPECT_EQ(1, soa->serial); + EXPECT_EQ(2, soa->refresh); + EXPECT_EQ(3, soa->retry); + EXPECT_EQ(4, soa->expire); + EXPECT_EQ(5, soa->minttl); + ares_free_data(soa); +} + +TEST_F(LibraryTest, ParseSoaAnyReplyErrors) { + DNSPacket pkt; + pkt.set_qid(0x1234).set_response().set_aa() + .add_question(new DNSQuestion("example.com", ns_t_any)) + .add_answer(new DNSSoaRR("example.com", 100, + "soa1.example.com", "fred.example.com", + 1, 2, 3, 4, 5)); + std::vector<byte> data; + struct ares_soa_reply* soa = nullptr; + + // No question. + pkt.questions_.clear(); + data = pkt.data(); + EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa)); + pkt.add_question(new DNSQuestion("example.com", ns_t_any)); + +#ifdef DISABLED + // Question != answer + pkt.questions_.clear(); + pkt.add_question(new DNSQuestion("Axample.com", ns_t_any)); + data = pkt.data(); + EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa)); + pkt.questions_.clear(); + pkt.add_question(new DNSQuestion("example.com", ns_t_any)); +#endif + + // Two questions + pkt.add_question(new DNSQuestion("example.com", ns_t_any)); + data = pkt.data(); + EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa)); + pkt.questions_.clear(); + pkt.add_question(new DNSQuestion("example.com", ns_t_any)); + + // Wrong sort of answer. + pkt.answers_.clear(); + pkt.add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com")); + data = pkt.data(); + EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa)); + pkt.answers_.clear(); + pkt.add_answer(new DNSSoaRR("example.com", 100, + "soa1.example.com", "fred.example.com", + 1, 2, 3, 4, 5)); + + // No answer. + pkt.answers_.clear(); + data = pkt.data(); + EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa)); + pkt.add_answer(new DNSSoaRR("example.com", 100, + "soa1.example.com", "fred.example.com", + 1, 2, 3, 4, 5)); + + // Truncated packets. + data = pkt.data(); + for (size_t len = 1; len < data.size(); len++) { + EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), len, &soa)); + } +} + +TEST_F(LibraryTest, ParseSoaAnyReplyAllocFail) { + DNSPacket pkt; + pkt.set_qid(0x1234).set_response().set_aa() + .add_question(new DNSQuestion("example.com", ns_t_any)) + .add_answer(new DNSSoaRR("example.com", 100, + "soa1.example.com", "fred.example.com", + 1, 2, 3, 4, 5)); + std::vector<byte> data = pkt.data(); + struct ares_soa_reply* soa = nullptr; + + for (int ii = 1; ii <= 5; ii++) { + ClearFails(); + SetAllocFail(ii); + EXPECT_EQ(ARES_ENOMEM, ares_parse_soa_reply(data.data(), data.size(), &soa)) << ii; + } +} + +} // namespace test +} // namespace ares diff --git a/contrib/libs/c-ares/test/ares-test-parse-soa.cc b/contrib/libs/c-ares/test/ares-test-parse-soa.cc index c0ffaaed50..3ef95ec7f1 100644 --- a/contrib/libs/c-ares/test/ares-test-parse-soa.cc +++ b/contrib/libs/c-ares/test/ares-test-parse-soa.cc @@ -50,7 +50,7 @@ TEST_F(LibraryTest, ParseSoaReplyErrors) { pkt.questions_.clear(); pkt.add_question(new DNSQuestion("Axample.com", ns_t_soa)); data = pkt.data(); - EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa)); + EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa)); pkt.questions_.clear(); pkt.add_question(new DNSQuestion("example.com", ns_t_soa)); #endif diff --git a/contrib/libs/c-ares/test/ares-test.cc b/contrib/libs/c-ares/test/ares-test.cc index ec4b460549..8c85b4ef93 100644 --- a/contrib/libs/c-ares/test/ares-test.cc +++ b/contrib/libs/c-ares/test/ares-test.cc @@ -1,5 +1,5 @@ #include "ares-test.h" -#include "ares-test-ai.h" +#include "ares-test-ai.h" #include "dns-proto.h" // Include ares internal files for DNS protocol details @@ -565,79 +565,79 @@ void HostCallback(void *data, int status, int timeouts, if (verbose) std::cerr << "HostCallback(" << *result << ")" << std::endl; } -std::ostream& operator<<(std::ostream& os, const AddrInfoResult& result) { - os << '{'; - if (result.done_ && result.ai_) { - os << StatusToString(result.status_) << " " << result.ai_; - } else { - os << "(incomplete)"; - } - os << '}'; - return os; -} - -std::ostream& operator<<(std::ostream& os, const AddrInfo& ai) { - os << '{'; - if (ai == nullptr) { - os << "nullptr}"; - return os; - } - - struct ares_addrinfo_cname *next_cname = ai->cnames; - while(next_cname) { - if(next_cname->alias) { - os << next_cname->alias << "->"; - } - if(next_cname->name) { - os << next_cname->name; - } - if((next_cname = next_cname->next)) - os << ", "; - else - os << " "; - } - - struct ares_addrinfo_node *next = ai->nodes; - while(next) { - //if(next->ai_canonname) { - //os << "'" << next->ai_canonname << "' "; - //} - unsigned short port = 0; - os << "addr=["; - if(next->ai_family == AF_INET) { - sockaddr_in* sin = (sockaddr_in*)next->ai_addr; - port = ntohs(sin->sin_port); - os << AddressToString(&sin->sin_addr, 4); - } - else if (next->ai_family == AF_INET6) { - sockaddr_in6* sin = (sockaddr_in6*)next->ai_addr; - port = ntohs(sin->sin6_port); - os << "[" << AddressToString(&sin->sin6_addr, 16) << "]"; - } - else - os << "unknown family"; - if(port) { - os << ":" << port; - } - os << "]"; - if((next = next->ai_next)) - os << ", "; - } - os << '}'; - return os; -} - -void AddrInfoCallback(void *data, int status, int timeouts, - struct ares_addrinfo *ai) { - EXPECT_NE(nullptr, data); - AddrInfoResult* result = reinterpret_cast<AddrInfoResult*>(data); - result->done_ = true; - result->status_ = status; - result->timeouts_= timeouts; - result->ai_ = AddrInfo(ai); - if (verbose) std::cerr << "AddrInfoCallback(" << *result << ")" << std::endl; -} - +std::ostream& operator<<(std::ostream& os, const AddrInfoResult& result) { + os << '{'; + if (result.done_ && result.ai_) { + os << StatusToString(result.status_) << " " << result.ai_; + } else { + os << "(incomplete)"; + } + os << '}'; + return os; +} + +std::ostream& operator<<(std::ostream& os, const AddrInfo& ai) { + os << '{'; + if (ai == nullptr) { + os << "nullptr}"; + return os; + } + + struct ares_addrinfo_cname *next_cname = ai->cnames; + while(next_cname) { + if(next_cname->alias) { + os << next_cname->alias << "->"; + } + if(next_cname->name) { + os << next_cname->name; + } + if((next_cname = next_cname->next)) + os << ", "; + else + os << " "; + } + + struct ares_addrinfo_node *next = ai->nodes; + while(next) { + //if(next->ai_canonname) { + //os << "'" << next->ai_canonname << "' "; + //} + unsigned short port = 0; + os << "addr=["; + if(next->ai_family == AF_INET) { + sockaddr_in* sin = (sockaddr_in*)next->ai_addr; + port = ntohs(sin->sin_port); + os << AddressToString(&sin->sin_addr, 4); + } + else if (next->ai_family == AF_INET6) { + sockaddr_in6* sin = (sockaddr_in6*)next->ai_addr; + port = ntohs(sin->sin6_port); + os << "[" << AddressToString(&sin->sin6_addr, 16) << "]"; + } + else + os << "unknown family"; + if(port) { + os << ":" << port; + } + os << "]"; + if((next = next->ai_next)) + os << ", "; + } + os << '}'; + return os; +} + +void AddrInfoCallback(void *data, int status, int timeouts, + struct ares_addrinfo *ai) { + EXPECT_NE(nullptr, data); + AddrInfoResult* result = reinterpret_cast<AddrInfoResult*>(data); + result->done_ = true; + result->status_ = status; + result->timeouts_= timeouts; + result->ai_ = AddrInfo(ai); + if (verbose) std::cerr << "AddrInfoCallback(" << *result << ")" << std::endl; +} + std::ostream& operator<<(std::ostream& os, const SearchResult& result) { os << '{'; if (result.done_) { diff --git a/contrib/libs/c-ares/test/ares-test.h b/contrib/libs/c-ares/test/ares-test.h index fd3bc31c27..541e29a87d 100644 --- a/contrib/libs/c-ares/test/ares-test.h +++ b/contrib/libs/c-ares/test/ares-test.h @@ -276,30 +276,30 @@ struct NameInfoResult { }; std::ostream& operator<<(std::ostream& os, const NameInfoResult& result); -struct AddrInfoDeleter { - void operator() (ares_addrinfo *ptr) { - if (ptr) ares_freeaddrinfo(ptr); - } -}; - -// C++ wrapper for struct ares_addrinfo. -using AddrInfo = std::unique_ptr<ares_addrinfo, AddrInfoDeleter>; - -std::ostream& operator<<(std::ostream& os, const AddrInfo& result); - -// Structure that describes the result of an ares_addrinfo_callback invocation. -struct AddrInfoResult { - AddrInfoResult() : done_(false), status_(-1), timeouts_(0) {} - // Whether the callback has been invoked. - bool done_; - // Explicitly provided result information. - int status_; - int timeouts_; - // Contents of the ares_addrinfo structure, if provided. - AddrInfo ai_; -}; -std::ostream& operator<<(std::ostream& os, const AddrInfoResult& result); - +struct AddrInfoDeleter { + void operator() (ares_addrinfo *ptr) { + if (ptr) ares_freeaddrinfo(ptr); + } +}; + +// C++ wrapper for struct ares_addrinfo. +using AddrInfo = std::unique_ptr<ares_addrinfo, AddrInfoDeleter>; + +std::ostream& operator<<(std::ostream& os, const AddrInfo& result); + +// Structure that describes the result of an ares_addrinfo_callback invocation. +struct AddrInfoResult { + AddrInfoResult() : done_(false), status_(-1), timeouts_(0) {} + // Whether the callback has been invoked. + bool done_; + // Explicitly provided result information. + int status_; + int timeouts_; + // Contents of the ares_addrinfo structure, if provided. + AddrInfo ai_; +}; +std::ostream& operator<<(std::ostream& os, const AddrInfoResult& result); + // Standard implementation of ares callbacks that fill out the corresponding // structures. void HostCallback(void *data, int status, int timeouts, @@ -308,8 +308,8 @@ void SearchCallback(void *data, int status, int timeouts, unsigned char *abuf, int alen); void NameInfoCallback(void *data, int status, int timeouts, char *node, char *service); -void AddrInfoCallback(void *data, int status, int timeouts, - struct ares_addrinfo *res); +void AddrInfoCallback(void *data, int status, int timeouts, + struct ares_addrinfo *res); // Retrieve the name servers used by a channel. std::vector<std::string> GetNameServers(ares_channel channel); @@ -345,40 +345,40 @@ class TempFile : public TransientFile { const char* filename() const { return filename_.c_str(); } }; -#ifdef _WIN32 -extern "C" { - -static int setenv(const char *name, const char *value, int overwrite) -{ - char *buffer; - size_t buf_size; - - if (name == NULL) - return -1; - - if (value == NULL) - value = ""; /* For unset */ - - if (!overwrite && getenv(name) != NULL) { - return -1; - } - - buf_size = strlen(name) + strlen(value) + 1 /* = */ + 1 /* NULL */; - buffer = (char *)malloc(buf_size); - _snprintf(buffer, buf_size, "%s=%s", name, value); - _putenv(buffer); - free(buffer); - return 0; -} - -static int unsetenv(const char *name) -{ - return setenv(name, NULL, 1); -} - -} /* extern "C" */ -#endif - +#ifdef _WIN32 +extern "C" { + +static int setenv(const char *name, const char *value, int overwrite) +{ + char *buffer; + size_t buf_size; + + if (name == NULL) + return -1; + + if (value == NULL) + value = ""; /* For unset */ + + if (!overwrite && getenv(name) != NULL) { + return -1; + } + + buf_size = strlen(name) + strlen(value) + 1 /* = */ + 1 /* NULL */; + buffer = (char *)malloc(buf_size); + _snprintf(buffer, buf_size, "%s=%s", name, value); + _putenv(buffer); + free(buffer); + return 0; +} + +static int unsetenv(const char *name) +{ + return setenv(name, NULL, 1); +} + +} /* extern "C" */ +#endif + // RAII class for a temporary environment variable value. class EnvValue { public: diff --git a/contrib/libs/c-ares/test/ya.make b/contrib/libs/c-ares/test/ya.make index ef42eab230..5eb7f6c6bf 100644 --- a/contrib/libs/c-ares/test/ya.make +++ b/contrib/libs/c-ares/test/ya.make @@ -38,7 +38,7 @@ SRCS( ares-test-internal.cc ares-test-live.cc ares-test-misc.cc - ares-test-mock-ai.cc + ares-test-mock-ai.cc ares-test-mock.cc ares-test-ns.cc ares-test-parse-a.cc @@ -47,7 +47,7 @@ SRCS( ares-test-parse-naptr.cc ares-test-parse-ns.cc ares-test-parse-ptr.cc - ares-test-parse-soa-any.cc + ares-test-parse-soa-any.cc ares-test-parse-soa.cc ares-test-parse-srv.cc ares-test-parse-txt.cc |