aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/c-ares/test
diff options
context:
space:
mode:
authordvshkurko <dvshkurko@yandex-team.ru>2022-02-10 16:45:52 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:52 +0300
commitc768a99151e47c3a4bb7b92c514d256abd301c4d (patch)
tree1a2c5ffcf89eb53ecd79dbc9bc0a195c27404d0c /contrib/libs/c-ares/test
parent321ee9bce31ec6e238be26dbcbe539cffa2c3309 (diff)
downloadydb-c768a99151e47c3a4bb7b92c514d256abd301c4d.tar.gz
Restoring authorship annotation for <dvshkurko@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/libs/c-ares/test')
-rw-r--r--contrib/libs/c-ares/test/ares-test-init.cc1318
-rw-r--r--contrib/libs/c-ares/test/ares-test-internal.cc970
-rw-r--r--contrib/libs/c-ares/test/ares-test-live.cc1258
-rw-r--r--contrib/libs/c-ares/test/ares-test-misc.cc1026
-rw-r--r--contrib/libs/c-ares/test/ares-test-mock.cc2314
-rw-r--r--contrib/libs/c-ares/test/ares-test-ns.cc398
-rw-r--r--contrib/libs/c-ares/test/ares-test-parse-a.cc714
-rw-r--r--contrib/libs/c-ares/test/ares-test-parse-aaaa.cc380
-rw-r--r--contrib/libs/c-ares/test/ares-test-parse-mx.cc282
-rw-r--r--contrib/libs/c-ares/test/ares-test-parse-naptr.cc296
-rw-r--r--contrib/libs/c-ares/test/ares-test-parse-ns.cc238
-rw-r--r--contrib/libs/c-ares/test/ares-test-parse-ptr.cc498
-rw-r--r--contrib/libs/c-ares/test/ares-test-parse-soa.cc214
-rw-r--r--contrib/libs/c-ares/test/ares-test-parse-srv.cc576
-rw-r--r--contrib/libs/c-ares/test/ares-test-parse-txt.cc532
-rw-r--r--contrib/libs/c-ares/test/ares-test-parse.cc438
-rw-r--r--contrib/libs/c-ares/test/ares-test.cc1396
-rw-r--r--contrib/libs/c-ares/test/ares-test.h858
-rw-r--r--contrib/libs/c-ares/test/config.h162
-rw-r--r--contrib/libs/c-ares/test/dns-proto-test.cc262
-rw-r--r--contrib/libs/c-ares/test/dns-proto.cc1276
-rw-r--r--contrib/libs/c-ares/test/dns-proto.h484
-rw-r--r--contrib/libs/c-ares/test/ya.make104
23 files changed, 7997 insertions, 7997 deletions
diff --git a/contrib/libs/c-ares/test/ares-test-init.cc b/contrib/libs/c-ares/test/ares-test-init.cc
index d20a1e7e6f..842b0e15ac 100644
--- a/contrib/libs/c-ares/test/ares-test-init.cc
+++ b/contrib/libs/c-ares/test/ares-test-init.cc
@@ -1,247 +1,247 @@
-#include "ares-test.h"
-
-// library initialization is only needed for windows builds
-#ifdef WIN32
-#define EXPECTED_NONINIT ARES_ENOTINITIALIZED
-#else
-#define EXPECTED_NONINIT ARES_SUCCESS
-#endif
-
-namespace ares {
-namespace test {
-
-TEST(LibraryInit, Basic) {
- EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
- EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
- EXPECT_EQ(ARES_SUCCESS, ares_library_initialized());
- ares_library_cleanup();
- EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
-}
-
-TEST(LibraryInit, UnexpectedCleanup) {
- EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
- ares_library_cleanup();
- EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
-}
-
-TEST(LibraryInit, DISABLED_InvalidParam) {
- // TODO: police flags argument to ares_library_init()
- EXPECT_EQ(ARES_EBADQUERY, ares_library_init(ARES_LIB_INIT_ALL << 2));
- EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
- ares_library_cleanup();
-}
-
-TEST(LibraryInit, Nested) {
- EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
- EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
- EXPECT_EQ(ARES_SUCCESS, ares_library_initialized());
- EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
- EXPECT_EQ(ARES_SUCCESS, ares_library_initialized());
- ares_library_cleanup();
- EXPECT_EQ(ARES_SUCCESS, ares_library_initialized());
- ares_library_cleanup();
- EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
-}
-
-TEST(LibraryInit, BasicChannelInit) {
- EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
- ares_channel channel = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
- EXPECT_NE(nullptr, channel);
- ares_destroy(channel);
- ares_library_cleanup();
-}
-
-TEST_F(LibraryTest, OptionsChannelInit) {
- struct ares_options opts = {0};
- int optmask = 0;
- opts.flags = ARES_FLAG_USEVC | ARES_FLAG_PRIMARY;
- optmask |= ARES_OPT_FLAGS;
- opts.timeout = 2000;
- optmask |= ARES_OPT_TIMEOUTMS;
- opts.tries = 2;
- optmask |= ARES_OPT_TRIES;
- opts.ndots = 4;
- optmask |= ARES_OPT_NDOTS;
- opts.udp_port = 54;
- optmask |= ARES_OPT_UDP_PORT;
- opts.tcp_port = 54;
- optmask |= ARES_OPT_TCP_PORT;
- opts.socket_send_buffer_size = 514;
- optmask |= ARES_OPT_SOCK_SNDBUF;
- opts.socket_receive_buffer_size = 514;
- optmask |= ARES_OPT_SOCK_RCVBUF;
- opts.ednspsz = 1280;
- optmask |= ARES_OPT_EDNSPSZ;
- opts.nservers = 2;
- opts.servers = (struct in_addr *)malloc(opts.nservers * sizeof(struct in_addr));
- opts.servers[0].s_addr = htonl(0x01020304);
- opts.servers[1].s_addr = htonl(0x02030405);
- optmask |= ARES_OPT_SERVERS;
- opts.ndomains = 2;
- opts.domains = (char **)malloc(opts.ndomains * sizeof(char *));
- opts.domains[0] = strdup("example.com");
- opts.domains[1] = strdup("example2.com");
- optmask |= ARES_OPT_DOMAINS;
- opts.lookups = strdup("b");
- optmask |= ARES_OPT_LOOKUPS;
- optmask |= ARES_OPT_ROTATE;
- opts.resolvconf_path = strdup("/etc/resolv.conf");
- optmask |= ARES_OPT_RESOLVCONF;
-
- ares_channel channel = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
- EXPECT_NE(nullptr, channel);
-
- ares_channel channel2 = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_dup(&channel2, channel));
-
- struct ares_options opts2 = {0};
- int optmask2 = 0;
- EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel2, &opts2, &optmask2));
-
- // Note that not all opts-settable fields are saved (e.g.
- // ednspsz, socket_{send,receive}_buffer_size).
- EXPECT_EQ(opts.flags, opts2.flags);
- EXPECT_EQ(opts.timeout, opts2.timeout);
- EXPECT_EQ(opts.tries, opts2.tries);
- EXPECT_EQ(opts.ndots, opts2.ndots);
- EXPECT_EQ(opts.udp_port, opts2.udp_port);
- EXPECT_EQ(opts.tcp_port, opts2.tcp_port);
- EXPECT_EQ(1, opts2.nservers); // Truncated by ARES_FLAG_PRIMARY
- EXPECT_EQ(opts.servers[0].s_addr, opts2.servers[0].s_addr);
- EXPECT_EQ(opts.ndomains, opts2.ndomains);
- EXPECT_EQ(std::string(opts.domains[0]), std::string(opts2.domains[0]));
- EXPECT_EQ(std::string(opts.domains[1]), std::string(opts2.domains[1]));
- EXPECT_EQ(std::string(opts.lookups), std::string(opts2.lookups));
- EXPECT_EQ(std::string(opts.resolvconf_path), std::string(opts2.resolvconf_path));
-
- ares_destroy_options(&opts);
- ares_destroy_options(&opts2);
- ares_destroy(channel);
- ares_destroy(channel2);
-}
-
-TEST_F(LibraryTest, ChannelAllocFail) {
- ares_channel channel;
- for (int ii = 1; ii <= 25; ii++) {
- ClearFails();
- SetAllocFail(ii);
- channel = nullptr;
- int rc = ares_init(&channel);
- // The number of allocations depends on local environment, so don't expect ENOMEM.
- if (rc == ARES_ENOMEM) {
- EXPECT_EQ(nullptr, channel);
- } else {
- ares_destroy(channel);
- }
- }
-}
-
-TEST_F(LibraryTest, OptionsChannelAllocFail) {
- struct ares_options opts = {0};
- int optmask = 0;
- opts.flags = ARES_FLAG_USEVC;
- optmask |= ARES_OPT_FLAGS;
- opts.timeout = 2;
- optmask |= ARES_OPT_TIMEOUT;
- opts.tries = 2;
- optmask |= ARES_OPT_TRIES;
- opts.ndots = 4;
- optmask |= ARES_OPT_NDOTS;
- opts.udp_port = 54;
- optmask |= ARES_OPT_UDP_PORT;
- opts.tcp_port = 54;
- optmask |= ARES_OPT_TCP_PORT;
- opts.socket_send_buffer_size = 514;
- optmask |= ARES_OPT_SOCK_SNDBUF;
- opts.socket_receive_buffer_size = 514;
- optmask |= ARES_OPT_SOCK_RCVBUF;
- opts.ednspsz = 1280;
- optmask |= ARES_OPT_EDNSPSZ;
- opts.nservers = 2;
- opts.servers = (struct in_addr *)malloc(opts.nservers * sizeof(struct in_addr));
- opts.servers[0].s_addr = htonl(0x01020304);
- opts.servers[1].s_addr = htonl(0x02030405);
- optmask |= ARES_OPT_SERVERS;
- opts.ndomains = 2;
- opts.domains = (char **)malloc(opts.ndomains * sizeof(char *));
- opts.domains[0] = strdup("example.com");
- opts.domains[1] = strdup("example2.com");
- optmask |= ARES_OPT_DOMAINS;
- opts.lookups = strdup("b");
- optmask |= ARES_OPT_LOOKUPS;
- optmask |= ARES_OPT_ROTATE;
- opts.resolvconf_path = strdup("/etc/resolv.conf");
- optmask |= ARES_OPT_RESOLVCONF;
-
- ares_channel channel = nullptr;
- for (int ii = 1; ii <= 8; ii++) {
- ClearFails();
- SetAllocFail(ii);
- int rc = ares_init_options(&channel, &opts, optmask);
- if (rc == ARES_ENOMEM) {
- EXPECT_EQ(nullptr, channel);
- } else {
- EXPECT_EQ(ARES_SUCCESS, rc);
- ares_destroy(channel);
- channel = nullptr;
- }
- }
- ClearFails();
-
- EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
- EXPECT_NE(nullptr, channel);
-
- // Add some servers and a sortlist for flavour.
- EXPECT_EQ(ARES_SUCCESS,
- ares_set_servers_csv(channel, "1.2.3.4,0102:0304:0506:0708:0910:1112:1314:1516,2.3.4.5"));
- EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel, "1.2.3.4 2.3.4.5"));
-
- ares_channel channel2 = nullptr;
- for (int ii = 1; ii <= 18; ii++) {
- ClearFails();
- SetAllocFail(ii);
- EXPECT_EQ(ARES_ENOMEM, ares_dup(&channel2, channel)) << ii;
- EXPECT_EQ(nullptr, channel2) << ii;
- }
-
- struct ares_options opts2;
- int optmask2 = 0;
- for (int ii = 1; ii <= 6; ii++) {
- memset(&opts2, 0, sizeof(opts2));
- ClearFails();
- SetAllocFail(ii);
- EXPECT_EQ(ARES_ENOMEM, ares_save_options(channel, &opts2, &optmask2)) << ii;
- // May still have allocations even after ARES_ENOMEM return code.
- ares_destroy_options(&opts2);
- }
- ares_destroy_options(&opts);
- ares_destroy(channel);
-}
-
-TEST_F(LibraryTest, FailChannelInit) {
- EXPECT_EQ(ARES_SUCCESS,
- ares_library_init_mem(ARES_LIB_INIT_ALL,
- &LibraryTest::amalloc,
- &LibraryTest::afree,
- &LibraryTest::arealloc));
- SetAllocFail(1);
- ares_channel channel = nullptr;
- EXPECT_EQ(ARES_ENOMEM, ares_init(&channel));
- EXPECT_EQ(nullptr, channel);
- ares_library_cleanup();
-}
-
-#ifndef WIN32
-TEST_F(LibraryTest, EnvInit) {
- ares_channel channel = nullptr;
- EnvValue v1("LOCALDOMAIN", "this.is.local");
- EnvValue v2("RES_OPTIONS", "options debug ndots:3 retry:3 rotate retrans:2");
- EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
- ares_destroy(channel);
-}
-
+#include "ares-test.h"
+
+// library initialization is only needed for windows builds
+#ifdef WIN32
+#define EXPECTED_NONINIT ARES_ENOTINITIALIZED
+#else
+#define EXPECTED_NONINIT ARES_SUCCESS
+#endif
+
+namespace ares {
+namespace test {
+
+TEST(LibraryInit, Basic) {
+ EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
+ EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
+ EXPECT_EQ(ARES_SUCCESS, ares_library_initialized());
+ ares_library_cleanup();
+ EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
+}
+
+TEST(LibraryInit, UnexpectedCleanup) {
+ EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
+ ares_library_cleanup();
+ EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
+}
+
+TEST(LibraryInit, DISABLED_InvalidParam) {
+ // TODO: police flags argument to ares_library_init()
+ EXPECT_EQ(ARES_EBADQUERY, ares_library_init(ARES_LIB_INIT_ALL << 2));
+ EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
+ ares_library_cleanup();
+}
+
+TEST(LibraryInit, Nested) {
+ EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
+ EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
+ EXPECT_EQ(ARES_SUCCESS, ares_library_initialized());
+ EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
+ EXPECT_EQ(ARES_SUCCESS, ares_library_initialized());
+ ares_library_cleanup();
+ EXPECT_EQ(ARES_SUCCESS, ares_library_initialized());
+ ares_library_cleanup();
+ EXPECT_EQ(EXPECTED_NONINIT, ares_library_initialized());
+}
+
+TEST(LibraryInit, BasicChannelInit) {
+ EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
+ ares_channel channel = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
+ EXPECT_NE(nullptr, channel);
+ ares_destroy(channel);
+ ares_library_cleanup();
+}
+
+TEST_F(LibraryTest, OptionsChannelInit) {
+ struct ares_options opts = {0};
+ int optmask = 0;
+ opts.flags = ARES_FLAG_USEVC | ARES_FLAG_PRIMARY;
+ optmask |= ARES_OPT_FLAGS;
+ opts.timeout = 2000;
+ optmask |= ARES_OPT_TIMEOUTMS;
+ opts.tries = 2;
+ optmask |= ARES_OPT_TRIES;
+ opts.ndots = 4;
+ optmask |= ARES_OPT_NDOTS;
+ opts.udp_port = 54;
+ optmask |= ARES_OPT_UDP_PORT;
+ opts.tcp_port = 54;
+ optmask |= ARES_OPT_TCP_PORT;
+ opts.socket_send_buffer_size = 514;
+ optmask |= ARES_OPT_SOCK_SNDBUF;
+ opts.socket_receive_buffer_size = 514;
+ optmask |= ARES_OPT_SOCK_RCVBUF;
+ opts.ednspsz = 1280;
+ optmask |= ARES_OPT_EDNSPSZ;
+ opts.nservers = 2;
+ opts.servers = (struct in_addr *)malloc(opts.nservers * sizeof(struct in_addr));
+ opts.servers[0].s_addr = htonl(0x01020304);
+ opts.servers[1].s_addr = htonl(0x02030405);
+ optmask |= ARES_OPT_SERVERS;
+ opts.ndomains = 2;
+ opts.domains = (char **)malloc(opts.ndomains * sizeof(char *));
+ opts.domains[0] = strdup("example.com");
+ opts.domains[1] = strdup("example2.com");
+ optmask |= ARES_OPT_DOMAINS;
+ opts.lookups = strdup("b");
+ optmask |= ARES_OPT_LOOKUPS;
+ optmask |= ARES_OPT_ROTATE;
+ opts.resolvconf_path = strdup("/etc/resolv.conf");
+ optmask |= ARES_OPT_RESOLVCONF;
+
+ ares_channel channel = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
+ EXPECT_NE(nullptr, channel);
+
+ ares_channel channel2 = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_dup(&channel2, channel));
+
+ struct ares_options opts2 = {0};
+ int optmask2 = 0;
+ EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel2, &opts2, &optmask2));
+
+ // Note that not all opts-settable fields are saved (e.g.
+ // ednspsz, socket_{send,receive}_buffer_size).
+ EXPECT_EQ(opts.flags, opts2.flags);
+ EXPECT_EQ(opts.timeout, opts2.timeout);
+ EXPECT_EQ(opts.tries, opts2.tries);
+ EXPECT_EQ(opts.ndots, opts2.ndots);
+ EXPECT_EQ(opts.udp_port, opts2.udp_port);
+ EXPECT_EQ(opts.tcp_port, opts2.tcp_port);
+ EXPECT_EQ(1, opts2.nservers); // Truncated by ARES_FLAG_PRIMARY
+ EXPECT_EQ(opts.servers[0].s_addr, opts2.servers[0].s_addr);
+ EXPECT_EQ(opts.ndomains, opts2.ndomains);
+ EXPECT_EQ(std::string(opts.domains[0]), std::string(opts2.domains[0]));
+ EXPECT_EQ(std::string(opts.domains[1]), std::string(opts2.domains[1]));
+ EXPECT_EQ(std::string(opts.lookups), std::string(opts2.lookups));
+ EXPECT_EQ(std::string(opts.resolvconf_path), std::string(opts2.resolvconf_path));
+
+ ares_destroy_options(&opts);
+ ares_destroy_options(&opts2);
+ ares_destroy(channel);
+ ares_destroy(channel2);
+}
+
+TEST_F(LibraryTest, ChannelAllocFail) {
+ ares_channel channel;
+ for (int ii = 1; ii <= 25; ii++) {
+ ClearFails();
+ SetAllocFail(ii);
+ channel = nullptr;
+ int rc = ares_init(&channel);
+ // The number of allocations depends on local environment, so don't expect ENOMEM.
+ if (rc == ARES_ENOMEM) {
+ EXPECT_EQ(nullptr, channel);
+ } else {
+ ares_destroy(channel);
+ }
+ }
+}
+
+TEST_F(LibraryTest, OptionsChannelAllocFail) {
+ struct ares_options opts = {0};
+ int optmask = 0;
+ opts.flags = ARES_FLAG_USEVC;
+ optmask |= ARES_OPT_FLAGS;
+ opts.timeout = 2;
+ optmask |= ARES_OPT_TIMEOUT;
+ opts.tries = 2;
+ optmask |= ARES_OPT_TRIES;
+ opts.ndots = 4;
+ optmask |= ARES_OPT_NDOTS;
+ opts.udp_port = 54;
+ optmask |= ARES_OPT_UDP_PORT;
+ opts.tcp_port = 54;
+ optmask |= ARES_OPT_TCP_PORT;
+ opts.socket_send_buffer_size = 514;
+ optmask |= ARES_OPT_SOCK_SNDBUF;
+ opts.socket_receive_buffer_size = 514;
+ optmask |= ARES_OPT_SOCK_RCVBUF;
+ opts.ednspsz = 1280;
+ optmask |= ARES_OPT_EDNSPSZ;
+ opts.nservers = 2;
+ opts.servers = (struct in_addr *)malloc(opts.nservers * sizeof(struct in_addr));
+ opts.servers[0].s_addr = htonl(0x01020304);
+ opts.servers[1].s_addr = htonl(0x02030405);
+ optmask |= ARES_OPT_SERVERS;
+ opts.ndomains = 2;
+ opts.domains = (char **)malloc(opts.ndomains * sizeof(char *));
+ opts.domains[0] = strdup("example.com");
+ opts.domains[1] = strdup("example2.com");
+ optmask |= ARES_OPT_DOMAINS;
+ opts.lookups = strdup("b");
+ optmask |= ARES_OPT_LOOKUPS;
+ optmask |= ARES_OPT_ROTATE;
+ opts.resolvconf_path = strdup("/etc/resolv.conf");
+ optmask |= ARES_OPT_RESOLVCONF;
+
+ ares_channel channel = nullptr;
+ for (int ii = 1; ii <= 8; ii++) {
+ ClearFails();
+ SetAllocFail(ii);
+ int rc = ares_init_options(&channel, &opts, optmask);
+ if (rc == ARES_ENOMEM) {
+ EXPECT_EQ(nullptr, channel);
+ } else {
+ EXPECT_EQ(ARES_SUCCESS, rc);
+ ares_destroy(channel);
+ channel = nullptr;
+ }
+ }
+ ClearFails();
+
+ EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
+ EXPECT_NE(nullptr, channel);
+
+ // Add some servers and a sortlist for flavour.
+ EXPECT_EQ(ARES_SUCCESS,
+ ares_set_servers_csv(channel, "1.2.3.4,0102:0304:0506:0708:0910:1112:1314:1516,2.3.4.5"));
+ EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel, "1.2.3.4 2.3.4.5"));
+
+ ares_channel channel2 = nullptr;
+ for (int ii = 1; ii <= 18; ii++) {
+ ClearFails();
+ SetAllocFail(ii);
+ EXPECT_EQ(ARES_ENOMEM, ares_dup(&channel2, channel)) << ii;
+ EXPECT_EQ(nullptr, channel2) << ii;
+ }
+
+ struct ares_options opts2;
+ int optmask2 = 0;
+ for (int ii = 1; ii <= 6; ii++) {
+ memset(&opts2, 0, sizeof(opts2));
+ ClearFails();
+ SetAllocFail(ii);
+ EXPECT_EQ(ARES_ENOMEM, ares_save_options(channel, &opts2, &optmask2)) << ii;
+ // May still have allocations even after ARES_ENOMEM return code.
+ ares_destroy_options(&opts2);
+ }
+ ares_destroy_options(&opts);
+ ares_destroy(channel);
+}
+
+TEST_F(LibraryTest, FailChannelInit) {
+ EXPECT_EQ(ARES_SUCCESS,
+ ares_library_init_mem(ARES_LIB_INIT_ALL,
+ &LibraryTest::amalloc,
+ &LibraryTest::afree,
+ &LibraryTest::arealloc));
+ SetAllocFail(1);
+ ares_channel channel = nullptr;
+ EXPECT_EQ(ARES_ENOMEM, ares_init(&channel));
+ EXPECT_EQ(nullptr, channel);
+ ares_library_cleanup();
+}
+
+#ifndef WIN32
+TEST_F(LibraryTest, EnvInit) {
+ ares_channel channel = nullptr;
+ EnvValue v1("LOCALDOMAIN", "this.is.local");
+ EnvValue v2("RES_OPTIONS", "options debug ndots:3 retry:3 rotate retrans:2");
+ EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
+ ares_destroy(channel);
+}
+
TEST_F(LibraryTest, EnvInitYt) {
ares_channel channel = nullptr;
EnvValue v1("LOCALDOMAIN", "this.is.local");
@@ -268,233 +268,233 @@ TEST_F(LibraryTest, EnvInitYtTimeouts) {
ares_destroy(channel);
}
-TEST_F(LibraryTest, EnvInitAllocFail) {
- ares_channel channel;
- EnvValue v1("LOCALDOMAIN", "this.is.local");
- EnvValue v2("RES_OPTIONS", "options debug ndots:3 retry:3 rotate retrans:2");
- for (int ii = 1; ii <= 10; ii++) {
- ClearFails();
- SetAllocFail(ii);
- channel = nullptr;
- int rc = ares_init(&channel);
- if (rc == ARES_SUCCESS) {
- ares_destroy(channel);
- } else {
- EXPECT_EQ(ARES_ENOMEM, rc);
- }
- }
-}
-#endif
-
-TEST_F(DefaultChannelTest, SetAddresses) {
- ares_set_local_ip4(channel_, 0x01020304);
- byte addr6[16] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
- ares_set_local_ip6(channel_, addr6);
- ares_set_local_dev(channel_, "dummy");
-}
-
-TEST_F(DefaultChannelTest, SetSortlistFailures) {
- EXPECT_EQ(ARES_ENODATA, ares_set_sortlist(nullptr, "1.2.3.4"));
- EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "xyzzy ; lwk"));
- EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "xyzzy ; 0x123"));
-}
-
-TEST_F(DefaultChannelTest, SetSortlistVariants) {
- EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "1.2.3.4"));
- EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "1.2.3.4 ; 2.3.4.5"));
- EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "129.1.1.1"));
- EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "192.1.1.1"));
- EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "224.1.1.1"));
- EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "225.1.1.1"));
-}
-
-TEST_F(DefaultChannelTest, SetSortlistAllocFail) {
- for (int ii = 1; ii <= 3; ii++) {
- ClearFails();
- SetAllocFail(ii);
- EXPECT_EQ(ARES_ENOMEM, ares_set_sortlist(channel_, "12.13.0.0/16 1234::5678/40 1.2.3.4")) << ii;
- }
-}
-
-#ifdef USE_WINSOCK
-TEST(Init, NoLibraryInit) {
- ares_channel channel = nullptr;
- EXPECT_EQ(ARES_ENOTINITIALIZED, ares_init(&channel));
-}
-#endif
-
-#ifdef HAVE_CONTAINER
-// These tests rely on the ability of non-root users to create a chroot
-// using Linux namespaces.
-
-
-// The library uses a variety of information sources to initialize a channel,
-// in particular to determine:
-// - search: the search domains to use
-// - servers: the name servers to use
-// - lookup: whether to check files or DNS or both (e.g. "fb")
-// - options: various resolver options
-// - sortlist: the order of preference for IP addresses
-//
-// The first source from the following list is used:
-// - init_by_options(): explicitly specified values in struct ares_options
-// - init_by_environment(): values from the environment:
-// - LOCALDOMAIN -> search (single value)
-// - RES_OPTIONS -> options
-// - init_by_resolv_conf(): values from various config files:
-// - /etc/resolv.conf -> search, lookup, servers, sortlist, options
-// - /etc/nsswitch.conf -> lookup
-// - /etc/host.conf -> lookup
-// - /etc/svc.conf -> lookup
-// - init_by_defaults(): fallback values:
-// - gethostname(3) -> domain
-// - "fb" -> lookup
-
-NameContentList filelist = {
- {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
- "sortlist 1.2.3.4/16 2.3.4.5\n"
- "search first.com second.com\n"},
- {"/etc/hosts", "3.4.5.6 ahostname.com\n"},
- {"/etc/nsswitch.conf", "hosts: files\n"}};
-CONTAINED_TEST_F(LibraryTest, ContainerChannelInit,
- "myhostname", "mydomainname.org", filelist) {
- ares_channel channel = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
- std::vector<std::string> actual = GetNameServers(channel);
- std::vector<std::string> expected = {"1.2.3.4"};
- EXPECT_EQ(expected, actual);
-
- struct ares_options opts;
- int optmask = 0;
- ares_save_options(channel, &opts, &optmask);
- EXPECT_EQ(2, opts.ndomains);
- EXPECT_EQ(std::string("first.com"), std::string(opts.domains[0]));
- EXPECT_EQ(std::string("second.com"), std::string(opts.domains[1]));
- ares_destroy_options(&opts);
-
- HostResult result;
- ares_gethostbyname(channel, "ahostname.com", AF_INET, HostCallback, &result);
- ProcessWork(channel, NoExtraFDs, nullptr);
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'ahostname.com' aliases=[] addrs=[3.4.5.6]}", ss.str());
-
- ares_destroy(channel);
- return HasFailure();
-}
-
-CONTAINED_TEST_F(LibraryTest, ContainerSortlistOptionInit,
- "myhostname", "mydomainname.org", filelist) {
- ares_channel channel = nullptr;
- struct ares_options opts = {0};
- int optmask = 0;
- optmask |= ARES_OPT_SORTLIST;
- opts.nsort = 0;
- // Explicitly specifying an empty sortlist in the options should override the
- // environment.
- EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
- ares_save_options(channel, &opts, &optmask);
- EXPECT_EQ(0, opts.nsort);
- EXPECT_EQ(nullptr, opts.sortlist);
- EXPECT_EQ(ARES_OPT_SORTLIST, (optmask & ARES_OPT_SORTLIST));
- ares_destroy_options(&opts);
-
- ares_destroy(channel);
- return HasFailure();
-}
-
-NameContentList fullresolv = {
- {"/etc/resolv.conf", " nameserver 1.2.3.4 \n"
- "search first.com second.com\n"
- "lookup bind\n"
- "options debug ndots:5\n"
- "sortlist 1.2.3.4/16 2.3.4.5\n"}};
-CONTAINED_TEST_F(LibraryTest, ContainerFullResolvInit,
- "myhostname", "mydomainname.org", fullresolv) {
- 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("b"), std::string(opts.lookups));
- EXPECT_EQ(5, opts.ndots);
- ares_destroy_options(&opts);
-
- ares_destroy(channel);
- return HasFailure();
-}
-
-// Allow path for resolv.conf to be configurable
-NameContentList myresolvconf = {
- {"/tmp/myresolv.cnf", " nameserver 1.2.3.4 \n"
- "search first.com second.com\n"
- "lookup bind\n"
- "options debug ndots:5\n"
- "sortlist 1.2.3.4/16 2.3.4.5\n"}};
-CONTAINED_TEST_F(LibraryTest, ContainerMyResolvConfInit,
- "myhostname", "mydomain.org", myresolvconf) {
- char filename[] = "/tmp/myresolv.cnf";
- ares_channel channel = nullptr;
- struct ares_options options = {0};
- options.resolvconf_path = strdup(filename);
- int optmask = ARES_OPT_RESOLVCONF;
- EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &options, optmask));
-
- optmask = 0;
- free(options.resolvconf_path);
- options.resolvconf_path = NULL;
-
- EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel, &options, &optmask));
- EXPECT_EQ(ARES_OPT_RESOLVCONF, (optmask & ARES_OPT_RESOLVCONF));
- EXPECT_EQ(std::string(filename), std::string(options.resolvconf_path));
-
- ares_destroy_options(&options);
- ares_destroy(channel);
- return HasFailure();
-}
-
-NameContentList hostconf = {
- {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
- "sortlist1.2.3.4\n" // malformed line
- "search first.com second.com\n"},
- {"/etc/host.conf", "order bind hosts\n"}};
-CONTAINED_TEST_F(LibraryTest, ContainerHostConfInit,
- "myhostname", "mydomainname.org", hostconf) {
- 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("bf"), std::string(opts.lookups));
- ares_destroy_options(&opts);
-
- ares_destroy(channel);
- return HasFailure();
-}
-
-NameContentList svcconf = {
- {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
- "search first.com second.com\n"},
- {"/etc/svc.conf", "hosts= bind\n"}};
-CONTAINED_TEST_F(LibraryTest, ContainerSvcConfInit,
- "myhostname", "mydomainname.org", svcconf) {
- 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("b"), std::string(opts.lookups));
- ares_destroy_options(&opts);
-
- ares_destroy(channel);
- return HasFailure();
-}
-
+TEST_F(LibraryTest, EnvInitAllocFail) {
+ ares_channel channel;
+ EnvValue v1("LOCALDOMAIN", "this.is.local");
+ EnvValue v2("RES_OPTIONS", "options debug ndots:3 retry:3 rotate retrans:2");
+ for (int ii = 1; ii <= 10; ii++) {
+ ClearFails();
+ SetAllocFail(ii);
+ channel = nullptr;
+ int rc = ares_init(&channel);
+ if (rc == ARES_SUCCESS) {
+ ares_destroy(channel);
+ } else {
+ EXPECT_EQ(ARES_ENOMEM, rc);
+ }
+ }
+}
+#endif
+
+TEST_F(DefaultChannelTest, SetAddresses) {
+ ares_set_local_ip4(channel_, 0x01020304);
+ byte addr6[16] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
+ ares_set_local_ip6(channel_, addr6);
+ ares_set_local_dev(channel_, "dummy");
+}
+
+TEST_F(DefaultChannelTest, SetSortlistFailures) {
+ EXPECT_EQ(ARES_ENODATA, ares_set_sortlist(nullptr, "1.2.3.4"));
+ EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "xyzzy ; lwk"));
+ EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "xyzzy ; 0x123"));
+}
+
+TEST_F(DefaultChannelTest, SetSortlistVariants) {
+ EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "1.2.3.4"));
+ EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "1.2.3.4 ; 2.3.4.5"));
+ EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "129.1.1.1"));
+ EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "192.1.1.1"));
+ EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "224.1.1.1"));
+ EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "225.1.1.1"));
+}
+
+TEST_F(DefaultChannelTest, SetSortlistAllocFail) {
+ for (int ii = 1; ii <= 3; ii++) {
+ ClearFails();
+ SetAllocFail(ii);
+ EXPECT_EQ(ARES_ENOMEM, ares_set_sortlist(channel_, "12.13.0.0/16 1234::5678/40 1.2.3.4")) << ii;
+ }
+}
+
+#ifdef USE_WINSOCK
+TEST(Init, NoLibraryInit) {
+ ares_channel channel = nullptr;
+ EXPECT_EQ(ARES_ENOTINITIALIZED, ares_init(&channel));
+}
+#endif
+
+#ifdef HAVE_CONTAINER
+// These tests rely on the ability of non-root users to create a chroot
+// using Linux namespaces.
+
+
+// The library uses a variety of information sources to initialize a channel,
+// in particular to determine:
+// - search: the search domains to use
+// - servers: the name servers to use
+// - lookup: whether to check files or DNS or both (e.g. "fb")
+// - options: various resolver options
+// - sortlist: the order of preference for IP addresses
+//
+// The first source from the following list is used:
+// - init_by_options(): explicitly specified values in struct ares_options
+// - init_by_environment(): values from the environment:
+// - LOCALDOMAIN -> search (single value)
+// - RES_OPTIONS -> options
+// - init_by_resolv_conf(): values from various config files:
+// - /etc/resolv.conf -> search, lookup, servers, sortlist, options
+// - /etc/nsswitch.conf -> lookup
+// - /etc/host.conf -> lookup
+// - /etc/svc.conf -> lookup
+// - init_by_defaults(): fallback values:
+// - gethostname(3) -> domain
+// - "fb" -> lookup
+
+NameContentList filelist = {
+ {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
+ "sortlist 1.2.3.4/16 2.3.4.5\n"
+ "search first.com second.com\n"},
+ {"/etc/hosts", "3.4.5.6 ahostname.com\n"},
+ {"/etc/nsswitch.conf", "hosts: files\n"}};
+CONTAINED_TEST_F(LibraryTest, ContainerChannelInit,
+ "myhostname", "mydomainname.org", filelist) {
+ ares_channel channel = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
+ std::vector<std::string> actual = GetNameServers(channel);
+ std::vector<std::string> expected = {"1.2.3.4"};
+ EXPECT_EQ(expected, actual);
+
+ struct ares_options opts;
+ int optmask = 0;
+ ares_save_options(channel, &opts, &optmask);
+ EXPECT_EQ(2, opts.ndomains);
+ EXPECT_EQ(std::string("first.com"), std::string(opts.domains[0]));
+ EXPECT_EQ(std::string("second.com"), std::string(opts.domains[1]));
+ ares_destroy_options(&opts);
+
+ HostResult result;
+ ares_gethostbyname(channel, "ahostname.com", AF_INET, HostCallback, &result);
+ ProcessWork(channel, NoExtraFDs, nullptr);
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'ahostname.com' aliases=[] addrs=[3.4.5.6]}", ss.str());
+
+ ares_destroy(channel);
+ return HasFailure();
+}
+
+CONTAINED_TEST_F(LibraryTest, ContainerSortlistOptionInit,
+ "myhostname", "mydomainname.org", filelist) {
+ ares_channel channel = nullptr;
+ struct ares_options opts = {0};
+ int optmask = 0;
+ optmask |= ARES_OPT_SORTLIST;
+ opts.nsort = 0;
+ // Explicitly specifying an empty sortlist in the options should override the
+ // environment.
+ EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
+ ares_save_options(channel, &opts, &optmask);
+ EXPECT_EQ(0, opts.nsort);
+ EXPECT_EQ(nullptr, opts.sortlist);
+ EXPECT_EQ(ARES_OPT_SORTLIST, (optmask & ARES_OPT_SORTLIST));
+ ares_destroy_options(&opts);
+
+ ares_destroy(channel);
+ return HasFailure();
+}
+
+NameContentList fullresolv = {
+ {"/etc/resolv.conf", " nameserver 1.2.3.4 \n"
+ "search first.com second.com\n"
+ "lookup bind\n"
+ "options debug ndots:5\n"
+ "sortlist 1.2.3.4/16 2.3.4.5\n"}};
+CONTAINED_TEST_F(LibraryTest, ContainerFullResolvInit,
+ "myhostname", "mydomainname.org", fullresolv) {
+ 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("b"), std::string(opts.lookups));
+ EXPECT_EQ(5, opts.ndots);
+ ares_destroy_options(&opts);
+
+ ares_destroy(channel);
+ return HasFailure();
+}
+
+// Allow path for resolv.conf to be configurable
+NameContentList myresolvconf = {
+ {"/tmp/myresolv.cnf", " nameserver 1.2.3.4 \n"
+ "search first.com second.com\n"
+ "lookup bind\n"
+ "options debug ndots:5\n"
+ "sortlist 1.2.3.4/16 2.3.4.5\n"}};
+CONTAINED_TEST_F(LibraryTest, ContainerMyResolvConfInit,
+ "myhostname", "mydomain.org", myresolvconf) {
+ char filename[] = "/tmp/myresolv.cnf";
+ ares_channel channel = nullptr;
+ struct ares_options options = {0};
+ options.resolvconf_path = strdup(filename);
+ int optmask = ARES_OPT_RESOLVCONF;
+ EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &options, optmask));
+
+ optmask = 0;
+ free(options.resolvconf_path);
+ options.resolvconf_path = NULL;
+
+ EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel, &options, &optmask));
+ EXPECT_EQ(ARES_OPT_RESOLVCONF, (optmask & ARES_OPT_RESOLVCONF));
+ EXPECT_EQ(std::string(filename), std::string(options.resolvconf_path));
+
+ ares_destroy_options(&options);
+ ares_destroy(channel);
+ return HasFailure();
+}
+
+NameContentList hostconf = {
+ {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
+ "sortlist1.2.3.4\n" // malformed line
+ "search first.com second.com\n"},
+ {"/etc/host.conf", "order bind hosts\n"}};
+CONTAINED_TEST_F(LibraryTest, ContainerHostConfInit,
+ "myhostname", "mydomainname.org", hostconf) {
+ 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("bf"), std::string(opts.lookups));
+ ares_destroy_options(&opts);
+
+ ares_destroy(channel);
+ return HasFailure();
+}
+
+NameContentList svcconf = {
+ {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
+ "search first.com second.com\n"},
+ {"/etc/svc.conf", "hosts= bind\n"}};
+CONTAINED_TEST_F(LibraryTest, ContainerSvcConfInit,
+ "myhostname", "mydomainname.org", svcconf) {
+ 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("b"), 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
@@ -513,191 +513,191 @@ CONTAINED_TEST_F(LibraryTest, ContainerMalformedResolvConfLookup,
return HasFailure();
}
-// Failures when expected config filenames are inaccessible.
-class MakeUnreadable {
- public:
- explicit MakeUnreadable(const std::string& filename)
- : filename_(filename) {
- chmod(filename_.c_str(), 0000);
- }
- ~MakeUnreadable() { chmod(filename_.c_str(), 0644); }
- private:
- std::string filename_;
-};
-
-CONTAINED_TEST_F(LibraryTest, ContainerResolvConfNotReadable,
- "myhostname", "mydomainname.org", filelist) {
- ares_channel channel = nullptr;
- MakeUnreadable hide("/etc/resolv.conf");
- // Unavailable /etc/resolv.conf falls back to defaults
- EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
- return HasFailure();
-}
-CONTAINED_TEST_F(LibraryTest, ContainerNsswitchConfNotReadable,
- "myhostname", "mydomainname.org", filelist) {
- ares_channel channel = nullptr;
- // Unavailable /etc/nsswitch.conf falls back to defaults.
- MakeUnreadable hide("/etc/nsswitch.conf");
- 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();
-}
-CONTAINED_TEST_F(LibraryTest, ContainerHostConfNotReadable,
- "myhostname", "mydomainname.org", hostconf) {
- ares_channel channel = nullptr;
- // Unavailable /etc/host.conf falls back to defaults.
- MakeUnreadable hide("/etc/host.conf");
- EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
- ares_destroy(channel);
- return HasFailure();
-}
-CONTAINED_TEST_F(LibraryTest, ContainerSvcConfNotReadable,
- "myhostname", "mydomainname.org", svcconf) {
- ares_channel channel = nullptr;
- // Unavailable /etc/svc.conf falls back to defaults.
- MakeUnreadable hide("/etc/svc.conf");
- EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
- ares_destroy(channel);
- return HasFailure();
-}
-
-NameContentList rotateenv = {
- {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
- "search first.com second.com\n"
- "options rotate\n"}};
-CONTAINED_TEST_F(LibraryTest, ContainerRotateInit,
- "myhostname", "mydomainname.org", rotateenv) {
- 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(ARES_OPT_ROTATE, (optmask & ARES_OPT_ROTATE));
- ares_destroy_options(&opts);
-
- ares_destroy(channel);
- return HasFailure();
-}
-
-CONTAINED_TEST_F(LibraryTest, ContainerRotateOverride,
- "myhostname", "mydomainname.org", rotateenv) {
- ares_channel channel = nullptr;
- struct ares_options opts = {0};
- int optmask = ARES_OPT_NOROTATE;
- EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
-
- optmask = 0;
- ares_save_options(channel, &opts, &optmask);
- EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE));
- ares_destroy_options(&opts);
-
- ares_destroy(channel);
- return HasFailure();
-}
-
-// Test that blacklisted IPv6 resolves are ignored. They're filtered from any
-// source, so resolv.conf is as good as any.
-NameContentList blacklistedIpv6 = {
- {"/etc/resolv.conf", " nameserver 254.192.1.1\n" // 0xfe.0xc0.0x01.0x01
- " nameserver fec0::dead\n" // Blacklisted
- " nameserver ffc0::c001\n" // Not blacklisted
- " domain first.com\n"},
- {"/etc/nsswitch.conf", "hosts: files\n"}};
-CONTAINED_TEST_F(LibraryTest, ContainerBlacklistedIpv6,
- "myhostname", "mydomainname.org", blacklistedIpv6) {
- ares_channel channel = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
- std::vector<std::string> actual = GetNameServers(channel);
- std::vector<std::string> expected = {
- "254.192.1.1",
- "ffc0:0000:0000:0000:0000:0000:0000:c001"
- };
- EXPECT_EQ(expected, actual);
-
- struct ares_options opts;
- int optmask = 0;
- ares_save_options(channel, &opts, &optmask);
- EXPECT_EQ(1, opts.ndomains);
- EXPECT_EQ(std::string("first.com"), std::string(opts.domains[0]));
- ares_destroy_options(&opts);
-
- ares_destroy(channel);
- return HasFailure();
-}
-
-NameContentList multiresolv = {
- {"/etc/resolv.conf", " nameserver 1::2 ; ;;\n"
- " domain first.com\n"},
- {"/etc/nsswitch.conf", "hosts: files\n"}};
-CONTAINED_TEST_F(LibraryTest, ContainerMultiResolvInit,
- "myhostname", "mydomainname.org", multiresolv) {
- ares_channel channel = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
- std::vector<std::string> actual = GetNameServers(channel);
- std::vector<std::string> expected = {"0001:0000:0000:0000:0000:0000:0000:0002"};
- EXPECT_EQ(expected, actual);
-
- struct ares_options opts;
- int optmask = 0;
- ares_save_options(channel, &opts, &optmask);
- EXPECT_EQ(1, opts.ndomains);
- EXPECT_EQ(std::string("first.com"), std::string(opts.domains[0]));
- ares_destroy_options(&opts);
-
- ares_destroy(channel);
- return HasFailure();
-}
-
-NameContentList systemdresolv = {
- {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
- "domain first.com\n"},
- {"/etc/nsswitch.conf", "hosts: junk resolve files\n"}};
-CONTAINED_TEST_F(LibraryTest, ContainerSystemdResolvInit,
- "myhostname", "mydomainname.org", systemdresolv) {
- 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("bf"), std::string(opts.lookups));
- ares_destroy_options(&opts);
-
- ares_destroy(channel);
- return HasFailure();
-}
-
-NameContentList empty = {}; // no files
-CONTAINED_TEST_F(LibraryTest, ContainerEmptyInit,
- "host.domain.org", "domain.org", empty) {
- ares_channel channel = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
- std::vector<std::string> actual = GetNameServers(channel);
- std::vector<std::string> expected = {"127.0.0.1"};
- EXPECT_EQ(expected, actual);
-
- struct ares_options opts;
- int optmask = 0;
- ares_save_options(channel, &opts, &optmask);
- EXPECT_EQ(1, opts.ndomains);
- EXPECT_EQ(std::string("domain.org"), std::string(opts.domains[0]));
- EXPECT_EQ(std::string("fb"), std::string(opts.lookups));
- ares_destroy_options(&opts);
-
-
- ares_destroy(channel);
- return HasFailure();
-}
-
-#endif
-
-} // namespace test
-} // namespace ares
+// Failures when expected config filenames are inaccessible.
+class MakeUnreadable {
+ public:
+ explicit MakeUnreadable(const std::string& filename)
+ : filename_(filename) {
+ chmod(filename_.c_str(), 0000);
+ }
+ ~MakeUnreadable() { chmod(filename_.c_str(), 0644); }
+ private:
+ std::string filename_;
+};
+
+CONTAINED_TEST_F(LibraryTest, ContainerResolvConfNotReadable,
+ "myhostname", "mydomainname.org", filelist) {
+ ares_channel channel = nullptr;
+ MakeUnreadable hide("/etc/resolv.conf");
+ // Unavailable /etc/resolv.conf falls back to defaults
+ EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
+ return HasFailure();
+}
+CONTAINED_TEST_F(LibraryTest, ContainerNsswitchConfNotReadable,
+ "myhostname", "mydomainname.org", filelist) {
+ ares_channel channel = nullptr;
+ // Unavailable /etc/nsswitch.conf falls back to defaults.
+ MakeUnreadable hide("/etc/nsswitch.conf");
+ 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();
+}
+CONTAINED_TEST_F(LibraryTest, ContainerHostConfNotReadable,
+ "myhostname", "mydomainname.org", hostconf) {
+ ares_channel channel = nullptr;
+ // Unavailable /etc/host.conf falls back to defaults.
+ MakeUnreadable hide("/etc/host.conf");
+ EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
+ ares_destroy(channel);
+ return HasFailure();
+}
+CONTAINED_TEST_F(LibraryTest, ContainerSvcConfNotReadable,
+ "myhostname", "mydomainname.org", svcconf) {
+ ares_channel channel = nullptr;
+ // Unavailable /etc/svc.conf falls back to defaults.
+ MakeUnreadable hide("/etc/svc.conf");
+ EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
+ ares_destroy(channel);
+ return HasFailure();
+}
+
+NameContentList rotateenv = {
+ {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
+ "search first.com second.com\n"
+ "options rotate\n"}};
+CONTAINED_TEST_F(LibraryTest, ContainerRotateInit,
+ "myhostname", "mydomainname.org", rotateenv) {
+ 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(ARES_OPT_ROTATE, (optmask & ARES_OPT_ROTATE));
+ ares_destroy_options(&opts);
+
+ ares_destroy(channel);
+ return HasFailure();
+}
+
+CONTAINED_TEST_F(LibraryTest, ContainerRotateOverride,
+ "myhostname", "mydomainname.org", rotateenv) {
+ ares_channel channel = nullptr;
+ struct ares_options opts = {0};
+ int optmask = ARES_OPT_NOROTATE;
+ EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
+
+ optmask = 0;
+ ares_save_options(channel, &opts, &optmask);
+ EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE));
+ ares_destroy_options(&opts);
+
+ ares_destroy(channel);
+ return HasFailure();
+}
+
+// Test that blacklisted IPv6 resolves are ignored. They're filtered from any
+// source, so resolv.conf is as good as any.
+NameContentList blacklistedIpv6 = {
+ {"/etc/resolv.conf", " nameserver 254.192.1.1\n" // 0xfe.0xc0.0x01.0x01
+ " nameserver fec0::dead\n" // Blacklisted
+ " nameserver ffc0::c001\n" // Not blacklisted
+ " domain first.com\n"},
+ {"/etc/nsswitch.conf", "hosts: files\n"}};
+CONTAINED_TEST_F(LibraryTest, ContainerBlacklistedIpv6,
+ "myhostname", "mydomainname.org", blacklistedIpv6) {
+ ares_channel channel = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
+ std::vector<std::string> actual = GetNameServers(channel);
+ std::vector<std::string> expected = {
+ "254.192.1.1",
+ "ffc0:0000:0000:0000:0000:0000:0000:c001"
+ };
+ EXPECT_EQ(expected, actual);
+
+ struct ares_options opts;
+ int optmask = 0;
+ ares_save_options(channel, &opts, &optmask);
+ EXPECT_EQ(1, opts.ndomains);
+ EXPECT_EQ(std::string("first.com"), std::string(opts.domains[0]));
+ ares_destroy_options(&opts);
+
+ ares_destroy(channel);
+ return HasFailure();
+}
+
+NameContentList multiresolv = {
+ {"/etc/resolv.conf", " nameserver 1::2 ; ;;\n"
+ " domain first.com\n"},
+ {"/etc/nsswitch.conf", "hosts: files\n"}};
+CONTAINED_TEST_F(LibraryTest, ContainerMultiResolvInit,
+ "myhostname", "mydomainname.org", multiresolv) {
+ ares_channel channel = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
+ std::vector<std::string> actual = GetNameServers(channel);
+ std::vector<std::string> expected = {"0001:0000:0000:0000:0000:0000:0000:0002"};
+ EXPECT_EQ(expected, actual);
+
+ struct ares_options opts;
+ int optmask = 0;
+ ares_save_options(channel, &opts, &optmask);
+ EXPECT_EQ(1, opts.ndomains);
+ EXPECT_EQ(std::string("first.com"), std::string(opts.domains[0]));
+ ares_destroy_options(&opts);
+
+ ares_destroy(channel);
+ return HasFailure();
+}
+
+NameContentList systemdresolv = {
+ {"/etc/resolv.conf", "nameserver 1.2.3.4\n"
+ "domain first.com\n"},
+ {"/etc/nsswitch.conf", "hosts: junk resolve files\n"}};
+CONTAINED_TEST_F(LibraryTest, ContainerSystemdResolvInit,
+ "myhostname", "mydomainname.org", systemdresolv) {
+ 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("bf"), std::string(opts.lookups));
+ ares_destroy_options(&opts);
+
+ ares_destroy(channel);
+ return HasFailure();
+}
+
+NameContentList empty = {}; // no files
+CONTAINED_TEST_F(LibraryTest, ContainerEmptyInit,
+ "host.domain.org", "domain.org", empty) {
+ ares_channel channel = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_init(&channel));
+ std::vector<std::string> actual = GetNameServers(channel);
+ std::vector<std::string> expected = {"127.0.0.1"};
+ EXPECT_EQ(expected, actual);
+
+ struct ares_options opts;
+ int optmask = 0;
+ ares_save_options(channel, &opts, &optmask);
+ EXPECT_EQ(1, opts.ndomains);
+ EXPECT_EQ(std::string("domain.org"), std::string(opts.domains[0]));
+ EXPECT_EQ(std::string("fb"), std::string(opts.lookups));
+ ares_destroy_options(&opts);
+
+
+ ares_destroy(channel);
+ return HasFailure();
+}
+
+#endif
+
+} // namespace test
+} // namespace ares
diff --git a/contrib/libs/c-ares/test/ares-test-internal.cc b/contrib/libs/c-ares/test/ares-test-internal.cc
index 26e91e73e8..96d4edece5 100644
--- a/contrib/libs/c-ares/test/ares-test-internal.cc
+++ b/contrib/libs/c-ares/test/ares-test-internal.cc
@@ -1,361 +1,361 @@
-#include "ares-test.h"
-#include "dns-proto.h"
-
-#include <stdio.h>
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <fcntl.h>
-
-extern "C" {
-// Remove command-line defines of package variables for the test project...
-#undef PACKAGE_NAME
-#undef PACKAGE_BUGREPORT
-#undef PACKAGE_STRING
-#undef PACKAGE_TARNAME
-// ... so we can include the library's config without symbol redefinitions.
-#include "ares_setup.h"
-#include "ares_nowarn.h"
-#include "ares_inet_net_pton.h"
-#include "ares_data.h"
-#include "ares_private.h"
-#include "bitncmp.h"
-
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#ifdef HAVE_SYS_UIO_H
-# include <sys/uio.h>
-#endif
-}
-
-#include <string>
-#include <vector>
-
-namespace ares {
-namespace test {
-
-#ifndef CARES_SYMBOL_HIDING
-void CheckPtoN4(int size, unsigned int value, const char *input) {
- struct in_addr a4;
- a4.s_addr = 0;
- uint32_t expected = htonl(value);
- EXPECT_EQ(size, ares_inet_net_pton(AF_INET, input, &a4, sizeof(a4)))
- << " for input " << input;
- EXPECT_EQ(expected, a4.s_addr) << " for input " << input;
-}
-#endif
-
-TEST_F(LibraryTest, InetPtoN) {
- struct in_addr a4;
- struct in6_addr a6;
-
-#ifndef CARES_SYMBOL_HIDING
- uint32_t expected;
-
- CheckPtoN4(4 * 8, 0x01020304, "1.2.3.4");
- CheckPtoN4(4 * 8, 0x81010101, "129.1.1.1");
- CheckPtoN4(4 * 8, 0xC0010101, "192.1.1.1");
- CheckPtoN4(4 * 8, 0xE0010101, "224.1.1.1");
- CheckPtoN4(4 * 8, 0xE1010101, "225.1.1.1");
- CheckPtoN4(4, 0xE0000000, "224");
- CheckPtoN4(4 * 8, 0xFD000000, "253");
- CheckPtoN4(4 * 8, 0xF0010101, "240.1.1.1");
- CheckPtoN4(4 * 8, 0x02030405, "02.3.4.5");
- CheckPtoN4(3 * 8, 0x01020304, "1.2.3.4/24");
- CheckPtoN4(3 * 8, 0x01020300, "1.2.3/24");
- CheckPtoN4(2 * 8, 0xa0000000, "0xa");
- CheckPtoN4(0, 0x02030405, "2.3.4.5/000");
- CheckPtoN4(1 * 8, 0x01020000, "1.2/8");
- CheckPtoN4(2 * 8, 0x01020000, "0x0102/16");
- CheckPtoN4(4 * 8, 0x02030405, "02.3.4.5");
-
- EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "::", &a6, sizeof(a6)));
- EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "::1", &a6, sizeof(a6)));
- EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "1234:5678::", &a6, sizeof(a6)));
- EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "12:34::ff", &a6, sizeof(a6)));
- EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.4", &a6, sizeof(a6)));
- EXPECT_EQ(23, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.4/23", &a6, sizeof(a6)));
- EXPECT_EQ(3 * 8, ares_inet_net_pton(AF_INET6, "12:34::ff/24", &a6, sizeof(a6)));
- EXPECT_EQ(0, ares_inet_net_pton(AF_INET6, "12:34::ff/0", &a6, sizeof(a6)));
- EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "12:34::ffff:0.2", &a6, sizeof(a6)));
- EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234", &a6, sizeof(a6)));
-
- // Various malformed versions
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "", &a4, sizeof(a4)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, " ", &a4, sizeof(a4)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x", &a4, sizeof(a4)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x ", &a4, sizeof(a4)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "x0", &a4, sizeof(a4)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0xXYZZY", &a4, sizeof(a4)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "xyzzy", &a4, sizeof(a4)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET+AF_INET6, "1.2.3.4", &a4, sizeof(a4)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "257.2.3.4", &a4, sizeof(a4)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "002.3.4.x", &a4, sizeof(a4)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "00.3.4.x", &a4, sizeof(a4)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.x", &a4, sizeof(a4)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5.6", &a4, sizeof(a4)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5.6/12", &a4, sizeof(a4)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4:5", &a4, sizeof(a4)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5/120", &a4, sizeof(a4)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5/1x", &a4, sizeof(a4)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5/x", &a4, sizeof(a4)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/240", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/02", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/2y", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/y", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ":x", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ":", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ": :1234", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "::12345", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234::2345:3456::0011", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234:", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234::", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1.2.3.4", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ":1234:1234:1234:1234:1234:1234:1234:1234", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ":1234:1234:1234:1234:1234:1234:1234:1234:", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234:5678", &a6, sizeof(a6)));
- // TODO(drysdale): check whether the next two tests should give -1.
- EXPECT_EQ(0, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234:5678:5678", &a6, sizeof(a6)));
- EXPECT_EQ(0, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234:5678:5678:5678", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:257.2.3.4", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:002.2.3.4", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.4.5.6", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.4.5", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.z", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3001.4", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3..4", &a6, sizeof(a6)));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.", &a6, sizeof(a6)));
-
- // Hex constants are allowed.
- EXPECT_EQ(4 * 8, ares_inet_net_pton(AF_INET, "0x01020304", &a4, sizeof(a4)));
- expected = htonl(0x01020304);
- EXPECT_EQ(expected, a4.s_addr);
- EXPECT_EQ(4 * 8, ares_inet_net_pton(AF_INET, "0x0a0b0c0d", &a4, sizeof(a4)));
- expected = htonl(0x0a0b0c0d);
- EXPECT_EQ(expected, a4.s_addr);
- EXPECT_EQ(4 * 8, ares_inet_net_pton(AF_INET, "0x0A0B0C0D", &a4, sizeof(a4)));
- expected = htonl(0x0a0b0c0d);
- EXPECT_EQ(expected, a4.s_addr);
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x0xyz", &a4, sizeof(a4)));
- EXPECT_EQ(4 * 8, ares_inet_net_pton(AF_INET, "0x1122334", &a4, sizeof(a4)));
- expected = htonl(0x11223340);
- EXPECT_EQ(expected, a4.s_addr); // huh?
-
- // No room, no room.
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "1.2.3.4", &a4, sizeof(a4) - 1));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff", &a6, sizeof(a6) - 1));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x01020304", &a4, 2));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x01020304", &a4, 0));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x0a0b0c0d", &a4, 0));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x0xyz", &a4, 0));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x1122334", &a4, sizeof(a4) - 1));
- EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "253", &a4, sizeof(a4) - 1));
-#endif
-
- EXPECT_EQ(1, ares_inet_pton(AF_INET, "1.2.3.4", &a4));
- EXPECT_EQ(1, ares_inet_pton(AF_INET6, "12:34::ff", &a6));
- EXPECT_EQ(1, ares_inet_pton(AF_INET6, "12:34::ffff:1.2.3.4", &a6));
- EXPECT_EQ(0, ares_inet_pton(AF_INET, "xyzzy", &a4));
- EXPECT_EQ(-1, ares_inet_pton(AF_INET+AF_INET6, "1.2.3.4", &a4));
-}
-
-TEST_F(LibraryTest, FreeCorruptData) {
- // ares_free_data(p) expects that there is a type field and a marker
- // field in the memory before p. Feed it incorrect versions of each.
- struct ares_data *data = (struct ares_data *)malloc(sizeof(struct ares_data));
- void* p = &(data->data);
-
- // Invalid type
- data->type = (ares_datatype)99;
- data->mark = ARES_DATATYPE_MARK;
- ares_free_data(p);
-
- // Invalid marker
- data->type = (ares_datatype)ARES_DATATYPE_MX_REPLY;
- data->mark = ARES_DATATYPE_MARK + 1;
- ares_free_data(p);
-
- // Null pointer
- ares_free_data(nullptr);
-
- free(data);
-}
-
-#ifndef CARES_SYMBOL_HIDING
-TEST_F(LibraryTest, FreeLongChain) {
- struct ares_addr_node *data = nullptr;
- for (int ii = 0; ii < 100000; ii++) {
- struct ares_addr_node *prev = (struct ares_addr_node*)ares_malloc_data(ARES_DATATYPE_ADDR_NODE);
- prev->next = data;
- data = prev;
- }
-
- ares_free_data(data);
-}
-
-TEST(LibraryInit, StrdupFailures) {
- EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
- char* copy = ares_strdup("string");
- EXPECT_NE(nullptr, copy);
- ares_free(copy);
- ares_library_cleanup();
-}
-
-TEST_F(LibraryTest, StrdupFailures) {
- SetAllocFail(1);
- char* copy = ares_strdup("string");
- EXPECT_EQ(nullptr, copy);
-}
-
-TEST_F(LibraryTest, MallocDataFail) {
- EXPECT_EQ(nullptr, ares_malloc_data((ares_datatype)99));
- SetAllocSizeFail(sizeof(struct ares_data));
- EXPECT_EQ(nullptr, ares_malloc_data(ARES_DATATYPE_MX_REPLY));
-}
-
-TEST(Misc, Bitncmp) {
- byte a[4] = {0x80, 0x01, 0x02, 0x03};
- byte b[4] = {0x80, 0x01, 0x02, 0x04};
- byte c[4] = {0x01, 0xFF, 0x80, 0x02};
- EXPECT_GT(0, ares__bitncmp(a, b, sizeof(a)*8));
- EXPECT_LT(0, ares__bitncmp(b, a, sizeof(a)*8));
- EXPECT_EQ(0, ares__bitncmp(a, a, sizeof(a)*8));
-
- for (int ii = 1; ii < (3*8+5); ii++) {
- EXPECT_EQ(0, ares__bitncmp(a, b, ii));
- EXPECT_EQ(0, ares__bitncmp(b, a, ii));
- EXPECT_LT(0, ares__bitncmp(a, c, ii));
- EXPECT_GT(0, ares__bitncmp(c, a, ii));
- }
-
- // Last byte differs at 5th bit
- EXPECT_EQ(0, ares__bitncmp(a, b, 3*8 + 3));
- EXPECT_EQ(0, ares__bitncmp(a, b, 3*8 + 4));
- EXPECT_EQ(0, ares__bitncmp(a, b, 3*8 + 5));
- EXPECT_GT(0, ares__bitncmp(a, b, 3*8 + 6));
- EXPECT_GT(0, ares__bitncmp(a, b, 3*8 + 7));
-}
-
-TEST_F(LibraryTest, Casts) {
- ares_ssize_t ssz = 100;
- unsigned int u = 100;
- int i = 100;
- long l = 100;
-
- unsigned int ru = aresx_sztoui(ssz);
- EXPECT_EQ(u, ru);
- int ri = aresx_sztosi(ssz);
- EXPECT_EQ(i, ri);
-
- ri = aresx_sltosi(l);
- EXPECT_EQ(l, (long)ri);
-}
-
-TEST_F(LibraryTest, ReadLine) {
- TempFile temp("abcde\n0123456789\nXYZ\n012345678901234567890\n\n");
- FILE *fp = fopen(temp.filename(), "r");
- size_t bufsize = 4;
- char *buf = (char *)ares_malloc(bufsize);
-
- EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
- EXPECT_EQ("abcde", std::string(buf));
- EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
- EXPECT_EQ("0123456789", std::string(buf));
- EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
- EXPECT_EQ("XYZ", std::string(buf));
- SetAllocFail(1);
- EXPECT_EQ(ARES_ENOMEM, ares__read_line(fp, &buf, &bufsize));
- EXPECT_EQ(nullptr, buf);
-
- fclose(fp);
- ares_free(buf);
-}
-
-TEST_F(LibraryTest, ReadLineNoBuf) {
- TempFile temp("abcde\n0123456789\nXYZ\n012345678901234567890");
- FILE *fp = fopen(temp.filename(), "r");
- size_t bufsize = 0;
- char *buf = nullptr;
-
- SetAllocFail(1);
- EXPECT_EQ(ARES_ENOMEM, ares__read_line(fp, &buf, &bufsize));
-
- EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
- EXPECT_EQ("abcde", std::string(buf));
- EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
- EXPECT_EQ("0123456789", std::string(buf));
- EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
- EXPECT_EQ("XYZ", std::string(buf));
- EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
- EXPECT_EQ("012345678901234567890", std::string(buf));
-
- fclose(fp);
- ares_free(buf);
-}
-
-TEST(Misc, GetHostent) {
- 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");
- struct hostent *host = nullptr;
- FILE *fp = fopen(hostsfile.filename(), "r");
- ASSERT_NE(nullptr, fp);
- EXPECT_EQ(ARES_EBADFAMILY, ares__get_hostent(fp, AF_INET+AF_INET6, &host));
- rewind(fp);
-
- EXPECT_EQ(ARES_SUCCESS, ares__get_hostent(fp, AF_INET, &host));
- ASSERT_NE(nullptr, host);
- std::stringstream ss1;
- ss1 << HostEnt(host);
- EXPECT_EQ("{'example.com' aliases=[] addrs=[1.2.3.4]}", ss1.str());
- ares_free_hostent(host);
- host = nullptr;
-
- EXPECT_EQ(ARES_SUCCESS, ares__get_hostent(fp, AF_INET, &host));
- ASSERT_NE(nullptr, host);
- std::stringstream ss2;
- ss2 << HostEnt(host);
- EXPECT_EQ("{'google.com' aliases=[www.google.com, www2.google.com] addrs=[2.3.4.5]}", ss2.str());
- ares_free_hostent(host);
- host = nullptr;
-
- EXPECT_EQ(ARES_EOF, ares__get_hostent(fp, AF_INET, &host));
-
- rewind(fp);
- EXPECT_EQ(ARES_SUCCESS, ares__get_hostent(fp, AF_INET6, &host));
- ASSERT_NE(nullptr, host);
- std::stringstream ss3;
- ss3 << HostEnt(host);
- EXPECT_EQ("{'ipv6.com' aliases=[] addrs=[0000:0000:0000:0000:0000:0000:0000:0001]}", ss3.str());
- ares_free_hostent(host);
- host = nullptr;
- EXPECT_EQ(ARES_EOF, ares__get_hostent(fp, AF_INET6, &host));
- fclose(fp);
-}
-
-TEST_F(LibraryTest, GetHostentAllocFail) {
- TempFile hostsfile("1.2.3.4 example.com alias1 alias2\n");
- struct hostent *host = nullptr;
- FILE *fp = fopen(hostsfile.filename(), "r");
- ASSERT_NE(nullptr, fp);
-
- for (int ii = 1; ii <= 8; ii++) {
- rewind(fp);
- ClearFails();
- SetAllocFail(ii);
- host = nullptr;
- EXPECT_EQ(ARES_ENOMEM, ares__get_hostent(fp, AF_INET, &host)) << ii;
- }
- fclose(fp);
-}
-
+#include "ares-test.h"
+#include "dns-proto.h"
+
+#include <stdio.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+
+extern "C" {
+// Remove command-line defines of package variables for the test project...
+#undef PACKAGE_NAME
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+// ... so we can include the library's config without symbol redefinitions.
+#include "ares_setup.h"
+#include "ares_nowarn.h"
+#include "ares_inet_net_pton.h"
+#include "ares_data.h"
+#include "ares_private.h"
+#include "bitncmp.h"
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#ifdef HAVE_SYS_UIO_H
+# include <sys/uio.h>
+#endif
+}
+
+#include <string>
+#include <vector>
+
+namespace ares {
+namespace test {
+
+#ifndef CARES_SYMBOL_HIDING
+void CheckPtoN4(int size, unsigned int value, const char *input) {
+ struct in_addr a4;
+ a4.s_addr = 0;
+ uint32_t expected = htonl(value);
+ EXPECT_EQ(size, ares_inet_net_pton(AF_INET, input, &a4, sizeof(a4)))
+ << " for input " << input;
+ EXPECT_EQ(expected, a4.s_addr) << " for input " << input;
+}
+#endif
+
+TEST_F(LibraryTest, InetPtoN) {
+ struct in_addr a4;
+ struct in6_addr a6;
+
+#ifndef CARES_SYMBOL_HIDING
+ uint32_t expected;
+
+ CheckPtoN4(4 * 8, 0x01020304, "1.2.3.4");
+ CheckPtoN4(4 * 8, 0x81010101, "129.1.1.1");
+ CheckPtoN4(4 * 8, 0xC0010101, "192.1.1.1");
+ CheckPtoN4(4 * 8, 0xE0010101, "224.1.1.1");
+ CheckPtoN4(4 * 8, 0xE1010101, "225.1.1.1");
+ CheckPtoN4(4, 0xE0000000, "224");
+ CheckPtoN4(4 * 8, 0xFD000000, "253");
+ CheckPtoN4(4 * 8, 0xF0010101, "240.1.1.1");
+ CheckPtoN4(4 * 8, 0x02030405, "02.3.4.5");
+ CheckPtoN4(3 * 8, 0x01020304, "1.2.3.4/24");
+ CheckPtoN4(3 * 8, 0x01020300, "1.2.3/24");
+ CheckPtoN4(2 * 8, 0xa0000000, "0xa");
+ CheckPtoN4(0, 0x02030405, "2.3.4.5/000");
+ CheckPtoN4(1 * 8, 0x01020000, "1.2/8");
+ CheckPtoN4(2 * 8, 0x01020000, "0x0102/16");
+ CheckPtoN4(4 * 8, 0x02030405, "02.3.4.5");
+
+ EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "::", &a6, sizeof(a6)));
+ EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "::1", &a6, sizeof(a6)));
+ EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "1234:5678::", &a6, sizeof(a6)));
+ EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "12:34::ff", &a6, sizeof(a6)));
+ EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.4", &a6, sizeof(a6)));
+ EXPECT_EQ(23, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.4/23", &a6, sizeof(a6)));
+ EXPECT_EQ(3 * 8, ares_inet_net_pton(AF_INET6, "12:34::ff/24", &a6, sizeof(a6)));
+ EXPECT_EQ(0, ares_inet_net_pton(AF_INET6, "12:34::ff/0", &a6, sizeof(a6)));
+ EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "12:34::ffff:0.2", &a6, sizeof(a6)));
+ EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234", &a6, sizeof(a6)));
+
+ // Various malformed versions
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "", &a4, sizeof(a4)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, " ", &a4, sizeof(a4)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x", &a4, sizeof(a4)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x ", &a4, sizeof(a4)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "x0", &a4, sizeof(a4)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0xXYZZY", &a4, sizeof(a4)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "xyzzy", &a4, sizeof(a4)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET+AF_INET6, "1.2.3.4", &a4, sizeof(a4)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "257.2.3.4", &a4, sizeof(a4)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "002.3.4.x", &a4, sizeof(a4)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "00.3.4.x", &a4, sizeof(a4)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.x", &a4, sizeof(a4)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5.6", &a4, sizeof(a4)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5.6/12", &a4, sizeof(a4)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4:5", &a4, sizeof(a4)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5/120", &a4, sizeof(a4)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5/1x", &a4, sizeof(a4)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5/x", &a4, sizeof(a4)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/240", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/02", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/2y", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/y", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ":x", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ":", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ": :1234", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "::12345", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234::2345:3456::0011", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234:", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234::", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1.2.3.4", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ":1234:1234:1234:1234:1234:1234:1234:1234", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ":1234:1234:1234:1234:1234:1234:1234:1234:", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234:5678", &a6, sizeof(a6)));
+ // TODO(drysdale): check whether the next two tests should give -1.
+ EXPECT_EQ(0, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234:5678:5678", &a6, sizeof(a6)));
+ EXPECT_EQ(0, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234:5678:5678:5678", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:257.2.3.4", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:002.2.3.4", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.4.5.6", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.4.5", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.z", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3001.4", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3..4", &a6, sizeof(a6)));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.", &a6, sizeof(a6)));
+
+ // Hex constants are allowed.
+ EXPECT_EQ(4 * 8, ares_inet_net_pton(AF_INET, "0x01020304", &a4, sizeof(a4)));
+ expected = htonl(0x01020304);
+ EXPECT_EQ(expected, a4.s_addr);
+ EXPECT_EQ(4 * 8, ares_inet_net_pton(AF_INET, "0x0a0b0c0d", &a4, sizeof(a4)));
+ expected = htonl(0x0a0b0c0d);
+ EXPECT_EQ(expected, a4.s_addr);
+ EXPECT_EQ(4 * 8, ares_inet_net_pton(AF_INET, "0x0A0B0C0D", &a4, sizeof(a4)));
+ expected = htonl(0x0a0b0c0d);
+ EXPECT_EQ(expected, a4.s_addr);
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x0xyz", &a4, sizeof(a4)));
+ EXPECT_EQ(4 * 8, ares_inet_net_pton(AF_INET, "0x1122334", &a4, sizeof(a4)));
+ expected = htonl(0x11223340);
+ EXPECT_EQ(expected, a4.s_addr); // huh?
+
+ // No room, no room.
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "1.2.3.4", &a4, sizeof(a4) - 1));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff", &a6, sizeof(a6) - 1));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x01020304", &a4, 2));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x01020304", &a4, 0));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x0a0b0c0d", &a4, 0));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x0xyz", &a4, 0));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x1122334", &a4, sizeof(a4) - 1));
+ EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "253", &a4, sizeof(a4) - 1));
+#endif
+
+ EXPECT_EQ(1, ares_inet_pton(AF_INET, "1.2.3.4", &a4));
+ EXPECT_EQ(1, ares_inet_pton(AF_INET6, "12:34::ff", &a6));
+ EXPECT_EQ(1, ares_inet_pton(AF_INET6, "12:34::ffff:1.2.3.4", &a6));
+ EXPECT_EQ(0, ares_inet_pton(AF_INET, "xyzzy", &a4));
+ EXPECT_EQ(-1, ares_inet_pton(AF_INET+AF_INET6, "1.2.3.4", &a4));
+}
+
+TEST_F(LibraryTest, FreeCorruptData) {
+ // ares_free_data(p) expects that there is a type field and a marker
+ // field in the memory before p. Feed it incorrect versions of each.
+ struct ares_data *data = (struct ares_data *)malloc(sizeof(struct ares_data));
+ void* p = &(data->data);
+
+ // Invalid type
+ data->type = (ares_datatype)99;
+ data->mark = ARES_DATATYPE_MARK;
+ ares_free_data(p);
+
+ // Invalid marker
+ data->type = (ares_datatype)ARES_DATATYPE_MX_REPLY;
+ data->mark = ARES_DATATYPE_MARK + 1;
+ ares_free_data(p);
+
+ // Null pointer
+ ares_free_data(nullptr);
+
+ free(data);
+}
+
+#ifndef CARES_SYMBOL_HIDING
+TEST_F(LibraryTest, FreeLongChain) {
+ struct ares_addr_node *data = nullptr;
+ for (int ii = 0; ii < 100000; ii++) {
+ struct ares_addr_node *prev = (struct ares_addr_node*)ares_malloc_data(ARES_DATATYPE_ADDR_NODE);
+ prev->next = data;
+ data = prev;
+ }
+
+ ares_free_data(data);
+}
+
+TEST(LibraryInit, StrdupFailures) {
+ EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
+ char* copy = ares_strdup("string");
+ EXPECT_NE(nullptr, copy);
+ ares_free(copy);
+ ares_library_cleanup();
+}
+
+TEST_F(LibraryTest, StrdupFailures) {
+ SetAllocFail(1);
+ char* copy = ares_strdup("string");
+ EXPECT_EQ(nullptr, copy);
+}
+
+TEST_F(LibraryTest, MallocDataFail) {
+ EXPECT_EQ(nullptr, ares_malloc_data((ares_datatype)99));
+ SetAllocSizeFail(sizeof(struct ares_data));
+ EXPECT_EQ(nullptr, ares_malloc_data(ARES_DATATYPE_MX_REPLY));
+}
+
+TEST(Misc, Bitncmp) {
+ byte a[4] = {0x80, 0x01, 0x02, 0x03};
+ byte b[4] = {0x80, 0x01, 0x02, 0x04};
+ byte c[4] = {0x01, 0xFF, 0x80, 0x02};
+ EXPECT_GT(0, ares__bitncmp(a, b, sizeof(a)*8));
+ EXPECT_LT(0, ares__bitncmp(b, a, sizeof(a)*8));
+ EXPECT_EQ(0, ares__bitncmp(a, a, sizeof(a)*8));
+
+ for (int ii = 1; ii < (3*8+5); ii++) {
+ EXPECT_EQ(0, ares__bitncmp(a, b, ii));
+ EXPECT_EQ(0, ares__bitncmp(b, a, ii));
+ EXPECT_LT(0, ares__bitncmp(a, c, ii));
+ EXPECT_GT(0, ares__bitncmp(c, a, ii));
+ }
+
+ // Last byte differs at 5th bit
+ EXPECT_EQ(0, ares__bitncmp(a, b, 3*8 + 3));
+ EXPECT_EQ(0, ares__bitncmp(a, b, 3*8 + 4));
+ EXPECT_EQ(0, ares__bitncmp(a, b, 3*8 + 5));
+ EXPECT_GT(0, ares__bitncmp(a, b, 3*8 + 6));
+ EXPECT_GT(0, ares__bitncmp(a, b, 3*8 + 7));
+}
+
+TEST_F(LibraryTest, Casts) {
+ ares_ssize_t ssz = 100;
+ unsigned int u = 100;
+ int i = 100;
+ long l = 100;
+
+ unsigned int ru = aresx_sztoui(ssz);
+ EXPECT_EQ(u, ru);
+ int ri = aresx_sztosi(ssz);
+ EXPECT_EQ(i, ri);
+
+ ri = aresx_sltosi(l);
+ EXPECT_EQ(l, (long)ri);
+}
+
+TEST_F(LibraryTest, ReadLine) {
+ TempFile temp("abcde\n0123456789\nXYZ\n012345678901234567890\n\n");
+ FILE *fp = fopen(temp.filename(), "r");
+ size_t bufsize = 4;
+ char *buf = (char *)ares_malloc(bufsize);
+
+ EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
+ EXPECT_EQ("abcde", std::string(buf));
+ EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
+ EXPECT_EQ("0123456789", std::string(buf));
+ EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
+ EXPECT_EQ("XYZ", std::string(buf));
+ SetAllocFail(1);
+ EXPECT_EQ(ARES_ENOMEM, ares__read_line(fp, &buf, &bufsize));
+ EXPECT_EQ(nullptr, buf);
+
+ fclose(fp);
+ ares_free(buf);
+}
+
+TEST_F(LibraryTest, ReadLineNoBuf) {
+ TempFile temp("abcde\n0123456789\nXYZ\n012345678901234567890");
+ FILE *fp = fopen(temp.filename(), "r");
+ size_t bufsize = 0;
+ char *buf = nullptr;
+
+ SetAllocFail(1);
+ EXPECT_EQ(ARES_ENOMEM, ares__read_line(fp, &buf, &bufsize));
+
+ EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
+ EXPECT_EQ("abcde", std::string(buf));
+ EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
+ EXPECT_EQ("0123456789", std::string(buf));
+ EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
+ EXPECT_EQ("XYZ", std::string(buf));
+ EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
+ EXPECT_EQ("012345678901234567890", std::string(buf));
+
+ fclose(fp);
+ ares_free(buf);
+}
+
+TEST(Misc, GetHostent) {
+ 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");
+ struct hostent *host = nullptr;
+ FILE *fp = fopen(hostsfile.filename(), "r");
+ ASSERT_NE(nullptr, fp);
+ EXPECT_EQ(ARES_EBADFAMILY, ares__get_hostent(fp, AF_INET+AF_INET6, &host));
+ rewind(fp);
+
+ EXPECT_EQ(ARES_SUCCESS, ares__get_hostent(fp, AF_INET, &host));
+ ASSERT_NE(nullptr, host);
+ std::stringstream ss1;
+ ss1 << HostEnt(host);
+ EXPECT_EQ("{'example.com' aliases=[] addrs=[1.2.3.4]}", ss1.str());
+ ares_free_hostent(host);
+ host = nullptr;
+
+ EXPECT_EQ(ARES_SUCCESS, ares__get_hostent(fp, AF_INET, &host));
+ ASSERT_NE(nullptr, host);
+ std::stringstream ss2;
+ ss2 << HostEnt(host);
+ EXPECT_EQ("{'google.com' aliases=[www.google.com, www2.google.com] addrs=[2.3.4.5]}", ss2.str());
+ ares_free_hostent(host);
+ host = nullptr;
+
+ EXPECT_EQ(ARES_EOF, ares__get_hostent(fp, AF_INET, &host));
+
+ rewind(fp);
+ EXPECT_EQ(ARES_SUCCESS, ares__get_hostent(fp, AF_INET6, &host));
+ ASSERT_NE(nullptr, host);
+ std::stringstream ss3;
+ ss3 << HostEnt(host);
+ EXPECT_EQ("{'ipv6.com' aliases=[] addrs=[0000:0000:0000:0000:0000:0000:0000:0001]}", ss3.str());
+ ares_free_hostent(host);
+ host = nullptr;
+ EXPECT_EQ(ARES_EOF, ares__get_hostent(fp, AF_INET6, &host));
+ fclose(fp);
+}
+
+TEST_F(LibraryTest, GetHostentAllocFail) {
+ TempFile hostsfile("1.2.3.4 example.com alias1 alias2\n");
+ struct hostent *host = nullptr;
+ FILE *fp = fopen(hostsfile.filename(), "r");
+ ASSERT_NE(nullptr, fp);
+
+ for (int ii = 1; ii <= 8; ii++) {
+ rewind(fp);
+ ClearFails();
+ SetAllocFail(ii);
+ host = nullptr;
+ EXPECT_EQ(ARES_ENOMEM, ares__get_hostent(fp, AF_INET, &host)) << 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"
@@ -457,135 +457,135 @@ TEST_F(LibraryTest, GetAddrInfoAllocFail) {
fclose(fp);
}
-TEST(Misc, OnionDomain) {
- EXPECT_EQ(0, ares__is_onion_domain("onion.no"));
- EXPECT_EQ(0, ares__is_onion_domain(".onion.no"));
- EXPECT_EQ(1, ares__is_onion_domain(".onion"));
- EXPECT_EQ(1, ares__is_onion_domain(".onion."));
- EXPECT_EQ(1, ares__is_onion_domain("yes.onion"));
- EXPECT_EQ(1, ares__is_onion_domain("yes.onion."));
- EXPECT_EQ(1, ares__is_onion_domain("YES.ONION"));
- EXPECT_EQ(1, ares__is_onion_domain("YES.ONION."));
-}
-#endif
-
-#ifdef CARES_EXPOSE_STATICS
-// These tests access internal static functions from the library, which
-// are only exposed when CARES_EXPOSE_STATICS has been configured. As such
-// they are tightly couple to the internal library implementation details.
-extern "C" char *ares_striendstr(const char*, const char*);
-TEST_F(LibraryTest, Striendstr) {
- EXPECT_EQ(nullptr, ares_striendstr("abc", "12345"));
- EXPECT_NE(nullptr, ares_striendstr("abc12345", "12345"));
- EXPECT_NE(nullptr, ares_striendstr("abcxyzzy", "XYZZY"));
- EXPECT_NE(nullptr, ares_striendstr("xyzzy", "XYZZY"));
- EXPECT_EQ(nullptr, ares_striendstr("xyxzy", "XYZZY"));
- EXPECT_NE(nullptr, ares_striendstr("", ""));
- const char *str = "plugh";
- EXPECT_NE(nullptr, ares_striendstr(str, str));
-}
+TEST(Misc, OnionDomain) {
+ EXPECT_EQ(0, ares__is_onion_domain("onion.no"));
+ EXPECT_EQ(0, ares__is_onion_domain(".onion.no"));
+ EXPECT_EQ(1, ares__is_onion_domain(".onion"));
+ EXPECT_EQ(1, ares__is_onion_domain(".onion."));
+ EXPECT_EQ(1, ares__is_onion_domain("yes.onion"));
+ EXPECT_EQ(1, ares__is_onion_domain("yes.onion."));
+ EXPECT_EQ(1, ares__is_onion_domain("YES.ONION"));
+ EXPECT_EQ(1, ares__is_onion_domain("YES.ONION."));
+}
+#endif
+
+#ifdef CARES_EXPOSE_STATICS
+// These tests access internal static functions from the library, which
+// are only exposed when CARES_EXPOSE_STATICS has been configured. As such
+// they are tightly couple to the internal library implementation details.
+extern "C" char *ares_striendstr(const char*, const char*);
+TEST_F(LibraryTest, Striendstr) {
+ EXPECT_EQ(nullptr, ares_striendstr("abc", "12345"));
+ EXPECT_NE(nullptr, ares_striendstr("abc12345", "12345"));
+ EXPECT_NE(nullptr, ares_striendstr("abcxyzzy", "XYZZY"));
+ EXPECT_NE(nullptr, ares_striendstr("xyzzy", "XYZZY"));
+ EXPECT_EQ(nullptr, ares_striendstr("xyxzy", "XYZZY"));
+ EXPECT_NE(nullptr, ares_striendstr("", ""));
+ const char *str = "plugh";
+ EXPECT_NE(nullptr, ares_striendstr(str, str));
+}
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;
+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));
-
- channel_->flags |= ARES_FLAG_NOSEARCH|ARES_FLAG_NOALIASES;
+
+ channel_->flags |= ARES_FLAG_NOSEARCH|ARES_FLAG_NOALIASES;
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("www", std::string(ptr));
+ ares_free(ptr);
+ ptr = nullptr;
+
+ SetAllocFail(1);
EXPECT_EQ(ARES_ENOMEM, ares__single_domain(channel_, "www", &ptr));
- EXPECT_EQ(nullptr, ptr);
-}
-#endif
-
-TEST_F(DefaultChannelTest, SaveInvalidChannel) {
- int saved = channel_->nservers;
- channel_->nservers = -1;
- struct ares_options opts;
- int optmask = 0;
- EXPECT_EQ(ARES_ENODATA, ares_save_options(channel_, &opts, &optmask));
- channel_->nservers = saved;
-}
-
-// Need to put this in own function due to nested lambda bug
-// in VS2013. (C2888)
-static int configure_socket(ares_socket_t s) {
- // transposed from ares-process, simplified non-block setter.
-#if defined(USE_BLOCKING_SOCKETS)
- return 0; /* returns success */
-#elif defined(HAVE_FCNTL_O_NONBLOCK)
- /* most recent unix versions */
- int flags;
- flags = fcntl(s, F_GETFL, 0);
- return fcntl(s, F_SETFL, flags | O_NONBLOCK);
-#elif defined(HAVE_IOCTL_FIONBIO)
- /* older unix versions */
- int flags = 1;
- return ioctl(s, FIONBIO, &flags);
-#elif defined(HAVE_IOCTLSOCKET_FIONBIO)
-#ifdef WATT32
- char flags = 1;
-#else
- /* Windows */
- unsigned long flags = 1UL;
-#endif
- return ioctlsocket(s, FIONBIO, &flags);
-#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
- /* Amiga */
- long flags = 1L;
- return IoctlSocket(s, FIONBIO, flags);
-#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
- /* BeOS */
- long b = 1L;
- return setsockopt(s, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
-#else
-# error "no non-blocking method was found/used/set"
-#endif
-}
-
-// TODO: This should not really be in this file, but we need ares config
-// flags, and here they are available.
-const struct ares_socket_functions VirtualizeIO::default_functions = {
- [](int af, int type, int protocol, void *) -> ares_socket_t {
- auto s = ::socket(af, type, protocol);
- if (s == ARES_SOCKET_BAD) {
- return s;
- }
- if (configure_socket(s) != 0) {
- sclose(s);
- return ares_socket_t(-1);
- }
- return s;
- },
- [](ares_socket_t s, void * p) {
- return :: sclose(s);
- },
- [](ares_socket_t s, const struct sockaddr * addr, socklen_t len, void *) {
- return ::connect(s, addr, len);
- },
- [](ares_socket_t s, void * dst, size_t len, int flags, struct sockaddr * addr, socklen_t * alen, void *) -> ares_ssize_t {
-#ifdef HAVE_RECVFROM
- return ::recvfrom(s, reinterpret_cast<RECV_TYPE_ARG2>(dst), len, flags, addr, alen);
-#else
- return sread(s, dst, len);
-#endif
- },
- [](ares_socket_t s, const struct iovec * vec, int len, void *) {
+ EXPECT_EQ(nullptr, ptr);
+}
+#endif
+
+TEST_F(DefaultChannelTest, SaveInvalidChannel) {
+ int saved = channel_->nservers;
+ channel_->nservers = -1;
+ struct ares_options opts;
+ int optmask = 0;
+ EXPECT_EQ(ARES_ENODATA, ares_save_options(channel_, &opts, &optmask));
+ channel_->nservers = saved;
+}
+
+// Need to put this in own function due to nested lambda bug
+// in VS2013. (C2888)
+static int configure_socket(ares_socket_t s) {
+ // transposed from ares-process, simplified non-block setter.
+#if defined(USE_BLOCKING_SOCKETS)
+ return 0; /* returns success */
+#elif defined(HAVE_FCNTL_O_NONBLOCK)
+ /* most recent unix versions */
+ int flags;
+ flags = fcntl(s, F_GETFL, 0);
+ return fcntl(s, F_SETFL, flags | O_NONBLOCK);
+#elif defined(HAVE_IOCTL_FIONBIO)
+ /* older unix versions */
+ int flags = 1;
+ return ioctl(s, FIONBIO, &flags);
+#elif defined(HAVE_IOCTLSOCKET_FIONBIO)
+#ifdef WATT32
+ char flags = 1;
+#else
+ /* Windows */
+ unsigned long flags = 1UL;
+#endif
+ return ioctlsocket(s, FIONBIO, &flags);
+#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
+ /* Amiga */
+ long flags = 1L;
+ return IoctlSocket(s, FIONBIO, flags);
+#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
+ /* BeOS */
+ long b = 1L;
+ return setsockopt(s, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
+#else
+# error "no non-blocking method was found/used/set"
+#endif
+}
+
+// TODO: This should not really be in this file, but we need ares config
+// flags, and here they are available.
+const struct ares_socket_functions VirtualizeIO::default_functions = {
+ [](int af, int type, int protocol, void *) -> ares_socket_t {
+ auto s = ::socket(af, type, protocol);
+ if (s == ARES_SOCKET_BAD) {
+ return s;
+ }
+ if (configure_socket(s) != 0) {
+ sclose(s);
+ return ares_socket_t(-1);
+ }
+ return s;
+ },
+ [](ares_socket_t s, void * p) {
+ return :: sclose(s);
+ },
+ [](ares_socket_t s, const struct sockaddr * addr, socklen_t len, void *) {
+ return ::connect(s, addr, len);
+ },
+ [](ares_socket_t s, void * dst, size_t len, int flags, struct sockaddr * addr, socklen_t * alen, void *) -> ares_ssize_t {
+#ifdef HAVE_RECVFROM
+ return ::recvfrom(s, reinterpret_cast<RECV_TYPE_ARG2>(dst), len, flags, addr, alen);
+#else
+ return sread(s, dst, len);
+#endif
+ },
+ [](ares_socket_t s, const struct iovec * vec, int len, void *) {
#ifndef HAVE_WRITEV
- return ares_writev(s, vec, len);
-#else
- return :: writev(s, vec, len);
-#endif
- }
-};
-
-
-} // namespace test
-} // namespace ares
+ return ares_writev(s, vec, len);
+#else
+ return :: writev(s, vec, len);
+#endif
+ }
+};
+
+
+} // namespace test
+} // namespace ares
diff --git a/contrib/libs/c-ares/test/ares-test-live.cc b/contrib/libs/c-ares/test/ares-test-live.cc
index b5de37734e..5510163e95 100644
--- a/contrib/libs/c-ares/test/ares-test-live.cc
+++ b/contrib/libs/c-ares/test/ares-test-live.cc
@@ -1,23 +1,23 @@
-// This file includes tests that attempt to do real lookups
-// of DNS names using the local machine's live infrastructure.
-// As a result, we don't check the results very closely, to allow
-// for varying local configurations.
-
-#include "ares-test.h"
-
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-
-namespace ares {
-namespace test {
-
-// Use the address of Google's public DNS servers as example addresses that are
-// likely to be accessible everywhere/everywhen.
-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};
-
+// This file includes tests that attempt to do real lookups
+// of DNS names using the local machine's live infrastructure.
+// As a result, we don't check the results very closely, to allow
+// for varying local configurations.
+
+#include "ares-test.h"
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
+namespace ares {
+namespace test {
+
+// Use the address of Google's public DNS servers as example addresses that are
+// likely to be accessible everywhere/everywhen.
+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;
@@ -82,620 +82,620 @@ MATCHER_P(IncludesAddrType, addrtype, "") {
//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);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- EXPECT_LT(0, (int)result.host_.addrs_.size());
- EXPECT_EQ(AF_INET, result.host_.addrtype_);
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveGetHostByNameV6) {
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET6, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- EXPECT_LT(0, (int)result.host_.addrs_.size());
- EXPECT_EQ(AF_INET6, result.host_.addrtype_);
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveGetHostByAddrV4) {
- HostResult result;
- ares_gethostbyaddr(channel_, gdns_addr4, sizeof(gdns_addr4), AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- EXPECT_LT(0, (int)result.host_.addrs_.size());
- EXPECT_EQ(AF_INET, result.host_.addrtype_);
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveGetHostByAddrV6) {
- HostResult result;
- ares_gethostbyaddr(channel_, gdns_addr6, sizeof(gdns_addr6), AF_INET6, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- EXPECT_LT(0, (int)result.host_.addrs_.size());
- EXPECT_EQ(AF_INET6, result.host_.addrtype_);
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetHostByNameFile) {
- struct hostent *host = nullptr;
-
- // Still need a channel even to query /etc/hosts.
- EXPECT_EQ(ARES_ENOTFOUND,
- ares_gethostbyname_file(nullptr, "localhost", AF_INET, &host));
-
- int rc = ares_gethostbyname_file(channel_, "bogus.mcname", AF_INET, &host);
- EXPECT_EQ(nullptr, host);
- EXPECT_EQ(ARES_ENOTFOUND, rc);
-
- rc = ares_gethostbyname_file(channel_, "localhost", AF_INET, &host);
- if (rc == ARES_SUCCESS) {
- EXPECT_NE(nullptr, host);
- ares_free_hostent(host);
- }
-}
-
-TEST_P(DefaultChannelModeTest, LiveGetLocalhostByNameV4) {
- HostResult result;
- ares_gethostbyname(channel_, "localhost", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- if ((result.status_ != ARES_ENOTFOUND) && (result.status_ != ARES_ECONNREFUSED)) {
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- EXPECT_EQ(1, (int)result.host_.addrs_.size());
- EXPECT_EQ(AF_INET, result.host_.addrtype_);
- EXPECT_NE(std::string::npos, result.host_.name_.find("localhost"));
- }
-}
-
-TEST_P(DefaultChannelModeTest, LiveGetLocalhostByNameV6) {
- HostResult result;
- ares_gethostbyname(channel_, "localhost", AF_INET6, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- if (result.status_ == ARES_SUCCESS) {
- EXPECT_EQ(1, (int)result.host_.addrs_.size());
- EXPECT_EQ(AF_INET6, result.host_.addrtype_);
- std::stringstream ss;
- ss << HostEnt(result.host_);
- EXPECT_NE(std::string::npos, result.host_.name_.find("localhost"));
- }
-}
-
-TEST_P(DefaultChannelModeTest, LiveGetLocalhostByNameIPV4) {
- HostResult result;
- ares_gethostbyname(channel_, "127.0.0.1", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- EXPECT_EQ(1, (int)result.host_.addrs_.size());
- EXPECT_EQ(AF_INET, result.host_.addrtype_);
- std::stringstream ss;
- ss << HostEnt(result.host_);
- EXPECT_EQ("{'127.0.0.1' aliases=[] addrs=[127.0.0.1]}", ss.str());
-}
-
-TEST_P(DefaultChannelModeTest, LiveGetLocalhostByNameIPV6) {
- HostResult result;
- ares_gethostbyname(channel_, "::1", AF_INET6, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- if (result.status_ != ARES_ENOTFOUND) {
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- EXPECT_EQ(1, (int)result.host_.addrs_.size());
- EXPECT_EQ(AF_INET6, result.host_.addrtype_);
- std::stringstream ss;
- ss << HostEnt(result.host_);
- EXPECT_EQ("{'::1' aliases=[] addrs=[0000:0000:0000:0000:0000:0000:0000:0001]}", ss.str());
- }
-}
-
-TEST_P(DefaultChannelModeTest, LiveGetLocalhostFailFamily) {
- HostResult result;
- ares_gethostbyname(channel_, "127.0.0.1", AF_INET+AF_INET6, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENOTIMP, result.status_);
-}
-
-TEST_P(DefaultChannelModeTest, LiveGetLocalhostByAddrV4) {
- HostResult result;
- struct in_addr addr;
- addr.s_addr = htonl(INADDR_LOOPBACK);
- ares_gethostbyaddr(channel_, &addr, sizeof(addr), AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- if (result.status_ != ARES_ENOTFOUND) {
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- EXPECT_LT(0, (int)result.host_.addrs_.size());
- EXPECT_EQ(AF_INET, result.host_.addrtype_);
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveGetHostByNameV4) {
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ EXPECT_LT(0, (int)result.host_.addrs_.size());
+ EXPECT_EQ(AF_INET, result.host_.addrtype_);
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveGetHostByNameV6) {
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET6, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ EXPECT_LT(0, (int)result.host_.addrs_.size());
+ EXPECT_EQ(AF_INET6, result.host_.addrtype_);
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveGetHostByAddrV4) {
+ HostResult result;
+ ares_gethostbyaddr(channel_, gdns_addr4, sizeof(gdns_addr4), AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ EXPECT_LT(0, (int)result.host_.addrs_.size());
+ EXPECT_EQ(AF_INET, result.host_.addrtype_);
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveGetHostByAddrV6) {
+ HostResult result;
+ ares_gethostbyaddr(channel_, gdns_addr6, sizeof(gdns_addr6), AF_INET6, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ EXPECT_LT(0, (int)result.host_.addrs_.size());
+ EXPECT_EQ(AF_INET6, result.host_.addrtype_);
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetHostByNameFile) {
+ struct hostent *host = nullptr;
+
+ // Still need a channel even to query /etc/hosts.
+ EXPECT_EQ(ARES_ENOTFOUND,
+ ares_gethostbyname_file(nullptr, "localhost", AF_INET, &host));
+
+ int rc = ares_gethostbyname_file(channel_, "bogus.mcname", AF_INET, &host);
+ EXPECT_EQ(nullptr, host);
+ EXPECT_EQ(ARES_ENOTFOUND, rc);
+
+ rc = ares_gethostbyname_file(channel_, "localhost", AF_INET, &host);
+ if (rc == ARES_SUCCESS) {
+ EXPECT_NE(nullptr, host);
+ ares_free_hostent(host);
+ }
+}
+
+TEST_P(DefaultChannelModeTest, LiveGetLocalhostByNameV4) {
+ HostResult result;
+ ares_gethostbyname(channel_, "localhost", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ if ((result.status_ != ARES_ENOTFOUND) && (result.status_ != ARES_ECONNREFUSED)) {
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ EXPECT_EQ(1, (int)result.host_.addrs_.size());
+ EXPECT_EQ(AF_INET, result.host_.addrtype_);
+ EXPECT_NE(std::string::npos, result.host_.name_.find("localhost"));
+ }
+}
+
+TEST_P(DefaultChannelModeTest, LiveGetLocalhostByNameV6) {
+ HostResult result;
+ ares_gethostbyname(channel_, "localhost", AF_INET6, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ if (result.status_ == ARES_SUCCESS) {
+ EXPECT_EQ(1, (int)result.host_.addrs_.size());
+ EXPECT_EQ(AF_INET6, result.host_.addrtype_);
+ std::stringstream ss;
+ ss << HostEnt(result.host_);
+ EXPECT_NE(std::string::npos, result.host_.name_.find("localhost"));
+ }
+}
+
+TEST_P(DefaultChannelModeTest, LiveGetLocalhostByNameIPV4) {
+ HostResult result;
+ ares_gethostbyname(channel_, "127.0.0.1", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ EXPECT_EQ(1, (int)result.host_.addrs_.size());
+ EXPECT_EQ(AF_INET, result.host_.addrtype_);
+ std::stringstream ss;
+ ss << HostEnt(result.host_);
+ EXPECT_EQ("{'127.0.0.1' aliases=[] addrs=[127.0.0.1]}", ss.str());
+}
+
+TEST_P(DefaultChannelModeTest, LiveGetLocalhostByNameIPV6) {
+ HostResult result;
+ ares_gethostbyname(channel_, "::1", AF_INET6, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ if (result.status_ != ARES_ENOTFOUND) {
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ EXPECT_EQ(1, (int)result.host_.addrs_.size());
+ EXPECT_EQ(AF_INET6, result.host_.addrtype_);
+ std::stringstream ss;
+ ss << HostEnt(result.host_);
+ EXPECT_EQ("{'::1' aliases=[] addrs=[0000:0000:0000:0000:0000:0000:0000:0001]}", ss.str());
+ }
+}
+
+TEST_P(DefaultChannelModeTest, LiveGetLocalhostFailFamily) {
+ HostResult result;
+ ares_gethostbyname(channel_, "127.0.0.1", AF_INET+AF_INET6, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ENOTIMP, result.status_);
+}
+
+TEST_P(DefaultChannelModeTest, LiveGetLocalhostByAddrV4) {
+ HostResult result;
+ struct in_addr addr;
+ addr.s_addr = htonl(INADDR_LOOPBACK);
+ ares_gethostbyaddr(channel_, &addr, sizeof(addr), AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ if (result.status_ != ARES_ENOTFOUND) {
+ 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"));
}
- }
-}
-
-TEST_P(DefaultChannelModeTest, LiveGetLocalhostByAddrV6) {
- HostResult result;
- struct in6_addr addr;
- memset(&addr, 0, sizeof(addr));
- addr.s6_addr[15] = 1; // in6addr_loopback
- ares_gethostbyaddr(channel_, &addr, sizeof(addr), AF_INET6, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- if (result.status_ != ARES_ENOTFOUND) {
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- EXPECT_LT(0, (int)result.host_.addrs_.size());
- EXPECT_EQ(AF_INET6, result.host_.addrtype_);
+ }
+}
+
+TEST_P(DefaultChannelModeTest, LiveGetLocalhostByAddrV6) {
+ HostResult result;
+ struct in6_addr addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.s6_addr[15] = 1; // in6addr_loopback
+ ares_gethostbyaddr(channel_, &addr, sizeof(addr), AF_INET6, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ if (result.status_ != ARES_ENOTFOUND) {
+ 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"));
- }
-}
-
-TEST_P(DefaultChannelModeTest, LiveGetHostByAddrFailFamily) {
- HostResult result;
- unsigned char addr[4] = {8, 8, 8, 8};
- ares_gethostbyaddr(channel_, addr, sizeof(addr), AF_INET6+AF_INET,
- HostCallback, &result);
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENOTIMP, result.status_);
-}
-
-TEST_P(DefaultChannelModeTest, LiveGetHostByAddrFailAddrSize) {
- HostResult result;
- unsigned char addr[4] = {8, 8, 8, 8};
- ares_gethostbyaddr(channel_, addr, sizeof(addr) - 1, AF_INET,
- HostCallback, &result);
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENOTIMP, result.status_);
-}
-
-TEST_P(DefaultChannelModeTest, LiveGetHostByAddrFailAlloc) {
- HostResult result;
- unsigned char addr[4] = {8, 8, 8, 8};
- SetAllocFail(1);
- ares_gethostbyaddr(channel_, addr, sizeof(addr), AF_INET,
- HostCallback, &result);
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENOMEM, result.status_);
-}
-
-INSTANTIATE_TEST_CASE_P(Modes, DefaultChannelModeTest,
- ::testing::Values("f", "b", "fb", "bf"));
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveSearchA) {
- SearchResult result;
- ares_search(channel_, "www.youtube.com.", ns_c_in, ns_t_a,
- SearchCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveSearchEmptyA) {
- SearchResult result;
- ares_search(channel_, "", ns_c_in, ns_t_a,
- SearchCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_NE(ARES_SUCCESS, result.status_);
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveSearchNS) {
- SearchResult result;
- ares_search(channel_, "google.com.", ns_c_in, ns_t_ns,
- SearchCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveSearchMX) {
- SearchResult result;
- ares_search(channel_, "google.com.", ns_c_in, ns_t_mx,
- SearchCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveSearchTXT) {
- SearchResult result;
- ares_search(channel_, "google.com.", ns_c_in, ns_t_txt,
- SearchCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveSearchSOA) {
- SearchResult result;
- ares_search(channel_, "google.com.", ns_c_in, ns_t_soa,
- SearchCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveSearchSRV) {
- SearchResult result;
- ares_search(channel_, "_imap._tcp.gmail.com.", ns_c_in, ns_t_srv,
- SearchCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveSearchANY) {
- SearchResult result;
- ares_search(channel_, "google.com.", ns_c_in, ns_t_any,
- SearchCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV4) {
- NameInfoResult result;
- struct sockaddr_in sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = htons(53);
- sockaddr.sin_addr.s_addr = htonl(0x08080808);
- ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
- ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_UDP,
- NameInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- if (verbose) std::cerr << "8.8.8.8:53 => " << result.node_ << "/" << result.service_ << std::endl;
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV4NoPort) {
- NameInfoResult result;
- struct sockaddr_in sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = htons(0);
- sockaddr.sin_addr.s_addr = htonl(0x08080808);
- ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
- ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_UDP,
- NameInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- if (verbose) std::cerr << "8.8.8.8:0 => " << result.node_ << "/" << result.service_ << std::endl;
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV4UnassignedPort) {
- NameInfoResult result;
- struct sockaddr_in sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = htons(4); // Unassigned at IANA
- sockaddr.sin_addr.s_addr = htonl(0x08080808);
- ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
- ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_UDP,
- NameInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- if (verbose) std::cerr << "8.8.8.8:4 => " << result.node_ << "/" << result.service_ << std::endl;
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV6Both) {
- NameInfoResult result;
- struct sockaddr_in6 sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin6_family = AF_INET6;
- sockaddr.sin6_port = htons(53);
- memcpy(sockaddr.sin6_addr.s6_addr, gdns_addr6, 16);
- ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
- ARES_NI_TCP|ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_NOFQDN,
- NameInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- if (verbose) std::cerr << "[2001:4860:4860::8888]:53 => " << result.node_ << "/" << result.service_ << std::endl;
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV6Neither) {
- NameInfoResult result;
- struct sockaddr_in6 sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin6_family = AF_INET6;
- sockaddr.sin6_port = htons(53);
- memcpy(sockaddr.sin6_addr.s6_addr, gdns_addr6, 16);
- ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
- ARES_NI_TCP|ARES_NI_NOFQDN, // Neither specified => assume lookup host.
- NameInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- if (verbose) std::cerr << "[2001:4860:4860::8888]:53 => " << result.node_ << "/" << result.service_ << std::endl;
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV4Numeric) {
- NameInfoResult result;
- struct sockaddr_in sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = htons(53);
- sockaddr.sin_addr.s_addr = htonl(0x08080808);
- ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
- ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_TCP|ARES_NI_NUMERICHOST,
- NameInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- EXPECT_EQ("8.8.8.8", result.node_);
- if (verbose) std::cerr << "8.8.8.8:53 => " << result.node_ << "/" << result.service_ << std::endl;
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV6Numeric) {
- NameInfoResult result;
- struct sockaddr_in6 sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin6_family = AF_INET6;
- sockaddr.sin6_port = htons(53);
- memcpy(sockaddr.sin6_addr.s6_addr, gdns_addr6, 16);
- ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
- ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_DCCP|ARES_NI_NUMERICHOST,
- NameInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- EXPECT_EQ("2001:4860:4860::8888%0", result.node_);
- if (verbose) std::cerr << "[2001:4860:4860::8888]:53 => " << result.node_ << "/" << result.service_ << std::endl;
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV6LinkLocal) {
- NameInfoResult result;
- struct sockaddr_in6 sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin6_family = AF_INET6;
- sockaddr.sin6_port = htons(53);
- unsigned char addr6[16] = {0xfe, 0x80, 0x01, 0x02, 0x01, 0x02, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04};
- memcpy(sockaddr.sin6_addr.s6_addr, addr6, 16);
- ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
- ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_DCCP|ARES_NI_NUMERICHOST,
- NameInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- EXPECT_EQ("fe80:102:102::304%0", result.node_);
- if (verbose) std::cerr << "[fe80:102:102::304]:53 => " << result.node_ << "/" << result.service_ << std::endl;
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV4NotFound) {
- NameInfoResult result;
- struct sockaddr_in sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = htons(4); // Port 4 unassigned at IANA
- // RFC5737 says 192.0.2.0 should not be used publically.
- sockaddr.sin_addr.s_addr = htonl(0xC0000200);
- ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
- ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_UDP,
- NameInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- EXPECT_EQ("192.0.2.0", result.node_);
- if (verbose) std::cerr << "192.0.2.0:53 => " << result.node_ << "/" << result.service_ << std::endl;
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV4NotFoundFail) {
- NameInfoResult result;
- struct sockaddr_in sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = htons(53);
- // RFC5737 says 192.0.2.0 should not be used publically.
- sockaddr.sin_addr.s_addr = htonl(0xC0000200);
- ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
- ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_UDP|ARES_NI_NAMEREQD,
- NameInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENOTFOUND, result.status_);
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV6NotFound) {
- NameInfoResult result;
- struct sockaddr_in6 sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin6_family = AF_INET6;
- sockaddr.sin6_port = htons(53);
- // 2001:db8::/32 is only supposed to be used in documentation.
- unsigned char addr6[16] = {0x20, 0x01, 0x0d, 0xb8, 0x01, 0x02, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04};
- memcpy(sockaddr.sin6_addr.s6_addr, addr6, 16);
- ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
- ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_UDP,
- NameInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- EXPECT_EQ("2001:db8:102::304%0", result.node_);
- if (verbose) std::cerr << "[2001:db8:102::304]:53 => " << result.node_ << "/" << result.service_ << std::endl;
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInvalidFamily) {
- NameInfoResult result;
- struct sockaddr_in6 sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin6_family = AF_INET6 + AF_INET;
- sockaddr.sin6_port = htons(53);
- memcpy(sockaddr.sin6_addr.s6_addr, gdns_addr6, 16);
- ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
- ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_UDP,
- NameInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENOTIMP, result.status_);
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInvalidFlags) {
- NameInfoResult result;
- struct sockaddr_in6 sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin6_family = AF_INET6;
- sockaddr.sin6_port = htons(53);
- memcpy(sockaddr.sin6_addr.s6_addr, gdns_addr6, 16);
- // Ask for both a name-required, and a numeric host.
- ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
- ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_UDP|ARES_NI_NUMERICHOST|ARES_NI_NAMEREQD,
- NameInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_EBADFLAGS, result.status_);
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetServiceInfo) {
- NameInfoResult result;
- struct sockaddr_in sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = htons(53);
- sockaddr.sin_addr.s_addr = htonl(0x08080808);
- // Just look up service info
- ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
- ARES_NI_LOOKUPSERVICE|ARES_NI_SCTP,
- NameInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- EXPECT_EQ("", result.node_);
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetServiceInfoNumeric) {
- NameInfoResult result;
- struct sockaddr_in sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = htons(53);
- sockaddr.sin_addr.s_addr = htonl(0x08080808);
- // Just look up service info
- ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
- ARES_NI_LOOKUPSERVICE|ARES_NI_SCTP|ARES_NI_NUMERICSERV,
- NameInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- EXPECT_EQ("", result.node_);
- EXPECT_EQ("53", result.service_);
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoAllocFail) {
- NameInfoResult result;
- struct sockaddr_in sockaddr;
- memset(&sockaddr, 0, sizeof(sockaddr));
- sockaddr.sin_family = AF_INET;
- sockaddr.sin_port = htons(53);
- sockaddr.sin_addr.s_addr = htonl(0x08080808);
- SetAllocFail(1);
- ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
- ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_UDP,
- NameInfoCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENOMEM, result.status_);
-}
-
-VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_GetSock) {
- ares_socket_t socks[3] = {ARES_SOCKET_BAD, ARES_SOCKET_BAD, ARES_SOCKET_BAD};
- int bitmask = ares_getsock(channel_, socks, 3);
- EXPECT_EQ(0, bitmask);
- bitmask = ares_getsock(channel_, nullptr, 0);
- EXPECT_EQ(0, bitmask);
-
- // Ask again with a pending query.
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- bitmask = ares_getsock(channel_, socks, 3);
- EXPECT_NE(0, bitmask);
- bitmask = ares_getsock(channel_, nullptr, 0);
- EXPECT_EQ(0, bitmask);
-
- Process();
-}
-
-TEST_F(LibraryTest, DISABLED_GetTCPSock) {
- ares_channel channel;
- struct ares_options opts = {0};
- opts.tcp_port = 53;
- opts.flags = ARES_FLAG_USEVC;
- int optmask = ARES_OPT_TCP_PORT | ARES_OPT_FLAGS;
- EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
- EXPECT_NE(nullptr, channel);
-
- ares_socket_t socks[3] = {ARES_SOCKET_BAD, ARES_SOCKET_BAD, ARES_SOCKET_BAD};
- int bitmask = ares_getsock(channel, socks, 3);
- EXPECT_EQ(0, bitmask);
- bitmask = ares_getsock(channel, nullptr, 0);
- EXPECT_EQ(0, bitmask);
-
- // Ask again with a pending query.
- HostResult result;
- ares_gethostbyname(channel, "www.google.com.", AF_INET, HostCallback, &result);
- bitmask = ares_getsock(channel, socks, 3);
- EXPECT_NE(0, bitmask);
- bitmask = ares_getsock(channel, nullptr, 0);
- EXPECT_EQ(0, bitmask);
-
- ProcessWork(channel, NoExtraFDs, nullptr);
-
- ares_destroy(channel);
-}
-
-TEST_F(DefaultChannelTest, VerifySocketFunctionCallback) {
- VirtualizeIO vio(channel_);
-
- auto my_functions = VirtualizeIO::default_functions;
- size_t count = 0;
-
- my_functions.asocket = [](int af, int type, int protocol, void * p) {
- EXPECT_NE(nullptr, p);
- (*reinterpret_cast<size_t *>(p))++;
- return ::socket(af, type, protocol);
- };
-
- ares_set_socket_functions(channel_, &my_functions, &count);
-
- {
- count = 0;
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_NE(0, count);
- }
-
- {
- count = 0;
- ares_channel copy;
- EXPECT_EQ(ARES_SUCCESS, ares_dup(&copy, channel_));
-
- HostResult result;
- ares_gethostbyname(copy, "www.google.com.", AF_INET, HostCallback, &result);
- ProcessWork(copy, NoExtraFDs, nullptr);
- EXPECT_TRUE(result.done_);
- ares_destroy(copy);
- EXPECT_NE(0, count);
- }
-
-}
-
+ }
+}
+
+TEST_P(DefaultChannelModeTest, LiveGetHostByAddrFailFamily) {
+ HostResult result;
+ unsigned char addr[4] = {8, 8, 8, 8};
+ ares_gethostbyaddr(channel_, addr, sizeof(addr), AF_INET6+AF_INET,
+ HostCallback, &result);
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ENOTIMP, result.status_);
+}
+
+TEST_P(DefaultChannelModeTest, LiveGetHostByAddrFailAddrSize) {
+ HostResult result;
+ unsigned char addr[4] = {8, 8, 8, 8};
+ ares_gethostbyaddr(channel_, addr, sizeof(addr) - 1, AF_INET,
+ HostCallback, &result);
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ENOTIMP, result.status_);
+}
+
+TEST_P(DefaultChannelModeTest, LiveGetHostByAddrFailAlloc) {
+ HostResult result;
+ unsigned char addr[4] = {8, 8, 8, 8};
+ SetAllocFail(1);
+ ares_gethostbyaddr(channel_, addr, sizeof(addr), AF_INET,
+ HostCallback, &result);
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ENOMEM, result.status_);
+}
+
+INSTANTIATE_TEST_CASE_P(Modes, DefaultChannelModeTest,
+ ::testing::Values("f", "b", "fb", "bf"));
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveSearchA) {
+ SearchResult result;
+ ares_search(channel_, "www.youtube.com.", ns_c_in, ns_t_a,
+ SearchCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveSearchEmptyA) {
+ SearchResult result;
+ ares_search(channel_, "", ns_c_in, ns_t_a,
+ SearchCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_NE(ARES_SUCCESS, result.status_);
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveSearchNS) {
+ SearchResult result;
+ ares_search(channel_, "google.com.", ns_c_in, ns_t_ns,
+ SearchCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveSearchMX) {
+ SearchResult result;
+ ares_search(channel_, "google.com.", ns_c_in, ns_t_mx,
+ SearchCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveSearchTXT) {
+ SearchResult result;
+ ares_search(channel_, "google.com.", ns_c_in, ns_t_txt,
+ SearchCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveSearchSOA) {
+ SearchResult result;
+ ares_search(channel_, "google.com.", ns_c_in, ns_t_soa,
+ SearchCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveSearchSRV) {
+ SearchResult result;
+ ares_search(channel_, "_imap._tcp.gmail.com.", ns_c_in, ns_t_srv,
+ SearchCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_LiveSearchANY) {
+ SearchResult result;
+ ares_search(channel_, "google.com.", ns_c_in, ns_t_any,
+ SearchCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV4) {
+ NameInfoResult result;
+ struct sockaddr_in sockaddr;
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = htons(53);
+ sockaddr.sin_addr.s_addr = htonl(0x08080808);
+ ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
+ ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_UDP,
+ NameInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ if (verbose) std::cerr << "8.8.8.8:53 => " << result.node_ << "/" << result.service_ << std::endl;
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV4NoPort) {
+ NameInfoResult result;
+ struct sockaddr_in sockaddr;
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = htons(0);
+ sockaddr.sin_addr.s_addr = htonl(0x08080808);
+ ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
+ ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_UDP,
+ NameInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ if (verbose) std::cerr << "8.8.8.8:0 => " << result.node_ << "/" << result.service_ << std::endl;
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV4UnassignedPort) {
+ NameInfoResult result;
+ struct sockaddr_in sockaddr;
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = htons(4); // Unassigned at IANA
+ sockaddr.sin_addr.s_addr = htonl(0x08080808);
+ ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
+ ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_UDP,
+ NameInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ if (verbose) std::cerr << "8.8.8.8:4 => " << result.node_ << "/" << result.service_ << std::endl;
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV6Both) {
+ NameInfoResult result;
+ struct sockaddr_in6 sockaddr;
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin6_family = AF_INET6;
+ sockaddr.sin6_port = htons(53);
+ memcpy(sockaddr.sin6_addr.s6_addr, gdns_addr6, 16);
+ ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
+ ARES_NI_TCP|ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_NOFQDN,
+ NameInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ if (verbose) std::cerr << "[2001:4860:4860::8888]:53 => " << result.node_ << "/" << result.service_ << std::endl;
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV6Neither) {
+ NameInfoResult result;
+ struct sockaddr_in6 sockaddr;
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin6_family = AF_INET6;
+ sockaddr.sin6_port = htons(53);
+ memcpy(sockaddr.sin6_addr.s6_addr, gdns_addr6, 16);
+ ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
+ ARES_NI_TCP|ARES_NI_NOFQDN, // Neither specified => assume lookup host.
+ NameInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ if (verbose) std::cerr << "[2001:4860:4860::8888]:53 => " << result.node_ << "/" << result.service_ << std::endl;
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV4Numeric) {
+ NameInfoResult result;
+ struct sockaddr_in sockaddr;
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = htons(53);
+ sockaddr.sin_addr.s_addr = htonl(0x08080808);
+ ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
+ ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_TCP|ARES_NI_NUMERICHOST,
+ NameInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ EXPECT_EQ("8.8.8.8", result.node_);
+ if (verbose) std::cerr << "8.8.8.8:53 => " << result.node_ << "/" << result.service_ << std::endl;
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV6Numeric) {
+ NameInfoResult result;
+ struct sockaddr_in6 sockaddr;
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin6_family = AF_INET6;
+ sockaddr.sin6_port = htons(53);
+ memcpy(sockaddr.sin6_addr.s6_addr, gdns_addr6, 16);
+ ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
+ ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_DCCP|ARES_NI_NUMERICHOST,
+ NameInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ EXPECT_EQ("2001:4860:4860::8888%0", result.node_);
+ if (verbose) std::cerr << "[2001:4860:4860::8888]:53 => " << result.node_ << "/" << result.service_ << std::endl;
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV6LinkLocal) {
+ NameInfoResult result;
+ struct sockaddr_in6 sockaddr;
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin6_family = AF_INET6;
+ sockaddr.sin6_port = htons(53);
+ unsigned char addr6[16] = {0xfe, 0x80, 0x01, 0x02, 0x01, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04};
+ memcpy(sockaddr.sin6_addr.s6_addr, addr6, 16);
+ ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
+ ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_DCCP|ARES_NI_NUMERICHOST,
+ NameInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ EXPECT_EQ("fe80:102:102::304%0", result.node_);
+ if (verbose) std::cerr << "[fe80:102:102::304]:53 => " << result.node_ << "/" << result.service_ << std::endl;
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV4NotFound) {
+ NameInfoResult result;
+ struct sockaddr_in sockaddr;
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = htons(4); // Port 4 unassigned at IANA
+ // RFC5737 says 192.0.2.0 should not be used publically.
+ sockaddr.sin_addr.s_addr = htonl(0xC0000200);
+ ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
+ ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_UDP,
+ NameInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ EXPECT_EQ("192.0.2.0", result.node_);
+ if (verbose) std::cerr << "192.0.2.0:53 => " << result.node_ << "/" << result.service_ << std::endl;
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV4NotFoundFail) {
+ NameInfoResult result;
+ struct sockaddr_in sockaddr;
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = htons(53);
+ // RFC5737 says 192.0.2.0 should not be used publically.
+ sockaddr.sin_addr.s_addr = htonl(0xC0000200);
+ ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
+ ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_UDP|ARES_NI_NAMEREQD,
+ NameInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ENOTFOUND, result.status_);
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV6NotFound) {
+ NameInfoResult result;
+ struct sockaddr_in6 sockaddr;
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin6_family = AF_INET6;
+ sockaddr.sin6_port = htons(53);
+ // 2001:db8::/32 is only supposed to be used in documentation.
+ unsigned char addr6[16] = {0x20, 0x01, 0x0d, 0xb8, 0x01, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04};
+ memcpy(sockaddr.sin6_addr.s6_addr, addr6, 16);
+ ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
+ ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_UDP,
+ NameInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ EXPECT_EQ("2001:db8:102::304%0", result.node_);
+ if (verbose) std::cerr << "[2001:db8:102::304]:53 => " << result.node_ << "/" << result.service_ << std::endl;
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInvalidFamily) {
+ NameInfoResult result;
+ struct sockaddr_in6 sockaddr;
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin6_family = AF_INET6 + AF_INET;
+ sockaddr.sin6_port = htons(53);
+ memcpy(sockaddr.sin6_addr.s6_addr, gdns_addr6, 16);
+ ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
+ ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_UDP,
+ NameInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ENOTIMP, result.status_);
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInvalidFlags) {
+ NameInfoResult result;
+ struct sockaddr_in6 sockaddr;
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin6_family = AF_INET6;
+ sockaddr.sin6_port = htons(53);
+ memcpy(sockaddr.sin6_addr.s6_addr, gdns_addr6, 16);
+ // Ask for both a name-required, and a numeric host.
+ ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
+ ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_UDP|ARES_NI_NUMERICHOST|ARES_NI_NAMEREQD,
+ NameInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_EBADFLAGS, result.status_);
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetServiceInfo) {
+ NameInfoResult result;
+ struct sockaddr_in sockaddr;
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = htons(53);
+ sockaddr.sin_addr.s_addr = htonl(0x08080808);
+ // Just look up service info
+ ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
+ ARES_NI_LOOKUPSERVICE|ARES_NI_SCTP,
+ NameInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ EXPECT_EQ("", result.node_);
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetServiceInfoNumeric) {
+ NameInfoResult result;
+ struct sockaddr_in sockaddr;
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = htons(53);
+ sockaddr.sin_addr.s_addr = htonl(0x08080808);
+ // Just look up service info
+ ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
+ ARES_NI_LOOKUPSERVICE|ARES_NI_SCTP|ARES_NI_NUMERICSERV,
+ NameInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ EXPECT_EQ("", result.node_);
+ EXPECT_EQ("53", result.service_);
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoAllocFail) {
+ NameInfoResult result;
+ struct sockaddr_in sockaddr;
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ sockaddr.sin_family = AF_INET;
+ sockaddr.sin_port = htons(53);
+ sockaddr.sin_addr.s_addr = htonl(0x08080808);
+ SetAllocFail(1);
+ ares_getnameinfo(channel_, (const struct sockaddr*)&sockaddr, sizeof(sockaddr),
+ ARES_NI_LOOKUPHOST|ARES_NI_LOOKUPSERVICE|ARES_NI_UDP,
+ NameInfoCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ENOMEM, result.status_);
+}
+
+VIRT_NONVIRT_TEST_F(DefaultChannelTest, DISABLED_GetSock) {
+ ares_socket_t socks[3] = {ARES_SOCKET_BAD, ARES_SOCKET_BAD, ARES_SOCKET_BAD};
+ int bitmask = ares_getsock(channel_, socks, 3);
+ EXPECT_EQ(0, bitmask);
+ bitmask = ares_getsock(channel_, nullptr, 0);
+ EXPECT_EQ(0, bitmask);
+
+ // Ask again with a pending query.
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ bitmask = ares_getsock(channel_, socks, 3);
+ EXPECT_NE(0, bitmask);
+ bitmask = ares_getsock(channel_, nullptr, 0);
+ EXPECT_EQ(0, bitmask);
+
+ Process();
+}
+
+TEST_F(LibraryTest, DISABLED_GetTCPSock) {
+ ares_channel channel;
+ struct ares_options opts = {0};
+ opts.tcp_port = 53;
+ opts.flags = ARES_FLAG_USEVC;
+ int optmask = ARES_OPT_TCP_PORT | ARES_OPT_FLAGS;
+ EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask));
+ EXPECT_NE(nullptr, channel);
+
+ ares_socket_t socks[3] = {ARES_SOCKET_BAD, ARES_SOCKET_BAD, ARES_SOCKET_BAD};
+ int bitmask = ares_getsock(channel, socks, 3);
+ EXPECT_EQ(0, bitmask);
+ bitmask = ares_getsock(channel, nullptr, 0);
+ EXPECT_EQ(0, bitmask);
+
+ // Ask again with a pending query.
+ HostResult result;
+ ares_gethostbyname(channel, "www.google.com.", AF_INET, HostCallback, &result);
+ bitmask = ares_getsock(channel, socks, 3);
+ EXPECT_NE(0, bitmask);
+ bitmask = ares_getsock(channel, nullptr, 0);
+ EXPECT_EQ(0, bitmask);
+
+ ProcessWork(channel, NoExtraFDs, nullptr);
+
+ ares_destroy(channel);
+}
+
+TEST_F(DefaultChannelTest, VerifySocketFunctionCallback) {
+ VirtualizeIO vio(channel_);
+
+ auto my_functions = VirtualizeIO::default_functions;
+ size_t count = 0;
+
+ my_functions.asocket = [](int af, int type, int protocol, void * p) {
+ EXPECT_NE(nullptr, p);
+ (*reinterpret_cast<size_t *>(p))++;
+ return ::socket(af, type, protocol);
+ };
+
+ ares_set_socket_functions(channel_, &my_functions, &count);
+
+ {
+ count = 0;
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_NE(0, count);
+ }
+
+ {
+ count = 0;
+ ares_channel copy;
+ EXPECT_EQ(ARES_SUCCESS, ares_dup(&copy, channel_));
+
+ HostResult result;
+ ares_gethostbyname(copy, "www.google.com.", AF_INET, HostCallback, &result);
+ ProcessWork(copy, NoExtraFDs, nullptr);
+ EXPECT_TRUE(result.done_);
+ ares_destroy(copy);
+ EXPECT_NE(0, count);
+ }
+
+}
+
TEST_F(DefaultChannelTest, LiveSetServers) {
struct ares_addr_node server1;
struct ares_addr_node server2;
@@ -705,7 +705,7 @@ TEST_F(DefaultChannelTest, LiveSetServers) {
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);
@@ -745,5 +745,5 @@ TEST_F(DefaultChannelTest, LiveSetServersCSV) {
}
-} // namespace test
-} // namespace ares
+} // 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 b42987ef39..6fc28a8f97 100644
--- a/contrib/libs/c-ares/test/ares-test-misc.cc
+++ b/contrib/libs/c-ares/test/ares-test-misc.cc
@@ -1,282 +1,282 @@
-#include "ares-test.h"
-#include "dns-proto.h"
-
-#include <string>
-#include <vector>
-
-namespace ares {
-namespace test {
-
-TEST_F(DefaultChannelTest, GetServers) {
- std::vector<std::string> servers = GetNameServers(channel_);
- if (verbose) {
- for (const std::string& server : servers) {
- std::cerr << "Nameserver: " << server << std::endl;
- }
- }
-}
-
-TEST_F(DefaultChannelTest, GetServersFailures) {
- EXPECT_EQ(ARES_SUCCESS,
- ares_set_servers_csv(channel_, "1.2.3.4,2.3.4.5"));
- struct ares_addr_node* servers = nullptr;
- SetAllocFail(1);
- EXPECT_EQ(ARES_ENOMEM, ares_get_servers(channel_, &servers));
- SetAllocFail(2);
- EXPECT_EQ(ARES_ENOMEM, ares_get_servers(channel_, &servers));
- EXPECT_EQ(ARES_ENODATA, ares_get_servers(nullptr, &servers));
-}
-
+#include "ares-test.h"
+#include "dns-proto.h"
+
+#include <string>
+#include <vector>
+
+namespace ares {
+namespace test {
+
+TEST_F(DefaultChannelTest, GetServers) {
+ std::vector<std::string> servers = GetNameServers(channel_);
+ if (verbose) {
+ for (const std::string& server : servers) {
+ std::cerr << "Nameserver: " << server << std::endl;
+ }
+ }
+}
+
+TEST_F(DefaultChannelTest, GetServersFailures) {
+ EXPECT_EQ(ARES_SUCCESS,
+ ares_set_servers_csv(channel_, "1.2.3.4,2.3.4.5"));
+ struct ares_addr_node* servers = nullptr;
+ SetAllocFail(1);
+ EXPECT_EQ(ARES_ENOMEM, ares_get_servers(channel_, &servers));
+ SetAllocFail(2);
+ EXPECT_EQ(ARES_ENOMEM, ares_get_servers(channel_, &servers));
+ EXPECT_EQ(ARES_ENODATA, ares_get_servers(nullptr, &servers));
+}
+
TEST_F(DefaultChannelTest, SetServers) {
- EXPECT_EQ(ARES_SUCCESS, ares_set_servers(channel_, nullptr));
- std::vector<std::string> empty;
- EXPECT_EQ(empty, GetNameServers(channel_));
-
- 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);
- EXPECT_EQ(ARES_ENODATA, ares_set_servers(nullptr, &server1));
-
- EXPECT_EQ(ARES_SUCCESS, ares_set_servers(channel_, &server1));
- std::vector<std::string> expected = {"1.2.3.4", "2.3.4.5"};
- EXPECT_EQ(expected, GetNameServers(channel_));
-}
-
+ EXPECT_EQ(ARES_SUCCESS, ares_set_servers(channel_, nullptr));
+ std::vector<std::string> empty;
+ EXPECT_EQ(empty, GetNameServers(channel_));
+
+ 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);
+ EXPECT_EQ(ARES_ENODATA, ares_set_servers(nullptr, &server1));
+
+ EXPECT_EQ(ARES_SUCCESS, ares_set_servers(channel_, &server1));
+ std::vector<std::string> expected = {"1.2.3.4", "2.3.4.5"};
+ EXPECT_EQ(expected, GetNameServers(channel_));
+}
+
TEST_F(DefaultChannelTest, SetServersPorts) {
- EXPECT_EQ(ARES_SUCCESS, ares_set_servers_ports(channel_, nullptr));
- std::vector<std::string> empty;
- EXPECT_EQ(empty, GetNameServers(channel_));
-
- 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));
-
- EXPECT_EQ(ARES_SUCCESS, ares_set_servers_ports(channel_, &server1));
- std::vector<std::string> expected = {"1.2.3.4:111", "2.3.4.5"};
- EXPECT_EQ(expected, GetNameServers(channel_));
-}
-
+ EXPECT_EQ(ARES_SUCCESS, ares_set_servers_ports(channel_, nullptr));
+ std::vector<std::string> empty;
+ EXPECT_EQ(empty, GetNameServers(channel_));
+
+ 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));
+
+ EXPECT_EQ(ARES_SUCCESS, ares_set_servers_ports(channel_, &server1));
+ std::vector<std::string> expected = {"1.2.3.4:111", "2.3.4.5"};
+ EXPECT_EQ(expected, GetNameServers(channel_));
+}
+
TEST_F(DefaultChannelTest, SetServersCSV) {
- EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "1.2.3.4"));
- EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "xyzzy,plugh"));
- EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "256.1.2.3"));
- EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "1.2.3.4.5"));
- EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "1:2:3:4:5"));
-
- EXPECT_EQ(ARES_SUCCESS,
- ares_set_servers_csv(channel_, "1.2.3.4,0102:0304:0506:0708:0910:1112:1314:1516,2.3.4.5"));
- std::vector<std::string> expected = {"1.2.3.4", "0102:0304:0506:0708:0910:1112:1314:1516", "2.3.4.5"};
- EXPECT_EQ(expected, GetNameServers(channel_));
-
- // Same, with spaces
- EXPECT_EQ(ARES_EBADSTR,
- ares_set_servers_csv(channel_, "1.2.3.4 , 0102:0304:0506:0708:0910:1112:1314:1516, 2.3.4.5"));
-
- // Same, with ports
- EXPECT_EQ(ARES_SUCCESS,
- ares_set_servers_csv(channel_, "1.2.3.4:54,[0102:0304:0506:0708:0910:1112:1314:1516]:80,2.3.4.5:55"));
- EXPECT_EQ(expected, GetNameServers(channel_));
- EXPECT_EQ(ARES_SUCCESS,
- ares_set_servers_ports_csv(channel_, "1.2.3.4:54,[0102:0304:0506:0708:0910:1112:1314:1516]:80,2.3.4.5:55"));
- std::vector<std::string> expected2 = {"1.2.3.4:54", "[0102:0304:0506:0708:0910:1112:1314:1516]:80", "2.3.4.5:55"};
- EXPECT_EQ(expected2, GetNameServers(channel_));
-
- // Should survive duplication
- ares_channel channel2;
- EXPECT_EQ(ARES_SUCCESS, ares_dup(&channel2, channel_));
- EXPECT_EQ(expected2, GetNameServers(channel2));
- ares_destroy(channel2);
-
- // Allocation failure cases
- for (int fail = 1; fail <= 5; fail++) {
- SetAllocFail(fail);
- EXPECT_EQ(ARES_ENOMEM,
- ares_set_servers_csv(channel_, "1.2.3.4,0102:0304:0506:0708:0910:1112:1314:1516,2.3.4.5"));
- }
-
- // Blank servers
- EXPECT_EQ(ARES_SUCCESS, ares_set_servers_csv(channel_, ""));
- std::vector<std::string> none;
- EXPECT_EQ(none, GetNameServers(channel_));
-
- EXPECT_EQ(ARES_EBADSTR, ares_set_servers_csv(channel_, "2.3.4.5,1.2.3.4:,3.4.5.6"));
- EXPECT_EQ(ARES_EBADSTR, ares_set_servers_csv(channel_, "2.3.4.5,1.2.3.4:Z,3.4.5.6"));
-}
-
+ EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "1.2.3.4"));
+ EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "xyzzy,plugh"));
+ EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "256.1.2.3"));
+ EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "1.2.3.4.5"));
+ EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "1:2:3:4:5"));
+
+ EXPECT_EQ(ARES_SUCCESS,
+ ares_set_servers_csv(channel_, "1.2.3.4,0102:0304:0506:0708:0910:1112:1314:1516,2.3.4.5"));
+ std::vector<std::string> expected = {"1.2.3.4", "0102:0304:0506:0708:0910:1112:1314:1516", "2.3.4.5"};
+ EXPECT_EQ(expected, GetNameServers(channel_));
+
+ // Same, with spaces
+ EXPECT_EQ(ARES_EBADSTR,
+ ares_set_servers_csv(channel_, "1.2.3.4 , 0102:0304:0506:0708:0910:1112:1314:1516, 2.3.4.5"));
+
+ // Same, with ports
+ EXPECT_EQ(ARES_SUCCESS,
+ ares_set_servers_csv(channel_, "1.2.3.4:54,[0102:0304:0506:0708:0910:1112:1314:1516]:80,2.3.4.5:55"));
+ EXPECT_EQ(expected, GetNameServers(channel_));
+ EXPECT_EQ(ARES_SUCCESS,
+ ares_set_servers_ports_csv(channel_, "1.2.3.4:54,[0102:0304:0506:0708:0910:1112:1314:1516]:80,2.3.4.5:55"));
+ std::vector<std::string> expected2 = {"1.2.3.4:54", "[0102:0304:0506:0708:0910:1112:1314:1516]:80", "2.3.4.5:55"};
+ EXPECT_EQ(expected2, GetNameServers(channel_));
+
+ // Should survive duplication
+ ares_channel channel2;
+ EXPECT_EQ(ARES_SUCCESS, ares_dup(&channel2, channel_));
+ EXPECT_EQ(expected2, GetNameServers(channel2));
+ ares_destroy(channel2);
+
+ // Allocation failure cases
+ for (int fail = 1; fail <= 5; fail++) {
+ SetAllocFail(fail);
+ EXPECT_EQ(ARES_ENOMEM,
+ ares_set_servers_csv(channel_, "1.2.3.4,0102:0304:0506:0708:0910:1112:1314:1516,2.3.4.5"));
+ }
+
+ // Blank servers
+ EXPECT_EQ(ARES_SUCCESS, ares_set_servers_csv(channel_, ""));
+ std::vector<std::string> none;
+ EXPECT_EQ(none, GetNameServers(channel_));
+
+ EXPECT_EQ(ARES_EBADSTR, ares_set_servers_csv(channel_, "2.3.4.5,1.2.3.4:,3.4.5.6"));
+ EXPECT_EQ(ARES_EBADSTR, ares_set_servers_csv(channel_, "2.3.4.5,1.2.3.4:Z,3.4.5.6"));
+}
+
TEST_F(DefaultChannelTest, TimeoutValue) {
- struct timeval tinfo;
- tinfo.tv_sec = 0;
- tinfo.tv_usec = 0;
- struct timeval tmax;
- tmax.tv_sec = 0;
- tmax.tv_usec = 10;
- struct timeval* pt;
-
- // No timers => get max back.
- pt = ares_timeout(channel_, &tmax, &tinfo);
- EXPECT_EQ(&tmax, pt);
- EXPECT_EQ(0, pt->tv_sec);
- EXPECT_EQ(10, pt->tv_usec);
-
- pt = ares_timeout(channel_, nullptr, &tinfo);
- EXPECT_EQ(nullptr, pt);
-
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
-
- // Now there's a timer running.
- pt = ares_timeout(channel_, &tmax, &tinfo);
- EXPECT_EQ(&tmax, pt);
- EXPECT_EQ(0, pt->tv_sec);
- EXPECT_EQ(10, pt->tv_usec);
-
- tmax.tv_sec = 100;
- pt = ares_timeout(channel_, &tmax, &tinfo);
- EXPECT_EQ(&tinfo, pt);
-
- pt = ares_timeout(channel_, nullptr, &tinfo);
- EXPECT_EQ(&tinfo, pt);
-
- Process();
-}
-
-TEST_F(LibraryTest, InetNtoP) {
- struct in_addr addr;
- addr.s_addr = htonl(0x01020304);
- char buffer[256];
- EXPECT_EQ(buffer, ares_inet_ntop(AF_INET, &addr, buffer, sizeof(buffer)));
- EXPECT_EQ("1.2.3.4", std::string(buffer));
-}
-
-TEST_F(LibraryTest, Mkquery) {
- byte* p;
- int len;
- ares_mkquery("example.com", ns_c_in, ns_t_a, 0x1234, 0, &p, &len);
- std::vector<byte> data(p, p + len);
- ares_free_string(p);
-
- std::string actual = PacketToString(data);
- DNSPacket pkt;
- pkt.set_qid(0x1234).add_question(new DNSQuestion("example.com", ns_t_a));
- std::string expected = PacketToString(pkt.data());
- EXPECT_EQ(expected, actual);
-}
-
-TEST_F(LibraryTest, CreateQuery) {
- byte* p;
- int len;
- EXPECT_EQ(ARES_SUCCESS,
- ares_create_query("exam\\@le.com", ns_c_in, ns_t_a, 0x1234, 0,
- &p, &len, 0));
- std::vector<byte> data(p, p + len);
- ares_free_string(p);
-
- std::string actual = PacketToString(data);
- DNSPacket pkt;
- pkt.set_qid(0x1234).add_question(new DNSQuestion("exam@le.com", ns_t_a));
- std::string expected = PacketToString(pkt.data());
- EXPECT_EQ(expected, actual);
-}
-
-TEST_F(LibraryTest, CreateQueryTrailingEscapedDot) {
- byte* p;
- int len;
- EXPECT_EQ(ARES_SUCCESS,
- ares_create_query("example.com\\.", ns_c_in, ns_t_a, 0x1234, 0,
- &p, &len, 0));
- std::vector<byte> data(p, p + len);
- ares_free_string(p);
-
- std::string actual = PacketToString(data);
- EXPECT_EQ("REQ QRY Q:{'example.com\\.' IN A}", actual);
-}
-
-TEST_F(LibraryTest, CreateQueryNameTooLong) {
- byte* p;
- int len;
- EXPECT_EQ(ARES_EBADNAME,
- ares_create_query(
- "a1234567890123456789.b1234567890123456789.c1234567890123456789.d1234567890123456789."
- "a1234567890123456789.b1234567890123456789.c1234567890123456789.d1234567890123456789."
- "a1234567890123456789.b1234567890123456789.c1234567890123456789.d1234567890123456789."
- "x1234567890123456789.y1234567890123456789.",
- ns_c_in, ns_t_a, 0x1234, 0, &p, &len, 0));
-}
-
-TEST_F(LibraryTest, CreateQueryFailures) {
- byte* p;
- int len;
- // RC1035 has a 255 byte limit on names.
- std::string longname;
- for (int ii = 0; ii < 17; ii++) {
- longname += "fedcba9876543210";
- }
- p = nullptr;
- EXPECT_EQ(ARES_EBADNAME,
- ares_create_query(longname.c_str(), ns_c_in, ns_t_a, 0x1234, 0,
- &p, &len, 0));
- if (p) ares_free_string(p);
-
- SetAllocFail(1);
-
- p = nullptr;
- EXPECT_EQ(ARES_ENOMEM,
- ares_create_query("example.com", ns_c_in, ns_t_a, 0x1234, 0,
- &p, &len, 0));
- if (p) ares_free_string(p);
-
- // 63-char limit on a single label
- std::string longlabel = "a.a123456789b123456789c123456789d123456789e123456789f123456789g123456789.org";
- p = nullptr;
- EXPECT_EQ(ARES_EBADNAME,
- ares_create_query(longlabel.c_str(), ns_c_in, ns_t_a, 0x1234, 0,
- &p, &len, 0));
- if (p) ares_free_string(p);
-
- // Empty non-terminal label
- p = nullptr;
- EXPECT_EQ(ARES_EBADNAME,
- ares_create_query("example..com", ns_c_in, ns_t_a, 0x1234, 0,
- &p, &len, 0));
- if (p) ares_free_string(p);
-}
-
-TEST_F(LibraryTest, CreateQueryOnionDomain) {
- byte* p;
- int len;
- EXPECT_EQ(ARES_ENOTFOUND,
- ares_create_query("dontleak.onion", ns_c_in, ns_t_a, 0x1234, 0,
- &p, &len, 0));
-}
-
-TEST_F(DefaultChannelTest, HostByNameOnionDomain) {
- HostResult result;
- ares_gethostbyname(channel_, "dontleak.onion", AF_INET, HostCallback, &result);
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENOTFOUND, result.status_);
-}
-
-TEST_F(DefaultChannelTest, HostByNameFileOnionDomain) {
- struct hostent *h;
- EXPECT_EQ(ARES_ENOTFOUND,
- ares_gethostbyname_file(channel_, "dontleak.onion", AF_INET, &h));
-}
-
+ struct timeval tinfo;
+ tinfo.tv_sec = 0;
+ tinfo.tv_usec = 0;
+ struct timeval tmax;
+ tmax.tv_sec = 0;
+ tmax.tv_usec = 10;
+ struct timeval* pt;
+
+ // No timers => get max back.
+ pt = ares_timeout(channel_, &tmax, &tinfo);
+ EXPECT_EQ(&tmax, pt);
+ EXPECT_EQ(0, pt->tv_sec);
+ EXPECT_EQ(10, pt->tv_usec);
+
+ pt = ares_timeout(channel_, nullptr, &tinfo);
+ EXPECT_EQ(nullptr, pt);
+
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+
+ // Now there's a timer running.
+ pt = ares_timeout(channel_, &tmax, &tinfo);
+ EXPECT_EQ(&tmax, pt);
+ EXPECT_EQ(0, pt->tv_sec);
+ EXPECT_EQ(10, pt->tv_usec);
+
+ tmax.tv_sec = 100;
+ pt = ares_timeout(channel_, &tmax, &tinfo);
+ EXPECT_EQ(&tinfo, pt);
+
+ pt = ares_timeout(channel_, nullptr, &tinfo);
+ EXPECT_EQ(&tinfo, pt);
+
+ Process();
+}
+
+TEST_F(LibraryTest, InetNtoP) {
+ struct in_addr addr;
+ addr.s_addr = htonl(0x01020304);
+ char buffer[256];
+ EXPECT_EQ(buffer, ares_inet_ntop(AF_INET, &addr, buffer, sizeof(buffer)));
+ EXPECT_EQ("1.2.3.4", std::string(buffer));
+}
+
+TEST_F(LibraryTest, Mkquery) {
+ byte* p;
+ int len;
+ ares_mkquery("example.com", ns_c_in, ns_t_a, 0x1234, 0, &p, &len);
+ std::vector<byte> data(p, p + len);
+ ares_free_string(p);
+
+ std::string actual = PacketToString(data);
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).add_question(new DNSQuestion("example.com", ns_t_a));
+ std::string expected = PacketToString(pkt.data());
+ EXPECT_EQ(expected, actual);
+}
+
+TEST_F(LibraryTest, CreateQuery) {
+ byte* p;
+ int len;
+ EXPECT_EQ(ARES_SUCCESS,
+ ares_create_query("exam\\@le.com", ns_c_in, ns_t_a, 0x1234, 0,
+ &p, &len, 0));
+ std::vector<byte> data(p, p + len);
+ ares_free_string(p);
+
+ std::string actual = PacketToString(data);
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).add_question(new DNSQuestion("exam@le.com", ns_t_a));
+ std::string expected = PacketToString(pkt.data());
+ EXPECT_EQ(expected, actual);
+}
+
+TEST_F(LibraryTest, CreateQueryTrailingEscapedDot) {
+ byte* p;
+ int len;
+ EXPECT_EQ(ARES_SUCCESS,
+ ares_create_query("example.com\\.", ns_c_in, ns_t_a, 0x1234, 0,
+ &p, &len, 0));
+ std::vector<byte> data(p, p + len);
+ ares_free_string(p);
+
+ std::string actual = PacketToString(data);
+ EXPECT_EQ("REQ QRY Q:{'example.com\\.' IN A}", actual);
+}
+
+TEST_F(LibraryTest, CreateQueryNameTooLong) {
+ byte* p;
+ int len;
+ EXPECT_EQ(ARES_EBADNAME,
+ ares_create_query(
+ "a1234567890123456789.b1234567890123456789.c1234567890123456789.d1234567890123456789."
+ "a1234567890123456789.b1234567890123456789.c1234567890123456789.d1234567890123456789."
+ "a1234567890123456789.b1234567890123456789.c1234567890123456789.d1234567890123456789."
+ "x1234567890123456789.y1234567890123456789.",
+ ns_c_in, ns_t_a, 0x1234, 0, &p, &len, 0));
+}
+
+TEST_F(LibraryTest, CreateQueryFailures) {
+ byte* p;
+ int len;
+ // RC1035 has a 255 byte limit on names.
+ std::string longname;
+ for (int ii = 0; ii < 17; ii++) {
+ longname += "fedcba9876543210";
+ }
+ p = nullptr;
+ EXPECT_EQ(ARES_EBADNAME,
+ ares_create_query(longname.c_str(), ns_c_in, ns_t_a, 0x1234, 0,
+ &p, &len, 0));
+ if (p) ares_free_string(p);
+
+ SetAllocFail(1);
+
+ p = nullptr;
+ EXPECT_EQ(ARES_ENOMEM,
+ ares_create_query("example.com", ns_c_in, ns_t_a, 0x1234, 0,
+ &p, &len, 0));
+ if (p) ares_free_string(p);
+
+ // 63-char limit on a single label
+ std::string longlabel = "a.a123456789b123456789c123456789d123456789e123456789f123456789g123456789.org";
+ p = nullptr;
+ EXPECT_EQ(ARES_EBADNAME,
+ ares_create_query(longlabel.c_str(), ns_c_in, ns_t_a, 0x1234, 0,
+ &p, &len, 0));
+ if (p) ares_free_string(p);
+
+ // Empty non-terminal label
+ p = nullptr;
+ EXPECT_EQ(ARES_EBADNAME,
+ ares_create_query("example..com", ns_c_in, ns_t_a, 0x1234, 0,
+ &p, &len, 0));
+ if (p) ares_free_string(p);
+}
+
+TEST_F(LibraryTest, CreateQueryOnionDomain) {
+ byte* p;
+ int len;
+ EXPECT_EQ(ARES_ENOTFOUND,
+ ares_create_query("dontleak.onion", ns_c_in, ns_t_a, 0x1234, 0,
+ &p, &len, 0));
+}
+
+TEST_F(DefaultChannelTest, HostByNameOnionDomain) {
+ HostResult result;
+ ares_gethostbyname(channel_, "dontleak.onion", AF_INET, HostCallback, &result);
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ENOTFOUND, result.status_);
+}
+
+TEST_F(DefaultChannelTest, HostByNameFileOnionDomain) {
+ struct hostent *h;
+ EXPECT_EQ(ARES_ENOTFOUND,
+ ares_gethostbyname_file(channel_, "dontleak.onion", AF_INET, &h));
+}
+
TEST_F(DefaultChannelTest, GetAddrinfoOnionDomain) {
AddrInfoResult result;
struct ares_addrinfo_hints hints = {};
@@ -286,241 +286,241 @@ TEST_F(DefaultChannelTest, GetAddrinfoOnionDomain) {
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.
-TEST_F(DefaultChannelTest, SearchOnionDomain) {
- SearchResult result;
- ares_search(channel_, "dontleak.onion", ns_c_in, ns_t_a,
- SearchCallback, &result);
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENOTFOUND, result.status_);
-}
-
-TEST_F(DefaultChannelTest, SendFailure) {
- unsigned char buf[2];
- SearchResult result;
- ares_send(channel_, buf, sizeof(buf), SearchCallback, &result);
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_EBADQUERY, result.status_);
-}
-
-std::string ExpandName(const std::vector<byte>& data, int offset,
- long *enclen) {
- char *name = nullptr;
- int rc = ares_expand_name(data.data() + offset, data.data(), data.size(),
- &name, enclen);
- EXPECT_EQ(ARES_SUCCESS, rc);
- std::string result;
- if (rc == ARES_SUCCESS) {
- result = name;
- } else {
- result = "<error>";
- }
- ares_free_string(name);
- return result;
-}
-
-TEST_F(LibraryTest, ExpandName) {
- long enclen;
- std::vector<byte> data1 = {1, 'a', 2, 'b', 'c', 3, 'd', 'e', 'f', 0};
- EXPECT_EQ("a.bc.def", ExpandName(data1, 0, &enclen));
- EXPECT_EQ(data1.size(), enclen);
-
- std::vector<byte> data2 = {0};
- EXPECT_EQ("", ExpandName(data2, 0, &enclen));
- EXPECT_EQ(1, enclen);
-
- // Complete name indirection
- std::vector<byte> data3 = {0x12, 0x23,
- 3, 'd', 'e', 'f', 0,
- 0xC0, 2};
- EXPECT_EQ("def", ExpandName(data3, 2, &enclen));
- EXPECT_EQ(5, enclen);
- EXPECT_EQ("def", ExpandName(data3, 7, &enclen));
- EXPECT_EQ(2, enclen);
-
- // One label then indirection
- std::vector<byte> data4 = {0x12, 0x23,
- 3, 'd', 'e', 'f', 0,
- 1, 'a', 0xC0, 2};
- EXPECT_EQ("def", ExpandName(data4, 2, &enclen));
- EXPECT_EQ(5, enclen);
- EXPECT_EQ("a.def", ExpandName(data4, 7, &enclen));
- EXPECT_EQ(4, enclen);
-
- // Two labels then indirection
- std::vector<byte> data5 = {0x12, 0x23,
- 3, 'd', 'e', 'f', 0,
- 1, 'a', 1, 'b', 0xC0, 2};
- EXPECT_EQ("def", ExpandName(data5, 2, &enclen));
- EXPECT_EQ(5, enclen);
- EXPECT_EQ("a.b.def", ExpandName(data5, 7, &enclen));
- EXPECT_EQ(6, enclen);
-
- // Empty name, indirection to empty name
- std::vector<byte> data6 = {0x12, 0x23,
- 0,
- 0xC0, 2};
- EXPECT_EQ("", ExpandName(data6, 2, &enclen));
- EXPECT_EQ(1, enclen);
- EXPECT_EQ("", ExpandName(data6, 3, &enclen));
- EXPECT_EQ(2, enclen);
-}
-
-TEST_F(LibraryTest, ExpandNameFailure) {
- std::vector<byte> data1 = {0x03, 'c', 'o', 'm', 0x00};
- char *name = nullptr;
- long enclen;
- SetAllocFail(1);
- EXPECT_EQ(ARES_ENOMEM,
- ares_expand_name(data1.data(), data1.data(), data1.size(),
- &name, &enclen));
-
- // Empty packet
- EXPECT_EQ(ARES_EBADNAME,
- ares_expand_name(data1.data(), data1.data(), 0, &name, &enclen));
-
- // Start beyond enclosing data
- EXPECT_EQ(ARES_EBADNAME,
- ares_expand_name(data1.data() + data1.size(), data1.data(), data1.size(),
- &name, &enclen));
-
- // Length beyond size of enclosing data
- std::vector<byte> data2a = {0x13, 'c', 'o', 'm', 0x00};
- EXPECT_EQ(ARES_EBADNAME,
- ares_expand_name(data2a.data(), data2a.data(), data2a.size(),
- &name, &enclen));
- std::vector<byte> data2b = {0x1};
- EXPECT_EQ(ARES_EBADNAME,
- ares_expand_name(data2b.data(), data2b.data(), data2b.size(),
- &name, &enclen));
- std::vector<byte> data2c = {0xC0};
- EXPECT_EQ(ARES_EBADNAME,
- ares_expand_name(data2c.data(), data2c.data(), data2c.size(),
- &name, &enclen));
-
- // Indirection beyond enclosing data
- std::vector<byte> data3a = {0xC0, 0x02};
- EXPECT_EQ(ARES_EBADNAME,
- ares_expand_name(data3a.data(), data3a.data(), data3a.size(),
- &name, &enclen));
- std::vector<byte> data3b = {0xC0, 0x0A, 'c', 'o', 'm', 0x00};
- EXPECT_EQ(ARES_EBADNAME,
- ares_expand_name(data3b.data(), data3b.data(), data3b.size(),
- &name, &enclen));
-
- // Invalid top bits in label length
- std::vector<byte> data4 = {0x03, 'c', 'o', 'm', 0x00, 0x80, 0x00};
- EXPECT_EQ(ARES_EBADNAME,
- ares_expand_name(data4.data() + 5, data4.data(), data4.size(),
- &name, &enclen));
-
- // Label too long: 64-byte label, with invalid top 2 bits of length (01).
- std::vector<byte> data5 = {0x40,
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
- 0x00};
- EXPECT_EQ(ARES_EBADNAME,
- ares_expand_name(data5.data(), data5.data(), data5.size(),
- &name, &enclen)) << name;
-
- // Incomplete indirect length
- std::vector<byte> data6 = {0x03, 'c', 'o', 'm', 0x00, 0xC0};
- EXPECT_EQ(ARES_EBADNAME,
- ares_expand_name(data6.data() + 5, data6.data(), data6.size(),
- &name, &enclen));
-
- // Indirection loops
- std::vector<byte> data7 = {0xC0, 0x02, 0xC0, 0x00};
- EXPECT_EQ(ARES_EBADNAME,
- ares_expand_name(data7.data(), data7.data(), data7.size(),
- &name, &enclen));
- std::vector<byte> data8 = {3, 'd', 'e', 'f', 0xC0, 0x08, 0x00, 0x00,
- 3, 'a', 'b', 'c', 0xC0, 0x00};
- EXPECT_EQ(ARES_EBADNAME,
- ares_expand_name(data8.data(), data8.data(), data8.size(),
- &name, &enclen));
- std::vector<byte> data9 = {0x12, 0x23, // start 2 bytes in
- 3, 'd', 'e', 'f', 0xC0, 0x02};
- EXPECT_EQ(ARES_EBADNAME,
- ares_expand_name(data9.data() + 2, data9.data(), data9.size(),
- &name, &enclen));
-}
-
-TEST_F(LibraryTest, CreateEDNSQuery) {
- byte* p;
- int len;
- EXPECT_EQ(ARES_SUCCESS,
- ares_create_query("example.com", ns_c_in, ns_t_a, 0x1234, 0,
- &p, &len, 1280));
- std::vector<byte> data(p, p + len);
- ares_free_string(p);
-
- std::string actual = PacketToString(data);
- DNSPacket pkt;
- pkt.set_qid(0x1234).add_question(new DNSQuestion("example.com", ns_t_a))
- .add_additional(new DNSOptRR(0, 1280));
- std::string expected = PacketToString(pkt.data());
- EXPECT_EQ(expected, actual);
-}
-
-TEST_F(LibraryTest, CreateRootQuery) {
- byte* p;
- int len;
- ares_create_query(".", ns_c_in, ns_t_a, 0x1234, 0, &p, &len, 0);
- std::vector<byte> data(p, p + len);
- ares_free_string(p);
-
- std::string actual = PacketToString(data);
- DNSPacket pkt;
- pkt.set_qid(0x1234).add_question(new DNSQuestion("", ns_t_a));
- std::string expected = PacketToString(pkt.data());
- EXPECT_EQ(expected, actual);
-}
-
-TEST_F(LibraryTest, Version) {
- // Assume linked to same version
- EXPECT_EQ(std::string(ARES_VERSION_STR),
- std::string(ares_version(nullptr)));
- int version;
- ares_version(&version);
- EXPECT_EQ(ARES_VERSION, version);
-}
-
-TEST_F(LibraryTest, Strerror) {
- EXPECT_EQ("Successful completion",
- std::string(ares_strerror(ARES_SUCCESS)));
- EXPECT_EQ("DNS query cancelled",
- std::string(ares_strerror(ARES_ECANCELLED)));
- EXPECT_EQ("unknown",
- std::string(ares_strerror(99)));
-}
-
-TEST_F(LibraryTest, ExpandString) {
- std::vector<byte> s1 = { 3, 'a', 'b', 'c'};
- char* result = nullptr;
- long len;
- EXPECT_EQ(ARES_SUCCESS,
- ares_expand_string(s1.data(), s1.data(), s1.size(),
- (unsigned char**)&result, &len));
- EXPECT_EQ("abc", std::string(result));
- EXPECT_EQ(1 + 3, len); // amount of data consumed includes 1 byte len
- ares_free_string(result);
- result = nullptr;
- EXPECT_EQ(ARES_EBADSTR,
- ares_expand_string(s1.data() + 1, s1.data(), s1.size(),
- (unsigned char**)&result, &len));
- EXPECT_EQ(ARES_EBADSTR,
- ares_expand_string(s1.data() + 4, s1.data(), s1.size(),
- (unsigned char**)&result, &len));
- SetAllocSizeFail(3 + 1);
- EXPECT_EQ(ARES_ENOMEM,
- ares_expand_string(s1.data(), s1.data(), s1.size(),
- (unsigned char**)&result, &len));
-}
-
-} // namespace test
-} // namespace ares
+// 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.
+TEST_F(DefaultChannelTest, SearchOnionDomain) {
+ SearchResult result;
+ ares_search(channel_, "dontleak.onion", ns_c_in, ns_t_a,
+ SearchCallback, &result);
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ENOTFOUND, result.status_);
+}
+
+TEST_F(DefaultChannelTest, SendFailure) {
+ unsigned char buf[2];
+ SearchResult result;
+ ares_send(channel_, buf, sizeof(buf), SearchCallback, &result);
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_EBADQUERY, result.status_);
+}
+
+std::string ExpandName(const std::vector<byte>& data, int offset,
+ long *enclen) {
+ char *name = nullptr;
+ int rc = ares_expand_name(data.data() + offset, data.data(), data.size(),
+ &name, enclen);
+ EXPECT_EQ(ARES_SUCCESS, rc);
+ std::string result;
+ if (rc == ARES_SUCCESS) {
+ result = name;
+ } else {
+ result = "<error>";
+ }
+ ares_free_string(name);
+ return result;
+}
+
+TEST_F(LibraryTest, ExpandName) {
+ long enclen;
+ std::vector<byte> data1 = {1, 'a', 2, 'b', 'c', 3, 'd', 'e', 'f', 0};
+ EXPECT_EQ("a.bc.def", ExpandName(data1, 0, &enclen));
+ EXPECT_EQ(data1.size(), enclen);
+
+ std::vector<byte> data2 = {0};
+ EXPECT_EQ("", ExpandName(data2, 0, &enclen));
+ EXPECT_EQ(1, enclen);
+
+ // Complete name indirection
+ std::vector<byte> data3 = {0x12, 0x23,
+ 3, 'd', 'e', 'f', 0,
+ 0xC0, 2};
+ EXPECT_EQ("def", ExpandName(data3, 2, &enclen));
+ EXPECT_EQ(5, enclen);
+ EXPECT_EQ("def", ExpandName(data3, 7, &enclen));
+ EXPECT_EQ(2, enclen);
+
+ // One label then indirection
+ std::vector<byte> data4 = {0x12, 0x23,
+ 3, 'd', 'e', 'f', 0,
+ 1, 'a', 0xC0, 2};
+ EXPECT_EQ("def", ExpandName(data4, 2, &enclen));
+ EXPECT_EQ(5, enclen);
+ EXPECT_EQ("a.def", ExpandName(data4, 7, &enclen));
+ EXPECT_EQ(4, enclen);
+
+ // Two labels then indirection
+ std::vector<byte> data5 = {0x12, 0x23,
+ 3, 'd', 'e', 'f', 0,
+ 1, 'a', 1, 'b', 0xC0, 2};
+ EXPECT_EQ("def", ExpandName(data5, 2, &enclen));
+ EXPECT_EQ(5, enclen);
+ EXPECT_EQ("a.b.def", ExpandName(data5, 7, &enclen));
+ EXPECT_EQ(6, enclen);
+
+ // Empty name, indirection to empty name
+ std::vector<byte> data6 = {0x12, 0x23,
+ 0,
+ 0xC0, 2};
+ EXPECT_EQ("", ExpandName(data6, 2, &enclen));
+ EXPECT_EQ(1, enclen);
+ EXPECT_EQ("", ExpandName(data6, 3, &enclen));
+ EXPECT_EQ(2, enclen);
+}
+
+TEST_F(LibraryTest, ExpandNameFailure) {
+ std::vector<byte> data1 = {0x03, 'c', 'o', 'm', 0x00};
+ char *name = nullptr;
+ long enclen;
+ SetAllocFail(1);
+ EXPECT_EQ(ARES_ENOMEM,
+ ares_expand_name(data1.data(), data1.data(), data1.size(),
+ &name, &enclen));
+
+ // Empty packet
+ EXPECT_EQ(ARES_EBADNAME,
+ ares_expand_name(data1.data(), data1.data(), 0, &name, &enclen));
+
+ // Start beyond enclosing data
+ EXPECT_EQ(ARES_EBADNAME,
+ ares_expand_name(data1.data() + data1.size(), data1.data(), data1.size(),
+ &name, &enclen));
+
+ // Length beyond size of enclosing data
+ std::vector<byte> data2a = {0x13, 'c', 'o', 'm', 0x00};
+ EXPECT_EQ(ARES_EBADNAME,
+ ares_expand_name(data2a.data(), data2a.data(), data2a.size(),
+ &name, &enclen));
+ std::vector<byte> data2b = {0x1};
+ EXPECT_EQ(ARES_EBADNAME,
+ ares_expand_name(data2b.data(), data2b.data(), data2b.size(),
+ &name, &enclen));
+ std::vector<byte> data2c = {0xC0};
+ EXPECT_EQ(ARES_EBADNAME,
+ ares_expand_name(data2c.data(), data2c.data(), data2c.size(),
+ &name, &enclen));
+
+ // Indirection beyond enclosing data
+ std::vector<byte> data3a = {0xC0, 0x02};
+ EXPECT_EQ(ARES_EBADNAME,
+ ares_expand_name(data3a.data(), data3a.data(), data3a.size(),
+ &name, &enclen));
+ std::vector<byte> data3b = {0xC0, 0x0A, 'c', 'o', 'm', 0x00};
+ EXPECT_EQ(ARES_EBADNAME,
+ ares_expand_name(data3b.data(), data3b.data(), data3b.size(),
+ &name, &enclen));
+
+ // Invalid top bits in label length
+ std::vector<byte> data4 = {0x03, 'c', 'o', 'm', 0x00, 0x80, 0x00};
+ EXPECT_EQ(ARES_EBADNAME,
+ ares_expand_name(data4.data() + 5, data4.data(), data4.size(),
+ &name, &enclen));
+
+ // Label too long: 64-byte label, with invalid top 2 bits of length (01).
+ std::vector<byte> data5 = {0x40,
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
+ 0x00};
+ EXPECT_EQ(ARES_EBADNAME,
+ ares_expand_name(data5.data(), data5.data(), data5.size(),
+ &name, &enclen)) << name;
+
+ // Incomplete indirect length
+ std::vector<byte> data6 = {0x03, 'c', 'o', 'm', 0x00, 0xC0};
+ EXPECT_EQ(ARES_EBADNAME,
+ ares_expand_name(data6.data() + 5, data6.data(), data6.size(),
+ &name, &enclen));
+
+ // Indirection loops
+ std::vector<byte> data7 = {0xC0, 0x02, 0xC0, 0x00};
+ EXPECT_EQ(ARES_EBADNAME,
+ ares_expand_name(data7.data(), data7.data(), data7.size(),
+ &name, &enclen));
+ std::vector<byte> data8 = {3, 'd', 'e', 'f', 0xC0, 0x08, 0x00, 0x00,
+ 3, 'a', 'b', 'c', 0xC0, 0x00};
+ EXPECT_EQ(ARES_EBADNAME,
+ ares_expand_name(data8.data(), data8.data(), data8.size(),
+ &name, &enclen));
+ std::vector<byte> data9 = {0x12, 0x23, // start 2 bytes in
+ 3, 'd', 'e', 'f', 0xC0, 0x02};
+ EXPECT_EQ(ARES_EBADNAME,
+ ares_expand_name(data9.data() + 2, data9.data(), data9.size(),
+ &name, &enclen));
+}
+
+TEST_F(LibraryTest, CreateEDNSQuery) {
+ byte* p;
+ int len;
+ EXPECT_EQ(ARES_SUCCESS,
+ ares_create_query("example.com", ns_c_in, ns_t_a, 0x1234, 0,
+ &p, &len, 1280));
+ std::vector<byte> data(p, p + len);
+ ares_free_string(p);
+
+ std::string actual = PacketToString(data);
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).add_question(new DNSQuestion("example.com", ns_t_a))
+ .add_additional(new DNSOptRR(0, 1280));
+ std::string expected = PacketToString(pkt.data());
+ EXPECT_EQ(expected, actual);
+}
+
+TEST_F(LibraryTest, CreateRootQuery) {
+ byte* p;
+ int len;
+ ares_create_query(".", ns_c_in, ns_t_a, 0x1234, 0, &p, &len, 0);
+ std::vector<byte> data(p, p + len);
+ ares_free_string(p);
+
+ std::string actual = PacketToString(data);
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).add_question(new DNSQuestion("", ns_t_a));
+ std::string expected = PacketToString(pkt.data());
+ EXPECT_EQ(expected, actual);
+}
+
+TEST_F(LibraryTest, Version) {
+ // Assume linked to same version
+ EXPECT_EQ(std::string(ARES_VERSION_STR),
+ std::string(ares_version(nullptr)));
+ int version;
+ ares_version(&version);
+ EXPECT_EQ(ARES_VERSION, version);
+}
+
+TEST_F(LibraryTest, Strerror) {
+ EXPECT_EQ("Successful completion",
+ std::string(ares_strerror(ARES_SUCCESS)));
+ EXPECT_EQ("DNS query cancelled",
+ std::string(ares_strerror(ARES_ECANCELLED)));
+ EXPECT_EQ("unknown",
+ std::string(ares_strerror(99)));
+}
+
+TEST_F(LibraryTest, ExpandString) {
+ std::vector<byte> s1 = { 3, 'a', 'b', 'c'};
+ char* result = nullptr;
+ long len;
+ EXPECT_EQ(ARES_SUCCESS,
+ ares_expand_string(s1.data(), s1.data(), s1.size(),
+ (unsigned char**)&result, &len));
+ EXPECT_EQ("abc", std::string(result));
+ EXPECT_EQ(1 + 3, len); // amount of data consumed includes 1 byte len
+ ares_free_string(result);
+ result = nullptr;
+ EXPECT_EQ(ARES_EBADSTR,
+ ares_expand_string(s1.data() + 1, s1.data(), s1.size(),
+ (unsigned char**)&result, &len));
+ EXPECT_EQ(ARES_EBADSTR,
+ ares_expand_string(s1.data() + 4, s1.data(), s1.size(),
+ (unsigned char**)&result, &len));
+ SetAllocSizeFail(3 + 1);
+ EXPECT_EQ(ARES_ENOMEM,
+ ares_expand_string(s1.data(), s1.data(), s1.size(),
+ (unsigned char**)&result, &len));
+}
+
+} // 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 fdae07fef6..80e9fc02b0 100644
--- a/contrib/libs/c-ares/test/ares-test-mock.cc
+++ b/contrib/libs/c-ares/test/ares-test-mock.cc
@@ -1,941 +1,941 @@
-#include "ares-test.h"
-#include "dns-proto.h"
-
-#include <sstream>
-#include <vector>
-
-using testing::InvokeWithoutArgs;
-using testing::DoAll;
-
-namespace ares {
-namespace test {
-
-TEST_P(MockChannelTest, Basic) {
- std::vector<byte> reply = {
- 0x00, 0x00, // qid
- 0x84, // response + query + AA + not-TC + not-RD
- 0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
- 0x00, 0x01, // 1 question
- 0x00, 0x01, // 1 answer RRs
- 0x00, 0x00, // 0 authority RRs
- 0x00, 0x00, // 0 additional RRs
- // Question
- 0x03, 'w', 'w', 'w',
- 0x06, 'g', 'o', 'o', 'g', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x01, // type A
- 0x00, 0x01, // class IN
- // Answer
- 0x03, 'w', 'w', 'w',
- 0x06, 'g', 'o', 'o', 'g', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x01, // type A
- 0x00, 0x01, // class IN
- 0x00, 0x00, 0x01, 0x00, // TTL
- 0x00, 0x04, // rdata length
- 0x01, 0x02, 0x03, 0x04
- };
-
- ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillByDefault(SetReplyData(&server_, reply));
-
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
-}
-
-// UDP only so mock server doesn't get confused by concatenated requests
+#include "ares-test.h"
+#include "dns-proto.h"
+
+#include <sstream>
+#include <vector>
+
+using testing::InvokeWithoutArgs;
+using testing::DoAll;
+
+namespace ares {
+namespace test {
+
+TEST_P(MockChannelTest, Basic) {
+ std::vector<byte> reply = {
+ 0x00, 0x00, // qid
+ 0x84, // response + query + AA + not-TC + not-RD
+ 0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError
+ 0x00, 0x01, // 1 question
+ 0x00, 0x01, // 1 answer RRs
+ 0x00, 0x00, // 0 authority RRs
+ 0x00, 0x00, // 0 additional RRs
+ // Question
+ 0x03, 'w', 'w', 'w',
+ 0x06, 'g', 'o', 'o', 'g', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x01, // type A
+ 0x00, 0x01, // class IN
+ // Answer
+ 0x03, 'w', 'w', 'w',
+ 0x06, 'g', 'o', 'o', 'g', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x01, // type A
+ 0x00, 0x01, // class IN
+ 0x00, 0x00, 0x01, 0x00, // TTL
+ 0x00, 0x04, // rdata length
+ 0x01, 0x02, 0x03, 0x04
+ };
+
+ ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillByDefault(SetReplyData(&server_, reply));
+
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
+}
+
+// UDP only so mock server doesn't get confused by concatenated requests
TEST_P(MockUDPChannelTest, GetHostByNameParallelLookups) {
- 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));
-
- HostResult result1;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result1);
- HostResult result2;
- ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result2);
- HostResult result3;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result3);
- Process();
- EXPECT_TRUE(result1.done_);
- EXPECT_TRUE(result2.done_);
- EXPECT_TRUE(result3.done_);
- std::stringstream ss1;
- ss1 << result1.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss1.str());
- std::stringstream ss2;
- ss2 << result2.host_;
- EXPECT_EQ("{'www.example.com' aliases=[] addrs=[1.2.3.4]}", ss2.str());
- std::stringstream ss3;
- ss3 << result3.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss3.str());
-}
-
-// UDP to TCP specific test
-TEST_P(MockUDPChannelTest, 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));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
-}
-
-static int sock_cb_count = 0;
-static int SocketConnectCallback(ares_socket_t fd, int type, void *data) {
- int rc = *(int*)data;
- if (verbose) std::cerr << "SocketConnectCallback(" << fd << ") invoked" << std::endl;
- sock_cb_count++;
- return rc;
-}
-
-TEST_P(MockChannelTest, SockCallback) {
- 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}));
- EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillOnce(SetReply(&server_, &rsp));
-
- // Get notified of new sockets
- int rc = ARES_SUCCESS;
- ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
-
- HostResult result;
- sock_cb_count = 0;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_EQ(1, sock_cb_count);
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
-}
-
-TEST_P(MockChannelTest, SockFailCallback) {
- // Notification of new sockets gives an error.
- int rc = -1;
- ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
-
- HostResult result;
- sock_cb_count = 0;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_LT(1, sock_cb_count);
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
-}
-
-static int sock_config_cb_count = 0;
-static int SocketConfigureCallback(ares_socket_t fd, int type, void *data) {
- int rc = *(int*)data;
- if (verbose) std::cerr << "SocketConfigureCallback(" << fd << ") invoked" << std::endl;
- sock_config_cb_count++;
- return rc;
-}
-
-TEST_P(MockChannelTest, SockConfigureCallback) {
- 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}));
- EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillOnce(SetReply(&server_, &rsp));
-
- // Get notified of new sockets
- int rc = ARES_SUCCESS;
- ares_set_socket_configure_callback(channel_, SocketConfigureCallback, &rc);
-
- HostResult result;
- sock_config_cb_count = 0;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_EQ(1, sock_config_cb_count);
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
-}
-
-TEST_P(MockChannelTest, SockConfigureFailCallback) {
- // Notification of new sockets gives an error.
- int rc = -1;
- ares_set_socket_configure_callback(channel_, SocketConfigureCallback, &rc);
-
- HostResult result;
- sock_config_cb_count = 0;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_LT(1, sock_config_cb_count);
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
-}
-
-// TCP only to prevent retries
-TEST_P(MockTCPChannelTest, MalformedResponse) {
- std::vector<byte> one = {0x01};
- EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillOnce(SetReplyData(&server_, one));
-
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ETIMEOUT, result.status_);
-}
-
-TEST_P(MockTCPChannelTest, 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));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_EFORMERR, result.status_);
-}
-
-TEST_P(MockTCPChannelTest, 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));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- // ARES_FLAG_NOCHECKRESP not set, so SERVFAIL consumed
- EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
-}
-
-TEST_P(MockTCPChannelTest, 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));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- // ARES_FLAG_NOCHECKRESP not set, so NOTIMPL consumed
- EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
-}
-
-TEST_P(MockTCPChannelTest, 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));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- // ARES_FLAG_NOCHECKRESP not set, so REFUSED consumed
- EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
-}
-
-TEST_P(MockTCPChannelTest, 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));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENODATA, result.status_);
-}
-
-class MockExtraOptsTest
- : public MockChannelOptsTest,
- public ::testing::WithParamInterface< std::pair<int, bool> > {
- public:
- MockExtraOptsTest()
- : 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(MockExtraOptsTest, 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));
-
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
-}
-
-class MockFlagsChannelOptsTest
- : public MockChannelOptsTest,
- public ::testing::WithParamInterface< std::pair<int, bool> > {
- public:
- MockFlagsChannelOptsTest(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 MockNoCheckRespChannelTest : public MockFlagsChannelOptsTest {
- public:
- MockNoCheckRespChannelTest() : MockFlagsChannelOptsTest(ARES_FLAG_NOCHECKRESP) {}
-};
-
-TEST_P(MockNoCheckRespChannelTest, 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));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ESERVFAIL, result.status_);
-}
-
-TEST_P(MockNoCheckRespChannelTest, 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));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENOTIMP, result.status_);
-}
-
-TEST_P(MockNoCheckRespChannelTest, 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));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_EREFUSED, result.status_);
-}
-
-class MockEDNSChannelTest : public MockFlagsChannelOptsTest {
- public:
- MockEDNSChannelTest() : MockFlagsChannelOptsTest(ARES_FLAG_EDNS) {}
-};
-
-TEST_P(MockEDNSChannelTest, 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));
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
-}
-
-TEST_P(MockChannelTest, 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));
-
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
-}
-
-// Relies on retries so is UDP-only
-TEST_P(MockUDPChannelTest, SearchDomainsWithResentReply) {
- DNSPacket nofirst;
- nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain)
- .add_question(new DNSQuestion("www.first.com", ns_t_a));
- EXPECT_CALL(server_, OnRequest("www.first.com", ns_t_a))
- .WillOnce(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));
- EXPECT_CALL(server_, OnRequest("www.second.org", ns_t_a))
- .WillOnce(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}));
- // Before sending the real answer, resend an earlier reply
- EXPECT_CALL(server_, OnRequest("www.third.gov", ns_t_a))
- .WillOnce(DoAll(SetReply(&server_, &nofirst),
- SetReplyQID(&server_, 123)))
- .WillOnce(DoAll(SetReply(&server_, &yesthird),
- SetReplyQID(&server_, -1)));
-
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
-}
-
-TEST_P(MockChannelTest, SearchDomainsBare) {
- 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 nothird;
- nothird.set_response().set_aa().set_rcode(ns_r_nxdomain)
- .add_question(new DNSQuestion("www.third.gov", ns_t_a));
- ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
- .WillByDefault(SetReply(&server_, &nothird));
- DNSPacket yesbare;
- yesbare.set_response().set_aa()
- .add_question(new DNSQuestion("www", ns_t_a))
- .add_answer(new DNSARR("www", 0x0200, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("www", ns_t_a))
- .WillByDefault(SetReply(&server_, &yesbare));
-
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www' aliases=[] addrs=[2.3.4.5]}", ss.str());
-}
-
-TEST_P(MockChannelTest, SearchNoDataThenSuccess) {
- // First two search domains recognize the name but have no A records.
- DNSPacket nofirst;
- nofirst.set_response().set_aa()
- .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()
- .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));
-
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
-}
-
-TEST_P(MockChannelTest, SearchNoDataThenNoDataBare) {
- // First two search domains recognize the name but have no A records.
- DNSPacket nofirst;
- nofirst.set_response().set_aa()
- .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()
- .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 nothird;
- nothird.set_response().set_aa()
- .add_question(new DNSQuestion("www.third.gov", ns_t_a));
- ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
- .WillByDefault(SetReply(&server_, &nothird));
- DNSPacket nobare;
- nobare.set_response().set_aa()
- .add_question(new DNSQuestion("www", ns_t_a));
- ON_CALL(server_, OnRequest("www", ns_t_a))
- .WillByDefault(SetReply(&server_, &nobare));
-
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENODATA, result.status_);
-}
-
-TEST_P(MockChannelTest, SearchNoDataThenFail) {
- // First two search domains recognize the name but have no A records.
- DNSPacket nofirst;
- nofirst.set_response().set_aa()
- .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()
- .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 nothird;
- nothird.set_response().set_aa()
- .add_question(new DNSQuestion("www.third.gov", ns_t_a));
- ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
- .WillByDefault(SetReply(&server_, &nothird));
- DNSPacket nobare;
- nobare.set_response().set_aa().set_rcode(ns_r_nxdomain)
- .add_question(new DNSQuestion("www", ns_t_a));
- ON_CALL(server_, OnRequest("www", ns_t_a))
- .WillByDefault(SetReply(&server_, &nobare));
-
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENODATA, result.status_);
-}
-
-TEST_P(MockChannelTest, SearchAllocFailure) {
- SearchResult result;
- SetAllocFail(1);
- ares_search(channel_, "fully.qualified.", ns_c_in, ns_t_a, SearchCallback, &result);
- /* Already done */
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ENOMEM, result.status_);
-}
-
-TEST_P(MockChannelTest, SearchHighNdots) {
- DNSPacket nobare;
- nobare.set_response().set_aa().set_rcode(ns_r_nxdomain)
- .add_question(new DNSQuestion("a.b.c.w.w.w", ns_t_a));
- ON_CALL(server_, OnRequest("a.b.c.w.w.w", ns_t_a))
- .WillByDefault(SetReply(&server_, &nobare));
- DNSPacket yesfirst;
- yesfirst.set_response().set_aa()
- .add_question(new DNSQuestion("a.b.c.w.w.w.first.com", ns_t_a))
- .add_answer(new DNSARR("a.b.c.w.w.w.first.com", 0x0200, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("a.b.c.w.w.w.first.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &yesfirst));
-
- SearchResult result;
- ares_search(channel_, "a.b.c.w.w.w", ns_c_in, ns_t_a, SearchCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- std::stringstream ss;
- ss << PacketToString(result.data_);
- EXPECT_EQ("RSP QRY AA NOERROR Q:{'a.b.c.w.w.w.first.com' IN A} "
- "A:{'a.b.c.w.w.w.first.com' IN A TTL=512 2.3.4.5}",
- ss.str());
-}
-
-TEST_P(MockChannelTest, UnspecifiedFamilyV6) {
- 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));
-
- HostResult result;
- ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- // Default to IPv6 when both are available.
- EXPECT_EQ("{'example.com' aliases=[] addrs=[2121:0000:0000:0000:0000:0000:0000:0303]}", ss.str());
-}
-
-TEST_P(MockChannelTest, UnspecifiedFamilyV4) {
- DNSPacket rsp6;
- rsp6.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_aaaa));
- 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));
-
- HostResult result;
- ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
-}
-
-TEST_P(MockChannelTest, UnspecifiedFamilyNoData) {
- DNSPacket rsp6;
- rsp6.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_aaaa))
- .add_answer(new DNSCnameRR("example.com", 100, "elsewhere.com"));
- 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));
- ON_CALL(server_, OnRequest("example.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &rsp4));
-
- HostResult result;
- ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'' aliases=[] addrs=[]}", ss.str());
-}
-
-TEST_P(MockChannelTest, UnspecifiedFamilyCname6A4) {
- DNSPacket rsp6;
- rsp6.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_aaaa))
- .add_answer(new DNSCnameRR("example.com", 100, "elsewhere.com"));
- 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, {1, 2, 3, 4}));
- ON_CALL(server_, OnRequest("example.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &rsp4));
-
- HostResult result;
- ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'example.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
-}
-
-TEST_P(MockChannelTest, ExplicitIP) {
- HostResult result;
- ares_gethostbyname(channel_, "1.2.3.4", AF_INET, HostCallback, &result);
- EXPECT_TRUE(result.done_); // Immediate return
- EXPECT_EQ(ARES_SUCCESS, result.status_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'1.2.3.4' aliases=[] addrs=[1.2.3.4]}", ss.str());
-}
-
-TEST_P(MockChannelTest, ExplicitIPAllocFail) {
- HostResult result;
- SetAllocSizeFail(strlen("1.2.3.4") + 1);
- ares_gethostbyname(channel_, "1.2.3.4", AF_INET, HostCallback, &result);
- EXPECT_TRUE(result.done_); // Immediate return
- EXPECT_EQ(ARES_ENOMEM, result.status_);
-}
-
-TEST_P(MockChannelTest, SortListV4) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_a))
- .add_answer(new DNSARR("example.com", 100, {22, 23, 24, 25}))
- .add_answer(new DNSARR("example.com", 100, {12, 13, 14, 15}))
- .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("example.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &rsp));
-
- {
- EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "12.13.0.0/255.255.0.0 1234::5678"));
- HostResult result;
- ares_gethostbyname(channel_, "example.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'example.com' aliases=[] addrs=[12.13.14.15, 22.23.24.25, 2.3.4.5]}", ss.str());
- }
- {
- EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "2.3.0.0/16 130.140.150.160/26"));
- HostResult result;
- ares_gethostbyname(channel_, "example.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5, 22.23.24.25, 12.13.14.15]}", ss.str());
- }
- struct ares_options options;
- memset(&options, 0, sizeof(options));
- int optmask = 0;
- EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &options, &optmask));
- EXPECT_TRUE((optmask & ARES_OPT_SORTLIST) == ARES_OPT_SORTLIST);
- ares_destroy_options(&options);
-}
-
-TEST_P(MockChannelTest, SortListV6) {
- DNSPacket rsp;
- rsp.set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_aaaa))
- .add_answer(new DNSAaaaRR("example.com", 100,
- {0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02}))
- .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_, &rsp));
-
- {
- ares_set_sortlist(channel_, "1111::/16 2.3.0.0/255.255.0.0");
- HostResult result;
- ares_gethostbyname(channel_, "example.com.", AF_INET6, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'example.com' aliases=[] addrs=[1111:0000:0000:0000:0000:0000:0000:0202, "
- "2121:0000:0000:0000:0000:0000:0000:0303]}", ss.str());
- }
- {
- ares_set_sortlist(channel_, "2121::/8");
- HostResult result;
- ares_gethostbyname(channel_, "example.com.", AF_INET6, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'example.com' aliases=[] addrs=[2121:0000:0000:0000:0000:0000:0000:0303, "
- "1111:0000:0000:0000:0000:0000:0000:0202]}", ss.str());
- }
-}
-
-// Relies on retries so is UDP-only
-TEST_P(MockUDPChannelTest, SearchDomainsAllocFail) {
- 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));
-
- // Fail a variety of different memory allocations, and confirm
- // that the operation either fails with ENOMEM or succeeds
- // with the expected result.
- const int kCount = 34;
- HostResult results[kCount];
- for (int ii = 1; ii <= kCount; ii++) {
- HostResult* result = &(results[ii - 1]);
- ClearFails();
- SetAllocFail(ii);
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, result);
- Process();
- EXPECT_TRUE(result->done_);
- if (result->status_ == ARES_SUCCESS) {
- std::stringstream ss;
- ss << result->host_;
- EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str()) << " failed alloc #" << ii;
- if (verbose) std::cerr << "Succeeded despite failure of alloc #" << ii << std::endl;
- }
- }
-
- // Explicitly destroy the channel now, so that the HostResult objects
- // are still valid (in case any pending work refers to them).
- ares_destroy(channel_);
- channel_ = nullptr;
-}
-
-// Relies on retries so is UDP-only
-TEST_P(MockUDPChannelTest, Resend) {
- std::vector<byte> nothing;
- DNSPacket reply;
- reply.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", ns_t_a))
- .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
-
- EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillOnce(SetReplyData(&server_, nothing))
- .WillOnce(SetReplyData(&server_, nothing))
- .WillOnce(SetReply(&server_, &reply));
-
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(2, result.timeouts_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
-}
-
-TEST_P(MockChannelTest, CancelImmediate) {
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- ares_cancel(channel_);
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ECANCELLED, result.status_);
- EXPECT_EQ(0, result.timeouts_);
-}
-
-TEST_P(MockChannelTest, CancelImmediateGetHostByAddr) {
- HostResult result;
- struct in_addr addr;
- addr.s_addr = htonl(0x08080808);
-
- ares_gethostbyaddr(channel_, &addr, sizeof(addr), AF_INET, HostCallback, &result);
- ares_cancel(channel_);
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ECANCELLED, result.status_);
- EXPECT_EQ(0, result.timeouts_);
-}
-
-// Relies on retries so is UDP-only
-TEST_P(MockUDPChannelTest, CancelLater) {
- std::vector<byte> nothing;
-
- // On second request, cancel the channel.
- EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillOnce(SetReplyData(&server_, nothing))
- .WillOnce(CancelChannel(&server_, channel_));
-
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_ECANCELLED, result.status_);
- EXPECT_EQ(0, result.timeouts_);
-}
-
-TEST_P(MockChannelTest, GetHostByNameDestroyAbsolute) {
- HostResult result;
- ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
-
- ares_destroy(channel_);
- channel_ = nullptr;
-
- EXPECT_TRUE(result.done_); // Synchronous
- EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
- EXPECT_EQ(0, result.timeouts_);
-}
-
-TEST_P(MockChannelTest, GetHostByNameDestroyRelative) {
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
-
- ares_destroy(channel_);
- channel_ = nullptr;
-
- EXPECT_TRUE(result.done_); // Synchronous
- EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
- EXPECT_EQ(0, result.timeouts_);
-}
-
+ 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));
+
+ HostResult result1;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result1);
+ HostResult result2;
+ ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result2);
+ HostResult result3;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result3);
+ Process();
+ EXPECT_TRUE(result1.done_);
+ EXPECT_TRUE(result2.done_);
+ EXPECT_TRUE(result3.done_);
+ std::stringstream ss1;
+ ss1 << result1.host_;
+ EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss1.str());
+ std::stringstream ss2;
+ ss2 << result2.host_;
+ EXPECT_EQ("{'www.example.com' aliases=[] addrs=[1.2.3.4]}", ss2.str());
+ std::stringstream ss3;
+ ss3 << result3.host_;
+ EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss3.str());
+}
+
+// UDP to TCP specific test
+TEST_P(MockUDPChannelTest, 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));
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
+}
+
+static int sock_cb_count = 0;
+static int SocketConnectCallback(ares_socket_t fd, int type, void *data) {
+ int rc = *(int*)data;
+ if (verbose) std::cerr << "SocketConnectCallback(" << fd << ") invoked" << std::endl;
+ sock_cb_count++;
+ return rc;
+}
+
+TEST_P(MockChannelTest, SockCallback) {
+ 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}));
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillOnce(SetReply(&server_, &rsp));
+
+ // Get notified of new sockets
+ int rc = ARES_SUCCESS;
+ ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
+
+ HostResult result;
+ sock_cb_count = 0;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_EQ(1, sock_cb_count);
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
+}
+
+TEST_P(MockChannelTest, SockFailCallback) {
+ // Notification of new sockets gives an error.
+ int rc = -1;
+ ares_set_socket_callback(channel_, SocketConnectCallback, &rc);
+
+ HostResult result;
+ sock_cb_count = 0;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_LT(1, sock_cb_count);
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
+}
+
+static int sock_config_cb_count = 0;
+static int SocketConfigureCallback(ares_socket_t fd, int type, void *data) {
+ int rc = *(int*)data;
+ if (verbose) std::cerr << "SocketConfigureCallback(" << fd << ") invoked" << std::endl;
+ sock_config_cb_count++;
+ return rc;
+}
+
+TEST_P(MockChannelTest, SockConfigureCallback) {
+ 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}));
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillOnce(SetReply(&server_, &rsp));
+
+ // Get notified of new sockets
+ int rc = ARES_SUCCESS;
+ ares_set_socket_configure_callback(channel_, SocketConfigureCallback, &rc);
+
+ HostResult result;
+ sock_config_cb_count = 0;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_EQ(1, sock_config_cb_count);
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
+}
+
+TEST_P(MockChannelTest, SockConfigureFailCallback) {
+ // Notification of new sockets gives an error.
+ int rc = -1;
+ ares_set_socket_configure_callback(channel_, SocketConfigureCallback, &rc);
+
+ HostResult result;
+ sock_config_cb_count = 0;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_LT(1, sock_config_cb_count);
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
+}
+
+// TCP only to prevent retries
+TEST_P(MockTCPChannelTest, MalformedResponse) {
+ std::vector<byte> one = {0x01};
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillOnce(SetReplyData(&server_, one));
+
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ETIMEOUT, result.status_);
+}
+
+TEST_P(MockTCPChannelTest, 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));
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_EFORMERR, result.status_);
+}
+
+TEST_P(MockTCPChannelTest, 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));
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ // ARES_FLAG_NOCHECKRESP not set, so SERVFAIL consumed
+ EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
+}
+
+TEST_P(MockTCPChannelTest, 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));
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ // ARES_FLAG_NOCHECKRESP not set, so NOTIMPL consumed
+ EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
+}
+
+TEST_P(MockTCPChannelTest, 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));
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ // ARES_FLAG_NOCHECKRESP not set, so REFUSED consumed
+ EXPECT_EQ(ARES_ECONNREFUSED, result.status_);
+}
+
+TEST_P(MockTCPChannelTest, 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));
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ENODATA, result.status_);
+}
+
+class MockExtraOptsTest
+ : public MockChannelOptsTest,
+ public ::testing::WithParamInterface< std::pair<int, bool> > {
+ public:
+ MockExtraOptsTest()
+ : 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(MockExtraOptsTest, 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));
+
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'www.google.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
+}
+
+class MockFlagsChannelOptsTest
+ : public MockChannelOptsTest,
+ public ::testing::WithParamInterface< std::pair<int, bool> > {
+ public:
+ MockFlagsChannelOptsTest(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 MockNoCheckRespChannelTest : public MockFlagsChannelOptsTest {
+ public:
+ MockNoCheckRespChannelTest() : MockFlagsChannelOptsTest(ARES_FLAG_NOCHECKRESP) {}
+};
+
+TEST_P(MockNoCheckRespChannelTest, 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));
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ESERVFAIL, result.status_);
+}
+
+TEST_P(MockNoCheckRespChannelTest, 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));
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ENOTIMP, result.status_);
+}
+
+TEST_P(MockNoCheckRespChannelTest, 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));
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_EREFUSED, result.status_);
+}
+
+class MockEDNSChannelTest : public MockFlagsChannelOptsTest {
+ public:
+ MockEDNSChannelTest() : MockFlagsChannelOptsTest(ARES_FLAG_EDNS) {}
+};
+
+TEST_P(MockEDNSChannelTest, 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));
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
+}
+
+TEST_P(MockChannelTest, 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));
+
+ HostResult result;
+ ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
+}
+
+// Relies on retries so is UDP-only
+TEST_P(MockUDPChannelTest, SearchDomainsWithResentReply) {
+ DNSPacket nofirst;
+ nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain)
+ .add_question(new DNSQuestion("www.first.com", ns_t_a));
+ EXPECT_CALL(server_, OnRequest("www.first.com", ns_t_a))
+ .WillOnce(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));
+ EXPECT_CALL(server_, OnRequest("www.second.org", ns_t_a))
+ .WillOnce(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}));
+ // Before sending the real answer, resend an earlier reply
+ EXPECT_CALL(server_, OnRequest("www.third.gov", ns_t_a))
+ .WillOnce(DoAll(SetReply(&server_, &nofirst),
+ SetReplyQID(&server_, 123)))
+ .WillOnce(DoAll(SetReply(&server_, &yesthird),
+ SetReplyQID(&server_, -1)));
+
+ HostResult result;
+ ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
+}
+
+TEST_P(MockChannelTest, SearchDomainsBare) {
+ 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 nothird;
+ nothird.set_response().set_aa().set_rcode(ns_r_nxdomain)
+ .add_question(new DNSQuestion("www.third.gov", ns_t_a));
+ ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
+ .WillByDefault(SetReply(&server_, &nothird));
+ DNSPacket yesbare;
+ yesbare.set_response().set_aa()
+ .add_question(new DNSQuestion("www", ns_t_a))
+ .add_answer(new DNSARR("www", 0x0200, {2, 3, 4, 5}));
+ ON_CALL(server_, OnRequest("www", ns_t_a))
+ .WillByDefault(SetReply(&server_, &yesbare));
+
+ HostResult result;
+ ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'www' aliases=[] addrs=[2.3.4.5]}", ss.str());
+}
+
+TEST_P(MockChannelTest, SearchNoDataThenSuccess) {
+ // First two search domains recognize the name but have no A records.
+ DNSPacket nofirst;
+ nofirst.set_response().set_aa()
+ .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()
+ .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));
+
+ HostResult result;
+ ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str());
+}
+
+TEST_P(MockChannelTest, SearchNoDataThenNoDataBare) {
+ // First two search domains recognize the name but have no A records.
+ DNSPacket nofirst;
+ nofirst.set_response().set_aa()
+ .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()
+ .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 nothird;
+ nothird.set_response().set_aa()
+ .add_question(new DNSQuestion("www.third.gov", ns_t_a));
+ ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
+ .WillByDefault(SetReply(&server_, &nothird));
+ DNSPacket nobare;
+ nobare.set_response().set_aa()
+ .add_question(new DNSQuestion("www", ns_t_a));
+ ON_CALL(server_, OnRequest("www", ns_t_a))
+ .WillByDefault(SetReply(&server_, &nobare));
+
+ HostResult result;
+ ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ENODATA, result.status_);
+}
+
+TEST_P(MockChannelTest, SearchNoDataThenFail) {
+ // First two search domains recognize the name but have no A records.
+ DNSPacket nofirst;
+ nofirst.set_response().set_aa()
+ .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()
+ .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 nothird;
+ nothird.set_response().set_aa()
+ .add_question(new DNSQuestion("www.third.gov", ns_t_a));
+ ON_CALL(server_, OnRequest("www.third.gov", ns_t_a))
+ .WillByDefault(SetReply(&server_, &nothird));
+ DNSPacket nobare;
+ nobare.set_response().set_aa().set_rcode(ns_r_nxdomain)
+ .add_question(new DNSQuestion("www", ns_t_a));
+ ON_CALL(server_, OnRequest("www", ns_t_a))
+ .WillByDefault(SetReply(&server_, &nobare));
+
+ HostResult result;
+ ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ENODATA, result.status_);
+}
+
+TEST_P(MockChannelTest, SearchAllocFailure) {
+ SearchResult result;
+ SetAllocFail(1);
+ ares_search(channel_, "fully.qualified.", ns_c_in, ns_t_a, SearchCallback, &result);
+ /* Already done */
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ENOMEM, result.status_);
+}
+
+TEST_P(MockChannelTest, SearchHighNdots) {
+ DNSPacket nobare;
+ nobare.set_response().set_aa().set_rcode(ns_r_nxdomain)
+ .add_question(new DNSQuestion("a.b.c.w.w.w", ns_t_a));
+ ON_CALL(server_, OnRequest("a.b.c.w.w.w", ns_t_a))
+ .WillByDefault(SetReply(&server_, &nobare));
+ DNSPacket yesfirst;
+ yesfirst.set_response().set_aa()
+ .add_question(new DNSQuestion("a.b.c.w.w.w.first.com", ns_t_a))
+ .add_answer(new DNSARR("a.b.c.w.w.w.first.com", 0x0200, {2, 3, 4, 5}));
+ ON_CALL(server_, OnRequest("a.b.c.w.w.w.first.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &yesfirst));
+
+ SearchResult result;
+ ares_search(channel_, "a.b.c.w.w.w", ns_c_in, ns_t_a, SearchCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ std::stringstream ss;
+ ss << PacketToString(result.data_);
+ EXPECT_EQ("RSP QRY AA NOERROR Q:{'a.b.c.w.w.w.first.com' IN A} "
+ "A:{'a.b.c.w.w.w.first.com' IN A TTL=512 2.3.4.5}",
+ ss.str());
+}
+
+TEST_P(MockChannelTest, UnspecifiedFamilyV6) {
+ 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));
+
+ HostResult result;
+ ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ // Default to IPv6 when both are available.
+ EXPECT_EQ("{'example.com' aliases=[] addrs=[2121:0000:0000:0000:0000:0000:0000:0303]}", ss.str());
+}
+
+TEST_P(MockChannelTest, UnspecifiedFamilyV4) {
+ DNSPacket rsp6;
+ rsp6.set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_aaaa));
+ 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));
+
+ HostResult result;
+ ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
+}
+
+TEST_P(MockChannelTest, UnspecifiedFamilyNoData) {
+ DNSPacket rsp6;
+ rsp6.set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_aaaa))
+ .add_answer(new DNSCnameRR("example.com", 100, "elsewhere.com"));
+ 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));
+ ON_CALL(server_, OnRequest("example.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &rsp4));
+
+ HostResult result;
+ ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'' aliases=[] addrs=[]}", ss.str());
+}
+
+TEST_P(MockChannelTest, UnspecifiedFamilyCname6A4) {
+ DNSPacket rsp6;
+ rsp6.set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_aaaa))
+ .add_answer(new DNSCnameRR("example.com", 100, "elsewhere.com"));
+ 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, {1, 2, 3, 4}));
+ ON_CALL(server_, OnRequest("example.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &rsp4));
+
+ HostResult result;
+ ares_gethostbyname(channel_, "example.com.", AF_UNSPEC, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'example.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
+}
+
+TEST_P(MockChannelTest, ExplicitIP) {
+ HostResult result;
+ ares_gethostbyname(channel_, "1.2.3.4", AF_INET, HostCallback, &result);
+ EXPECT_TRUE(result.done_); // Immediate return
+ EXPECT_EQ(ARES_SUCCESS, result.status_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'1.2.3.4' aliases=[] addrs=[1.2.3.4]}", ss.str());
+}
+
+TEST_P(MockChannelTest, ExplicitIPAllocFail) {
+ HostResult result;
+ SetAllocSizeFail(strlen("1.2.3.4") + 1);
+ ares_gethostbyname(channel_, "1.2.3.4", AF_INET, HostCallback, &result);
+ EXPECT_TRUE(result.done_); // Immediate return
+ EXPECT_EQ(ARES_ENOMEM, result.status_);
+}
+
+TEST_P(MockChannelTest, SortListV4) {
+ DNSPacket rsp;
+ rsp.set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_a))
+ .add_answer(new DNSARR("example.com", 100, {22, 23, 24, 25}))
+ .add_answer(new DNSARR("example.com", 100, {12, 13, 14, 15}))
+ .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5}));
+ ON_CALL(server_, OnRequest("example.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &rsp));
+
+ {
+ EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "12.13.0.0/255.255.0.0 1234::5678"));
+ HostResult result;
+ ares_gethostbyname(channel_, "example.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'example.com' aliases=[] addrs=[12.13.14.15, 22.23.24.25, 2.3.4.5]}", ss.str());
+ }
+ {
+ EXPECT_EQ(ARES_SUCCESS, ares_set_sortlist(channel_, "2.3.0.0/16 130.140.150.160/26"));
+ HostResult result;
+ ares_gethostbyname(channel_, "example.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5, 22.23.24.25, 12.13.14.15]}", ss.str());
+ }
+ struct ares_options options;
+ memset(&options, 0, sizeof(options));
+ int optmask = 0;
+ EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &options, &optmask));
+ EXPECT_TRUE((optmask & ARES_OPT_SORTLIST) == ARES_OPT_SORTLIST);
+ ares_destroy_options(&options);
+}
+
+TEST_P(MockChannelTest, SortListV6) {
+ DNSPacket rsp;
+ rsp.set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_aaaa))
+ .add_answer(new DNSAaaaRR("example.com", 100,
+ {0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02}))
+ .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_, &rsp));
+
+ {
+ ares_set_sortlist(channel_, "1111::/16 2.3.0.0/255.255.0.0");
+ HostResult result;
+ ares_gethostbyname(channel_, "example.com.", AF_INET6, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'example.com' aliases=[] addrs=[1111:0000:0000:0000:0000:0000:0000:0202, "
+ "2121:0000:0000:0000:0000:0000:0000:0303]}", ss.str());
+ }
+ {
+ ares_set_sortlist(channel_, "2121::/8");
+ HostResult result;
+ ares_gethostbyname(channel_, "example.com.", AF_INET6, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'example.com' aliases=[] addrs=[2121:0000:0000:0000:0000:0000:0000:0303, "
+ "1111:0000:0000:0000:0000:0000:0000:0202]}", ss.str());
+ }
+}
+
+// Relies on retries so is UDP-only
+TEST_P(MockUDPChannelTest, SearchDomainsAllocFail) {
+ 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));
+
+ // Fail a variety of different memory allocations, and confirm
+ // that the operation either fails with ENOMEM or succeeds
+ // with the expected result.
+ const int kCount = 34;
+ HostResult results[kCount];
+ for (int ii = 1; ii <= kCount; ii++) {
+ HostResult* result = &(results[ii - 1]);
+ ClearFails();
+ SetAllocFail(ii);
+ ares_gethostbyname(channel_, "www", AF_INET, HostCallback, result);
+ Process();
+ EXPECT_TRUE(result->done_);
+ if (result->status_ == ARES_SUCCESS) {
+ std::stringstream ss;
+ ss << result->host_;
+ EXPECT_EQ("{'www.third.gov' aliases=[] addrs=[2.3.4.5]}", ss.str()) << " failed alloc #" << ii;
+ if (verbose) std::cerr << "Succeeded despite failure of alloc #" << ii << std::endl;
+ }
+ }
+
+ // Explicitly destroy the channel now, so that the HostResult objects
+ // are still valid (in case any pending work refers to them).
+ ares_destroy(channel_);
+ channel_ = nullptr;
+}
+
+// Relies on retries so is UDP-only
+TEST_P(MockUDPChannelTest, Resend) {
+ std::vector<byte> nothing;
+ DNSPacket reply;
+ reply.set_response().set_aa()
+ .add_question(new DNSQuestion("www.google.com", ns_t_a))
+ .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
+
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillOnce(SetReplyData(&server_, nothing))
+ .WillOnce(SetReplyData(&server_, nothing))
+ .WillOnce(SetReply(&server_, &reply));
+
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(2, result.timeouts_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
+}
+
+TEST_P(MockChannelTest, CancelImmediate) {
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ ares_cancel(channel_);
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ECANCELLED, result.status_);
+ EXPECT_EQ(0, result.timeouts_);
+}
+
+TEST_P(MockChannelTest, CancelImmediateGetHostByAddr) {
+ HostResult result;
+ struct in_addr addr;
+ addr.s_addr = htonl(0x08080808);
+
+ ares_gethostbyaddr(channel_, &addr, sizeof(addr), AF_INET, HostCallback, &result);
+ ares_cancel(channel_);
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ECANCELLED, result.status_);
+ EXPECT_EQ(0, result.timeouts_);
+}
+
+// Relies on retries so is UDP-only
+TEST_P(MockUDPChannelTest, CancelLater) {
+ std::vector<byte> nothing;
+
+ // On second request, cancel the channel.
+ EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillOnce(SetReplyData(&server_, nothing))
+ .WillOnce(CancelChannel(&server_, channel_));
+
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_ECANCELLED, result.status_);
+ EXPECT_EQ(0, result.timeouts_);
+}
+
+TEST_P(MockChannelTest, GetHostByNameDestroyAbsolute) {
+ HostResult result;
+ ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
+
+ ares_destroy(channel_);
+ channel_ = nullptr;
+
+ EXPECT_TRUE(result.done_); // Synchronous
+ EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
+ EXPECT_EQ(0, result.timeouts_);
+}
+
+TEST_P(MockChannelTest, GetHostByNameDestroyRelative) {
+ HostResult result;
+ ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
+
+ ares_destroy(channel_);
+ channel_ = nullptr;
+
+ EXPECT_TRUE(result.done_); // Synchronous
+ EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
+ EXPECT_EQ(0, result.timeouts_);
+}
+
TEST_P(MockChannelTest, GetHostByNameCNAMENoData) {
DNSPacket response;
response.set_response().set_aa()
@@ -951,223 +951,223 @@ TEST_P(MockChannelTest, GetHostByNameCNAMENoData) {
EXPECT_EQ(ARES_ENODATA, result.status_);
}
-TEST_P(MockChannelTest, GetHostByAddrDestroy) {
- unsigned char gdns_addr4[4] = {0x08, 0x08, 0x08, 0x08};
- HostResult result;
- ares_gethostbyaddr(channel_, gdns_addr4, sizeof(gdns_addr4), AF_INET, HostCallback, &result);
-
- ares_destroy(channel_);
- channel_ = nullptr;
-
- EXPECT_TRUE(result.done_); // Synchronous
- EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
- EXPECT_EQ(0, result.timeouts_);
-}
-
-#ifndef WIN32
-TEST_P(MockChannelTest, HostAlias) {
- DNSPacket reply;
- reply.set_response().set_aa()
- .add_question(new DNSQuestion("www.google.com", ns_t_a))
- .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
- ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &reply));
-
- TempFile aliases("\n\n# www commentedout\nwww www.google.com\n");
- EnvValue with_env("HOSTALIASES", aliases.filename());
-
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
-}
-
-TEST_P(MockChannelTest, HostAliasMissing) {
- DNSPacket yesfirst;
- yesfirst.set_response().set_aa()
- .add_question(new DNSQuestion("www.first.com", ns_t_a))
- .add_answer(new DNSARR("www.first.com", 0x0200, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &yesfirst));
-
- TempFile aliases("\n\n# www commentedout\nww www.google.com\n");
- EnvValue with_env("HOSTALIASES", aliases.filename());
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.first.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
-}
-
-TEST_P(MockChannelTest, HostAliasMissingFile) {
- DNSPacket yesfirst;
- yesfirst.set_response().set_aa()
- .add_question(new DNSQuestion("www.first.com", ns_t_a))
- .add_answer(new DNSARR("www.first.com", 0x0200, {2, 3, 4, 5}));
- ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
- .WillByDefault(SetReply(&server_, &yesfirst));
-
- EnvValue with_env("HOSTALIASES", "bogus.mcfile");
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.first.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
-}
-
-TEST_P(MockChannelTest, HostAliasUnreadable) {
- TempFile aliases("www www.google.com\n");
- chmod(aliases.filename(), 0);
- EnvValue with_env("HOSTALIASES", aliases.filename());
-
- HostResult result;
- ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
- EXPECT_TRUE(result.done_);
- EXPECT_EQ(ARES_EFILE, result.status_);
- chmod(aliases.filename(), 0777);
-}
-#endif
-
-class MockMultiServerChannelTest
- : public MockChannelOptsTest,
- public ::testing::WithParamInterface< std::pair<int, bool> > {
- public:
- MockMultiServerChannelTest(bool rotate)
- : MockChannelOptsTest(3, GetParam().first, GetParam().second, nullptr, rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE) {}
- void CheckExample() {
- HostResult result;
- ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
- Process();
- EXPECT_TRUE(result.done_);
- std::stringstream ss;
- ss << result.host_;
- EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
- }
-};
-
-class RotateMultiMockTest : public MockMultiServerChannelTest {
- public:
- RotateMultiMockTest() : MockMultiServerChannelTest(true) {}
-};
-
-class NoRotateMultiMockTest : public MockMultiServerChannelTest {
- public:
- NoRotateMultiMockTest() : MockMultiServerChannelTest(false) {}
-};
-
-
-TEST_P(RotateMultiMockTest, 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(), &notimplrsp));
- 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(), &notimplrsp));
- 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(), &notimplrsp));
- EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[1].get(), &okrsp));
- CheckExample();
-}
-
-TEST_P(NoRotateMultiMockTest, 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(), &notimplrsp));
- 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(), &notimplrsp));
- 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(), &notimplrsp));
- EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
- .WillOnce(SetReply(servers_[2].get(), &okrsp));
- CheckExample();
-}
-
-INSTANTIATE_TEST_CASE_P(AddressFamilies, MockChannelTest, ::testing::ValuesIn(ares::test::families_modes));
-
-INSTANTIATE_TEST_CASE_P(AddressFamilies, MockUDPChannelTest, ::testing::ValuesIn(ares::test::families));
-
-INSTANTIATE_TEST_CASE_P(AddressFamilies, MockTCPChannelTest, ::testing::ValuesIn(ares::test::families));
-
-INSTANTIATE_TEST_CASE_P(AddressFamilies, MockExtraOptsTest, ::testing::ValuesIn(ares::test::families_modes));
-
-INSTANTIATE_TEST_CASE_P(AddressFamilies, MockNoCheckRespChannelTest, ::testing::ValuesIn(ares::test::families_modes));
-
-INSTANTIATE_TEST_CASE_P(AddressFamilies, MockEDNSChannelTest, ::testing::ValuesIn(ares::test::families_modes));
-
-INSTANTIATE_TEST_CASE_P(TransportModes, RotateMultiMockTest, ::testing::ValuesIn(ares::test::families_modes));
-
-INSTANTIATE_TEST_CASE_P(TransportModes, NoRotateMultiMockTest, ::testing::ValuesIn(ares::test::families_modes));
-
-} // namespace test
-} // namespace ares
+TEST_P(MockChannelTest, GetHostByAddrDestroy) {
+ unsigned char gdns_addr4[4] = {0x08, 0x08, 0x08, 0x08};
+ HostResult result;
+ ares_gethostbyaddr(channel_, gdns_addr4, sizeof(gdns_addr4), AF_INET, HostCallback, &result);
+
+ ares_destroy(channel_);
+ channel_ = nullptr;
+
+ EXPECT_TRUE(result.done_); // Synchronous
+ EXPECT_EQ(ARES_EDESTRUCTION, result.status_);
+ EXPECT_EQ(0, result.timeouts_);
+}
+
+#ifndef WIN32
+TEST_P(MockChannelTest, HostAlias) {
+ DNSPacket reply;
+ reply.set_response().set_aa()
+ .add_question(new DNSQuestion("www.google.com", ns_t_a))
+ .add_answer(new DNSARR("www.google.com", 0x0100, {0x01, 0x02, 0x03, 0x04}));
+ ON_CALL(server_, OnRequest("www.google.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &reply));
+
+ TempFile aliases("\n\n# www commentedout\nwww www.google.com\n");
+ EnvValue with_env("HOSTALIASES", aliases.filename());
+
+ HostResult result;
+ ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'www.google.com' aliases=[] addrs=[1.2.3.4]}", ss.str());
+}
+
+TEST_P(MockChannelTest, HostAliasMissing) {
+ DNSPacket yesfirst;
+ yesfirst.set_response().set_aa()
+ .add_question(new DNSQuestion("www.first.com", ns_t_a))
+ .add_answer(new DNSARR("www.first.com", 0x0200, {2, 3, 4, 5}));
+ ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &yesfirst));
+
+ TempFile aliases("\n\n# www commentedout\nww www.google.com\n");
+ EnvValue with_env("HOSTALIASES", aliases.filename());
+ HostResult result;
+ ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'www.first.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
+}
+
+TEST_P(MockChannelTest, HostAliasMissingFile) {
+ DNSPacket yesfirst;
+ yesfirst.set_response().set_aa()
+ .add_question(new DNSQuestion("www.first.com", ns_t_a))
+ .add_answer(new DNSARR("www.first.com", 0x0200, {2, 3, 4, 5}));
+ ON_CALL(server_, OnRequest("www.first.com", ns_t_a))
+ .WillByDefault(SetReply(&server_, &yesfirst));
+
+ EnvValue with_env("HOSTALIASES", "bogus.mcfile");
+ HostResult result;
+ ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'www.first.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
+}
+
+TEST_P(MockChannelTest, HostAliasUnreadable) {
+ TempFile aliases("www www.google.com\n");
+ chmod(aliases.filename(), 0);
+ EnvValue with_env("HOSTALIASES", aliases.filename());
+
+ HostResult result;
+ ares_gethostbyname(channel_, "www", AF_INET, HostCallback, &result);
+ EXPECT_TRUE(result.done_);
+ EXPECT_EQ(ARES_EFILE, result.status_);
+ chmod(aliases.filename(), 0777);
+}
+#endif
+
+class MockMultiServerChannelTest
+ : public MockChannelOptsTest,
+ public ::testing::WithParamInterface< std::pair<int, bool> > {
+ public:
+ MockMultiServerChannelTest(bool rotate)
+ : MockChannelOptsTest(3, GetParam().first, GetParam().second, nullptr, rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE) {}
+ void CheckExample() {
+ HostResult result;
+ ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result);
+ Process();
+ EXPECT_TRUE(result.done_);
+ std::stringstream ss;
+ ss << result.host_;
+ EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
+ }
+};
+
+class RotateMultiMockTest : public MockMultiServerChannelTest {
+ public:
+ RotateMultiMockTest() : MockMultiServerChannelTest(true) {}
+};
+
+class NoRotateMultiMockTest : public MockMultiServerChannelTest {
+ public:
+ NoRotateMultiMockTest() : MockMultiServerChannelTest(false) {}
+};
+
+
+TEST_P(RotateMultiMockTest, 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(), &notimplrsp));
+ 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(), &notimplrsp));
+ 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(), &notimplrsp));
+ EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[1].get(), &okrsp));
+ CheckExample();
+}
+
+TEST_P(NoRotateMultiMockTest, 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(), &notimplrsp));
+ 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(), &notimplrsp));
+ 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(), &notimplrsp));
+ EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a))
+ .WillOnce(SetReply(servers_[2].get(), &okrsp));
+ CheckExample();
+}
+
+INSTANTIATE_TEST_CASE_P(AddressFamilies, MockChannelTest, ::testing::ValuesIn(ares::test::families_modes));
+
+INSTANTIATE_TEST_CASE_P(AddressFamilies, MockUDPChannelTest, ::testing::ValuesIn(ares::test::families));
+
+INSTANTIATE_TEST_CASE_P(AddressFamilies, MockTCPChannelTest, ::testing::ValuesIn(ares::test::families));
+
+INSTANTIATE_TEST_CASE_P(AddressFamilies, MockExtraOptsTest, ::testing::ValuesIn(ares::test::families_modes));
+
+INSTANTIATE_TEST_CASE_P(AddressFamilies, MockNoCheckRespChannelTest, ::testing::ValuesIn(ares::test::families_modes));
+
+INSTANTIATE_TEST_CASE_P(AddressFamilies, MockEDNSChannelTest, ::testing::ValuesIn(ares::test::families_modes));
+
+INSTANTIATE_TEST_CASE_P(TransportModes, RotateMultiMockTest, ::testing::ValuesIn(ares::test::families_modes));
+
+INSTANTIATE_TEST_CASE_P(TransportModes, NoRotateMultiMockTest, ::testing::ValuesIn(ares::test::families_modes));
+
+} // namespace test
+} // namespace ares
diff --git a/contrib/libs/c-ares/test/ares-test-ns.cc b/contrib/libs/c-ares/test/ares-test-ns.cc
index 77ebdcc2e2..c3c455214d 100644
--- a/contrib/libs/c-ares/test/ares-test-ns.cc
+++ b/contrib/libs/c-ares/test/ares-test-ns.cc
@@ -1,199 +1,199 @@
-#include "ares-test.h"
-
-#ifdef HAVE_CONTAINER
-
-#include <sys/mount.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <iostream>
-#include <functional>
-#include <string>
-#include <sstream>
-#include <vector>
-
-namespace ares {
-namespace test {
-
-namespace {
-
-struct ContainerInfo {
- ContainerFilesystem* fs_;
- std::string hostname_;
- std::string domainname_;
- VoidToIntFn fn_;
-};
-
-int EnterContainer(void *data) {
- ContainerInfo *container = (ContainerInfo*)data;
-
- if (verbose) {
- std::cerr << "Running function in container {chroot='"
- << container->fs_->root() << "', hostname='" << container->hostname_
- << "', domainname='" << container->domainname_ << "'}"
- << std::endl;
- }
-
- // Ensure we are apparently root before continuing.
- int count = 10;
- while (getuid() != 0 && count > 0) {
- usleep(100000);
- count--;
- }
- if (getuid() != 0) {
- std::cerr << "Child in user namespace has uid " << getuid() << std::endl;
- return -1;
- }
- if (!container->fs_->mountpt().empty()) {
- // We want to bind mount this inside the specified directory.
- std::string innerdir = container->fs_->root() + container->fs_->mountpt();
- if (verbose) std::cerr << " mount --bind " << container->fs_->mountpt()
- << " " << innerdir << std::endl;
- int rc = mount(container->fs_->mountpt().c_str(), innerdir.c_str(),
- "none", MS_BIND, 0);
- if (rc != 0) {
- std::cerr << "Warning: failed to bind mount " << container->fs_->mountpt() << " at "
- << innerdir << ", errno=" << errno << std::endl;
- }
- }
-
- // Move into the specified directory.
- if (chdir(container->fs_->root().c_str()) != 0) {
- std::cerr << "Failed to chdir('" << container->fs_->root()
- << "'), errno=" << errno << std::endl;
- return -1;
- }
- // And make it the new root directory;
- char buffer[PATH_MAX + 1];
- if (getcwd(buffer, PATH_MAX) == NULL) {
- std::cerr << "failed to retrieve cwd, errno=" << errno << std::endl;
- return -1;
- }
- buffer[PATH_MAX] = '\0';
- if (chroot(buffer) != 0) {
- std::cerr << "chroot('" << buffer << "') failed, errno=" << errno << std::endl;
- return -1;
- }
-
- // Set host/domainnames if specified
- if (!container->hostname_.empty()) {
- if (sethostname(container->hostname_.c_str(),
- container->hostname_.size()) != 0) {
- std::cerr << "Failed to sethostname('" << container->hostname_
- << "'), errno=" << errno << std::endl;
- return -1;
- }
- }
- if (!container->domainname_.empty()) {
- if (setdomainname(container->domainname_.c_str(),
- container->domainname_.size()) != 0) {
- std::cerr << "Failed to setdomainname('" << container->domainname_
- << "'), errno=" << errno << std::endl;
- return -1;
- }
- }
-
- return container->fn_();
-}
-
-} // namespace
-
-// Run a function while:
-// - chroot()ed into a particular directory
-// - having a specified hostname/domainname
-
-int RunInContainer(ContainerFilesystem* fs, const std::string& hostname,
- const std::string& domainname, VoidToIntFn fn) {
- const int stack_size = 1024 * 1024;
- std::vector<byte> stack(stack_size, 0);
- ContainerInfo container = {fs, hostname, domainname, fn};
-
- // Start a child process in a new user and UTS namespace
- pid_t child = clone(EnterContainer, stack.data() + stack_size,
- CLONE_VM|CLONE_NEWNS|CLONE_NEWUSER|CLONE_NEWUTS|SIGCHLD,
- (void *)&container);
- if (child < 0) {
- std::cerr << "Failed to clone(), errno=" << errno << std::endl;
- return -1;
- }
-
- // Build the UID map that makes us look like root inside the namespace.
- std::stringstream mapfiless;
- mapfiless << "/proc/" << child << "/uid_map";
- std::string mapfile = mapfiless.str();
- int fd = open(mapfile.c_str(), O_CREAT|O_WRONLY|O_TRUNC, 0644);
- if (fd < 0) {
- std::cerr << "Failed to create '" << mapfile << "'" << std::endl;
- return -1;
- }
- std::stringstream contentss;
- contentss << "0 " << getuid() << " 1" << std::endl;
- std::string content = contentss.str();
- int rc = write(fd, content.c_str(), content.size());
- if (rc != (int)content.size()) {
- std::cerr << "Failed to write uid map to '" << mapfile << "'" << std::endl;
- }
- close(fd);
-
- // Wait for the child process and retrieve its status.
- int status;
- waitpid(child, &status, 0);
- if (rc <= 0) {
- std::cerr << "Failed to waitpid(" << child << ")" << std::endl;
- return -1;
- }
- if (!WIFEXITED(status)) {
- std::cerr << "Child " << child << " did not exit normally" << std::endl;
- return -1;
- }
- return status;
-}
-
-ContainerFilesystem::ContainerFilesystem(NameContentList files, const std::string& mountpt) {
- rootdir_ = TempNam(nullptr, "ares-chroot");
- mkdir(rootdir_.c_str(), 0755);
- dirs_.push_front(rootdir_);
- for (const auto& nc : files) {
- std::string fullpath = rootdir_ + nc.first;
- int idx = fullpath.rfind('/');
- std::string dir = fullpath.substr(0, idx);
- EnsureDirExists(dir);
- files_.push_back(std::unique_ptr<TransientFile>(
- new TransientFile(fullpath, nc.second)));
- }
- if (!mountpt.empty()) {
- char buffer[PATH_MAX + 1];
- if (realpath(mountpt.c_str(), buffer)) {
- mountpt_ = buffer;
- std::string fullpath = rootdir_ + mountpt_;
- EnsureDirExists(fullpath);
- }
- }
-}
-
-ContainerFilesystem::~ContainerFilesystem() {
- files_.clear();
- for (const std::string& dir : dirs_) {
- rmdir(dir.c_str());
- }
-}
-
-void ContainerFilesystem::EnsureDirExists(const std::string& dir) {
- if (std::find(dirs_.begin(), dirs_.end(), dir) != dirs_.end()) {
- return;
- }
- size_t idx = dir.rfind('/');
- if (idx != std::string::npos) {
- std::string prevdir = dir.substr(0, idx);
- EnsureDirExists(prevdir);
- }
- // Ensure this directory is in the list before its ancestors.
- mkdir(dir.c_str(), 0755);
- dirs_.push_front(dir);
-}
-
-} // namespace test
-} // namespace ares
-
-#endif
+#include "ares-test.h"
+
+#ifdef HAVE_CONTAINER
+
+#include <sys/mount.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <iostream>
+#include <functional>
+#include <string>
+#include <sstream>
+#include <vector>
+
+namespace ares {
+namespace test {
+
+namespace {
+
+struct ContainerInfo {
+ ContainerFilesystem* fs_;
+ std::string hostname_;
+ std::string domainname_;
+ VoidToIntFn fn_;
+};
+
+int EnterContainer(void *data) {
+ ContainerInfo *container = (ContainerInfo*)data;
+
+ if (verbose) {
+ std::cerr << "Running function in container {chroot='"
+ << container->fs_->root() << "', hostname='" << container->hostname_
+ << "', domainname='" << container->domainname_ << "'}"
+ << std::endl;
+ }
+
+ // Ensure we are apparently root before continuing.
+ int count = 10;
+ while (getuid() != 0 && count > 0) {
+ usleep(100000);
+ count--;
+ }
+ if (getuid() != 0) {
+ std::cerr << "Child in user namespace has uid " << getuid() << std::endl;
+ return -1;
+ }
+ if (!container->fs_->mountpt().empty()) {
+ // We want to bind mount this inside the specified directory.
+ std::string innerdir = container->fs_->root() + container->fs_->mountpt();
+ if (verbose) std::cerr << " mount --bind " << container->fs_->mountpt()
+ << " " << innerdir << std::endl;
+ int rc = mount(container->fs_->mountpt().c_str(), innerdir.c_str(),
+ "none", MS_BIND, 0);
+ if (rc != 0) {
+ std::cerr << "Warning: failed to bind mount " << container->fs_->mountpt() << " at "
+ << innerdir << ", errno=" << errno << std::endl;
+ }
+ }
+
+ // Move into the specified directory.
+ if (chdir(container->fs_->root().c_str()) != 0) {
+ std::cerr << "Failed to chdir('" << container->fs_->root()
+ << "'), errno=" << errno << std::endl;
+ return -1;
+ }
+ // And make it the new root directory;
+ char buffer[PATH_MAX + 1];
+ if (getcwd(buffer, PATH_MAX) == NULL) {
+ std::cerr << "failed to retrieve cwd, errno=" << errno << std::endl;
+ return -1;
+ }
+ buffer[PATH_MAX] = '\0';
+ if (chroot(buffer) != 0) {
+ std::cerr << "chroot('" << buffer << "') failed, errno=" << errno << std::endl;
+ return -1;
+ }
+
+ // Set host/domainnames if specified
+ if (!container->hostname_.empty()) {
+ if (sethostname(container->hostname_.c_str(),
+ container->hostname_.size()) != 0) {
+ std::cerr << "Failed to sethostname('" << container->hostname_
+ << "'), errno=" << errno << std::endl;
+ return -1;
+ }
+ }
+ if (!container->domainname_.empty()) {
+ if (setdomainname(container->domainname_.c_str(),
+ container->domainname_.size()) != 0) {
+ std::cerr << "Failed to setdomainname('" << container->domainname_
+ << "'), errno=" << errno << std::endl;
+ return -1;
+ }
+ }
+
+ return container->fn_();
+}
+
+} // namespace
+
+// Run a function while:
+// - chroot()ed into a particular directory
+// - having a specified hostname/domainname
+
+int RunInContainer(ContainerFilesystem* fs, const std::string& hostname,
+ const std::string& domainname, VoidToIntFn fn) {
+ const int stack_size = 1024 * 1024;
+ std::vector<byte> stack(stack_size, 0);
+ ContainerInfo container = {fs, hostname, domainname, fn};
+
+ // Start a child process in a new user and UTS namespace
+ pid_t child = clone(EnterContainer, stack.data() + stack_size,
+ CLONE_VM|CLONE_NEWNS|CLONE_NEWUSER|CLONE_NEWUTS|SIGCHLD,
+ (void *)&container);
+ if (child < 0) {
+ std::cerr << "Failed to clone(), errno=" << errno << std::endl;
+ return -1;
+ }
+
+ // Build the UID map that makes us look like root inside the namespace.
+ std::stringstream mapfiless;
+ mapfiless << "/proc/" << child << "/uid_map";
+ std::string mapfile = mapfiless.str();
+ int fd = open(mapfile.c_str(), O_CREAT|O_WRONLY|O_TRUNC, 0644);
+ if (fd < 0) {
+ std::cerr << "Failed to create '" << mapfile << "'" << std::endl;
+ return -1;
+ }
+ std::stringstream contentss;
+ contentss << "0 " << getuid() << " 1" << std::endl;
+ std::string content = contentss.str();
+ int rc = write(fd, content.c_str(), content.size());
+ if (rc != (int)content.size()) {
+ std::cerr << "Failed to write uid map to '" << mapfile << "'" << std::endl;
+ }
+ close(fd);
+
+ // Wait for the child process and retrieve its status.
+ int status;
+ waitpid(child, &status, 0);
+ if (rc <= 0) {
+ std::cerr << "Failed to waitpid(" << child << ")" << std::endl;
+ return -1;
+ }
+ if (!WIFEXITED(status)) {
+ std::cerr << "Child " << child << " did not exit normally" << std::endl;
+ return -1;
+ }
+ return status;
+}
+
+ContainerFilesystem::ContainerFilesystem(NameContentList files, const std::string& mountpt) {
+ rootdir_ = TempNam(nullptr, "ares-chroot");
+ mkdir(rootdir_.c_str(), 0755);
+ dirs_.push_front(rootdir_);
+ for (const auto& nc : files) {
+ std::string fullpath = rootdir_ + nc.first;
+ int idx = fullpath.rfind('/');
+ std::string dir = fullpath.substr(0, idx);
+ EnsureDirExists(dir);
+ files_.push_back(std::unique_ptr<TransientFile>(
+ new TransientFile(fullpath, nc.second)));
+ }
+ if (!mountpt.empty()) {
+ char buffer[PATH_MAX + 1];
+ if (realpath(mountpt.c_str(), buffer)) {
+ mountpt_ = buffer;
+ std::string fullpath = rootdir_ + mountpt_;
+ EnsureDirExists(fullpath);
+ }
+ }
+}
+
+ContainerFilesystem::~ContainerFilesystem() {
+ files_.clear();
+ for (const std::string& dir : dirs_) {
+ rmdir(dir.c_str());
+ }
+}
+
+void ContainerFilesystem::EnsureDirExists(const std::string& dir) {
+ if (std::find(dirs_.begin(), dirs_.end(), dir) != dirs_.end()) {
+ return;
+ }
+ size_t idx = dir.rfind('/');
+ if (idx != std::string::npos) {
+ std::string prevdir = dir.substr(0, idx);
+ EnsureDirExists(prevdir);
+ }
+ // Ensure this directory is in the list before its ancestors.
+ mkdir(dir.c_str(), 0755);
+ dirs_.push_front(dir);
+}
+
+} // namespace test
+} // namespace ares
+
+#endif
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 65bc822c05..7f6a987c13 100644
--- a/contrib/libs/c-ares/test/ares-test-parse-a.cc
+++ b/contrib/libs/c-ares/test/ares-test-parse-a.cc
@@ -1,41 +1,41 @@
-#include "ares-test.h"
-#include "dns-proto.h"
-
-#include <sstream>
-#include <vector>
-
-namespace ares {
-namespace test {
-
-TEST_F(LibraryTest, ParseAReplyOK) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_a))
+#include "ares-test.h"
+#include "dns-proto.h"
+
+#include <sstream>
+#include <vector>
+
+namespace ares {
+namespace test {
+
+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}));
- 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
+ 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, 0x00, // num authority RRs
- 0x00, 0x00, // num additional RRs
- // Question
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x01, // type A
- 0x00, 0x01, // class IN
- // Answer 1
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x01, // RR type
- 0x00, 0x01, // class IN
- 0x01, 0x02, 0x03, 0x04, // TTL
- 0x00, 0x04, // rdata length
- 0x02, 0x03, 0x04, 0x05,
+ 0x00, 0x00, // num authority RRs
+ 0x00, 0x00, // num additional RRs
+ // Question
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x01, // type A
+ 0x00, 0x01, // class IN
+ // Answer 1
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x01, // RR type
+ 0x00, 0x01, // class IN
+ 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',
@@ -45,334 +45,334 @@ TEST_F(LibraryTest, ParseAReplyOK) {
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;
- struct ares_addrttl info[5];
- int count = 5;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(1, count);
- EXPECT_EQ(0x01020304, info[0].ttl);
- unsigned long expected_addr = htonl(0x02030405);
- EXPECT_EQ(expected_addr, info[0].ipaddr.s_addr);
- EXPECT_EQ("2.3.4.5", AddressToString(&(info[0].ipaddr), 4));
- ASSERT_NE(nullptr, host);
- std::stringstream ss;
- ss << HostEnt(host);
- EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
- ares_free_hostent(host);
-
- // Repeat without providing a hostent
- EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
- nullptr, info, &count));
- EXPECT_EQ(1, count);
- EXPECT_EQ(0x01020304, info[0].ttl);
- EXPECT_EQ(expected_addr, info[0].ipaddr.s_addr);
- EXPECT_EQ("2.3.4.5", AddressToString(&(info[0].ipaddr), 4));
-}
-
-TEST_F(LibraryTest, ParseMalformedAReply) {
- std::vector<byte> data = {
- 0x12, 0x34, // [0:2) qid
- 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
+ };
+ EXPECT_EQ(data, pkt.data());
+ struct hostent *host = nullptr;
+ struct ares_addrttl info[5];
+ int count = 5;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(1, count);
+ EXPECT_EQ(0x01020304, info[0].ttl);
+ unsigned long expected_addr = htonl(0x02030405);
+ EXPECT_EQ(expected_addr, info[0].ipaddr.s_addr);
+ EXPECT_EQ("2.3.4.5", AddressToString(&(info[0].ipaddr), 4));
+ ASSERT_NE(nullptr, host);
+ std::stringstream ss;
+ ss << HostEnt(host);
+ EXPECT_EQ("{'example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
+ ares_free_hostent(host);
+
+ // Repeat without providing a hostent
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
+ nullptr, info, &count));
+ EXPECT_EQ(1, count);
+ EXPECT_EQ(0x01020304, info[0].ttl);
+ EXPECT_EQ(expected_addr, info[0].ipaddr.s_addr);
+ EXPECT_EQ("2.3.4.5", AddressToString(&(info[0].ipaddr), 4));
+}
+
+TEST_F(LibraryTest, ParseMalformedAReply) {
+ std::vector<byte> data = {
+ 0x12, 0x34, // [0:2) qid
+ 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, 0x00, // [8:10) num authority RRs
- 0x00, 0x00, // [10:12) num additional RRs
- // Question
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', // [12:20)
- 0x03, 'c', 'o', 'm', // [20,24)
- 0x00, // [24]
- 0x00, 0x01, // [25:26) type A
- 0x00, 0x01, // [27:29) class IN
- // Answer 1
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', // [29:37)
- 0x03, 'c', 'o', 'm', // [37:41)
- 0x00, // [41]
- 0x00, 0x01, // [42:44) RR type
- 0x00, 0x01, // [44:46) class IN
- 0x01, 0x02, 0x03, 0x04, // [46:50) TTL
- 0x00, 0x04, // [50:52) rdata length
- 0x02, 0x03, 0x04, 0x05, // [52,56)
- };
- struct hostent *host = nullptr;
- struct ares_addrttl info[2];
- int count = 2;
-
- // Invalid RR-len.
- std::vector<byte> invalid_rrlen(data);
- invalid_rrlen[51] = 180;
- EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(invalid_rrlen.data(), invalid_rrlen.size(),
- &host, info, &count));
-
- // Truncate mid-question.
- EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), 26,
- &host, info, &count));
-
- // Truncate mid-answer.
- EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), 42,
- &host, info, &count));
-}
-
-TEST_F(LibraryTest, ParseAReplyNoData) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_a));
- std::vector<byte> data = pkt.data();
- struct hostent *host = nullptr;
- struct ares_addrttl info[2];
- int count = 2;
- EXPECT_EQ(ARES_ENODATA, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(0, count);
- EXPECT_EQ(nullptr, host);
-
- // Again but with a CNAME.
- pkt.add_answer(new DNSCnameRR("example.com", 200, "c.example.com"));
+ 0x00, 0x00, // [8:10) num authority RRs
+ 0x00, 0x00, // [10:12) num additional RRs
+ // Question
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', // [12:20)
+ 0x03, 'c', 'o', 'm', // [20,24)
+ 0x00, // [24]
+ 0x00, 0x01, // [25:26) type A
+ 0x00, 0x01, // [27:29) class IN
+ // Answer 1
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', // [29:37)
+ 0x03, 'c', 'o', 'm', // [37:41)
+ 0x00, // [41]
+ 0x00, 0x01, // [42:44) RR type
+ 0x00, 0x01, // [44:46) class IN
+ 0x01, 0x02, 0x03, 0x04, // [46:50) TTL
+ 0x00, 0x04, // [50:52) rdata length
+ 0x02, 0x03, 0x04, 0x05, // [52,56)
+ };
+ struct hostent *host = nullptr;
+ struct ares_addrttl info[2];
+ int count = 2;
+
+ // Invalid RR-len.
+ std::vector<byte> invalid_rrlen(data);
+ invalid_rrlen[51] = 180;
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(invalid_rrlen.data(), invalid_rrlen.size(),
+ &host, info, &count));
+
+ // Truncate mid-question.
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), 26,
+ &host, info, &count));
+
+ // Truncate mid-answer.
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), 42,
+ &host, info, &count));
+}
+
+TEST_F(LibraryTest, ParseAReplyNoData) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_a));
+ std::vector<byte> data = pkt.data();
+ struct hostent *host = nullptr;
+ struct ares_addrttl info[2];
+ int count = 2;
+ EXPECT_EQ(ARES_ENODATA, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(0, count);
+ EXPECT_EQ(nullptr, host);
+
+ // 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(),
- &host, info, &count));
- EXPECT_EQ(0, count);
+ &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);
-}
-
-TEST_F(LibraryTest, ParseAReplyVariantA) {
- DNSPacket pkt;
- pkt.set_qid(6366).set_rd().set_ra()
- .add_question(new DNSQuestion("mit.edu", ns_t_a))
- .add_answer(new DNSARR("mit.edu", 52, {18,7,22,69}))
- .add_auth(new DNSNsRR("mit.edu", 292, "W20NS.mit.edu"))
- .add_auth(new DNSNsRR("mit.edu", 292, "BITSY.mit.edu"))
- .add_auth(new DNSNsRR("mit.edu", 292, "STRAWB.mit.edu"))
- .add_additional(new DNSARR("STRAWB.mit.edu", 292, {18,71,0,151}));
- struct hostent *host = nullptr;
- struct ares_addrttl info[2];
- int count = 2;
- std::vector<byte> data = pkt.data();
- EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(1, count);
- EXPECT_EQ("18.7.22.69", AddressToString(&(info[0].ipaddr), 4));
- EXPECT_EQ(52, info[0].ttl);
- ares_free_hostent(host);
-}
-
-TEST_F(LibraryTest, ParseAReplyJustCname) {
- DNSPacket pkt;
- pkt.set_qid(6366).set_rd().set_ra()
- .add_question(new DNSQuestion("mit.edu", ns_t_a))
- .add_answer(new DNSCnameRR("mit.edu", 52, "other.mit.edu"));
- struct hostent *host = nullptr;
- struct ares_addrttl info[2];
- int count = 2;
- std::vector<byte> data = pkt.data();
- EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(0, count);
- ASSERT_NE(nullptr, host);
- std::stringstream ss;
- ss << HostEnt(host);
- EXPECT_EQ("{'other.mit.edu' aliases=[mit.edu] addrs=[]}", ss.str());
- ares_free_hostent(host);
-}
-
-TEST_F(LibraryTest, ParseAReplyVariantCname) {
- DNSPacket pkt;
- pkt.set_qid(6366).set_rd().set_ra()
- .add_question(new DNSQuestion("query.example.com", ns_t_a))
- .add_answer(new DNSCnameRR("query.example.com", 200, "redirect.query.example.com"))
- .add_answer(new DNSARR("redirect.query.example.com", 300, {129,97,123,22}))
- .add_auth(new DNSNsRR("example.com", 218, "aa.ns1.example.com"))
- .add_auth(new DNSNsRR("example.com", 218, "ns2.example.com"))
- .add_auth(new DNSNsRR("example.com", 218, "ns3.example.com"))
- .add_auth(new DNSNsRR("example.com", 218, "ns4.example.com"))
- .add_additional(new DNSARR("aa.ns1.example.com", 218, {129,97,1,1}))
- .add_additional(new DNSARR("ns2.example.com", 218, {129,97,1,2}))
- .add_additional(new DNSARR("ns3.example.com", 218, {129,97,1,3}))
- .add_additional(new DNSARR("ns4.example.com", 218, {129,97,1,4}));
- struct hostent *host = nullptr;
- struct ares_addrttl info[2];
- int count = 2;
- std::vector<byte> data = pkt.data();
- EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(1, count);
- EXPECT_EQ("129.97.123.22", AddressToString(&(info[0].ipaddr), 4));
- // TTL is reduced to match CNAME's.
- EXPECT_EQ(200, info[0].ttl);
- ares_free_hostent(host);
-
- // Repeat parsing without places to put the results.
- count = 0;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
- nullptr, info, &count));
-}
-
-TEST_F(LibraryTest, ParseAReplyVariantCnameChain) {
- DNSPacket pkt;
- pkt.set_qid(6366).set_rd().set_ra()
- .add_question(new DNSQuestion("c1.localhost", ns_t_a))
- .add_answer(new DNSCnameRR("c1.localhost", 604800, "c2.localhost"))
- .add_answer(new DNSCnameRR("c2.localhost", 604800, "c3.localhost"))
- .add_answer(new DNSCnameRR("c3.localhost", 604800, "c4.localhost"))
- .add_answer(new DNSARR("c4.localhost", 604800, {8,8,8,8}))
- .add_auth(new DNSNsRR("localhost", 604800, "localhost"))
- .add_additional(new DNSARR("localhost", 604800, {127,0,0,1}))
- .add_additional(new DNSAaaaRR("localhost", 604800,
- {0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}));
- struct hostent *host = nullptr;
- struct ares_addrttl info[2];
- int count = 2;
- std::vector<byte> data = pkt.data();
- EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(1, count);
- EXPECT_EQ("8.8.8.8", AddressToString(&(info[0].ipaddr), 4));
- EXPECT_EQ(604800, info[0].ttl);
- ares_free_hostent(host);
-}
-
-TEST_F(LibraryTest, DISABLED_ParseAReplyVariantCnameLast) {
- DNSPacket pkt;
- pkt.set_qid(6366).set_rd().set_ra()
- .add_question(new DNSQuestion("query.example.com", ns_t_a))
- .add_answer(new DNSARR("redirect.query.example.com", 300, {129,97,123,221}))
- .add_answer(new DNSARR("redirect.query.example.com", 300, {129,97,123,222}))
- .add_answer(new DNSARR("redirect.query.example.com", 300, {129,97,123,223}))
- .add_answer(new DNSARR("redirect.query.example.com", 300, {129,97,123,224}))
- .add_answer(new DNSCnameRR("query.example.com", 60, "redirect.query.example.com"))
- .add_additional(new DNSTxtRR("query.example.com", 60, {"text record"}));
- struct hostent *host = nullptr;
- struct ares_addrttl info[8];
- int count = 8;
- std::vector<byte> data = pkt.data();
- EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(4, count);
- EXPECT_EQ("129.97.123.221", AddressToString(&(info[0].ipaddr), 4));
- EXPECT_EQ("129.97.123.222", AddressToString(&(info[1].ipaddr), 4));
- EXPECT_EQ("129.97.123.223", AddressToString(&(info[2].ipaddr), 4));
- EXPECT_EQ("129.97.123.224", AddressToString(&(info[3].ipaddr), 4));
- EXPECT_EQ(300, info[0].ttl);
- EXPECT_EQ(300, info[1].ttl);
- EXPECT_EQ(300, info[2].ttl);
- EXPECT_EQ(300, info[3].ttl);
- ares_free_hostent(host);
-}
-
-TEST_F(LibraryTest, ParseAReplyErrors) {
- 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", 100, {0x02, 0x03, 0x04, 0x05}));
- std::vector<byte> data;
-
- struct hostent *host = nullptr;
- struct ares_addrttl info[2];
- int count = 2;
-
- // No question.
- pkt.questions_.clear();
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(nullptr, host);
- pkt.add_question(new DNSQuestion("example.com", ns_t_a));
-
- // Question != answer
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("Axample.com", ns_t_a));
- data = pkt.data();
- EXPECT_EQ(ARES_ENODATA, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(nullptr, host);
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("example.com", ns_t_a));
-
-#ifdef DISABLED
- // Not a response.
- pkt.set_response(false);
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(nullptr, host);
- pkt.set_response(true);
-
- // Bad return code.
- pkt.set_rcode(ns_r_formerr);
- data = pkt.data();
- EXPECT_EQ(ARES_ENODATA, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(nullptr, host);
- pkt.set_rcode(ns_r_noerror);
-#endif
-
- // Two questions
- pkt.add_question(new DNSQuestion("example.com", ns_t_a));
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(nullptr, host);
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("example.com", ns_t_a));
-
- // 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_ENODATA, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(nullptr, host);
- pkt.answers_.clear();
- pkt.add_answer(new DNSARR("example.com", 100, {0x02, 0x03, 0x04, 0x05}));
-
- // No answer.
- pkt.answers_.clear();
- data = pkt.data();
- EXPECT_EQ(ARES_ENODATA, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(nullptr, host);
- pkt.add_answer(new DNSARR("example.com", 100, {0x02, 0x03, 0x04, 0x05}));
-
- // Truncated packets.
- data = pkt.data();
- for (size_t len = 1; len < data.size(); len++) {
- EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), len,
- &host, info, &count));
- EXPECT_EQ(nullptr, host);
- EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), len,
- nullptr, info, &count));
- }
-}
-
-TEST_F(LibraryTest, ParseAReplyAllocFail) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_a))
- .add_answer(new DNSCnameRR("example.com", 300, "c.example.com"))
- .add_answer(new DNSARR("c.example.com", 500, {0x02, 0x03, 0x04, 0x05}));
- std::vector<byte> data = pkt.data();
-
- struct hostent *host = nullptr;
- struct ares_addrttl info[2];
- int count = 2;
-
- for (int ii = 1; ii <= 8; ii++) {
- ClearFails();
- SetAllocFail(ii);
- EXPECT_EQ(ARES_ENOMEM, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count)) << ii;
- EXPECT_EQ(nullptr, host);
- }
-}
-
-} // namespace test
-} // namespace ares
+}
+
+TEST_F(LibraryTest, ParseAReplyVariantA) {
+ DNSPacket pkt;
+ pkt.set_qid(6366).set_rd().set_ra()
+ .add_question(new DNSQuestion("mit.edu", ns_t_a))
+ .add_answer(new DNSARR("mit.edu", 52, {18,7,22,69}))
+ .add_auth(new DNSNsRR("mit.edu", 292, "W20NS.mit.edu"))
+ .add_auth(new DNSNsRR("mit.edu", 292, "BITSY.mit.edu"))
+ .add_auth(new DNSNsRR("mit.edu", 292, "STRAWB.mit.edu"))
+ .add_additional(new DNSARR("STRAWB.mit.edu", 292, {18,71,0,151}));
+ struct hostent *host = nullptr;
+ struct ares_addrttl info[2];
+ int count = 2;
+ std::vector<byte> data = pkt.data();
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(1, count);
+ EXPECT_EQ("18.7.22.69", AddressToString(&(info[0].ipaddr), 4));
+ EXPECT_EQ(52, info[0].ttl);
+ ares_free_hostent(host);
+}
+
+TEST_F(LibraryTest, ParseAReplyJustCname) {
+ DNSPacket pkt;
+ pkt.set_qid(6366).set_rd().set_ra()
+ .add_question(new DNSQuestion("mit.edu", ns_t_a))
+ .add_answer(new DNSCnameRR("mit.edu", 52, "other.mit.edu"));
+ struct hostent *host = nullptr;
+ struct ares_addrttl info[2];
+ int count = 2;
+ std::vector<byte> data = pkt.data();
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(0, count);
+ ASSERT_NE(nullptr, host);
+ std::stringstream ss;
+ ss << HostEnt(host);
+ EXPECT_EQ("{'other.mit.edu' aliases=[mit.edu] addrs=[]}", ss.str());
+ ares_free_hostent(host);
+}
+
+TEST_F(LibraryTest, ParseAReplyVariantCname) {
+ DNSPacket pkt;
+ pkt.set_qid(6366).set_rd().set_ra()
+ .add_question(new DNSQuestion("query.example.com", ns_t_a))
+ .add_answer(new DNSCnameRR("query.example.com", 200, "redirect.query.example.com"))
+ .add_answer(new DNSARR("redirect.query.example.com", 300, {129,97,123,22}))
+ .add_auth(new DNSNsRR("example.com", 218, "aa.ns1.example.com"))
+ .add_auth(new DNSNsRR("example.com", 218, "ns2.example.com"))
+ .add_auth(new DNSNsRR("example.com", 218, "ns3.example.com"))
+ .add_auth(new DNSNsRR("example.com", 218, "ns4.example.com"))
+ .add_additional(new DNSARR("aa.ns1.example.com", 218, {129,97,1,1}))
+ .add_additional(new DNSARR("ns2.example.com", 218, {129,97,1,2}))
+ .add_additional(new DNSARR("ns3.example.com", 218, {129,97,1,3}))
+ .add_additional(new DNSARR("ns4.example.com", 218, {129,97,1,4}));
+ struct hostent *host = nullptr;
+ struct ares_addrttl info[2];
+ int count = 2;
+ std::vector<byte> data = pkt.data();
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(1, count);
+ EXPECT_EQ("129.97.123.22", AddressToString(&(info[0].ipaddr), 4));
+ // TTL is reduced to match CNAME's.
+ EXPECT_EQ(200, info[0].ttl);
+ ares_free_hostent(host);
+
+ // Repeat parsing without places to put the results.
+ count = 0;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
+ nullptr, info, &count));
+}
+
+TEST_F(LibraryTest, ParseAReplyVariantCnameChain) {
+ DNSPacket pkt;
+ pkt.set_qid(6366).set_rd().set_ra()
+ .add_question(new DNSQuestion("c1.localhost", ns_t_a))
+ .add_answer(new DNSCnameRR("c1.localhost", 604800, "c2.localhost"))
+ .add_answer(new DNSCnameRR("c2.localhost", 604800, "c3.localhost"))
+ .add_answer(new DNSCnameRR("c3.localhost", 604800, "c4.localhost"))
+ .add_answer(new DNSARR("c4.localhost", 604800, {8,8,8,8}))
+ .add_auth(new DNSNsRR("localhost", 604800, "localhost"))
+ .add_additional(new DNSARR("localhost", 604800, {127,0,0,1}))
+ .add_additional(new DNSAaaaRR("localhost", 604800,
+ {0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}));
+ struct hostent *host = nullptr;
+ struct ares_addrttl info[2];
+ int count = 2;
+ std::vector<byte> data = pkt.data();
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(1, count);
+ EXPECT_EQ("8.8.8.8", AddressToString(&(info[0].ipaddr), 4));
+ EXPECT_EQ(604800, info[0].ttl);
+ ares_free_hostent(host);
+}
+
+TEST_F(LibraryTest, DISABLED_ParseAReplyVariantCnameLast) {
+ DNSPacket pkt;
+ pkt.set_qid(6366).set_rd().set_ra()
+ .add_question(new DNSQuestion("query.example.com", ns_t_a))
+ .add_answer(new DNSARR("redirect.query.example.com", 300, {129,97,123,221}))
+ .add_answer(new DNSARR("redirect.query.example.com", 300, {129,97,123,222}))
+ .add_answer(new DNSARR("redirect.query.example.com", 300, {129,97,123,223}))
+ .add_answer(new DNSARR("redirect.query.example.com", 300, {129,97,123,224}))
+ .add_answer(new DNSCnameRR("query.example.com", 60, "redirect.query.example.com"))
+ .add_additional(new DNSTxtRR("query.example.com", 60, {"text record"}));
+ struct hostent *host = nullptr;
+ struct ares_addrttl info[8];
+ int count = 8;
+ std::vector<byte> data = pkt.data();
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(4, count);
+ EXPECT_EQ("129.97.123.221", AddressToString(&(info[0].ipaddr), 4));
+ EXPECT_EQ("129.97.123.222", AddressToString(&(info[1].ipaddr), 4));
+ EXPECT_EQ("129.97.123.223", AddressToString(&(info[2].ipaddr), 4));
+ EXPECT_EQ("129.97.123.224", AddressToString(&(info[3].ipaddr), 4));
+ EXPECT_EQ(300, info[0].ttl);
+ EXPECT_EQ(300, info[1].ttl);
+ EXPECT_EQ(300, info[2].ttl);
+ EXPECT_EQ(300, info[3].ttl);
+ ares_free_hostent(host);
+}
+
+TEST_F(LibraryTest, ParseAReplyErrors) {
+ 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", 100, {0x02, 0x03, 0x04, 0x05}));
+ std::vector<byte> data;
+
+ struct hostent *host = nullptr;
+ struct ares_addrttl info[2];
+ int count = 2;
+
+ // No question.
+ pkt.questions_.clear();
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(nullptr, host);
+ pkt.add_question(new DNSQuestion("example.com", ns_t_a));
+
+ // Question != answer
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("Axample.com", ns_t_a));
+ data = pkt.data();
+ EXPECT_EQ(ARES_ENODATA, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(nullptr, host);
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("example.com", ns_t_a));
+
+#ifdef DISABLED
+ // Not a response.
+ pkt.set_response(false);
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(nullptr, host);
+ pkt.set_response(true);
+
+ // Bad return code.
+ pkt.set_rcode(ns_r_formerr);
+ data = pkt.data();
+ EXPECT_EQ(ARES_ENODATA, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(nullptr, host);
+ pkt.set_rcode(ns_r_noerror);
+#endif
+
+ // Two questions
+ pkt.add_question(new DNSQuestion("example.com", ns_t_a));
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(nullptr, host);
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("example.com", ns_t_a));
+
+ // 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_ENODATA, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(nullptr, host);
+ pkt.answers_.clear();
+ pkt.add_answer(new DNSARR("example.com", 100, {0x02, 0x03, 0x04, 0x05}));
+
+ // No answer.
+ pkt.answers_.clear();
+ data = pkt.data();
+ EXPECT_EQ(ARES_ENODATA, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(nullptr, host);
+ pkt.add_answer(new DNSARR("example.com", 100, {0x02, 0x03, 0x04, 0x05}));
+
+ // Truncated packets.
+ data = pkt.data();
+ for (size_t len = 1; len < data.size(); len++) {
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), len,
+ &host, info, &count));
+ EXPECT_EQ(nullptr, host);
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_a_reply(data.data(), len,
+ nullptr, info, &count));
+ }
+}
+
+TEST_F(LibraryTest, ParseAReplyAllocFail) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_a))
+ .add_answer(new DNSCnameRR("example.com", 300, "c.example.com"))
+ .add_answer(new DNSARR("c.example.com", 500, {0x02, 0x03, 0x04, 0x05}));
+ std::vector<byte> data = pkt.data();
+
+ struct hostent *host = nullptr;
+ struct ares_addrttl info[2];
+ int count = 2;
+
+ for (int ii = 1; ii <= 8; ii++) {
+ ClearFails();
+ SetAllocFail(ii);
+ EXPECT_EQ(ARES_ENOMEM, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count)) << ii;
+ EXPECT_EQ(nullptr, host);
+ }
+}
+
+} // namespace test
+} // namespace ares
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 9a12378387..1314c837a6 100644
--- a/contrib/libs/c-ares/test/ares-test-parse-aaaa.cc
+++ b/contrib/libs/c-ares/test/ares-test-parse-aaaa.cc
@@ -1,192 +1,192 @@
-#include "ares-test.h"
-#include "dns-proto.h"
-
-#include <sstream>
-#include <vector>
-
-namespace ares {
-namespace test {
-
-TEST_F(LibraryTest, ParseAaaaReplyOK) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_aaaa))
- .add_answer(new DNSAaaaRR("example.com", 100,
- {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
+#include "ares-test.h"
+#include "dns-proto.h"
+
+#include <sstream>
+#include <vector>
+
+namespace ares {
+namespace test {
+
+TEST_F(LibraryTest, ParseAaaaReplyOK) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .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}));
- std::vector<byte> data = pkt.data();
- struct hostent *host = nullptr;
- struct ares_addr6ttl info[5];
- int count = 5;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_aaaa_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(1, count);
- EXPECT_EQ(100, info[0].ttl);
- EXPECT_EQ(0x01, info[0].ip6addr._S6_un._S6_u8[0]);
- EXPECT_EQ(0x02, info[0].ip6addr._S6_un._S6_u8[4]);
- ASSERT_NE(nullptr, host);
- std::stringstream ss;
- ss << HostEnt(host);
- EXPECT_EQ("{'example.com' aliases=[] addrs=[0101:0101:0202:0202:0303:0303:0404:0404]}", ss.str());
- ares_free_hostent(host);
-
- // Repeat without providing places to put the results
- count = 0;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_aaaa_reply(data.data(), data.size(),
- nullptr, info, &count));
-}
-
-TEST_F(LibraryTest, ParseAaaaReplyCname) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_aaaa))
- .add_answer(new DNSCnameRR("example.com", 50, "c.example.com"))
- .add_answer(new DNSAaaaRR("c.example.com", 100,
- {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
- 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04}));
- std::vector<byte> data = pkt.data();
- struct hostent *host = nullptr;
- struct ares_addr6ttl info[5];
- int count = 5;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_aaaa_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(1, count);
- // CNAME TTL overrides AAAA TTL.
- EXPECT_EQ(50, info[0].ttl);
- EXPECT_EQ(0x01, info[0].ip6addr._S6_un._S6_u8[0]);
- EXPECT_EQ(0x02, info[0].ip6addr._S6_un._S6_u8[4]);
- ASSERT_NE(nullptr, host);
- std::stringstream ss;
- ss << HostEnt(host);
- EXPECT_EQ("{'c.example.com' aliases=[example.com] addrs=[0101:0101:0202:0202:0303:0303:0404:0404]}", ss.str());
- ares_free_hostent(host);
-
- // Repeat without providing a hostent
- count = 5;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_aaaa_reply(data.data(), data.size(),
- nullptr, info, &count));
- EXPECT_EQ(1, count);
- EXPECT_EQ(50, info[0].ttl);
- EXPECT_EQ(0x01, info[0].ip6addr._S6_un._S6_u8[0]);
- EXPECT_EQ(0x02, info[0].ip6addr._S6_un._S6_u8[4]);
-}
-
-TEST_F(LibraryTest, ParseAaaaReplyNoData) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_aaaa));
- std::vector<byte> data = pkt.data();
- struct hostent *host = nullptr;
- struct ares_addr6ttl info[2];
- int count = 2;
- EXPECT_EQ(ARES_ENODATA, ares_parse_aaaa_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(0, count);
- EXPECT_EQ(nullptr, host);
-
- // Again but with a CNAME.
- pkt.add_answer(new DNSCnameRR("example.com", 200, "c.example.com"));
- EXPECT_EQ(ARES_ENODATA, ares_parse_aaaa_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(0, count);
- EXPECT_EQ(nullptr, host);
-}
-
-TEST_F(LibraryTest, ParseAaaaReplyErrors) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .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}));
- std::vector<byte> data;
-
- struct hostent *host = nullptr;
- struct ares_addr6ttl info[2];
- int count = 2;
-
- // No question.
- pkt.questions_.clear();
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_aaaa_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(nullptr, host);
- pkt.add_question(new DNSQuestion("example.com", ns_t_aaaa));
-
- // Question != answer
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("Axample.com", ns_t_aaaa));
- data = pkt.data();
- EXPECT_EQ(ARES_ENODATA, ares_parse_aaaa_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(nullptr, host);
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("example.com", ns_t_aaaa));
-
- // Two questions.
- pkt.add_question(new DNSQuestion("example.com", ns_t_aaaa));
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_aaaa_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(nullptr, host);
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("example.com", ns_t_aaaa));
-
- // 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_ENODATA, ares_parse_aaaa_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(nullptr, host);
- pkt.answers_.clear();
- pkt.add_answer(new DNSAaaaRR("example.com", 100,
- {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
- 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04}));
-
- // No answer.
- pkt.answers_.clear();
- data = pkt.data();
- EXPECT_EQ(ARES_ENODATA, ares_parse_aaaa_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(nullptr, host);
- pkt.add_answer(new DNSAaaaRR("example.com", 100,
- {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
- 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04}));
-
- // Truncated packets.
- data = pkt.data();
- for (size_t len = 1; len < data.size(); len++) {
- EXPECT_EQ(ARES_EBADRESP, ares_parse_aaaa_reply(data.data(), len,
- &host, info, &count));
- EXPECT_EQ(nullptr, host);
- EXPECT_EQ(ARES_EBADRESP, ares_parse_aaaa_reply(data.data(), len,
- nullptr, info, &count));
- }
-}
-
-TEST_F(LibraryTest, ParseAaaaReplyAllocFail) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_aaaa))
- .add_answer(new DNSCnameRR("example.com", 300, "c.example.com"))
- .add_answer(new DNSAaaaRR("c.example.com", 100,
- {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
- 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04}));
- std::vector<byte> data = pkt.data();
- struct hostent *host = nullptr;
- struct ares_addr6ttl info[2];
- int count = 2;
-
- for (int ii = 1; ii <= 8; ii++) {
- ClearFails();
- SetAllocFail(ii);
- EXPECT_EQ(ARES_ENOMEM, ares_parse_aaaa_reply(data.data(), data.size(),
- &host, info, &count)) << ii;
- EXPECT_EQ(nullptr, host);
- }
-}
-
-} // namespace test
-} // namespace ares
+ std::vector<byte> data = pkt.data();
+ struct hostent *host = nullptr;
+ struct ares_addr6ttl info[5];
+ int count = 5;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_aaaa_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(1, count);
+ EXPECT_EQ(100, info[0].ttl);
+ EXPECT_EQ(0x01, info[0].ip6addr._S6_un._S6_u8[0]);
+ EXPECT_EQ(0x02, info[0].ip6addr._S6_un._S6_u8[4]);
+ ASSERT_NE(nullptr, host);
+ std::stringstream ss;
+ ss << HostEnt(host);
+ EXPECT_EQ("{'example.com' aliases=[] addrs=[0101:0101:0202:0202:0303:0303:0404:0404]}", ss.str());
+ ares_free_hostent(host);
+
+ // Repeat without providing places to put the results
+ count = 0;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_aaaa_reply(data.data(), data.size(),
+ nullptr, info, &count));
+}
+
+TEST_F(LibraryTest, ParseAaaaReplyCname) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_aaaa))
+ .add_answer(new DNSCnameRR("example.com", 50, "c.example.com"))
+ .add_answer(new DNSAaaaRR("c.example.com", 100,
+ {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
+ 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04}));
+ std::vector<byte> data = pkt.data();
+ struct hostent *host = nullptr;
+ struct ares_addr6ttl info[5];
+ int count = 5;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_aaaa_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(1, count);
+ // CNAME TTL overrides AAAA TTL.
+ EXPECT_EQ(50, info[0].ttl);
+ EXPECT_EQ(0x01, info[0].ip6addr._S6_un._S6_u8[0]);
+ EXPECT_EQ(0x02, info[0].ip6addr._S6_un._S6_u8[4]);
+ ASSERT_NE(nullptr, host);
+ std::stringstream ss;
+ ss << HostEnt(host);
+ EXPECT_EQ("{'c.example.com' aliases=[example.com] addrs=[0101:0101:0202:0202:0303:0303:0404:0404]}", ss.str());
+ ares_free_hostent(host);
+
+ // Repeat without providing a hostent
+ count = 5;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_aaaa_reply(data.data(), data.size(),
+ nullptr, info, &count));
+ EXPECT_EQ(1, count);
+ EXPECT_EQ(50, info[0].ttl);
+ EXPECT_EQ(0x01, info[0].ip6addr._S6_un._S6_u8[0]);
+ EXPECT_EQ(0x02, info[0].ip6addr._S6_un._S6_u8[4]);
+}
+
+TEST_F(LibraryTest, ParseAaaaReplyNoData) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_aaaa));
+ std::vector<byte> data = pkt.data();
+ struct hostent *host = nullptr;
+ struct ares_addr6ttl info[2];
+ int count = 2;
+ EXPECT_EQ(ARES_ENODATA, ares_parse_aaaa_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(0, count);
+ EXPECT_EQ(nullptr, host);
+
+ // Again but with a CNAME.
+ pkt.add_answer(new DNSCnameRR("example.com", 200, "c.example.com"));
+ EXPECT_EQ(ARES_ENODATA, ares_parse_aaaa_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(0, count);
+ EXPECT_EQ(nullptr, host);
+}
+
+TEST_F(LibraryTest, ParseAaaaReplyErrors) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .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}));
+ std::vector<byte> data;
+
+ struct hostent *host = nullptr;
+ struct ares_addr6ttl info[2];
+ int count = 2;
+
+ // No question.
+ pkt.questions_.clear();
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_aaaa_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(nullptr, host);
+ pkt.add_question(new DNSQuestion("example.com", ns_t_aaaa));
+
+ // Question != answer
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("Axample.com", ns_t_aaaa));
+ data = pkt.data();
+ EXPECT_EQ(ARES_ENODATA, ares_parse_aaaa_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(nullptr, host);
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("example.com", ns_t_aaaa));
+
+ // Two questions.
+ pkt.add_question(new DNSQuestion("example.com", ns_t_aaaa));
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_aaaa_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(nullptr, host);
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("example.com", ns_t_aaaa));
+
+ // 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_ENODATA, ares_parse_aaaa_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(nullptr, host);
+ pkt.answers_.clear();
+ pkt.add_answer(new DNSAaaaRR("example.com", 100,
+ {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
+ 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04}));
+
+ // No answer.
+ pkt.answers_.clear();
+ data = pkt.data();
+ EXPECT_EQ(ARES_ENODATA, ares_parse_aaaa_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(nullptr, host);
+ pkt.add_answer(new DNSAaaaRR("example.com", 100,
+ {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
+ 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04}));
+
+ // Truncated packets.
+ data = pkt.data();
+ for (size_t len = 1; len < data.size(); len++) {
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_aaaa_reply(data.data(), len,
+ &host, info, &count));
+ EXPECT_EQ(nullptr, host);
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_aaaa_reply(data.data(), len,
+ nullptr, info, &count));
+ }
+}
+
+TEST_F(LibraryTest, ParseAaaaReplyAllocFail) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_aaaa))
+ .add_answer(new DNSCnameRR("example.com", 300, "c.example.com"))
+ .add_answer(new DNSAaaaRR("c.example.com", 100,
+ {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
+ 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04}));
+ std::vector<byte> data = pkt.data();
+ struct hostent *host = nullptr;
+ struct ares_addr6ttl info[2];
+ int count = 2;
+
+ for (int ii = 1; ii <= 8; ii++) {
+ ClearFails();
+ SetAllocFail(ii);
+ EXPECT_EQ(ARES_ENOMEM, ares_parse_aaaa_reply(data.data(), data.size(),
+ &host, info, &count)) << ii;
+ EXPECT_EQ(nullptr, host);
+ }
+}
+
+} // namespace test
+} // namespace ares
diff --git a/contrib/libs/c-ares/test/ares-test-parse-mx.cc b/contrib/libs/c-ares/test/ares-test-parse-mx.cc
index 56ce266f6d..37324a6d4c 100644
--- a/contrib/libs/c-ares/test/ares-test-parse-mx.cc
+++ b/contrib/libs/c-ares/test/ares-test-parse-mx.cc
@@ -1,141 +1,141 @@
-#include "ares-test.h"
-#include "dns-proto.h"
-
-#include <sstream>
-#include <vector>
-
-namespace ares {
-namespace test {
-
-TEST_F(LibraryTest, ParseMxReplyOK) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_mx))
- .add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"))
- .add_answer(new DNSMxRR("example.com", 100, 200, "mx2.example.com"));
- std::vector<byte> data = pkt.data();
-
- struct ares_mx_reply* mx = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_mx_reply(data.data(), data.size(), &mx));
- ASSERT_NE(nullptr, mx);
- EXPECT_EQ("mx1.example.com", std::string(mx->host));
- EXPECT_EQ(100, mx->priority);
-
- struct ares_mx_reply* mx2 = mx->next;
- ASSERT_NE(nullptr, mx2);
- EXPECT_EQ("mx2.example.com", std::string(mx2->host));
- EXPECT_EQ(200, mx2->priority);
- EXPECT_EQ(nullptr, mx2->next);
-
- ares_free_data(mx);
-}
-
-TEST_F(LibraryTest, ParseMxReplyMalformed) {
- 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, 0x01, // num answer RRs
- 0x00, 0x00, // num authority RRs
- 0x00, 0x00, // num additional RRs
- // Question
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x0F, // type MX
- 0x00, 0x01, // class IN
- // Answer 1
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x0F, // RR type
- 0x00, 0x01, // class IN
- 0x01, 0x02, 0x03, 0x04, // TTL
- 0x00, 0x01, // rdata length -- too short
- 0x02,
- };
-
- struct ares_mx_reply* mx = nullptr;
- EXPECT_EQ(ARES_EBADRESP, ares_parse_mx_reply(data.data(), data.size(), &mx));
- ASSERT_EQ(nullptr, mx);
-}
-
-
-TEST_F(LibraryTest, ParseMxReplyErrors) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_mx))
- .add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"));
- std::vector<byte> data;
- struct ares_mx_reply* mx = nullptr;
-
- // No question.
- pkt.questions_.clear();
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_mx_reply(data.data(), data.size(), &mx));
- EXPECT_EQ(nullptr, mx);
- pkt.add_question(new DNSQuestion("example.com", ns_t_mx));
-
-#ifdef DISABLED
- // Question != answer
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("Axample.com", ns_t_mx));
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_mx_reply(data.data(), data.size(), &mx));
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("example.com", ns_t_mx));
-#endif
-
- // Two questions.
- pkt.add_question(new DNSQuestion("example.com", ns_t_mx));
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_mx_reply(data.data(), data.size(), &mx));
- EXPECT_EQ(nullptr, mx);
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("example.com", ns_t_mx));
-
- // Wrong sort of answer.
- // TODO(drysdale): check if this should be ARES_ENODATA?
- pkt.answers_.clear();
- pkt.add_answer(new DNSSrvRR("example.abc.def.com", 180, 0, 10, 8160, "example.abc.def.com"));
- data = pkt.data();
- EXPECT_EQ(ARES_SUCCESS, ares_parse_mx_reply(data.data(), data.size(), &mx));
- EXPECT_EQ(nullptr, mx);
- pkt.answers_.clear();
- pkt.add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"));
-
- // No answer.
- pkt.answers_.clear();
- data = pkt.data();
- EXPECT_EQ(ARES_ENODATA, ares_parse_mx_reply(data.data(), data.size(), &mx));
- EXPECT_EQ(nullptr, mx);
- pkt.add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"));
-
- // Truncated packets.
- data = pkt.data();
- for (size_t len = 1; len < data.size(); len++) {
- int rc = ares_parse_mx_reply(data.data(), len, &mx);
- EXPECT_EQ(nullptr, mx);
- EXPECT_TRUE(rc == ARES_EBADRESP || rc == ARES_EBADNAME);
- }
-}
-
-TEST_F(LibraryTest, ParseMxReplyAllocFail) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_mx))
- .add_answer(new DNSCnameRR("example.com", 300, "c.example.com"))
- .add_answer(new DNSMxRR("c.example.com", 100, 100, "mx1.example.com"));
- std::vector<byte> data = pkt.data();
- struct ares_mx_reply* mx = nullptr;
-
- for (int ii = 1; ii <= 5; ii++) {
- ClearFails();
- SetAllocFail(ii);
- EXPECT_EQ(ARES_ENOMEM, ares_parse_mx_reply(data.data(), data.size(), &mx)) << ii;
- }
-}
-
-} // namespace test
-} // namespace ares
+#include "ares-test.h"
+#include "dns-proto.h"
+
+#include <sstream>
+#include <vector>
+
+namespace ares {
+namespace test {
+
+TEST_F(LibraryTest, ParseMxReplyOK) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_mx))
+ .add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"))
+ .add_answer(new DNSMxRR("example.com", 100, 200, "mx2.example.com"));
+ std::vector<byte> data = pkt.data();
+
+ struct ares_mx_reply* mx = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_mx_reply(data.data(), data.size(), &mx));
+ ASSERT_NE(nullptr, mx);
+ EXPECT_EQ("mx1.example.com", std::string(mx->host));
+ EXPECT_EQ(100, mx->priority);
+
+ struct ares_mx_reply* mx2 = mx->next;
+ ASSERT_NE(nullptr, mx2);
+ EXPECT_EQ("mx2.example.com", std::string(mx2->host));
+ EXPECT_EQ(200, mx2->priority);
+ EXPECT_EQ(nullptr, mx2->next);
+
+ ares_free_data(mx);
+}
+
+TEST_F(LibraryTest, ParseMxReplyMalformed) {
+ 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, 0x01, // num answer RRs
+ 0x00, 0x00, // num authority RRs
+ 0x00, 0x00, // num additional RRs
+ // Question
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x0F, // type MX
+ 0x00, 0x01, // class IN
+ // Answer 1
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x0F, // RR type
+ 0x00, 0x01, // class IN
+ 0x01, 0x02, 0x03, 0x04, // TTL
+ 0x00, 0x01, // rdata length -- too short
+ 0x02,
+ };
+
+ struct ares_mx_reply* mx = nullptr;
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_mx_reply(data.data(), data.size(), &mx));
+ ASSERT_EQ(nullptr, mx);
+}
+
+
+TEST_F(LibraryTest, ParseMxReplyErrors) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_mx))
+ .add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"));
+ std::vector<byte> data;
+ struct ares_mx_reply* mx = nullptr;
+
+ // No question.
+ pkt.questions_.clear();
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_mx_reply(data.data(), data.size(), &mx));
+ EXPECT_EQ(nullptr, mx);
+ pkt.add_question(new DNSQuestion("example.com", ns_t_mx));
+
+#ifdef DISABLED
+ // Question != answer
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("Axample.com", ns_t_mx));
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_mx_reply(data.data(), data.size(), &mx));
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("example.com", ns_t_mx));
+#endif
+
+ // Two questions.
+ pkt.add_question(new DNSQuestion("example.com", ns_t_mx));
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_mx_reply(data.data(), data.size(), &mx));
+ EXPECT_EQ(nullptr, mx);
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("example.com", ns_t_mx));
+
+ // Wrong sort of answer.
+ // TODO(drysdale): check if this should be ARES_ENODATA?
+ pkt.answers_.clear();
+ pkt.add_answer(new DNSSrvRR("example.abc.def.com", 180, 0, 10, 8160, "example.abc.def.com"));
+ data = pkt.data();
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_mx_reply(data.data(), data.size(), &mx));
+ EXPECT_EQ(nullptr, mx);
+ pkt.answers_.clear();
+ pkt.add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"));
+
+ // No answer.
+ pkt.answers_.clear();
+ data = pkt.data();
+ EXPECT_EQ(ARES_ENODATA, ares_parse_mx_reply(data.data(), data.size(), &mx));
+ EXPECT_EQ(nullptr, mx);
+ pkt.add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com"));
+
+ // Truncated packets.
+ data = pkt.data();
+ for (size_t len = 1; len < data.size(); len++) {
+ int rc = ares_parse_mx_reply(data.data(), len, &mx);
+ EXPECT_EQ(nullptr, mx);
+ EXPECT_TRUE(rc == ARES_EBADRESP || rc == ARES_EBADNAME);
+ }
+}
+
+TEST_F(LibraryTest, ParseMxReplyAllocFail) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_mx))
+ .add_answer(new DNSCnameRR("example.com", 300, "c.example.com"))
+ .add_answer(new DNSMxRR("c.example.com", 100, 100, "mx1.example.com"));
+ std::vector<byte> data = pkt.data();
+ struct ares_mx_reply* mx = nullptr;
+
+ for (int ii = 1; ii <= 5; ii++) {
+ ClearFails();
+ SetAllocFail(ii);
+ EXPECT_EQ(ARES_ENOMEM, ares_parse_mx_reply(data.data(), data.size(), &mx)) << ii;
+ }
+}
+
+} // namespace test
+} // namespace ares
diff --git a/contrib/libs/c-ares/test/ares-test-parse-naptr.cc b/contrib/libs/c-ares/test/ares-test-parse-naptr.cc
index 109c2a2604..3238a1923d 100644
--- a/contrib/libs/c-ares/test/ares-test-parse-naptr.cc
+++ b/contrib/libs/c-ares/test/ares-test-parse-naptr.cc
@@ -1,148 +1,148 @@
-#include "ares-test.h"
-#include "dns-proto.h"
-
-#include <sstream>
-#include <vector>
-
-namespace ares {
-namespace test {
-
-TEST_F(LibraryTest, ParseNaptrReplyOK) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_naptr))
- .add_answer(new DNSNaptrRR("example.com", 100,
- 10, 20, "SP", "service", "regexp", "replace"))
- .add_answer(new DNSNaptrRR("example.com", 0x0010,
- 11, 21, "SP", "service2", "regexp2", "replace2"));
- std::vector<byte> data = pkt.data();
-
- struct ares_naptr_reply* naptr = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
- ASSERT_NE(nullptr, naptr);
- EXPECT_EQ("SP", std::string((char*)naptr->flags));
- EXPECT_EQ("service", std::string((char*)naptr->service));
- EXPECT_EQ("regexp", std::string((char*)naptr->regexp));
- EXPECT_EQ("replace", std::string((char*)naptr->replacement));
- EXPECT_EQ(10, naptr->order);
- EXPECT_EQ(20, naptr->preference);
-
- struct ares_naptr_reply* naptr2 = naptr->next;
- ASSERT_NE(nullptr, naptr2);
- EXPECT_EQ("SP", std::string((char*)naptr2->flags));
- EXPECT_EQ("service2", std::string((char*)naptr2->service));
- EXPECT_EQ("regexp2", std::string((char*)naptr2->regexp));
- EXPECT_EQ("replace2", std::string((char*)naptr2->replacement));
- EXPECT_EQ(11, naptr2->order);
- EXPECT_EQ(21, naptr2->preference);
- EXPECT_EQ(nullptr, naptr2->next);
-
- ares_free_data(naptr);
-}
-
-TEST_F(LibraryTest, ParseNaptrReplyErrors) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_naptr))
- .add_answer(new DNSNaptrRR("example.com", 100,
- 10, 20, "SP", "service", "regexp", "replace"));
- std::vector<byte> data;
- struct ares_naptr_reply* naptr = nullptr;
-
- // No question.
- pkt.questions_.clear();
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
- pkt.add_question(new DNSQuestion("example.com", ns_t_naptr));
-
-#ifdef DISABLED
- // Question != answer
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("Axample.com", ns_t_naptr));
- data = pkt.data();
- EXPECT_EQ(ARES_ENODATA, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("example.com", ns_t_naptr));
-#endif
-
- // Two questions
- pkt.add_question(new DNSQuestion("example.com", ns_t_naptr));
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("example.com", ns_t_naptr));
-
- // 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_SUCCESS, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
- EXPECT_EQ(nullptr, naptr);
- pkt.answers_.clear();
- pkt.add_answer(new DNSNaptrRR("example.com", 100,
- 10, 20, "SP", "service", "regexp", "replace"));
-
- // No answer.
- pkt.answers_.clear();
- data = pkt.data();
- EXPECT_EQ(ARES_ENODATA, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
- pkt.add_answer(new DNSNaptrRR("example.com", 100,
- 10, 20, "SP", "service", "regexp", "replace"));
-
- // Truncated packets.
- data = pkt.data();
- for (size_t len = 1; len < data.size(); len++) {
- int rc = ares_parse_naptr_reply(data.data(), len, &naptr);
- EXPECT_TRUE(rc == ARES_EBADRESP || rc == ARES_EBADNAME);
- }
-}
-
-TEST_F(LibraryTest, ParseNaptrReplyTooShort) {
- 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, 0x01, // num answer RRs
- 0x00, 0x00, // num authority RRs
- 0x00, 0x00, // num additional RRs
- // Question
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x23, // type NAPTR
- 0x00, 0x01, // class IN
- // Answer 1
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x23, // RR type
- 0x00, 0x01, // class IN
- 0x01, 0x02, 0x03, 0x04, // TTL
- 0x00, 0x01, // rdata length
- 0x00, // Too short: expect 2 x int16 and 3 x name (min 1 byte each)
- };
- struct ares_naptr_reply* naptr = nullptr;
- EXPECT_EQ(ARES_EBADRESP, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
-}
-
-TEST_F(LibraryTest, ParseNaptrReplyAllocFail) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_naptr))
- .add_answer(new DNSNaptrRR("example.com", 100,
- 10, 20, "SP", "service", "regexp", "replace"))
- .add_answer(new DNSNaptrRR("example.com", 0x0010,
- 11, 21, "SP", "service2", "regexp2", "replace2"));
- std::vector<byte> data = pkt.data();
- struct ares_naptr_reply* naptr = nullptr;
-
- for (int ii = 1; ii <= 13; ii++) {
- ClearFails();
- SetAllocFail(ii);
- EXPECT_EQ(ARES_ENOMEM, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
- }
-}
-
-} // namespace test
-} // namespace ares
+#include "ares-test.h"
+#include "dns-proto.h"
+
+#include <sstream>
+#include <vector>
+
+namespace ares {
+namespace test {
+
+TEST_F(LibraryTest, ParseNaptrReplyOK) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_naptr))
+ .add_answer(new DNSNaptrRR("example.com", 100,
+ 10, 20, "SP", "service", "regexp", "replace"))
+ .add_answer(new DNSNaptrRR("example.com", 0x0010,
+ 11, 21, "SP", "service2", "regexp2", "replace2"));
+ std::vector<byte> data = pkt.data();
+
+ struct ares_naptr_reply* naptr = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
+ ASSERT_NE(nullptr, naptr);
+ EXPECT_EQ("SP", std::string((char*)naptr->flags));
+ EXPECT_EQ("service", std::string((char*)naptr->service));
+ EXPECT_EQ("regexp", std::string((char*)naptr->regexp));
+ EXPECT_EQ("replace", std::string((char*)naptr->replacement));
+ EXPECT_EQ(10, naptr->order);
+ EXPECT_EQ(20, naptr->preference);
+
+ struct ares_naptr_reply* naptr2 = naptr->next;
+ ASSERT_NE(nullptr, naptr2);
+ EXPECT_EQ("SP", std::string((char*)naptr2->flags));
+ EXPECT_EQ("service2", std::string((char*)naptr2->service));
+ EXPECT_EQ("regexp2", std::string((char*)naptr2->regexp));
+ EXPECT_EQ("replace2", std::string((char*)naptr2->replacement));
+ EXPECT_EQ(11, naptr2->order);
+ EXPECT_EQ(21, naptr2->preference);
+ EXPECT_EQ(nullptr, naptr2->next);
+
+ ares_free_data(naptr);
+}
+
+TEST_F(LibraryTest, ParseNaptrReplyErrors) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_naptr))
+ .add_answer(new DNSNaptrRR("example.com", 100,
+ 10, 20, "SP", "service", "regexp", "replace"));
+ std::vector<byte> data;
+ struct ares_naptr_reply* naptr = nullptr;
+
+ // No question.
+ pkt.questions_.clear();
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
+ pkt.add_question(new DNSQuestion("example.com", ns_t_naptr));
+
+#ifdef DISABLED
+ // Question != answer
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("Axample.com", ns_t_naptr));
+ data = pkt.data();
+ EXPECT_EQ(ARES_ENODATA, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("example.com", ns_t_naptr));
+#endif
+
+ // Two questions
+ pkt.add_question(new DNSQuestion("example.com", ns_t_naptr));
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("example.com", ns_t_naptr));
+
+ // 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_SUCCESS, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
+ EXPECT_EQ(nullptr, naptr);
+ pkt.answers_.clear();
+ pkt.add_answer(new DNSNaptrRR("example.com", 100,
+ 10, 20, "SP", "service", "regexp", "replace"));
+
+ // No answer.
+ pkt.answers_.clear();
+ data = pkt.data();
+ EXPECT_EQ(ARES_ENODATA, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
+ pkt.add_answer(new DNSNaptrRR("example.com", 100,
+ 10, 20, "SP", "service", "regexp", "replace"));
+
+ // Truncated packets.
+ data = pkt.data();
+ for (size_t len = 1; len < data.size(); len++) {
+ int rc = ares_parse_naptr_reply(data.data(), len, &naptr);
+ EXPECT_TRUE(rc == ARES_EBADRESP || rc == ARES_EBADNAME);
+ }
+}
+
+TEST_F(LibraryTest, ParseNaptrReplyTooShort) {
+ 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, 0x01, // num answer RRs
+ 0x00, 0x00, // num authority RRs
+ 0x00, 0x00, // num additional RRs
+ // Question
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x23, // type NAPTR
+ 0x00, 0x01, // class IN
+ // Answer 1
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x23, // RR type
+ 0x00, 0x01, // class IN
+ 0x01, 0x02, 0x03, 0x04, // TTL
+ 0x00, 0x01, // rdata length
+ 0x00, // Too short: expect 2 x int16 and 3 x name (min 1 byte each)
+ };
+ struct ares_naptr_reply* naptr = nullptr;
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
+}
+
+TEST_F(LibraryTest, ParseNaptrReplyAllocFail) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_naptr))
+ .add_answer(new DNSNaptrRR("example.com", 100,
+ 10, 20, "SP", "service", "regexp", "replace"))
+ .add_answer(new DNSNaptrRR("example.com", 0x0010,
+ 11, 21, "SP", "service2", "regexp2", "replace2"));
+ std::vector<byte> data = pkt.data();
+ struct ares_naptr_reply* naptr = nullptr;
+
+ for (int ii = 1; ii <= 13; ii++) {
+ ClearFails();
+ SetAllocFail(ii);
+ EXPECT_EQ(ARES_ENOMEM, ares_parse_naptr_reply(data.data(), data.size(), &naptr));
+ }
+}
+
+} // namespace test
+} // namespace ares
diff --git a/contrib/libs/c-ares/test/ares-test-parse-ns.cc b/contrib/libs/c-ares/test/ares-test-parse-ns.cc
index 55d031857f..cd65318969 100644
--- a/contrib/libs/c-ares/test/ares-test-parse-ns.cc
+++ b/contrib/libs/c-ares/test/ares-test-parse-ns.cc
@@ -1,119 +1,119 @@
-#include "ares-test.h"
-#include "dns-proto.h"
-
-#include <sstream>
-#include <vector>
-
-namespace ares {
-namespace test {
-
-TEST_F(LibraryTest, ParseNsReplyOK) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_ns))
- .add_answer(new DNSNsRR("example.com", 100, "ns.example.com"));
- std::vector<byte> data = pkt.data();
-
- struct hostent *host = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_ns_reply(data.data(), data.size(), &host));
- ASSERT_NE(nullptr, host);
- std::stringstream ss;
- ss << HostEnt(host);
- EXPECT_EQ("{'example.com' aliases=[ns.example.com] addrs=[]}", ss.str());
- ares_free_hostent(host);
-}
-
-TEST_F(LibraryTest, ParseNsReplyMultiple) {
- DNSPacket pkt;
- pkt.set_qid(10501).set_response().set_rd().set_ra()
- .add_question(new DNSQuestion("google.com", ns_t_ns))
- .add_answer(new DNSNsRR("google.com", 59, "ns1.google.com"))
- .add_answer(new DNSNsRR("google.com", 59, "ns2.google.com"))
- .add_answer(new DNSNsRR("google.com", 59, "ns3.google.com"))
- .add_answer(new DNSNsRR("google.com", 59, "ns4.google.com"))
- .add_additional(new DNSARR("ns4.google.com", 247, {216,239,38,10}))
- .add_additional(new DNSARR("ns2.google.com", 247, {216,239,34,10}))
- .add_additional(new DNSARR("ns1.google.com", 247, {216,239,32,10}))
- .add_additional(new DNSARR("ns3.google.com", 247, {216,239,36,10}));
- std::vector<byte> data = pkt.data();
-
- struct hostent *host = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_ns_reply(data.data(), data.size(), &host));
- ASSERT_NE(nullptr, host);
- std::stringstream ss;
- ss << HostEnt(host);
- EXPECT_EQ("{'google.com' aliases=[ns1.google.com, ns2.google.com, ns3.google.com, ns4.google.com] addrs=[]}", ss.str());
- ares_free_hostent(host);
-}
-
-TEST_F(LibraryTest, ParseNsReplyErrors) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_ns))
- .add_answer(new DNSNsRR("example.com", 100, "ns.example.com"));
- std::vector<byte> data;
- struct hostent *host = nullptr;
-
- // No question.
- pkt.questions_.clear();
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_ns_reply(data.data(), data.size(), &host));
- pkt.add_question(new DNSQuestion("example.com", ns_t_ns));
-
-#ifdef DISABLED
- // Question != answer
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("Axample.com", ns_t_ns));
- data = pkt.data();
- EXPECT_EQ(ARES_ENODATA, ares_parse_ns_reply(data.data(), data.size(), &host));
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("example.com", ns_t_ns));
-#endif
-
- // Two questions.
- pkt.add_question(new DNSQuestion("example.com", ns_t_ns));
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_ns_reply(data.data(), data.size(), &host));
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("example.com", ns_t_ns));
-
- // 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_ENODATA, ares_parse_ns_reply(data.data(), data.size(), &host));
- pkt.answers_.clear();
- pkt.add_answer(new DNSNsRR("example.com", 100, "ns.example.com"));
-
- // No answer.
- pkt.answers_.clear();
- data = pkt.data();
- EXPECT_EQ(ARES_ENODATA, ares_parse_ns_reply(data.data(), data.size(), &host));
- pkt.add_answer(new DNSNsRR("example.com", 100, "ns.example.com"));
-
- // Truncated packets.
- data = pkt.data();
- for (size_t len = 1; len < data.size(); len++) {
- EXPECT_EQ(ARES_EBADRESP, ares_parse_ns_reply(data.data(), len, &host));
- }
-}
-
-TEST_F(LibraryTest, ParseNsReplyAllocFail) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_ns))
- .add_answer(new DNSCnameRR("example.com", 300, "c.example.com"))
- .add_answer(new DNSNsRR("c.example.com", 100, "ns.example.com"));
- std::vector<byte> data = pkt.data();
- struct hostent *host = nullptr;
-
- for (int ii = 1; ii <= 8; ii++) {
- ClearFails();
- SetAllocFail(ii);
- EXPECT_EQ(ARES_ENOMEM, ares_parse_ns_reply(data.data(), data.size(), &host)) << ii;
- }
-}
-
-
-} // namespace test
-} // namespace ares
+#include "ares-test.h"
+#include "dns-proto.h"
+
+#include <sstream>
+#include <vector>
+
+namespace ares {
+namespace test {
+
+TEST_F(LibraryTest, ParseNsReplyOK) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_ns))
+ .add_answer(new DNSNsRR("example.com", 100, "ns.example.com"));
+ std::vector<byte> data = pkt.data();
+
+ struct hostent *host = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_ns_reply(data.data(), data.size(), &host));
+ ASSERT_NE(nullptr, host);
+ std::stringstream ss;
+ ss << HostEnt(host);
+ EXPECT_EQ("{'example.com' aliases=[ns.example.com] addrs=[]}", ss.str());
+ ares_free_hostent(host);
+}
+
+TEST_F(LibraryTest, ParseNsReplyMultiple) {
+ DNSPacket pkt;
+ pkt.set_qid(10501).set_response().set_rd().set_ra()
+ .add_question(new DNSQuestion("google.com", ns_t_ns))
+ .add_answer(new DNSNsRR("google.com", 59, "ns1.google.com"))
+ .add_answer(new DNSNsRR("google.com", 59, "ns2.google.com"))
+ .add_answer(new DNSNsRR("google.com", 59, "ns3.google.com"))
+ .add_answer(new DNSNsRR("google.com", 59, "ns4.google.com"))
+ .add_additional(new DNSARR("ns4.google.com", 247, {216,239,38,10}))
+ .add_additional(new DNSARR("ns2.google.com", 247, {216,239,34,10}))
+ .add_additional(new DNSARR("ns1.google.com", 247, {216,239,32,10}))
+ .add_additional(new DNSARR("ns3.google.com", 247, {216,239,36,10}));
+ std::vector<byte> data = pkt.data();
+
+ struct hostent *host = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_ns_reply(data.data(), data.size(), &host));
+ ASSERT_NE(nullptr, host);
+ std::stringstream ss;
+ ss << HostEnt(host);
+ EXPECT_EQ("{'google.com' aliases=[ns1.google.com, ns2.google.com, ns3.google.com, ns4.google.com] addrs=[]}", ss.str());
+ ares_free_hostent(host);
+}
+
+TEST_F(LibraryTest, ParseNsReplyErrors) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_ns))
+ .add_answer(new DNSNsRR("example.com", 100, "ns.example.com"));
+ std::vector<byte> data;
+ struct hostent *host = nullptr;
+
+ // No question.
+ pkt.questions_.clear();
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_ns_reply(data.data(), data.size(), &host));
+ pkt.add_question(new DNSQuestion("example.com", ns_t_ns));
+
+#ifdef DISABLED
+ // Question != answer
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("Axample.com", ns_t_ns));
+ data = pkt.data();
+ EXPECT_EQ(ARES_ENODATA, ares_parse_ns_reply(data.data(), data.size(), &host));
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("example.com", ns_t_ns));
+#endif
+
+ // Two questions.
+ pkt.add_question(new DNSQuestion("example.com", ns_t_ns));
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_ns_reply(data.data(), data.size(), &host));
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("example.com", ns_t_ns));
+
+ // 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_ENODATA, ares_parse_ns_reply(data.data(), data.size(), &host));
+ pkt.answers_.clear();
+ pkt.add_answer(new DNSNsRR("example.com", 100, "ns.example.com"));
+
+ // No answer.
+ pkt.answers_.clear();
+ data = pkt.data();
+ EXPECT_EQ(ARES_ENODATA, ares_parse_ns_reply(data.data(), data.size(), &host));
+ pkt.add_answer(new DNSNsRR("example.com", 100, "ns.example.com"));
+
+ // Truncated packets.
+ data = pkt.data();
+ for (size_t len = 1; len < data.size(); len++) {
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_ns_reply(data.data(), len, &host));
+ }
+}
+
+TEST_F(LibraryTest, ParseNsReplyAllocFail) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_ns))
+ .add_answer(new DNSCnameRR("example.com", 300, "c.example.com"))
+ .add_answer(new DNSNsRR("c.example.com", 100, "ns.example.com"));
+ std::vector<byte> data = pkt.data();
+ struct hostent *host = nullptr;
+
+ for (int ii = 1; ii <= 8; ii++) {
+ ClearFails();
+ SetAllocFail(ii);
+ EXPECT_EQ(ARES_ENOMEM, ares_parse_ns_reply(data.data(), data.size(), &host)) << ii;
+ }
+}
+
+
+} // namespace test
+} // namespace ares
diff --git a/contrib/libs/c-ares/test/ares-test-parse-ptr.cc b/contrib/libs/c-ares/test/ares-test-parse-ptr.cc
index 7b1a86bac0..75f74c16f7 100644
--- a/contrib/libs/c-ares/test/ares-test-parse-ptr.cc
+++ b/contrib/libs/c-ares/test/ares-test-parse-ptr.cc
@@ -1,249 +1,249 @@
-#include "ares-test.h"
-#include "dns-proto.h"
-
-#include <sstream>
-#include <vector>
-
-namespace ares {
-namespace test {
-
-TEST_F(LibraryTest, ParsePtrReplyOK) {
- byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other.com"));
- std::vector<byte> data = pkt.data();
-
- struct hostent *host = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_ptr_reply(data.data(), data.size(),
- addrv4, sizeof(addrv4), AF_INET, &host, NULL));
- ASSERT_NE(nullptr, host);
- std::stringstream ss;
- ss << HostEnt(host);
- EXPECT_EQ("{'other.com' aliases=[other.com] addrs=[16.32.48.64]}", ss.str());
- ares_free_hostent(host);
-}
-
-TEST_F(LibraryTest, ParsePtrReplyCname) {
- byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr))
- .add_answer(new DNSCnameRR("64.48.32.16.in-addr.arpa", 50, "64.48.32.8.in-addr.arpa"))
- .add_answer(new DNSPtrRR("64.48.32.8.in-addr.arpa", 100, "other.com"));
- std::vector<byte> data = pkt.data();
-
- struct hostent *host = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_ptr_reply(data.data(), data.size(),
- addrv4, sizeof(addrv4), AF_INET, &host, NULL));
- ASSERT_NE(nullptr, host);
- std::stringstream ss;
- ss << HostEnt(host);
- EXPECT_EQ("{'other.com' aliases=[other.com] addrs=[16.32.48.64]}", ss.str());
- ares_free_hostent(host);
-}
-
-
-struct DNSMalformedCnameRR : public DNSCnameRR {
- DNSMalformedCnameRR(const std::string& name, int ttl, const std::string& other)
- : DNSCnameRR(name, ttl, other) {}
- std::vector<byte> data() const {
- std::vector<byte> data = DNSRR::data();
- std::vector<byte> encname = EncodeString(other_);
- encname[0] = encname[0] + 63; // invalid label length
- int len = encname.size();
- PushInt16(&data, len);
- data.insert(data.end(), encname.begin(), encname.end());
- return data;
- }
-};
-
-TEST_F(LibraryTest, ParsePtrReplyMalformedCname) {
- byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr))
- .add_answer(new DNSMalformedCnameRR("64.48.32.16.in-addr.arpa", 50, "64.48.32.8.in-addr.arpa"))
- .add_answer(new DNSPtrRR("64.48.32.8.in-addr.arpa", 100, "other.com"));
- std::vector<byte> data = pkt.data();
-
- struct hostent *host = nullptr;
- EXPECT_EQ(ARES_EBADRESP, ares_parse_ptr_reply(data.data(), data.size(),
- addrv4, sizeof(addrv4), AF_INET, &host, NULL));
- ASSERT_EQ(nullptr, host);
-}
-
-TEST_F(LibraryTest, ParseManyPtrReply) {
- byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "main.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other1.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other2.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other3.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other4.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other5.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other6.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other7.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other8.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other9.com"));
- std::vector<byte> data = pkt.data();
-
- struct hostent *host = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_ptr_reply(data.data(), data.size(),
- addrv4, sizeof(addrv4), AF_INET, &host, NULL));
- ASSERT_NE(nullptr, host);
- ares_free_hostent(host);
-}
-
-TEST_F(LibraryTest, ParsePtrReplyAdditional) {
- byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 55, "other.com"))
- .add_auth(new DNSNsRR("16.in-addr.arpa", 234, "ns1.other.com"))
- .add_auth(new DNSNsRR("16.in-addr.arpa", 234, "bb.ns2.other.com"))
- .add_auth(new DNSNsRR("16.in-addr.arpa", 234, "ns3.other.com"))
- .add_additional(new DNSARR("ns1.other.com", 229, {10,20,30,41}))
- .add_additional(new DNSARR("bb.ns2.other.com", 229, {10,20,30,42}))
- .add_additional(new DNSARR("ns3.other.com", 229, {10,20,30,43}));
- std::vector<byte> data = pkt.data();
-
- struct hostent *host = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_ptr_reply(data.data(), data.size(),
- addrv4, sizeof(addrv4), AF_INET, &host, NULL));
- ASSERT_NE(nullptr, host);
- std::stringstream ss;
- ss << HostEnt(host);
- EXPECT_EQ("{'other.com' aliases=[other.com] addrs=[16.32.48.64]}", ss.str());
- ares_free_hostent(host);
-}
-
-TEST_F(LibraryTest, ParsePtrReplyErrors) {
- byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other.com"));
- std::vector<byte> data;
- struct hostent *host = nullptr;
-
- // No question.
- pkt.questions_.clear();
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_ptr_reply(data.data(), data.size(),
- addrv4, sizeof(addrv4), AF_INET, &host, NULL));
- pkt.add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr));
-
- // Question != answer
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("99.48.32.16.in-addr.arpa", ns_t_ptr));
- data = pkt.data();
- EXPECT_EQ(ARES_ENODATA, ares_parse_ptr_reply(data.data(), data.size(),
- addrv4, sizeof(addrv4), AF_INET, &host, NULL));
- EXPECT_EQ(nullptr, host);
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr));
-
- // Two questions.
- pkt.add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr));
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_ptr_reply(data.data(), data.size(),
- addrv4, sizeof(addrv4), AF_INET, &host, NULL));
- EXPECT_EQ(nullptr, host);
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr));
-
- // 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_ENODATA, ares_parse_ptr_reply(data.data(), data.size(),
- addrv4, sizeof(addrv4), AF_INET, &host, NULL));
- EXPECT_EQ(nullptr, host);
- pkt.answers_.clear();
- pkt.add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other.com"));
-
- // No answer.
- pkt.answers_.clear();
- data = pkt.data();
- EXPECT_EQ(ARES_ENODATA, ares_parse_ptr_reply(data.data(), data.size(),
- addrv4, sizeof(addrv4), AF_INET, &host, NULL));
- EXPECT_EQ(nullptr, host);
- pkt.add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other.com"));
-
- // Truncated packets.
- data = pkt.data();
- for (size_t len = 1; len < data.size(); len++) {
- EXPECT_EQ(ARES_EBADRESP, ares_parse_ptr_reply(data.data(), len,
- addrv4, sizeof(addrv4), AF_INET, &host, NULL));
- EXPECT_EQ(nullptr, host);
- }
-
- // Truncated packets with CNAME.
- pkt.add_answer(new DNSCnameRR("64.48.32.16.in-addr.arpa", 50, "64.48.32.8.in-addr.arpa"));
- data = pkt.data();
- for (size_t len = 1; len < data.size(); len++) {
- EXPECT_EQ(ARES_EBADRESP, ares_parse_ptr_reply(data.data(), len,
- addrv4, sizeof(addrv4), AF_INET, &host, NULL));
- EXPECT_EQ(nullptr, host);
- }
-}
-
-TEST_F(LibraryTest, ParsePtrReplyAllocFailSome) {
- byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "main.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other1.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other2.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other3.com"));
- std::vector<byte> data = pkt.data();
- struct hostent *host = nullptr;
-
- for (int ii = 1; ii <= 18; ii++) {
- ClearFails();
- SetAllocFail(ii);
- EXPECT_EQ(ARES_ENOMEM, ares_parse_ptr_reply(data.data(), data.size(),
- addrv4, sizeof(addrv4), AF_INET, &host, NULL)) << ii;
- }
-}
-
-TEST_F(LibraryTest, ParsePtrReplyAllocFailMany) {
- byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "main.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other1.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other2.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other3.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other4.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other5.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other6.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other7.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other8.com"))
- .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other9.com"));
- std::vector<byte> data = pkt.data();
- struct hostent *host = nullptr;
-
- for (int ii = 1; ii <= 63; ii++) {
- ClearFails();
- SetAllocFail(ii);
- int rc = ares_parse_ptr_reply(data.data(), data.size(),
- addrv4, sizeof(addrv4), AF_INET, &host, NULL);
- if (rc != ARES_ENOMEM) {
- EXPECT_EQ(ARES_SUCCESS, rc);
- ares_free_hostent(host);
- host = nullptr;
- }
- }
-}
-
-
-} // namespace test
-} // namespace ares
+#include "ares-test.h"
+#include "dns-proto.h"
+
+#include <sstream>
+#include <vector>
+
+namespace ares {
+namespace test {
+
+TEST_F(LibraryTest, ParsePtrReplyOK) {
+ byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other.com"));
+ std::vector<byte> data = pkt.data();
+
+ struct hostent *host = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_ptr_reply(data.data(), data.size(),
+ addrv4, sizeof(addrv4), AF_INET, &host, NULL));
+ ASSERT_NE(nullptr, host);
+ std::stringstream ss;
+ ss << HostEnt(host);
+ EXPECT_EQ("{'other.com' aliases=[other.com] addrs=[16.32.48.64]}", ss.str());
+ ares_free_hostent(host);
+}
+
+TEST_F(LibraryTest, ParsePtrReplyCname) {
+ byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr))
+ .add_answer(new DNSCnameRR("64.48.32.16.in-addr.arpa", 50, "64.48.32.8.in-addr.arpa"))
+ .add_answer(new DNSPtrRR("64.48.32.8.in-addr.arpa", 100, "other.com"));
+ std::vector<byte> data = pkt.data();
+
+ struct hostent *host = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_ptr_reply(data.data(), data.size(),
+ addrv4, sizeof(addrv4), AF_INET, &host, NULL));
+ ASSERT_NE(nullptr, host);
+ std::stringstream ss;
+ ss << HostEnt(host);
+ EXPECT_EQ("{'other.com' aliases=[other.com] addrs=[16.32.48.64]}", ss.str());
+ ares_free_hostent(host);
+}
+
+
+struct DNSMalformedCnameRR : public DNSCnameRR {
+ DNSMalformedCnameRR(const std::string& name, int ttl, const std::string& other)
+ : DNSCnameRR(name, ttl, other) {}
+ std::vector<byte> data() const {
+ std::vector<byte> data = DNSRR::data();
+ std::vector<byte> encname = EncodeString(other_);
+ encname[0] = encname[0] + 63; // invalid label length
+ int len = encname.size();
+ PushInt16(&data, len);
+ data.insert(data.end(), encname.begin(), encname.end());
+ return data;
+ }
+};
+
+TEST_F(LibraryTest, ParsePtrReplyMalformedCname) {
+ byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr))
+ .add_answer(new DNSMalformedCnameRR("64.48.32.16.in-addr.arpa", 50, "64.48.32.8.in-addr.arpa"))
+ .add_answer(new DNSPtrRR("64.48.32.8.in-addr.arpa", 100, "other.com"));
+ std::vector<byte> data = pkt.data();
+
+ struct hostent *host = nullptr;
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_ptr_reply(data.data(), data.size(),
+ addrv4, sizeof(addrv4), AF_INET, &host, NULL));
+ ASSERT_EQ(nullptr, host);
+}
+
+TEST_F(LibraryTest, ParseManyPtrReply) {
+ byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "main.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other1.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other2.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other3.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other4.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other5.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other6.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other7.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other8.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other9.com"));
+ std::vector<byte> data = pkt.data();
+
+ struct hostent *host = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_ptr_reply(data.data(), data.size(),
+ addrv4, sizeof(addrv4), AF_INET, &host, NULL));
+ ASSERT_NE(nullptr, host);
+ ares_free_hostent(host);
+}
+
+TEST_F(LibraryTest, ParsePtrReplyAdditional) {
+ byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 55, "other.com"))
+ .add_auth(new DNSNsRR("16.in-addr.arpa", 234, "ns1.other.com"))
+ .add_auth(new DNSNsRR("16.in-addr.arpa", 234, "bb.ns2.other.com"))
+ .add_auth(new DNSNsRR("16.in-addr.arpa", 234, "ns3.other.com"))
+ .add_additional(new DNSARR("ns1.other.com", 229, {10,20,30,41}))
+ .add_additional(new DNSARR("bb.ns2.other.com", 229, {10,20,30,42}))
+ .add_additional(new DNSARR("ns3.other.com", 229, {10,20,30,43}));
+ std::vector<byte> data = pkt.data();
+
+ struct hostent *host = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_ptr_reply(data.data(), data.size(),
+ addrv4, sizeof(addrv4), AF_INET, &host, NULL));
+ ASSERT_NE(nullptr, host);
+ std::stringstream ss;
+ ss << HostEnt(host);
+ EXPECT_EQ("{'other.com' aliases=[other.com] addrs=[16.32.48.64]}", ss.str());
+ ares_free_hostent(host);
+}
+
+TEST_F(LibraryTest, ParsePtrReplyErrors) {
+ byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other.com"));
+ std::vector<byte> data;
+ struct hostent *host = nullptr;
+
+ // No question.
+ pkt.questions_.clear();
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_ptr_reply(data.data(), data.size(),
+ addrv4, sizeof(addrv4), AF_INET, &host, NULL));
+ pkt.add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr));
+
+ // Question != answer
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("99.48.32.16.in-addr.arpa", ns_t_ptr));
+ data = pkt.data();
+ EXPECT_EQ(ARES_ENODATA, ares_parse_ptr_reply(data.data(), data.size(),
+ addrv4, sizeof(addrv4), AF_INET, &host, NULL));
+ EXPECT_EQ(nullptr, host);
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr));
+
+ // Two questions.
+ pkt.add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr));
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_ptr_reply(data.data(), data.size(),
+ addrv4, sizeof(addrv4), AF_INET, &host, NULL));
+ EXPECT_EQ(nullptr, host);
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr));
+
+ // 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_ENODATA, ares_parse_ptr_reply(data.data(), data.size(),
+ addrv4, sizeof(addrv4), AF_INET, &host, NULL));
+ EXPECT_EQ(nullptr, host);
+ pkt.answers_.clear();
+ pkt.add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other.com"));
+
+ // No answer.
+ pkt.answers_.clear();
+ data = pkt.data();
+ EXPECT_EQ(ARES_ENODATA, ares_parse_ptr_reply(data.data(), data.size(),
+ addrv4, sizeof(addrv4), AF_INET, &host, NULL));
+ EXPECT_EQ(nullptr, host);
+ pkt.add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other.com"));
+
+ // Truncated packets.
+ data = pkt.data();
+ for (size_t len = 1; len < data.size(); len++) {
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_ptr_reply(data.data(), len,
+ addrv4, sizeof(addrv4), AF_INET, &host, NULL));
+ EXPECT_EQ(nullptr, host);
+ }
+
+ // Truncated packets with CNAME.
+ pkt.add_answer(new DNSCnameRR("64.48.32.16.in-addr.arpa", 50, "64.48.32.8.in-addr.arpa"));
+ data = pkt.data();
+ for (size_t len = 1; len < data.size(); len++) {
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_ptr_reply(data.data(), len,
+ addrv4, sizeof(addrv4), AF_INET, &host, NULL));
+ EXPECT_EQ(nullptr, host);
+ }
+}
+
+TEST_F(LibraryTest, ParsePtrReplyAllocFailSome) {
+ byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "main.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other1.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other2.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other3.com"));
+ std::vector<byte> data = pkt.data();
+ struct hostent *host = nullptr;
+
+ for (int ii = 1; ii <= 18; ii++) {
+ ClearFails();
+ SetAllocFail(ii);
+ EXPECT_EQ(ARES_ENOMEM, ares_parse_ptr_reply(data.data(), data.size(),
+ addrv4, sizeof(addrv4), AF_INET, &host, NULL)) << ii;
+ }
+}
+
+TEST_F(LibraryTest, ParsePtrReplyAllocFailMany) {
+ byte addrv4[4] = {0x10, 0x20, 0x30, 0x40};
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "main.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other1.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other2.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other3.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other4.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other5.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other6.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other7.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other8.com"))
+ .add_answer(new DNSPtrRR("64.48.32.16.in-addr.arpa", 100, "other9.com"));
+ std::vector<byte> data = pkt.data();
+ struct hostent *host = nullptr;
+
+ for (int ii = 1; ii <= 63; ii++) {
+ ClearFails();
+ SetAllocFail(ii);
+ int rc = ares_parse_ptr_reply(data.data(), data.size(),
+ addrv4, sizeof(addrv4), AF_INET, &host, NULL);
+ if (rc != ARES_ENOMEM) {
+ EXPECT_EQ(ARES_SUCCESS, rc);
+ ares_free_hostent(host);
+ host = nullptr;
+ }
+ }
+}
+
+
+} // 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 e6f5dcdab7..c0ffaaed50 100644
--- a/contrib/libs/c-ares/test/ares-test-parse-soa.cc
+++ b/contrib/libs/c-ares/test/ares-test-parse-soa.cc
@@ -1,108 +1,108 @@
-#include "ares-test.h"
-#include "dns-proto.h"
-
-#include <sstream>
-#include <vector>
-
-namespace ares {
-namespace test {
-
-TEST_F(LibraryTest, ParseSoaReplyOK) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_soa))
- .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, ParseSoaReplyErrors) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_soa))
- .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_soa));
-
-#ifdef DISABLED
- // Question != answer
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("Axample.com", ns_t_soa));
- data = pkt.data();
+#include "ares-test.h"
+#include "dns-proto.h"
+
+#include <sstream>
+#include <vector>
+
+namespace ares {
+namespace test {
+
+TEST_F(LibraryTest, ParseSoaReplyOK) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_soa))
+ .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, ParseSoaReplyErrors) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_soa))
+ .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.questions_.clear();
- pkt.add_question(new DNSQuestion("example.com", ns_t_soa));
-#endif
-
- // Two questions
- pkt.add_question(new DNSQuestion("example.com", ns_t_soa));
- 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_soa));
-
- // 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, ParseSoaReplyAllocFail) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_soa))
- .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
+ pkt.add_question(new DNSQuestion("example.com", ns_t_soa));
+
+#ifdef DISABLED
+ // Question != answer
+ 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));
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("example.com", ns_t_soa));
+#endif
+
+ // Two questions
+ pkt.add_question(new DNSQuestion("example.com", ns_t_soa));
+ 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_soa));
+
+ // 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, ParseSoaReplyAllocFail) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_soa))
+ .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-srv.cc b/contrib/libs/c-ares/test/ares-test-parse-srv.cc
index d3e3183d03..cc651d6d4e 100644
--- a/contrib/libs/c-ares/test/ares-test-parse-srv.cc
+++ b/contrib/libs/c-ares/test/ares-test-parse-srv.cc
@@ -1,288 +1,288 @@
-#include "ares-test.h"
-#include "dns-proto.h"
-
-#include <sstream>
-#include <vector>
-
-namespace ares {
-namespace test {
-
-TEST_F(LibraryTest, ParseSrvReplyOK) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_srv))
- .add_answer(new DNSSrvRR("example.com", 100, 10, 20, 30, "srv.example.com"))
- .add_answer(new DNSSrvRR("example.com", 100, 11, 21, 31, "srv2.example.com"));
- std::vector<byte> data = pkt.data();
-
- struct ares_srv_reply* srv = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_srv_reply(data.data(), data.size(), &srv));
- ASSERT_NE(nullptr, srv);
-
- EXPECT_EQ("srv.example.com", std::string(srv->host));
- EXPECT_EQ(10, srv->priority);
- EXPECT_EQ(20, srv->weight);
- EXPECT_EQ(30, srv->port);
-
- struct ares_srv_reply* srv2 = srv->next;
- ASSERT_NE(nullptr, srv2);
- EXPECT_EQ("srv2.example.com", std::string(srv2->host));
- EXPECT_EQ(11, srv2->priority);
- EXPECT_EQ(21, srv2->weight);
- EXPECT_EQ(31, srv2->port);
- EXPECT_EQ(nullptr, srv2->next);
-
- ares_free_data(srv);
-}
-
-TEST_F(LibraryTest, ParseSrvReplySingle) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.abc.def.com", ns_t_srv))
- .add_answer(new DNSSrvRR("example.abc.def.com", 180, 0, 10, 8160, "example.abc.def.com"))
- .add_auth(new DNSNsRR("abc.def.com", 44, "else1.where.com"))
- .add_auth(new DNSNsRR("abc.def.com", 44, "else2.where.com"))
- .add_auth(new DNSNsRR("abc.def.com", 44, "else3.where.com"))
- .add_auth(new DNSNsRR("abc.def.com", 44, "else4.where.com"))
- .add_auth(new DNSNsRR("abc.def.com", 44, "else5.where.com"))
- .add_additional(new DNSARR("else2.where.com", 42, {172,19,0,1}))
- .add_additional(new DNSARR("else5.where.com", 42, {172,19,0,2}));
- std::vector<byte> data = pkt.data();
-
- struct ares_srv_reply* srv = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_srv_reply(data.data(), data.size(), &srv));
- ASSERT_NE(nullptr, srv);
-
- EXPECT_EQ("example.abc.def.com", std::string(srv->host));
- EXPECT_EQ(0, srv->priority);
- EXPECT_EQ(10, srv->weight);
- EXPECT_EQ(8160, srv->port);
- EXPECT_EQ(nullptr, srv->next);
-
- ares_free_data(srv);
-}
-
-TEST_F(LibraryTest, ParseSrvReplyMalformed) {
- 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, 0x01, // num answer RRs
- 0x00, 0x00, // num authority RRs
- 0x00, 0x00, // num additional RRs
- // Question
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x21, // type SRV
- 0x00, 0x01, // class IN
- // Answer 1
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x21, // RR type
- 0x00, 0x01, // class IN
- 0x01, 0x02, 0x03, 0x04, // TTL
- 0x00, 0x04, // rdata length -- too short
- 0x02, 0x03, 0x04, 0x05,
- };
-
- struct ares_srv_reply* srv = nullptr;
- EXPECT_EQ(ARES_EBADRESP, ares_parse_srv_reply(data.data(), data.size(), &srv));
- ASSERT_EQ(nullptr, srv);
-}
-
-TEST_F(LibraryTest, ParseSrvReplyMultiple) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_ra().set_rd()
- .add_question(new DNSQuestion("srv.example.com", ns_t_srv))
- .add_answer(new DNSSrvRR("srv.example.com", 300, 0, 5, 6789, "a1.srv.example.com"))
- .add_answer(new DNSSrvRR("srv.example.com", 300, 0, 5, 4567, "a2.srv.example.com"))
- .add_answer(new DNSSrvRR("srv.example.com", 300, 0, 5, 5678, "a3.srv.example.com"))
- .add_auth(new DNSNsRR("example.com", 300, "ns1.example.com"))
- .add_auth(new DNSNsRR("example.com", 300, "ns2.example.com"))
- .add_auth(new DNSNsRR("example.com", 300, "ns3.example.com"))
- .add_additional(new DNSARR("a1.srv.example.com", 300, {172,19,1,1}))
- .add_additional(new DNSARR("a2.srv.example.com", 300, {172,19,1,2}))
- .add_additional(new DNSARR("a3.srv.example.com", 300, {172,19,1,3}))
- .add_additional(new DNSARR("n1.example.com", 300, {172,19,0,1}))
- .add_additional(new DNSARR("n2.example.com", 300, {172,19,0,2}))
- .add_additional(new DNSARR("n3.example.com", 300, {172,19,0,3}));
- std::vector<byte> data = pkt.data();
-
- struct ares_srv_reply* srv0 = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_srv_reply(data.data(), data.size(), &srv0));
- ASSERT_NE(nullptr, srv0);
- struct ares_srv_reply* srv = srv0;
-
- EXPECT_EQ("a1.srv.example.com", std::string(srv->host));
- EXPECT_EQ(0, srv->priority);
- EXPECT_EQ(5, srv->weight);
- EXPECT_EQ(6789, srv->port);
- EXPECT_NE(nullptr, srv->next);
- srv = srv->next;
-
- EXPECT_EQ("a2.srv.example.com", std::string(srv->host));
- EXPECT_EQ(0, srv->priority);
- EXPECT_EQ(5, srv->weight);
- EXPECT_EQ(4567, srv->port);
- EXPECT_NE(nullptr, srv->next);
- srv = srv->next;
-
- EXPECT_EQ("a3.srv.example.com", std::string(srv->host));
- EXPECT_EQ(0, srv->priority);
- EXPECT_EQ(5, srv->weight);
- EXPECT_EQ(5678, srv->port);
- EXPECT_EQ(nullptr, srv->next);
-
- ares_free_data(srv0);
-}
-
-TEST_F(LibraryTest, ParseSrvReplyCname) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.abc.def.com", ns_t_srv))
- .add_answer(new DNSCnameRR("example.abc.def.com", 300, "cname.abc.def.com"))
- .add_answer(new DNSSrvRR("cname.abc.def.com", 300, 0, 10, 1234, "srv.abc.def.com"))
- .add_auth(new DNSNsRR("abc.def.com", 44, "else1.where.com"))
- .add_auth(new DNSNsRR("abc.def.com", 44, "else2.where.com"))
- .add_auth(new DNSNsRR("abc.def.com", 44, "else3.where.com"))
- .add_additional(new DNSARR("example.abc.def.com", 300, {172,19,0,1}))
- .add_additional(new DNSARR("else1.where.com", 42, {172,19,0,1}))
- .add_additional(new DNSARR("else2.where.com", 42, {172,19,0,2}))
- .add_additional(new DNSARR("else3.where.com", 42, {172,19,0,3}));
- std::vector<byte> data = pkt.data();
-
- struct ares_srv_reply* srv = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_srv_reply(data.data(), data.size(), &srv));
- ASSERT_NE(nullptr, srv);
-
- EXPECT_EQ("srv.abc.def.com", std::string(srv->host));
- EXPECT_EQ(0, srv->priority);
- EXPECT_EQ(10, srv->weight);
- EXPECT_EQ(1234, srv->port);
- EXPECT_EQ(nullptr, srv->next);
-
- ares_free_data(srv);
-}
-
-TEST_F(LibraryTest, ParseSrvReplyCnameMultiple) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_ra().set_rd()
- .add_question(new DNSQuestion("query.example.com", ns_t_srv))
- .add_answer(new DNSCnameRR("query.example.com", 300, "srv.example.com"))
- .add_answer(new DNSSrvRR("srv.example.com", 300, 0, 5, 6789, "a1.srv.example.com"))
- .add_answer(new DNSSrvRR("srv.example.com", 300, 0, 5, 4567, "a2.srv.example.com"))
- .add_answer(new DNSSrvRR("srv.example.com", 300, 0, 5, 5678, "a3.srv.example.com"))
- .add_auth(new DNSNsRR("example.com", 300, "ns1.example.com"))
- .add_auth(new DNSNsRR("example.com", 300, "ns2.example.com"))
- .add_auth(new DNSNsRR("example.com", 300, "ns3.example.com"))
- .add_additional(new DNSARR("a1.srv.example.com", 300, {172,19,1,1}))
- .add_additional(new DNSARR("a2.srv.example.com", 300, {172,19,1,2}))
- .add_additional(new DNSARR("a3.srv.example.com", 300, {172,19,1,3}))
- .add_additional(new DNSARR("n1.example.com", 300, {172,19,0,1}))
- .add_additional(new DNSARR("n2.example.com", 300, {172,19,0,2}))
- .add_additional(new DNSARR("n3.example.com", 300, {172,19,0,3}));
- std::vector<byte> data = pkt.data();
-
- struct ares_srv_reply* srv0 = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_srv_reply(data.data(), data.size(), &srv0));
- ASSERT_NE(nullptr, srv0);
- struct ares_srv_reply* srv = srv0;
-
- EXPECT_EQ("a1.srv.example.com", std::string(srv->host));
- EXPECT_EQ(0, srv->priority);
- EXPECT_EQ(5, srv->weight);
- EXPECT_EQ(6789, srv->port);
- EXPECT_NE(nullptr, srv->next);
- srv = srv->next;
-
- EXPECT_EQ("a2.srv.example.com", std::string(srv->host));
- EXPECT_EQ(0, srv->priority);
- EXPECT_EQ(5, srv->weight);
- EXPECT_EQ(4567, srv->port);
- EXPECT_NE(nullptr, srv->next);
- srv = srv->next;
-
- EXPECT_EQ("a3.srv.example.com", std::string(srv->host));
- EXPECT_EQ(0, srv->priority);
- EXPECT_EQ(5, srv->weight);
- EXPECT_EQ(5678, srv->port);
- EXPECT_EQ(nullptr, srv->next);
-
- ares_free_data(srv0);
-}
-
-TEST_F(LibraryTest, ParseSrvReplyErrors) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.abc.def.com", ns_t_srv))
- .add_answer(new DNSSrvRR("example.abc.def.com", 180, 0, 10, 8160, "example.abc.def.com"));
- std::vector<byte> data;
- struct ares_srv_reply* srv = nullptr;
-
- // No question.
- pkt.questions_.clear();
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_srv_reply(data.data(), data.size(), &srv));
- pkt.add_question(new DNSQuestion("example.abc.def.com", ns_t_srv));
-
-#ifdef DISABLED
- // Question != answer
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("Axample.com", ns_t_srv));
- data = pkt.data();
- EXPECT_EQ(ARES_ENODATA, ares_parse_srv_reply(data.data(), data.size(), &srv));
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("example.com", ns_t_srv));
-#endif
-
- // Two questions.
- pkt.add_question(new DNSQuestion("example.abc.def.com", ns_t_srv));
- data = pkt.data();
- EXPECT_EQ(ARES_EBADRESP, ares_parse_srv_reply(data.data(), data.size(), &srv));
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr));
-
- // 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_SUCCESS, ares_parse_srv_reply(data.data(), data.size(), &srv));
- EXPECT_EQ(nullptr, srv);
- pkt.answers_.clear();
- pkt.add_answer(new DNSSrvRR("example.abc.def.com", 180, 0, 10, 8160, "example.abc.def.com"));
-
- // No answer.
- pkt.answers_.clear();
- data = pkt.data();
- EXPECT_EQ(ARES_ENODATA, ares_parse_srv_reply(data.data(), data.size(), &srv));
- pkt.add_answer(new DNSSrvRR("example.abc.def.com", 180, 0, 10, 8160, "example.abc.def.com"));
-
- // Truncated packets.
- data = pkt.data();
- for (size_t len = 1; len < data.size(); len++) {
- int rc = ares_parse_srv_reply(data.data(), len, &srv);
- EXPECT_TRUE(rc == ARES_EBADRESP || rc == ARES_EBADNAME);
- }
-}
-
-TEST_F(LibraryTest, ParseSrvReplyAllocFail) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.abc.def.com", ns_t_srv))
- .add_answer(new DNSCnameRR("example.com", 300, "c.example.com"))
- .add_answer(new DNSSrvRR("example.abc.def.com", 180, 0, 10, 8160, "example.abc.def.com"));
- std::vector<byte> data = pkt.data();
- struct ares_srv_reply* srv = nullptr;
-
- for (int ii = 1; ii <= 5; ii++) {
- ClearFails();
- SetAllocFail(ii);
- EXPECT_EQ(ARES_ENOMEM, ares_parse_srv_reply(data.data(), data.size(), &srv)) << ii;
- }
-}
-
-} // namespace test
-} // namespace ares
+#include "ares-test.h"
+#include "dns-proto.h"
+
+#include <sstream>
+#include <vector>
+
+namespace ares {
+namespace test {
+
+TEST_F(LibraryTest, ParseSrvReplyOK) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_srv))
+ .add_answer(new DNSSrvRR("example.com", 100, 10, 20, 30, "srv.example.com"))
+ .add_answer(new DNSSrvRR("example.com", 100, 11, 21, 31, "srv2.example.com"));
+ std::vector<byte> data = pkt.data();
+
+ struct ares_srv_reply* srv = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_srv_reply(data.data(), data.size(), &srv));
+ ASSERT_NE(nullptr, srv);
+
+ EXPECT_EQ("srv.example.com", std::string(srv->host));
+ EXPECT_EQ(10, srv->priority);
+ EXPECT_EQ(20, srv->weight);
+ EXPECT_EQ(30, srv->port);
+
+ struct ares_srv_reply* srv2 = srv->next;
+ ASSERT_NE(nullptr, srv2);
+ EXPECT_EQ("srv2.example.com", std::string(srv2->host));
+ EXPECT_EQ(11, srv2->priority);
+ EXPECT_EQ(21, srv2->weight);
+ EXPECT_EQ(31, srv2->port);
+ EXPECT_EQ(nullptr, srv2->next);
+
+ ares_free_data(srv);
+}
+
+TEST_F(LibraryTest, ParseSrvReplySingle) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.abc.def.com", ns_t_srv))
+ .add_answer(new DNSSrvRR("example.abc.def.com", 180, 0, 10, 8160, "example.abc.def.com"))
+ .add_auth(new DNSNsRR("abc.def.com", 44, "else1.where.com"))
+ .add_auth(new DNSNsRR("abc.def.com", 44, "else2.where.com"))
+ .add_auth(new DNSNsRR("abc.def.com", 44, "else3.where.com"))
+ .add_auth(new DNSNsRR("abc.def.com", 44, "else4.where.com"))
+ .add_auth(new DNSNsRR("abc.def.com", 44, "else5.where.com"))
+ .add_additional(new DNSARR("else2.where.com", 42, {172,19,0,1}))
+ .add_additional(new DNSARR("else5.where.com", 42, {172,19,0,2}));
+ std::vector<byte> data = pkt.data();
+
+ struct ares_srv_reply* srv = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_srv_reply(data.data(), data.size(), &srv));
+ ASSERT_NE(nullptr, srv);
+
+ EXPECT_EQ("example.abc.def.com", std::string(srv->host));
+ EXPECT_EQ(0, srv->priority);
+ EXPECT_EQ(10, srv->weight);
+ EXPECT_EQ(8160, srv->port);
+ EXPECT_EQ(nullptr, srv->next);
+
+ ares_free_data(srv);
+}
+
+TEST_F(LibraryTest, ParseSrvReplyMalformed) {
+ 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, 0x01, // num answer RRs
+ 0x00, 0x00, // num authority RRs
+ 0x00, 0x00, // num additional RRs
+ // Question
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x21, // type SRV
+ 0x00, 0x01, // class IN
+ // Answer 1
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x21, // RR type
+ 0x00, 0x01, // class IN
+ 0x01, 0x02, 0x03, 0x04, // TTL
+ 0x00, 0x04, // rdata length -- too short
+ 0x02, 0x03, 0x04, 0x05,
+ };
+
+ struct ares_srv_reply* srv = nullptr;
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_srv_reply(data.data(), data.size(), &srv));
+ ASSERT_EQ(nullptr, srv);
+}
+
+TEST_F(LibraryTest, ParseSrvReplyMultiple) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_ra().set_rd()
+ .add_question(new DNSQuestion("srv.example.com", ns_t_srv))
+ .add_answer(new DNSSrvRR("srv.example.com", 300, 0, 5, 6789, "a1.srv.example.com"))
+ .add_answer(new DNSSrvRR("srv.example.com", 300, 0, 5, 4567, "a2.srv.example.com"))
+ .add_answer(new DNSSrvRR("srv.example.com", 300, 0, 5, 5678, "a3.srv.example.com"))
+ .add_auth(new DNSNsRR("example.com", 300, "ns1.example.com"))
+ .add_auth(new DNSNsRR("example.com", 300, "ns2.example.com"))
+ .add_auth(new DNSNsRR("example.com", 300, "ns3.example.com"))
+ .add_additional(new DNSARR("a1.srv.example.com", 300, {172,19,1,1}))
+ .add_additional(new DNSARR("a2.srv.example.com", 300, {172,19,1,2}))
+ .add_additional(new DNSARR("a3.srv.example.com", 300, {172,19,1,3}))
+ .add_additional(new DNSARR("n1.example.com", 300, {172,19,0,1}))
+ .add_additional(new DNSARR("n2.example.com", 300, {172,19,0,2}))
+ .add_additional(new DNSARR("n3.example.com", 300, {172,19,0,3}));
+ std::vector<byte> data = pkt.data();
+
+ struct ares_srv_reply* srv0 = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_srv_reply(data.data(), data.size(), &srv0));
+ ASSERT_NE(nullptr, srv0);
+ struct ares_srv_reply* srv = srv0;
+
+ EXPECT_EQ("a1.srv.example.com", std::string(srv->host));
+ EXPECT_EQ(0, srv->priority);
+ EXPECT_EQ(5, srv->weight);
+ EXPECT_EQ(6789, srv->port);
+ EXPECT_NE(nullptr, srv->next);
+ srv = srv->next;
+
+ EXPECT_EQ("a2.srv.example.com", std::string(srv->host));
+ EXPECT_EQ(0, srv->priority);
+ EXPECT_EQ(5, srv->weight);
+ EXPECT_EQ(4567, srv->port);
+ EXPECT_NE(nullptr, srv->next);
+ srv = srv->next;
+
+ EXPECT_EQ("a3.srv.example.com", std::string(srv->host));
+ EXPECT_EQ(0, srv->priority);
+ EXPECT_EQ(5, srv->weight);
+ EXPECT_EQ(5678, srv->port);
+ EXPECT_EQ(nullptr, srv->next);
+
+ ares_free_data(srv0);
+}
+
+TEST_F(LibraryTest, ParseSrvReplyCname) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.abc.def.com", ns_t_srv))
+ .add_answer(new DNSCnameRR("example.abc.def.com", 300, "cname.abc.def.com"))
+ .add_answer(new DNSSrvRR("cname.abc.def.com", 300, 0, 10, 1234, "srv.abc.def.com"))
+ .add_auth(new DNSNsRR("abc.def.com", 44, "else1.where.com"))
+ .add_auth(new DNSNsRR("abc.def.com", 44, "else2.where.com"))
+ .add_auth(new DNSNsRR("abc.def.com", 44, "else3.where.com"))
+ .add_additional(new DNSARR("example.abc.def.com", 300, {172,19,0,1}))
+ .add_additional(new DNSARR("else1.where.com", 42, {172,19,0,1}))
+ .add_additional(new DNSARR("else2.where.com", 42, {172,19,0,2}))
+ .add_additional(new DNSARR("else3.where.com", 42, {172,19,0,3}));
+ std::vector<byte> data = pkt.data();
+
+ struct ares_srv_reply* srv = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_srv_reply(data.data(), data.size(), &srv));
+ ASSERT_NE(nullptr, srv);
+
+ EXPECT_EQ("srv.abc.def.com", std::string(srv->host));
+ EXPECT_EQ(0, srv->priority);
+ EXPECT_EQ(10, srv->weight);
+ EXPECT_EQ(1234, srv->port);
+ EXPECT_EQ(nullptr, srv->next);
+
+ ares_free_data(srv);
+}
+
+TEST_F(LibraryTest, ParseSrvReplyCnameMultiple) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_ra().set_rd()
+ .add_question(new DNSQuestion("query.example.com", ns_t_srv))
+ .add_answer(new DNSCnameRR("query.example.com", 300, "srv.example.com"))
+ .add_answer(new DNSSrvRR("srv.example.com", 300, 0, 5, 6789, "a1.srv.example.com"))
+ .add_answer(new DNSSrvRR("srv.example.com", 300, 0, 5, 4567, "a2.srv.example.com"))
+ .add_answer(new DNSSrvRR("srv.example.com", 300, 0, 5, 5678, "a3.srv.example.com"))
+ .add_auth(new DNSNsRR("example.com", 300, "ns1.example.com"))
+ .add_auth(new DNSNsRR("example.com", 300, "ns2.example.com"))
+ .add_auth(new DNSNsRR("example.com", 300, "ns3.example.com"))
+ .add_additional(new DNSARR("a1.srv.example.com", 300, {172,19,1,1}))
+ .add_additional(new DNSARR("a2.srv.example.com", 300, {172,19,1,2}))
+ .add_additional(new DNSARR("a3.srv.example.com", 300, {172,19,1,3}))
+ .add_additional(new DNSARR("n1.example.com", 300, {172,19,0,1}))
+ .add_additional(new DNSARR("n2.example.com", 300, {172,19,0,2}))
+ .add_additional(new DNSARR("n3.example.com", 300, {172,19,0,3}));
+ std::vector<byte> data = pkt.data();
+
+ struct ares_srv_reply* srv0 = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_srv_reply(data.data(), data.size(), &srv0));
+ ASSERT_NE(nullptr, srv0);
+ struct ares_srv_reply* srv = srv0;
+
+ EXPECT_EQ("a1.srv.example.com", std::string(srv->host));
+ EXPECT_EQ(0, srv->priority);
+ EXPECT_EQ(5, srv->weight);
+ EXPECT_EQ(6789, srv->port);
+ EXPECT_NE(nullptr, srv->next);
+ srv = srv->next;
+
+ EXPECT_EQ("a2.srv.example.com", std::string(srv->host));
+ EXPECT_EQ(0, srv->priority);
+ EXPECT_EQ(5, srv->weight);
+ EXPECT_EQ(4567, srv->port);
+ EXPECT_NE(nullptr, srv->next);
+ srv = srv->next;
+
+ EXPECT_EQ("a3.srv.example.com", std::string(srv->host));
+ EXPECT_EQ(0, srv->priority);
+ EXPECT_EQ(5, srv->weight);
+ EXPECT_EQ(5678, srv->port);
+ EXPECT_EQ(nullptr, srv->next);
+
+ ares_free_data(srv0);
+}
+
+TEST_F(LibraryTest, ParseSrvReplyErrors) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.abc.def.com", ns_t_srv))
+ .add_answer(new DNSSrvRR("example.abc.def.com", 180, 0, 10, 8160, "example.abc.def.com"));
+ std::vector<byte> data;
+ struct ares_srv_reply* srv = nullptr;
+
+ // No question.
+ pkt.questions_.clear();
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_srv_reply(data.data(), data.size(), &srv));
+ pkt.add_question(new DNSQuestion("example.abc.def.com", ns_t_srv));
+
+#ifdef DISABLED
+ // Question != answer
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("Axample.com", ns_t_srv));
+ data = pkt.data();
+ EXPECT_EQ(ARES_ENODATA, ares_parse_srv_reply(data.data(), data.size(), &srv));
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("example.com", ns_t_srv));
+#endif
+
+ // Two questions.
+ pkt.add_question(new DNSQuestion("example.abc.def.com", ns_t_srv));
+ data = pkt.data();
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_srv_reply(data.data(), data.size(), &srv));
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("64.48.32.16.in-addr.arpa", ns_t_ptr));
+
+ // 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_SUCCESS, ares_parse_srv_reply(data.data(), data.size(), &srv));
+ EXPECT_EQ(nullptr, srv);
+ pkt.answers_.clear();
+ pkt.add_answer(new DNSSrvRR("example.abc.def.com", 180, 0, 10, 8160, "example.abc.def.com"));
+
+ // No answer.
+ pkt.answers_.clear();
+ data = pkt.data();
+ EXPECT_EQ(ARES_ENODATA, ares_parse_srv_reply(data.data(), data.size(), &srv));
+ pkt.add_answer(new DNSSrvRR("example.abc.def.com", 180, 0, 10, 8160, "example.abc.def.com"));
+
+ // Truncated packets.
+ data = pkt.data();
+ for (size_t len = 1; len < data.size(); len++) {
+ int rc = ares_parse_srv_reply(data.data(), len, &srv);
+ EXPECT_TRUE(rc == ARES_EBADRESP || rc == ARES_EBADNAME);
+ }
+}
+
+TEST_F(LibraryTest, ParseSrvReplyAllocFail) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.abc.def.com", ns_t_srv))
+ .add_answer(new DNSCnameRR("example.com", 300, "c.example.com"))
+ .add_answer(new DNSSrvRR("example.abc.def.com", 180, 0, 10, 8160, "example.abc.def.com"));
+ std::vector<byte> data = pkt.data();
+ struct ares_srv_reply* srv = nullptr;
+
+ for (int ii = 1; ii <= 5; ii++) {
+ ClearFails();
+ SetAllocFail(ii);
+ EXPECT_EQ(ARES_ENOMEM, ares_parse_srv_reply(data.data(), data.size(), &srv)) << ii;
+ }
+}
+
+} // namespace test
+} // namespace ares
diff --git a/contrib/libs/c-ares/test/ares-test-parse-txt.cc b/contrib/libs/c-ares/test/ares-test-parse-txt.cc
index 80a9dad7d1..8aaaaa3b47 100644
--- a/contrib/libs/c-ares/test/ares-test-parse-txt.cc
+++ b/contrib/libs/c-ares/test/ares-test-parse-txt.cc
@@ -1,266 +1,266 @@
-#include "ares-test.h"
-#include "dns-proto.h"
-
-#include <sstream>
-#include <vector>
-
-namespace ares {
-namespace test {
-
-TEST_F(LibraryTest, ParseTxtReplyOK) {
- DNSPacket pkt;
- std::string expected1 = "txt1.example.com";
- std::string expected2a = "txt2a";
- std::string expected2b("ABC\0ABC", 7);
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_mx))
- .add_answer(new DNSTxtRR("example.com", 100, {expected1}))
- .add_answer(new DNSTxtRR("example.com", 100, {expected2a, expected2b}));
- std::vector<byte> data = pkt.data();
-
- struct ares_txt_reply* txt = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_txt_reply(data.data(), data.size(), &txt));
- ASSERT_NE(nullptr, txt);
- EXPECT_EQ(std::vector<byte>(expected1.data(), expected1.data() + expected1.size()),
- std::vector<byte>(txt->txt, txt->txt + txt->length));
-
- struct ares_txt_reply* txt2 = txt->next;
- ASSERT_NE(nullptr, txt2);
- EXPECT_EQ(std::vector<byte>(expected2a.data(), expected2a.data() + expected2a.size()),
- std::vector<byte>(txt2->txt, txt2->txt + txt2->length));
-
- struct ares_txt_reply* txt3 = txt2->next;
- ASSERT_NE(nullptr, txt3);
- EXPECT_EQ(std::vector<byte>(expected2b.data(), expected2b.data() + expected2b.size()),
- std::vector<byte>(txt3->txt, txt3->txt + txt3->length));
- EXPECT_EQ(nullptr, txt3->next);
-
- ares_free_data(txt);
-}
-
-TEST_F(LibraryTest, ParseTxtExtReplyOK) {
- DNSPacket pkt;
- std::string expected1 = "txt1.example.com";
- std::string expected2a = "txt2a";
- std::string expected2b("ABC\0ABC", 7);
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_mx))
- .add_answer(new DNSTxtRR("example.com", 100, {expected1}))
- .add_answer(new DNSTxtRR("example.com", 100, {expected2a, expected2b}));
- std::vector<byte> data = pkt.data();
-
- struct ares_txt_ext* txt = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_txt_reply_ext(data.data(), data.size(), &txt));
- ASSERT_NE(nullptr, txt);
- EXPECT_EQ(std::vector<byte>(expected1.data(), expected1.data() + expected1.size()),
- std::vector<byte>(txt->txt, txt->txt + txt->length));
- EXPECT_EQ(1, txt->record_start);
-
- struct ares_txt_ext* txt2 = txt->next;
- ASSERT_NE(nullptr, txt2);
- EXPECT_EQ(std::vector<byte>(expected2a.data(), expected2a.data() + expected2a.size()),
- std::vector<byte>(txt2->txt, txt2->txt + txt2->length));
- EXPECT_EQ(1, txt2->record_start);
-
- struct ares_txt_ext* txt3 = txt2->next;
- ASSERT_NE(nullptr, txt3);
- EXPECT_EQ(std::vector<byte>(expected2b.data(), expected2b.data() + expected2b.size()),
- std::vector<byte>(txt3->txt, txt3->txt + txt3->length));
- EXPECT_EQ(nullptr, txt3->next);
- EXPECT_EQ(0, txt3->record_start);
-
- ares_free_data(txt);
-}
-
-TEST_F(LibraryTest, ParseTxtMalformedReply1) {
- 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, 0x01, // num answer RRs
- 0x00, 0x00, // num authority RRs
- 0x00, 0x00, // num additional RRs
- // Question
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x10, // type TXT
- 0x00, 0x01, // class IN
- // Answer 1
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x10, // RR type
- 0x00, 0x01, // class IN
- 0x01, 0x02, 0x03, 0x04, // TTL
- 0x00, 0x03, // rdata length
- 0x12, 'a', 'b', // invalid length
- };
-
- struct ares_txt_reply* txt = nullptr;
- EXPECT_EQ(ARES_EBADRESP, ares_parse_txt_reply(data.data(), data.size(), &txt));
- ASSERT_EQ(nullptr, txt);
-}
-
-TEST_F(LibraryTest, ParseTxtMalformedReply2) {
- 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, 0x01, // num answer RRs
- 0x00, 0x00, // num authority RRs
- 0x00, 0x00, // num additional RRs
- // Question
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x10, // type TXT
- 0x00, 0x01, // class IN
- // Answer 1
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x10, // RR type
- // truncated
- };
-
- struct ares_txt_reply* txt = nullptr;
- EXPECT_EQ(ARES_EBADRESP, ares_parse_txt_reply(data.data(), data.size(), &txt));
- ASSERT_EQ(nullptr, txt);
-}
-
-TEST_F(LibraryTest, ParseTxtMalformedReply3) {
- 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, 0x01, // num answer RRs
- 0x00, 0x00, // num authority RRs
- 0x00, 0x00, // num additional RRs
- // Question
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x10, // type TXT
- 0x00, 0x01, // class IN
- // Answer 1
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x10, // RR type
- 0x00, 0x01, // class IN
- 0x01, 0x02, 0x03, 0x04, // TTL
- 0x00, 0x13, // rdata length INVALID
- 0x02, 'a', 'b',
- };
-
- struct ares_txt_reply* txt = nullptr;
- EXPECT_EQ(ARES_EBADRESP, ares_parse_txt_reply(data.data(), data.size(), &txt));
- ASSERT_EQ(nullptr, txt);
-}
-
-TEST_F(LibraryTest, ParseTxtMalformedReply4) {
- 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, 0x01, // num answer RRs
- 0x00, 0x00, // num authority RRs
- 0x00, 0x00, // num additional RRs
- // Question
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x10, // type TXT
- 0x00, // TRUNCATED
- };
-
- struct ares_txt_reply* txt = nullptr;
- EXPECT_EQ(ARES_EBADRESP, ares_parse_txt_reply(data.data(), data.size(), &txt));
- ASSERT_EQ(nullptr, txt);
-}
-
-TEST_F(LibraryTest, ParseTxtReplyErrors) {
- DNSPacket pkt;
- std::string expected1 = "txt1.example.com";
- std::string expected2a = "txt2a";
- std::string expected2b = "txt2b";
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_mx))
- .add_answer(new DNSTxtRR("example.com", 100, {expected1}))
- .add_answer(new DNSTxtRR("example.com", 100, {expected1}))
- .add_answer(new DNSTxtRR("example.com", 100, {expected2a, expected2b}));
- std::vector<byte> data = pkt.data();
- struct ares_txt_reply* txt = nullptr;
-
- // No question.
- pkt.questions_.clear();
- data = pkt.data();
- txt = nullptr;
- EXPECT_EQ(ARES_EBADRESP, ares_parse_txt_reply(data.data(), data.size(), &txt));
- EXPECT_EQ(nullptr, txt);
- pkt.add_question(new DNSQuestion("example.com", ns_t_mx));
-
-#ifdef DISABLED
- // Question != answer
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("Axample.com", ns_t_txt));
- data = pkt.data();
- EXPECT_EQ(ARES_ENODATA, ares_parse_txt_reply(data.data(), data.size(), &txt));
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("example.com", ns_t_txt));
-#endif
-
- // Two questions.
- pkt.add_question(new DNSQuestion("example.com", ns_t_mx));
- data = pkt.data();
- txt = nullptr;
- EXPECT_EQ(ARES_EBADRESP, ares_parse_txt_reply(data.data(), data.size(), &txt));
- EXPECT_EQ(nullptr, txt);
- pkt.questions_.clear();
- pkt.add_question(new DNSQuestion("example.com", ns_t_mx));
-
- // No answer.
- pkt.answers_.clear();
- data = pkt.data();
- txt = nullptr;
- EXPECT_EQ(ARES_ENODATA, ares_parse_txt_reply(data.data(), data.size(), &txt));
- EXPECT_EQ(nullptr, txt);
- pkt.add_answer(new DNSTxtRR("example.com", 100, {expected1}));
-
- // Truncated packets.
- for (size_t len = 1; len < data.size(); len++) {
- txt = nullptr;
- EXPECT_NE(ARES_SUCCESS, ares_parse_txt_reply(data.data(), len, &txt));
- EXPECT_EQ(nullptr, txt);
- }
-}
-
-TEST_F(LibraryTest, ParseTxtReplyAllocFail) {
- DNSPacket pkt;
- std::string expected1 = "txt1.example.com";
- std::string expected2a = "txt2a";
- std::string expected2b = "txt2b";
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com", ns_t_mx))
- .add_answer(new DNSCnameRR("example.com", 300, "c.example.com"))
- .add_answer(new DNSTxtRR("c.example.com", 100, {expected1}))
- .add_answer(new DNSTxtRR("c.example.com", 100, {expected1}))
- .add_answer(new DNSTxtRR("c.example.com", 100, {expected2a, expected2b}));
- std::vector<byte> data = pkt.data();
- struct ares_txt_reply* txt = nullptr;
-
- for (int ii = 1; ii <= 13; ii++) {
- ClearFails();
- SetAllocFail(ii);
- EXPECT_EQ(ARES_ENOMEM, ares_parse_txt_reply(data.data(), data.size(), &txt)) << ii;
- }
-}
-
-
-} // namespace test
-} // namespace ares
+#include "ares-test.h"
+#include "dns-proto.h"
+
+#include <sstream>
+#include <vector>
+
+namespace ares {
+namespace test {
+
+TEST_F(LibraryTest, ParseTxtReplyOK) {
+ DNSPacket pkt;
+ std::string expected1 = "txt1.example.com";
+ std::string expected2a = "txt2a";
+ std::string expected2b("ABC\0ABC", 7);
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_mx))
+ .add_answer(new DNSTxtRR("example.com", 100, {expected1}))
+ .add_answer(new DNSTxtRR("example.com", 100, {expected2a, expected2b}));
+ std::vector<byte> data = pkt.data();
+
+ struct ares_txt_reply* txt = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_txt_reply(data.data(), data.size(), &txt));
+ ASSERT_NE(nullptr, txt);
+ EXPECT_EQ(std::vector<byte>(expected1.data(), expected1.data() + expected1.size()),
+ std::vector<byte>(txt->txt, txt->txt + txt->length));
+
+ struct ares_txt_reply* txt2 = txt->next;
+ ASSERT_NE(nullptr, txt2);
+ EXPECT_EQ(std::vector<byte>(expected2a.data(), expected2a.data() + expected2a.size()),
+ std::vector<byte>(txt2->txt, txt2->txt + txt2->length));
+
+ struct ares_txt_reply* txt3 = txt2->next;
+ ASSERT_NE(nullptr, txt3);
+ EXPECT_EQ(std::vector<byte>(expected2b.data(), expected2b.data() + expected2b.size()),
+ std::vector<byte>(txt3->txt, txt3->txt + txt3->length));
+ EXPECT_EQ(nullptr, txt3->next);
+
+ ares_free_data(txt);
+}
+
+TEST_F(LibraryTest, ParseTxtExtReplyOK) {
+ DNSPacket pkt;
+ std::string expected1 = "txt1.example.com";
+ std::string expected2a = "txt2a";
+ std::string expected2b("ABC\0ABC", 7);
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_mx))
+ .add_answer(new DNSTxtRR("example.com", 100, {expected1}))
+ .add_answer(new DNSTxtRR("example.com", 100, {expected2a, expected2b}));
+ std::vector<byte> data = pkt.data();
+
+ struct ares_txt_ext* txt = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_txt_reply_ext(data.data(), data.size(), &txt));
+ ASSERT_NE(nullptr, txt);
+ EXPECT_EQ(std::vector<byte>(expected1.data(), expected1.data() + expected1.size()),
+ std::vector<byte>(txt->txt, txt->txt + txt->length));
+ EXPECT_EQ(1, txt->record_start);
+
+ struct ares_txt_ext* txt2 = txt->next;
+ ASSERT_NE(nullptr, txt2);
+ EXPECT_EQ(std::vector<byte>(expected2a.data(), expected2a.data() + expected2a.size()),
+ std::vector<byte>(txt2->txt, txt2->txt + txt2->length));
+ EXPECT_EQ(1, txt2->record_start);
+
+ struct ares_txt_ext* txt3 = txt2->next;
+ ASSERT_NE(nullptr, txt3);
+ EXPECT_EQ(std::vector<byte>(expected2b.data(), expected2b.data() + expected2b.size()),
+ std::vector<byte>(txt3->txt, txt3->txt + txt3->length));
+ EXPECT_EQ(nullptr, txt3->next);
+ EXPECT_EQ(0, txt3->record_start);
+
+ ares_free_data(txt);
+}
+
+TEST_F(LibraryTest, ParseTxtMalformedReply1) {
+ 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, 0x01, // num answer RRs
+ 0x00, 0x00, // num authority RRs
+ 0x00, 0x00, // num additional RRs
+ // Question
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x10, // type TXT
+ 0x00, 0x01, // class IN
+ // Answer 1
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x10, // RR type
+ 0x00, 0x01, // class IN
+ 0x01, 0x02, 0x03, 0x04, // TTL
+ 0x00, 0x03, // rdata length
+ 0x12, 'a', 'b', // invalid length
+ };
+
+ struct ares_txt_reply* txt = nullptr;
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_txt_reply(data.data(), data.size(), &txt));
+ ASSERT_EQ(nullptr, txt);
+}
+
+TEST_F(LibraryTest, ParseTxtMalformedReply2) {
+ 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, 0x01, // num answer RRs
+ 0x00, 0x00, // num authority RRs
+ 0x00, 0x00, // num additional RRs
+ // Question
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x10, // type TXT
+ 0x00, 0x01, // class IN
+ // Answer 1
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x10, // RR type
+ // truncated
+ };
+
+ struct ares_txt_reply* txt = nullptr;
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_txt_reply(data.data(), data.size(), &txt));
+ ASSERT_EQ(nullptr, txt);
+}
+
+TEST_F(LibraryTest, ParseTxtMalformedReply3) {
+ 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, 0x01, // num answer RRs
+ 0x00, 0x00, // num authority RRs
+ 0x00, 0x00, // num additional RRs
+ // Question
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x10, // type TXT
+ 0x00, 0x01, // class IN
+ // Answer 1
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x10, // RR type
+ 0x00, 0x01, // class IN
+ 0x01, 0x02, 0x03, 0x04, // TTL
+ 0x00, 0x13, // rdata length INVALID
+ 0x02, 'a', 'b',
+ };
+
+ struct ares_txt_reply* txt = nullptr;
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_txt_reply(data.data(), data.size(), &txt));
+ ASSERT_EQ(nullptr, txt);
+}
+
+TEST_F(LibraryTest, ParseTxtMalformedReply4) {
+ 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, 0x01, // num answer RRs
+ 0x00, 0x00, // num authority RRs
+ 0x00, 0x00, // num additional RRs
+ // Question
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x10, // type TXT
+ 0x00, // TRUNCATED
+ };
+
+ struct ares_txt_reply* txt = nullptr;
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_txt_reply(data.data(), data.size(), &txt));
+ ASSERT_EQ(nullptr, txt);
+}
+
+TEST_F(LibraryTest, ParseTxtReplyErrors) {
+ DNSPacket pkt;
+ std::string expected1 = "txt1.example.com";
+ std::string expected2a = "txt2a";
+ std::string expected2b = "txt2b";
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_mx))
+ .add_answer(new DNSTxtRR("example.com", 100, {expected1}))
+ .add_answer(new DNSTxtRR("example.com", 100, {expected1}))
+ .add_answer(new DNSTxtRR("example.com", 100, {expected2a, expected2b}));
+ std::vector<byte> data = pkt.data();
+ struct ares_txt_reply* txt = nullptr;
+
+ // No question.
+ pkt.questions_.clear();
+ data = pkt.data();
+ txt = nullptr;
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_txt_reply(data.data(), data.size(), &txt));
+ EXPECT_EQ(nullptr, txt);
+ pkt.add_question(new DNSQuestion("example.com", ns_t_mx));
+
+#ifdef DISABLED
+ // Question != answer
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("Axample.com", ns_t_txt));
+ data = pkt.data();
+ EXPECT_EQ(ARES_ENODATA, ares_parse_txt_reply(data.data(), data.size(), &txt));
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("example.com", ns_t_txt));
+#endif
+
+ // Two questions.
+ pkt.add_question(new DNSQuestion("example.com", ns_t_mx));
+ data = pkt.data();
+ txt = nullptr;
+ EXPECT_EQ(ARES_EBADRESP, ares_parse_txt_reply(data.data(), data.size(), &txt));
+ EXPECT_EQ(nullptr, txt);
+ pkt.questions_.clear();
+ pkt.add_question(new DNSQuestion("example.com", ns_t_mx));
+
+ // No answer.
+ pkt.answers_.clear();
+ data = pkt.data();
+ txt = nullptr;
+ EXPECT_EQ(ARES_ENODATA, ares_parse_txt_reply(data.data(), data.size(), &txt));
+ EXPECT_EQ(nullptr, txt);
+ pkt.add_answer(new DNSTxtRR("example.com", 100, {expected1}));
+
+ // Truncated packets.
+ for (size_t len = 1; len < data.size(); len++) {
+ txt = nullptr;
+ EXPECT_NE(ARES_SUCCESS, ares_parse_txt_reply(data.data(), len, &txt));
+ EXPECT_EQ(nullptr, txt);
+ }
+}
+
+TEST_F(LibraryTest, ParseTxtReplyAllocFail) {
+ DNSPacket pkt;
+ std::string expected1 = "txt1.example.com";
+ std::string expected2a = "txt2a";
+ std::string expected2b = "txt2b";
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com", ns_t_mx))
+ .add_answer(new DNSCnameRR("example.com", 300, "c.example.com"))
+ .add_answer(new DNSTxtRR("c.example.com", 100, {expected1}))
+ .add_answer(new DNSTxtRR("c.example.com", 100, {expected1}))
+ .add_answer(new DNSTxtRR("c.example.com", 100, {expected2a, expected2b}));
+ std::vector<byte> data = pkt.data();
+ struct ares_txt_reply* txt = nullptr;
+
+ for (int ii = 1; ii <= 13; ii++) {
+ ClearFails();
+ SetAllocFail(ii);
+ EXPECT_EQ(ARES_ENOMEM, ares_parse_txt_reply(data.data(), data.size(), &txt)) << ii;
+ }
+}
+
+
+} // namespace test
+} // namespace ares
diff --git a/contrib/libs/c-ares/test/ares-test-parse.cc b/contrib/libs/c-ares/test/ares-test-parse.cc
index 95744c3eb5..4c54fc9902 100644
--- a/contrib/libs/c-ares/test/ares-test-parse.cc
+++ b/contrib/libs/c-ares/test/ares-test-parse.cc
@@ -1,219 +1,219 @@
-#include "ares-test.h"
-#include "dns-proto.h"
-
-#include <sstream>
-#include <vector>
-
-namespace ares {
-namespace test {
-
-TEST_F(LibraryTest, ParseRootName) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion(".", ns_t_a))
- .add_answer(new DNSARR(".", 100, {0x02, 0x03, 0x04, 0x05}));
- std::vector<byte> data = pkt.data();
-
- struct hostent *host = nullptr;
- struct ares_addrttl info[2];
- int count = 2;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(1, count);
- std::stringstream ss;
- ss << HostEnt(host);
- EXPECT_EQ("{'' aliases=[] addrs=[2.3.4.5]}", ss.str());
- ares_free_hostent(host);
-}
-
-TEST_F(LibraryTest, ParseIndirectRootName) {
- 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, 0x01, // num answer RRs
- 0x00, 0x00, // num authority RRs
- 0x00, 0x00, // num additional RRs
- // Question
- 0xC0, 0x04, // weird: pointer to a random zero earlier in the message
- 0x00, 0x01, // type A
- 0x00, 0x01, // class IN
- // Answer 1
- 0xC0, 0x04,
- 0x00, 0x01, // RR type
- 0x00, 0x01, // class IN
- 0x01, 0x02, 0x03, 0x04, // TTL
- 0x00, 0x04, // rdata length
- 0x02, 0x03, 0x04, 0x05,
- };
-
- struct hostent *host = nullptr;
- struct ares_addrttl info[2];
- int count = 2;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(1, count);
- std::stringstream ss;
- ss << HostEnt(host);
- EXPECT_EQ("{'' aliases=[] addrs=[2.3.4.5]}", ss.str());
- ares_free_hostent(host);
-}
-
-TEST_F(LibraryTest, ParseEscapedName) {
- 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, 0x01, // num answer RRs
- 0x00, 0x00, // num authority RRs
- 0x00, 0x00, // num additional RRs
- // Question
- 0x05, 'a', '\\', 'b', '.', 'c',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x01, // type A
- 0x00, 0x01, // class IN
- // Answer 1
- 0x05, 'a', '\\', 'b', '.', 'c',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x01, // RR type
- 0x00, 0x01, // class IN
- 0x01, 0x02, 0x03, 0x04, // TTL
- 0x00, 0x04, // rdata length
- 0x02, 0x03, 0x04, 0x05,
- };
- struct hostent *host = nullptr;
- struct ares_addrttl info[2];
- int count = 2;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- EXPECT_EQ(1, count);
- HostEnt hent(host);
- std::stringstream ss;
- ss << hent;
- // The printable name is expanded with escapes.
- EXPECT_EQ(11, hent.name_.size());
- EXPECT_EQ('a', hent.name_[0]);
- EXPECT_EQ('\\', hent.name_[1]);
- EXPECT_EQ('\\', hent.name_[2]);
- EXPECT_EQ('b', hent.name_[3]);
- EXPECT_EQ('\\', hent.name_[4]);
- EXPECT_EQ('.', hent.name_[5]);
- EXPECT_EQ('c', hent.name_[6]);
- ares_free_hostent(host);
-}
-
-TEST_F(LibraryTest, ParsePartialCompressedName) {
- 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, 0x01, // num answer RRs
- 0x00, 0x00, // num authority RRs
- 0x00, 0x00, // num additional RRs
- // Question
- 0x03, 'w', 'w', 'w',
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x01, // type A
- 0x00, 0x01, // class IN
- // Answer 1
- 0x03, 'w', 'w', 'w',
- 0xc0, 0x10, // offset 16
- 0x00, 0x01, // RR type
- 0x00, 0x01, // class IN
- 0x01, 0x02, 0x03, 0x04, // TTL
- 0x00, 0x04, // rdata length
- 0x02, 0x03, 0x04, 0x05,
- };
- struct hostent *host = nullptr;
- struct ares_addrttl info[2];
- int count = 2;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- ASSERT_NE(nullptr, host);
- std::stringstream ss;
- ss << HostEnt(host);
- EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
- ares_free_hostent(host);
-}
-
-TEST_F(LibraryTest, ParseFullyCompressedName) {
- 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, 0x01, // num answer RRs
- 0x00, 0x00, // num authority RRs
- 0x00, 0x00, // num additional RRs
- // Question
- 0x03, 'w', 'w', 'w',
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x01, // type A
- 0x00, 0x01, // class IN
- // Answer 1
- 0xc0, 0x0c, // offset 12
- 0x00, 0x01, // RR type
- 0x00, 0x01, // class IN
- 0x01, 0x02, 0x03, 0x04, // TTL
- 0x00, 0x04, // rdata length
- 0x02, 0x03, 0x04, 0x05,
- };
- struct hostent *host = nullptr;
- struct ares_addrttl info[2];
- int count = 2;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- ASSERT_NE(nullptr, host);
- std::stringstream ss;
- ss << HostEnt(host);
- EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
- ares_free_hostent(host);
-}
-
-TEST_F(LibraryTest, ParseFullyCompressedName2) {
- 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, 0x01, // num answer RRs
- 0x00, 0x00, // num authority RRs
- 0x00, 0x00, // num additional RRs
- // Question
- 0xC0, 0x12, // pointer to later in message
- 0x00, 0x01, // type A
- 0x00, 0x01, // class IN
- // Answer 1
- 0x03, 'w', 'w', 'w',
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x01, // RR type
- 0x00, 0x01, // class IN
- 0x01, 0x02, 0x03, 0x04, // TTL
- 0x00, 0x04, // rdata length
- 0x02, 0x03, 0x04, 0x05,
- };
- struct hostent *host = nullptr;
- struct ares_addrttl info[2];
- int count = 2;
- EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
- &host, info, &count));
- ASSERT_NE(nullptr, host);
- std::stringstream ss;
- ss << HostEnt(host);
- EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
- ares_free_hostent(host);
-}
-
-} // namespace test
-} // namespace ares
+#include "ares-test.h"
+#include "dns-proto.h"
+
+#include <sstream>
+#include <vector>
+
+namespace ares {
+namespace test {
+
+TEST_F(LibraryTest, ParseRootName) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion(".", ns_t_a))
+ .add_answer(new DNSARR(".", 100, {0x02, 0x03, 0x04, 0x05}));
+ std::vector<byte> data = pkt.data();
+
+ struct hostent *host = nullptr;
+ struct ares_addrttl info[2];
+ int count = 2;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(1, count);
+ std::stringstream ss;
+ ss << HostEnt(host);
+ EXPECT_EQ("{'' aliases=[] addrs=[2.3.4.5]}", ss.str());
+ ares_free_hostent(host);
+}
+
+TEST_F(LibraryTest, ParseIndirectRootName) {
+ 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, 0x01, // num answer RRs
+ 0x00, 0x00, // num authority RRs
+ 0x00, 0x00, // num additional RRs
+ // Question
+ 0xC0, 0x04, // weird: pointer to a random zero earlier in the message
+ 0x00, 0x01, // type A
+ 0x00, 0x01, // class IN
+ // Answer 1
+ 0xC0, 0x04,
+ 0x00, 0x01, // RR type
+ 0x00, 0x01, // class IN
+ 0x01, 0x02, 0x03, 0x04, // TTL
+ 0x00, 0x04, // rdata length
+ 0x02, 0x03, 0x04, 0x05,
+ };
+
+ struct hostent *host = nullptr;
+ struct ares_addrttl info[2];
+ int count = 2;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(1, count);
+ std::stringstream ss;
+ ss << HostEnt(host);
+ EXPECT_EQ("{'' aliases=[] addrs=[2.3.4.5]}", ss.str());
+ ares_free_hostent(host);
+}
+
+TEST_F(LibraryTest, ParseEscapedName) {
+ 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, 0x01, // num answer RRs
+ 0x00, 0x00, // num authority RRs
+ 0x00, 0x00, // num additional RRs
+ // Question
+ 0x05, 'a', '\\', 'b', '.', 'c',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x01, // type A
+ 0x00, 0x01, // class IN
+ // Answer 1
+ 0x05, 'a', '\\', 'b', '.', 'c',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x01, // RR type
+ 0x00, 0x01, // class IN
+ 0x01, 0x02, 0x03, 0x04, // TTL
+ 0x00, 0x04, // rdata length
+ 0x02, 0x03, 0x04, 0x05,
+ };
+ struct hostent *host = nullptr;
+ struct ares_addrttl info[2];
+ int count = 2;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ EXPECT_EQ(1, count);
+ HostEnt hent(host);
+ std::stringstream ss;
+ ss << hent;
+ // The printable name is expanded with escapes.
+ EXPECT_EQ(11, hent.name_.size());
+ EXPECT_EQ('a', hent.name_[0]);
+ EXPECT_EQ('\\', hent.name_[1]);
+ EXPECT_EQ('\\', hent.name_[2]);
+ EXPECT_EQ('b', hent.name_[3]);
+ EXPECT_EQ('\\', hent.name_[4]);
+ EXPECT_EQ('.', hent.name_[5]);
+ EXPECT_EQ('c', hent.name_[6]);
+ ares_free_hostent(host);
+}
+
+TEST_F(LibraryTest, ParsePartialCompressedName) {
+ 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, 0x01, // num answer RRs
+ 0x00, 0x00, // num authority RRs
+ 0x00, 0x00, // num additional RRs
+ // Question
+ 0x03, 'w', 'w', 'w',
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x01, // type A
+ 0x00, 0x01, // class IN
+ // Answer 1
+ 0x03, 'w', 'w', 'w',
+ 0xc0, 0x10, // offset 16
+ 0x00, 0x01, // RR type
+ 0x00, 0x01, // class IN
+ 0x01, 0x02, 0x03, 0x04, // TTL
+ 0x00, 0x04, // rdata length
+ 0x02, 0x03, 0x04, 0x05,
+ };
+ struct hostent *host = nullptr;
+ struct ares_addrttl info[2];
+ int count = 2;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ ASSERT_NE(nullptr, host);
+ std::stringstream ss;
+ ss << HostEnt(host);
+ EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
+ ares_free_hostent(host);
+}
+
+TEST_F(LibraryTest, ParseFullyCompressedName) {
+ 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, 0x01, // num answer RRs
+ 0x00, 0x00, // num authority RRs
+ 0x00, 0x00, // num additional RRs
+ // Question
+ 0x03, 'w', 'w', 'w',
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x01, // type A
+ 0x00, 0x01, // class IN
+ // Answer 1
+ 0xc0, 0x0c, // offset 12
+ 0x00, 0x01, // RR type
+ 0x00, 0x01, // class IN
+ 0x01, 0x02, 0x03, 0x04, // TTL
+ 0x00, 0x04, // rdata length
+ 0x02, 0x03, 0x04, 0x05,
+ };
+ struct hostent *host = nullptr;
+ struct ares_addrttl info[2];
+ int count = 2;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ ASSERT_NE(nullptr, host);
+ std::stringstream ss;
+ ss << HostEnt(host);
+ EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
+ ares_free_hostent(host);
+}
+
+TEST_F(LibraryTest, ParseFullyCompressedName2) {
+ 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, 0x01, // num answer RRs
+ 0x00, 0x00, // num authority RRs
+ 0x00, 0x00, // num additional RRs
+ // Question
+ 0xC0, 0x12, // pointer to later in message
+ 0x00, 0x01, // type A
+ 0x00, 0x01, // class IN
+ // Answer 1
+ 0x03, 'w', 'w', 'w',
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x01, // RR type
+ 0x00, 0x01, // class IN
+ 0x01, 0x02, 0x03, 0x04, // TTL
+ 0x00, 0x04, // rdata length
+ 0x02, 0x03, 0x04, 0x05,
+ };
+ struct hostent *host = nullptr;
+ struct ares_addrttl info[2];
+ int count = 2;
+ EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(),
+ &host, info, &count));
+ ASSERT_NE(nullptr, host);
+ std::stringstream ss;
+ ss << HostEnt(host);
+ EXPECT_EQ("{'www.example.com' aliases=[] addrs=[2.3.4.5]}", ss.str());
+ ares_free_hostent(host);
+}
+
+} // namespace test
+} // namespace ares
diff --git a/contrib/libs/c-ares/test/ares-test.cc b/contrib/libs/c-ares/test/ares-test.cc
index 90d05013f0..ec4b460549 100644
--- a/contrib/libs/c-ares/test/ares-test.cc
+++ b/contrib/libs/c-ares/test/ares-test.cc
@@ -1,570 +1,570 @@
-#include "ares-test.h"
+#include "ares-test.h"
#include "ares-test-ai.h"
-#include "dns-proto.h"
-
-// Include ares internal files for DNS protocol details
-#include "nameser.h"
-#include "ares_dns.h"
-
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_NETINET_TCP_H
-#include <netinet/tcp.h>
-#endif
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <functional>
-#include <sstream>
-
-#ifdef WIN32
-#define BYTE_CAST (char *)
-#define mkdir_(d, p) mkdir(d)
-#else
-#define BYTE_CAST
-#define mkdir_(d, p) mkdir(d, p)
-#endif
-
-namespace ares {
-namespace test {
-
-bool verbose = false;
-int mock_port = 5300;
-
-const std::vector<int> both_families = {AF_INET, AF_INET6};
-const std::vector<int> ipv4_family = {AF_INET};
-const std::vector<int> ipv6_family = {AF_INET6};
-
-const std::vector<std::pair<int, bool>> both_families_both_modes = {
- std::make_pair<int, bool>(AF_INET, false),
- std::make_pair<int, bool>(AF_INET, true),
- std::make_pair<int, bool>(AF_INET6, false),
- std::make_pair<int, bool>(AF_INET6, true)
-};
-const std::vector<std::pair<int, bool>> ipv4_family_both_modes = {
- std::make_pair<int, bool>(AF_INET, false),
- std::make_pair<int, bool>(AF_INET, true)
-};
-const std::vector<std::pair<int, bool>> ipv6_family_both_modes = {
- std::make_pair<int, bool>(AF_INET6, false),
- std::make_pair<int, bool>(AF_INET6, true)
-};
-
-// Which parameters to use in tests
-std::vector<int> families = both_families;
-std::vector<std::pair<int, bool>> families_modes = both_families_both_modes;
-
-unsigned long long LibraryTest::fails_ = 0;
-std::map<size_t, int> LibraryTest::size_fails_;
-
-void ProcessWork(ares_channel channel,
- std::function<std::set<int>()> get_extrafds,
- std::function<void(int)> process_extra) {
- int nfds, count;
- fd_set readers, writers;
- struct timeval tv;
- while (true) {
- // Retrieve the set of file descriptors that the library wants us to monitor.
- FD_ZERO(&readers);
- FD_ZERO(&writers);
- nfds = ares_fds(channel, &readers, &writers);
- if (nfds == 0) // no work left to do in the library
- return;
-
- // Add in the extra FDs if present.
- std::set<int> extrafds = get_extrafds();
- for (int extrafd : extrafds) {
- FD_SET(extrafd, &readers);
- if (extrafd >= nfds) {
- nfds = extrafd + 1;
- }
- }
-
- // Wait for activity or timeout.
- tv.tv_sec = 0;
- tv.tv_usec = 100000; // 100ms
- count = select(nfds, &readers, &writers, nullptr, &tv);
- if (count < 0) {
- fprintf(stderr, "select() failed, errno %d\n", errno);
- return;
- }
-
- // Let the library process any activity.
- ares_process(channel, &readers, &writers);
-
- // Let the provided callback process any activity on the extra FD.
- for (int extrafd : extrafds) {
- if (FD_ISSET(extrafd, &readers)) {
- process_extra(extrafd);
- }
- }
- }
-}
-
-// static
-void LibraryTest::SetAllocFail(int nth) {
- assert(nth > 0);
- assert(nth <= (int)(8 * sizeof(fails_)));
- fails_ |= (1LL << (nth - 1));
-}
-
-// static
-void LibraryTest::SetAllocSizeFail(size_t size) {
- size_fails_[size]++;
-}
-
-// static
-void LibraryTest::ClearFails() {
- fails_ = 0;
- size_fails_.clear();
-}
-
-
-// static
-bool LibraryTest::ShouldAllocFail(size_t size) {
- bool fail = (fails_ & 0x01);
- fails_ >>= 1;
- if (size_fails_[size] > 0) {
- size_fails_[size]--;
- fail = true;
- }
- return fail;
-}
-
-// static
-void* LibraryTest::amalloc(size_t size) {
- if (ShouldAllocFail(size)) {
- if (verbose) std::cerr << "Failing malloc(" << size << ") request" << std::endl;
- return nullptr;
- } else {
- return malloc(size);
- }
-}
-
-// static
-void* LibraryTest::arealloc(void *ptr, size_t size) {
- if (ShouldAllocFail(size)) {
- if (verbose) std::cerr << "Failing realloc(" << ptr << ", " << size << ") request" << std::endl;
- return nullptr;
- } else {
- return realloc(ptr, size);
- }
-}
-
-// static
-void LibraryTest::afree(void *ptr) {
- free(ptr);
-}
-
-std::set<int> NoExtraFDs() {
- return std::set<int>();
-}
-
-void DefaultChannelTest::Process() {
- ProcessWork(channel_, NoExtraFDs, nullptr);
-}
-
-void DefaultChannelModeTest::Process() {
- ProcessWork(channel_, NoExtraFDs, nullptr);
-}
-
-MockServer::MockServer(int family, int port, int tcpport)
- : udpport_(port), tcpport_(tcpport ? tcpport : udpport_), qid_(-1) {
- // Create a TCP socket to receive data on.
- tcpfd_ = socket(family, SOCK_STREAM, 0);
- EXPECT_NE(-1, tcpfd_);
- int optval = 1;
- setsockopt(tcpfd_, SOL_SOCKET, SO_REUSEADDR,
- BYTE_CAST &optval , sizeof(int));
- // Send TCP data right away.
- setsockopt(tcpfd_, IPPROTO_TCP, TCP_NODELAY,
- BYTE_CAST &optval , sizeof(int));
-
- // Create a UDP socket to receive data on.
- udpfd_ = socket(family, SOCK_DGRAM, 0);
- EXPECT_NE(-1, udpfd_);
-
- // Bind the sockets to the given port.
- if (family == AF_INET) {
- struct sockaddr_in addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl(INADDR_ANY);
- addr.sin_port = htons(tcpport_);
- int tcprc = bind(tcpfd_, (struct sockaddr*)&addr, sizeof(addr));
- EXPECT_EQ(0, tcprc) << "Failed to bind AF_INET to TCP port " << tcpport_;
- addr.sin_port = htons(udpport_);
- int udprc = bind(udpfd_, (struct sockaddr*)&addr, sizeof(addr));
- EXPECT_EQ(0, udprc) << "Failed to bind AF_INET to UDP port " << udpport_;
- } else {
- EXPECT_EQ(AF_INET6, family);
- struct sockaddr_in6 addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin6_family = AF_INET6;
- memset(&addr.sin6_addr, 0, sizeof(addr.sin6_addr)); // in6addr_any
- addr.sin6_port = htons(tcpport_);
- int tcprc = bind(tcpfd_, (struct sockaddr*)&addr, sizeof(addr));
- EXPECT_EQ(0, tcprc) << "Failed to bind AF_INET6 to TCP port " << tcpport_;
- addr.sin6_port = htons(udpport_);
- int udprc = bind(udpfd_, (struct sockaddr*)&addr, sizeof(addr));
- EXPECT_EQ(0, udprc) << "Failed to bind AF_INET6 to UDP port " << udpport_;
- }
- if (verbose) std::cerr << "Configured "
- << (family == AF_INET ? "IPv4" : "IPv6")
- << " mock server with TCP socket " << tcpfd_
- << " on port " << tcpport_
- << " and UDP socket " << udpfd_
- << " on port " << udpport_ << std::endl;
-
- // For TCP, also need to listen for connections.
- EXPECT_EQ(0, listen(tcpfd_, 5)) << "Failed to listen for TCP connections";
-}
-
-MockServer::~MockServer() {
- for (int fd : connfds_) {
- sclose(fd);
- }
- sclose(tcpfd_);
- sclose(udpfd_);
-}
-
-void MockServer::ProcessFD(int fd) {
- if (fd != tcpfd_ && fd != udpfd_ && connfds_.find(fd) == connfds_.end()) {
- // Not one of our FDs.
- return;
- }
- if (fd == tcpfd_) {
- int connfd = accept(tcpfd_, NULL, NULL);
- if (connfd < 0) {
- std::cerr << "Error accepting connection on fd " << fd << std::endl;
- } else {
- connfds_.insert(connfd);
- }
- return;
- }
-
- // Activity on a data-bearing file descriptor.
- struct sockaddr_storage addr;
- socklen_t addrlen = sizeof(addr);
- byte buffer[2048];
- int len = recvfrom(fd, BYTE_CAST buffer, sizeof(buffer), 0,
- (struct sockaddr *)&addr, &addrlen);
- byte* data = buffer;
- if (fd != udpfd_) {
- if (len == 0) {
- connfds_.erase(std::find(connfds_.begin(), connfds_.end(), fd));
- sclose(fd);
- return;
- }
- if (len < 2) {
- std::cerr << "Packet too short (" << len << ")" << std::endl;
- return;
- }
- int tcplen = (data[0] << 8) + data[1];
- data += 2;
- len -= 2;
- if (tcplen != len) {
- std::cerr << "Warning: TCP length " << tcplen
- << " doesn't match remaining data length " << len << std::endl;
- }
- }
-
- // Assume the packet is a well-formed DNS request and extract the request
- // details.
- if (len < NS_HFIXEDSZ) {
- std::cerr << "Packet too short (" << len << ")" << std::endl;
- return;
- }
- int qid = DNS_HEADER_QID(data);
- if (DNS_HEADER_QR(data) != 0) {
- std::cerr << "Not a request" << std::endl;
- return;
- }
- if (DNS_HEADER_OPCODE(data) != ns_o_query) {
- std::cerr << "Not a query (opcode " << DNS_HEADER_OPCODE(data)
- << ")" << std::endl;
- return;
- }
- if (DNS_HEADER_QDCOUNT(data) != 1) {
- std::cerr << "Unexpected question count (" << DNS_HEADER_QDCOUNT(data)
- << ")" << std::endl;
- return;
- }
- byte* question = data + 12;
- int qlen = len - 12;
-
- char *name = nullptr;
- long enclen;
- ares_expand_name(question, data, len, &name, &enclen);
- if (!name) {
- std::cerr << "Failed to retrieve name" << std::endl;
- return;
- }
- qlen -= enclen;
- question += enclen;
- std::string namestr(name);
- ares_free_string(name);
-
- if (qlen < 4) {
- std::cerr << "Unexpected question size (" << qlen
- << " bytes after name)" << std::endl;
- return;
- }
- if (DNS_QUESTION_CLASS(question) != ns_c_in) {
- std::cerr << "Unexpected question class (" << DNS_QUESTION_CLASS(question)
- << ")" << std::endl;
- return;
- }
- int rrtype = DNS_QUESTION_TYPE(question);
-
- if (verbose) {
- std::vector<byte> req(data, data + len);
- std::cerr << "received " << (fd == udpfd_ ? "UDP" : "TCP") << " request " << PacketToString(req)
- << " on port " << (fd == udpfd_ ? udpport_ : tcpport_) << std::endl;
- std::cerr << "ProcessRequest(" << qid << ", '" << namestr
- << "', " << RRTypeToString(rrtype) << ")" << std::endl;
- }
- ProcessRequest(fd, &addr, addrlen, qid, namestr, rrtype);
-}
-
-std::set<int> MockServer::fds() const {
- std::set<int> result = connfds_;
- result.insert(tcpfd_);
- result.insert(udpfd_);
- return result;
-}
-
-void MockServer::ProcessRequest(int fd, struct sockaddr_storage* addr, int addrlen,
- int qid, const std::string& name, int rrtype) {
- // Before processing, let gMock know the request is happening.
- OnRequest(name, rrtype);
-
- if (reply_.size() == 0) {
- return;
- }
-
- // Make a local copy of the current pending reply.
- std::vector<byte> reply = reply_;
-
- if (qid_ >= 0) {
- // Use the explicitly specified query ID.
- qid = qid_;
- }
- if (reply.size() >= 2) {
- // Overwrite the query ID if space to do so.
- reply[0] = (byte)((qid >> 8) & 0xff);
- reply[1] = (byte)(qid & 0xff);
- }
- if (verbose) std::cerr << "sending reply " << PacketToString(reply)
- << " on port " << ((fd == udpfd_) ? udpport_ : tcpport_) << std::endl;
-
- // Prefix with 2-byte length if TCP.
- if (fd != udpfd_) {
- int len = reply.size();
- std::vector<byte> vlen = {(byte)((len & 0xFF00) >> 8), (byte)(len & 0xFF)};
- reply.insert(reply.begin(), vlen.begin(), vlen.end());
- // Also, don't bother with the destination address.
- addr = nullptr;
- addrlen = 0;
- }
-
- int rc = sendto(fd, BYTE_CAST reply.data(), reply.size(), 0,
- (struct sockaddr *)addr, addrlen);
- if (rc < static_cast<int>(reply.size())) {
- std::cerr << "Failed to send full reply, rc=" << rc << std::endl;
- }
-}
-
-// static
-MockChannelOptsTest::NiceMockServers MockChannelOptsTest::BuildServers(int count, int family, int base_port) {
- NiceMockServers servers;
- assert(count > 0);
- for (int ii = 0; ii < count; ii++) {
- std::unique_ptr<NiceMockServer> server(new NiceMockServer(family, base_port + ii));
- servers.push_back(std::move(server));
- }
- return servers;
-}
-
-MockChannelOptsTest::MockChannelOptsTest(int count,
- int family,
- bool force_tcp,
- struct ares_options* givenopts,
- int optmask)
- : servers_(BuildServers(count, family, mock_port)),
- server_(*servers_[0].get()), channel_(nullptr) {
- // Set up channel options.
- struct ares_options opts;
- if (givenopts) {
- memcpy(&opts, givenopts, sizeof(opts));
- } else {
- memset(&opts, 0, sizeof(opts));
- }
-
- // Point the library at the first mock server by default (overridden below).
- opts.udp_port = mock_port;
- optmask |= ARES_OPT_UDP_PORT;
- opts.tcp_port = mock_port;
- optmask |= ARES_OPT_TCP_PORT;
-
- // If not already overridden, set short-ish timeouts.
- if (!(optmask & (ARES_OPT_TIMEOUTMS|ARES_OPT_TIMEOUT))) {
- opts.timeout = 1500;
- optmask |= ARES_OPT_TIMEOUTMS;
- }
- // If not already overridden, set 3 retries.
- if (!(optmask & ARES_OPT_TRIES)) {
- opts.tries = 3;
- optmask |= ARES_OPT_TRIES;
- }
- // If not already overridden, set search domains.
- const char *domains[3] = {"first.com", "second.org", "third.gov"};
- if (!(optmask & ARES_OPT_DOMAINS)) {
- opts.ndomains = 3;
- opts.domains = (char**)domains;
- optmask |= ARES_OPT_DOMAINS;
- }
- if (force_tcp) {
- opts.flags |= ARES_FLAG_USEVC;
- optmask |= ARES_OPT_FLAGS;
- }
-
- EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel_, &opts, optmask));
- EXPECT_NE(nullptr, channel_);
-
- // Set up servers after construction so we can set individual ports
- struct ares_addr_port_node* prev = nullptr;
- struct ares_addr_port_node* first = nullptr;
- for (const auto& server : servers_) {
- struct ares_addr_port_node* node = (struct ares_addr_port_node*)malloc(sizeof(*node));
- if (prev) {
- prev->next = node;
- } else {
- first = node;
- }
- node->next = nullptr;
- node->family = family;
- node->udp_port = server->udpport();
- node->tcp_port = server->tcpport();
- if (family == AF_INET) {
- node->addr.addr4.s_addr = htonl(0x7F000001);
- } else {
- memset(&node->addr.addr6, 0, sizeof(node->addr.addr6));
- node->addr.addr6._S6_un._S6_u8[15] = 1;
- }
- prev = node;
- }
- EXPECT_EQ(ARES_SUCCESS, ares_set_servers_ports(channel_, first));
-
- while (first) {
- prev = first;
- first = first->next;
- free(prev);
- }
- if (verbose) {
- std::cerr << "Configured library with servers:";
- std::vector<std::string> servers = GetNameServers(channel_);
- for (const auto& server : servers) {
- std::cerr << " " << server;
- }
- std::cerr << std::endl;
- }
-}
-
-MockChannelOptsTest::~MockChannelOptsTest() {
- if (channel_) {
- ares_destroy(channel_);
- }
- channel_ = nullptr;
-}
-
-std::set<int> MockChannelOptsTest::fds() const {
- std::set<int> fds;
- for (const auto& server : servers_) {
- std::set<int> serverfds = server->fds();
- fds.insert(serverfds.begin(), serverfds.end());
- }
- return fds;
-}
-
-void MockChannelOptsTest::ProcessFD(int fd) {
- for (auto& server : servers_) {
- server->ProcessFD(fd);
- }
-}
-
-void MockChannelOptsTest::Process() {
- using namespace std::placeholders;
- ProcessWork(channel_,
- std::bind(&MockChannelOptsTest::fds, this),
- std::bind(&MockChannelOptsTest::ProcessFD, this, _1));
-}
-
-std::ostream& operator<<(std::ostream& os, const HostResult& result) {
- os << '{';
- if (result.done_) {
- os << StatusToString(result.status_) << " " << result.host_;
- } else {
- os << "(incomplete)";
- }
- os << '}';
- return os;
-}
-
-HostEnt::HostEnt(const struct hostent *hostent) : addrtype_(-1) {
- if (!hostent)
- return;
- if (hostent->h_name)
- name_ = hostent->h_name;
- if (hostent->h_aliases) {
- char** palias = hostent->h_aliases;
- while (*palias != nullptr) {
- aliases_.push_back(*palias);
- palias++;
- }
- }
- addrtype_ = hostent->h_addrtype;
- if (hostent->h_addr_list) {
- char** paddr = hostent->h_addr_list;
- while (*paddr != nullptr) {
- std::string addr = AddressToString(*paddr, hostent->h_length);
- addrs_.push_back(addr);
- paddr++;
- }
- }
-}
-
-std::ostream& operator<<(std::ostream& os, const HostEnt& host) {
- os << '{';
- os << "'" << host.name_ << "' "
- << "aliases=[";
- for (size_t ii = 0; ii < host.aliases_.size(); ii++) {
- if (ii > 0) os << ", ";
- os << host.aliases_[ii];
- }
- os << "] ";
- os << "addrs=[";
- for (size_t ii = 0; ii < host.addrs_.size(); ii++) {
- if (ii > 0) os << ", ";
- os << host.addrs_[ii];
- }
- os << "]";
- os << '}';
- return os;
-}
-
-void HostCallback(void *data, int status, int timeouts,
- struct hostent *hostent) {
- EXPECT_NE(nullptr, data);
- HostResult* result = reinterpret_cast<HostResult*>(data);
- result->done_ = true;
- result->status_ = status;
- result->timeouts_ = timeouts;
- result->host_ = HostEnt(hostent);
- if (verbose) std::cerr << "HostCallback(" << *result << ")" << std::endl;
-}
-
+#include "dns-proto.h"
+
+// Include ares internal files for DNS protocol details
+#include "nameser.h"
+#include "ares_dns.h"
+
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <functional>
+#include <sstream>
+
+#ifdef WIN32
+#define BYTE_CAST (char *)
+#define mkdir_(d, p) mkdir(d)
+#else
+#define BYTE_CAST
+#define mkdir_(d, p) mkdir(d, p)
+#endif
+
+namespace ares {
+namespace test {
+
+bool verbose = false;
+int mock_port = 5300;
+
+const std::vector<int> both_families = {AF_INET, AF_INET6};
+const std::vector<int> ipv4_family = {AF_INET};
+const std::vector<int> ipv6_family = {AF_INET6};
+
+const std::vector<std::pair<int, bool>> both_families_both_modes = {
+ std::make_pair<int, bool>(AF_INET, false),
+ std::make_pair<int, bool>(AF_INET, true),
+ std::make_pair<int, bool>(AF_INET6, false),
+ std::make_pair<int, bool>(AF_INET6, true)
+};
+const std::vector<std::pair<int, bool>> ipv4_family_both_modes = {
+ std::make_pair<int, bool>(AF_INET, false),
+ std::make_pair<int, bool>(AF_INET, true)
+};
+const std::vector<std::pair<int, bool>> ipv6_family_both_modes = {
+ std::make_pair<int, bool>(AF_INET6, false),
+ std::make_pair<int, bool>(AF_INET6, true)
+};
+
+// Which parameters to use in tests
+std::vector<int> families = both_families;
+std::vector<std::pair<int, bool>> families_modes = both_families_both_modes;
+
+unsigned long long LibraryTest::fails_ = 0;
+std::map<size_t, int> LibraryTest::size_fails_;
+
+void ProcessWork(ares_channel channel,
+ std::function<std::set<int>()> get_extrafds,
+ std::function<void(int)> process_extra) {
+ int nfds, count;
+ fd_set readers, writers;
+ struct timeval tv;
+ while (true) {
+ // Retrieve the set of file descriptors that the library wants us to monitor.
+ FD_ZERO(&readers);
+ FD_ZERO(&writers);
+ nfds = ares_fds(channel, &readers, &writers);
+ if (nfds == 0) // no work left to do in the library
+ return;
+
+ // Add in the extra FDs if present.
+ std::set<int> extrafds = get_extrafds();
+ for (int extrafd : extrafds) {
+ FD_SET(extrafd, &readers);
+ if (extrafd >= nfds) {
+ nfds = extrafd + 1;
+ }
+ }
+
+ // Wait for activity or timeout.
+ tv.tv_sec = 0;
+ tv.tv_usec = 100000; // 100ms
+ count = select(nfds, &readers, &writers, nullptr, &tv);
+ if (count < 0) {
+ fprintf(stderr, "select() failed, errno %d\n", errno);
+ return;
+ }
+
+ // Let the library process any activity.
+ ares_process(channel, &readers, &writers);
+
+ // Let the provided callback process any activity on the extra FD.
+ for (int extrafd : extrafds) {
+ if (FD_ISSET(extrafd, &readers)) {
+ process_extra(extrafd);
+ }
+ }
+ }
+}
+
+// static
+void LibraryTest::SetAllocFail(int nth) {
+ assert(nth > 0);
+ assert(nth <= (int)(8 * sizeof(fails_)));
+ fails_ |= (1LL << (nth - 1));
+}
+
+// static
+void LibraryTest::SetAllocSizeFail(size_t size) {
+ size_fails_[size]++;
+}
+
+// static
+void LibraryTest::ClearFails() {
+ fails_ = 0;
+ size_fails_.clear();
+}
+
+
+// static
+bool LibraryTest::ShouldAllocFail(size_t size) {
+ bool fail = (fails_ & 0x01);
+ fails_ >>= 1;
+ if (size_fails_[size] > 0) {
+ size_fails_[size]--;
+ fail = true;
+ }
+ return fail;
+}
+
+// static
+void* LibraryTest::amalloc(size_t size) {
+ if (ShouldAllocFail(size)) {
+ if (verbose) std::cerr << "Failing malloc(" << size << ") request" << std::endl;
+ return nullptr;
+ } else {
+ return malloc(size);
+ }
+}
+
+// static
+void* LibraryTest::arealloc(void *ptr, size_t size) {
+ if (ShouldAllocFail(size)) {
+ if (verbose) std::cerr << "Failing realloc(" << ptr << ", " << size << ") request" << std::endl;
+ return nullptr;
+ } else {
+ return realloc(ptr, size);
+ }
+}
+
+// static
+void LibraryTest::afree(void *ptr) {
+ free(ptr);
+}
+
+std::set<int> NoExtraFDs() {
+ return std::set<int>();
+}
+
+void DefaultChannelTest::Process() {
+ ProcessWork(channel_, NoExtraFDs, nullptr);
+}
+
+void DefaultChannelModeTest::Process() {
+ ProcessWork(channel_, NoExtraFDs, nullptr);
+}
+
+MockServer::MockServer(int family, int port, int tcpport)
+ : udpport_(port), tcpport_(tcpport ? tcpport : udpport_), qid_(-1) {
+ // Create a TCP socket to receive data on.
+ tcpfd_ = socket(family, SOCK_STREAM, 0);
+ EXPECT_NE(-1, tcpfd_);
+ int optval = 1;
+ setsockopt(tcpfd_, SOL_SOCKET, SO_REUSEADDR,
+ BYTE_CAST &optval , sizeof(int));
+ // Send TCP data right away.
+ setsockopt(tcpfd_, IPPROTO_TCP, TCP_NODELAY,
+ BYTE_CAST &optval , sizeof(int));
+
+ // Create a UDP socket to receive data on.
+ udpfd_ = socket(family, SOCK_DGRAM, 0);
+ EXPECT_NE(-1, udpfd_);
+
+ // Bind the sockets to the given port.
+ if (family == AF_INET) {
+ struct sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ addr.sin_port = htons(tcpport_);
+ int tcprc = bind(tcpfd_, (struct sockaddr*)&addr, sizeof(addr));
+ EXPECT_EQ(0, tcprc) << "Failed to bind AF_INET to TCP port " << tcpport_;
+ addr.sin_port = htons(udpport_);
+ int udprc = bind(udpfd_, (struct sockaddr*)&addr, sizeof(addr));
+ EXPECT_EQ(0, udprc) << "Failed to bind AF_INET to UDP port " << udpport_;
+ } else {
+ EXPECT_EQ(AF_INET6, family);
+ struct sockaddr_in6 addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin6_family = AF_INET6;
+ memset(&addr.sin6_addr, 0, sizeof(addr.sin6_addr)); // in6addr_any
+ addr.sin6_port = htons(tcpport_);
+ int tcprc = bind(tcpfd_, (struct sockaddr*)&addr, sizeof(addr));
+ EXPECT_EQ(0, tcprc) << "Failed to bind AF_INET6 to TCP port " << tcpport_;
+ addr.sin6_port = htons(udpport_);
+ int udprc = bind(udpfd_, (struct sockaddr*)&addr, sizeof(addr));
+ EXPECT_EQ(0, udprc) << "Failed to bind AF_INET6 to UDP port " << udpport_;
+ }
+ if (verbose) std::cerr << "Configured "
+ << (family == AF_INET ? "IPv4" : "IPv6")
+ << " mock server with TCP socket " << tcpfd_
+ << " on port " << tcpport_
+ << " and UDP socket " << udpfd_
+ << " on port " << udpport_ << std::endl;
+
+ // For TCP, also need to listen for connections.
+ EXPECT_EQ(0, listen(tcpfd_, 5)) << "Failed to listen for TCP connections";
+}
+
+MockServer::~MockServer() {
+ for (int fd : connfds_) {
+ sclose(fd);
+ }
+ sclose(tcpfd_);
+ sclose(udpfd_);
+}
+
+void MockServer::ProcessFD(int fd) {
+ if (fd != tcpfd_ && fd != udpfd_ && connfds_.find(fd) == connfds_.end()) {
+ // Not one of our FDs.
+ return;
+ }
+ if (fd == tcpfd_) {
+ int connfd = accept(tcpfd_, NULL, NULL);
+ if (connfd < 0) {
+ std::cerr << "Error accepting connection on fd " << fd << std::endl;
+ } else {
+ connfds_.insert(connfd);
+ }
+ return;
+ }
+
+ // Activity on a data-bearing file descriptor.
+ struct sockaddr_storage addr;
+ socklen_t addrlen = sizeof(addr);
+ byte buffer[2048];
+ int len = recvfrom(fd, BYTE_CAST buffer, sizeof(buffer), 0,
+ (struct sockaddr *)&addr, &addrlen);
+ byte* data = buffer;
+ if (fd != udpfd_) {
+ if (len == 0) {
+ connfds_.erase(std::find(connfds_.begin(), connfds_.end(), fd));
+ sclose(fd);
+ return;
+ }
+ if (len < 2) {
+ std::cerr << "Packet too short (" << len << ")" << std::endl;
+ return;
+ }
+ int tcplen = (data[0] << 8) + data[1];
+ data += 2;
+ len -= 2;
+ if (tcplen != len) {
+ std::cerr << "Warning: TCP length " << tcplen
+ << " doesn't match remaining data length " << len << std::endl;
+ }
+ }
+
+ // Assume the packet is a well-formed DNS request and extract the request
+ // details.
+ if (len < NS_HFIXEDSZ) {
+ std::cerr << "Packet too short (" << len << ")" << std::endl;
+ return;
+ }
+ int qid = DNS_HEADER_QID(data);
+ if (DNS_HEADER_QR(data) != 0) {
+ std::cerr << "Not a request" << std::endl;
+ return;
+ }
+ if (DNS_HEADER_OPCODE(data) != ns_o_query) {
+ std::cerr << "Not a query (opcode " << DNS_HEADER_OPCODE(data)
+ << ")" << std::endl;
+ return;
+ }
+ if (DNS_HEADER_QDCOUNT(data) != 1) {
+ std::cerr << "Unexpected question count (" << DNS_HEADER_QDCOUNT(data)
+ << ")" << std::endl;
+ return;
+ }
+ byte* question = data + 12;
+ int qlen = len - 12;
+
+ char *name = nullptr;
+ long enclen;
+ ares_expand_name(question, data, len, &name, &enclen);
+ if (!name) {
+ std::cerr << "Failed to retrieve name" << std::endl;
+ return;
+ }
+ qlen -= enclen;
+ question += enclen;
+ std::string namestr(name);
+ ares_free_string(name);
+
+ if (qlen < 4) {
+ std::cerr << "Unexpected question size (" << qlen
+ << " bytes after name)" << std::endl;
+ return;
+ }
+ if (DNS_QUESTION_CLASS(question) != ns_c_in) {
+ std::cerr << "Unexpected question class (" << DNS_QUESTION_CLASS(question)
+ << ")" << std::endl;
+ return;
+ }
+ int rrtype = DNS_QUESTION_TYPE(question);
+
+ if (verbose) {
+ std::vector<byte> req(data, data + len);
+ std::cerr << "received " << (fd == udpfd_ ? "UDP" : "TCP") << " request " << PacketToString(req)
+ << " on port " << (fd == udpfd_ ? udpport_ : tcpport_) << std::endl;
+ std::cerr << "ProcessRequest(" << qid << ", '" << namestr
+ << "', " << RRTypeToString(rrtype) << ")" << std::endl;
+ }
+ ProcessRequest(fd, &addr, addrlen, qid, namestr, rrtype);
+}
+
+std::set<int> MockServer::fds() const {
+ std::set<int> result = connfds_;
+ result.insert(tcpfd_);
+ result.insert(udpfd_);
+ return result;
+}
+
+void MockServer::ProcessRequest(int fd, struct sockaddr_storage* addr, int addrlen,
+ int qid, const std::string& name, int rrtype) {
+ // Before processing, let gMock know the request is happening.
+ OnRequest(name, rrtype);
+
+ if (reply_.size() == 0) {
+ return;
+ }
+
+ // Make a local copy of the current pending reply.
+ std::vector<byte> reply = reply_;
+
+ if (qid_ >= 0) {
+ // Use the explicitly specified query ID.
+ qid = qid_;
+ }
+ if (reply.size() >= 2) {
+ // Overwrite the query ID if space to do so.
+ reply[0] = (byte)((qid >> 8) & 0xff);
+ reply[1] = (byte)(qid & 0xff);
+ }
+ if (verbose) std::cerr << "sending reply " << PacketToString(reply)
+ << " on port " << ((fd == udpfd_) ? udpport_ : tcpport_) << std::endl;
+
+ // Prefix with 2-byte length if TCP.
+ if (fd != udpfd_) {
+ int len = reply.size();
+ std::vector<byte> vlen = {(byte)((len & 0xFF00) >> 8), (byte)(len & 0xFF)};
+ reply.insert(reply.begin(), vlen.begin(), vlen.end());
+ // Also, don't bother with the destination address.
+ addr = nullptr;
+ addrlen = 0;
+ }
+
+ int rc = sendto(fd, BYTE_CAST reply.data(), reply.size(), 0,
+ (struct sockaddr *)addr, addrlen);
+ if (rc < static_cast<int>(reply.size())) {
+ std::cerr << "Failed to send full reply, rc=" << rc << std::endl;
+ }
+}
+
+// static
+MockChannelOptsTest::NiceMockServers MockChannelOptsTest::BuildServers(int count, int family, int base_port) {
+ NiceMockServers servers;
+ assert(count > 0);
+ for (int ii = 0; ii < count; ii++) {
+ std::unique_ptr<NiceMockServer> server(new NiceMockServer(family, base_port + ii));
+ servers.push_back(std::move(server));
+ }
+ return servers;
+}
+
+MockChannelOptsTest::MockChannelOptsTest(int count,
+ int family,
+ bool force_tcp,
+ struct ares_options* givenopts,
+ int optmask)
+ : servers_(BuildServers(count, family, mock_port)),
+ server_(*servers_[0].get()), channel_(nullptr) {
+ // Set up channel options.
+ struct ares_options opts;
+ if (givenopts) {
+ memcpy(&opts, givenopts, sizeof(opts));
+ } else {
+ memset(&opts, 0, sizeof(opts));
+ }
+
+ // Point the library at the first mock server by default (overridden below).
+ opts.udp_port = mock_port;
+ optmask |= ARES_OPT_UDP_PORT;
+ opts.tcp_port = mock_port;
+ optmask |= ARES_OPT_TCP_PORT;
+
+ // If not already overridden, set short-ish timeouts.
+ if (!(optmask & (ARES_OPT_TIMEOUTMS|ARES_OPT_TIMEOUT))) {
+ opts.timeout = 1500;
+ optmask |= ARES_OPT_TIMEOUTMS;
+ }
+ // If not already overridden, set 3 retries.
+ if (!(optmask & ARES_OPT_TRIES)) {
+ opts.tries = 3;
+ optmask |= ARES_OPT_TRIES;
+ }
+ // If not already overridden, set search domains.
+ const char *domains[3] = {"first.com", "second.org", "third.gov"};
+ if (!(optmask & ARES_OPT_DOMAINS)) {
+ opts.ndomains = 3;
+ opts.domains = (char**)domains;
+ optmask |= ARES_OPT_DOMAINS;
+ }
+ if (force_tcp) {
+ opts.flags |= ARES_FLAG_USEVC;
+ optmask |= ARES_OPT_FLAGS;
+ }
+
+ EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel_, &opts, optmask));
+ EXPECT_NE(nullptr, channel_);
+
+ // Set up servers after construction so we can set individual ports
+ struct ares_addr_port_node* prev = nullptr;
+ struct ares_addr_port_node* first = nullptr;
+ for (const auto& server : servers_) {
+ struct ares_addr_port_node* node = (struct ares_addr_port_node*)malloc(sizeof(*node));
+ if (prev) {
+ prev->next = node;
+ } else {
+ first = node;
+ }
+ node->next = nullptr;
+ node->family = family;
+ node->udp_port = server->udpport();
+ node->tcp_port = server->tcpport();
+ if (family == AF_INET) {
+ node->addr.addr4.s_addr = htonl(0x7F000001);
+ } else {
+ memset(&node->addr.addr6, 0, sizeof(node->addr.addr6));
+ node->addr.addr6._S6_un._S6_u8[15] = 1;
+ }
+ prev = node;
+ }
+ EXPECT_EQ(ARES_SUCCESS, ares_set_servers_ports(channel_, first));
+
+ while (first) {
+ prev = first;
+ first = first->next;
+ free(prev);
+ }
+ if (verbose) {
+ std::cerr << "Configured library with servers:";
+ std::vector<std::string> servers = GetNameServers(channel_);
+ for (const auto& server : servers) {
+ std::cerr << " " << server;
+ }
+ std::cerr << std::endl;
+ }
+}
+
+MockChannelOptsTest::~MockChannelOptsTest() {
+ if (channel_) {
+ ares_destroy(channel_);
+ }
+ channel_ = nullptr;
+}
+
+std::set<int> MockChannelOptsTest::fds() const {
+ std::set<int> fds;
+ for (const auto& server : servers_) {
+ std::set<int> serverfds = server->fds();
+ fds.insert(serverfds.begin(), serverfds.end());
+ }
+ return fds;
+}
+
+void MockChannelOptsTest::ProcessFD(int fd) {
+ for (auto& server : servers_) {
+ server->ProcessFD(fd);
+ }
+}
+
+void MockChannelOptsTest::Process() {
+ using namespace std::placeholders;
+ ProcessWork(channel_,
+ std::bind(&MockChannelOptsTest::fds, this),
+ std::bind(&MockChannelOptsTest::ProcessFD, this, _1));
+}
+
+std::ostream& operator<<(std::ostream& os, const HostResult& result) {
+ os << '{';
+ if (result.done_) {
+ os << StatusToString(result.status_) << " " << result.host_;
+ } else {
+ os << "(incomplete)";
+ }
+ os << '}';
+ return os;
+}
+
+HostEnt::HostEnt(const struct hostent *hostent) : addrtype_(-1) {
+ if (!hostent)
+ return;
+ if (hostent->h_name)
+ name_ = hostent->h_name;
+ if (hostent->h_aliases) {
+ char** palias = hostent->h_aliases;
+ while (*palias != nullptr) {
+ aliases_.push_back(*palias);
+ palias++;
+ }
+ }
+ addrtype_ = hostent->h_addrtype;
+ if (hostent->h_addr_list) {
+ char** paddr = hostent->h_addr_list;
+ while (*paddr != nullptr) {
+ std::string addr = AddressToString(*paddr, hostent->h_length);
+ addrs_.push_back(addr);
+ paddr++;
+ }
+ }
+}
+
+std::ostream& operator<<(std::ostream& os, const HostEnt& host) {
+ os << '{';
+ os << "'" << host.name_ << "' "
+ << "aliases=[";
+ for (size_t ii = 0; ii < host.aliases_.size(); ii++) {
+ if (ii > 0) os << ", ";
+ os << host.aliases_[ii];
+ }
+ os << "] ";
+ os << "addrs=[";
+ for (size_t ii = 0; ii < host.addrs_.size(); ii++) {
+ if (ii > 0) os << ", ";
+ os << host.addrs_[ii];
+ }
+ os << "]";
+ os << '}';
+ return os;
+}
+
+void HostCallback(void *data, int status, int timeouts,
+ struct hostent *hostent) {
+ EXPECT_NE(nullptr, data);
+ HostResult* result = reinterpret_cast<HostResult*>(data);
+ result->done_ = true;
+ result->status_ = status;
+ result->timeouts_ = timeouts;
+ result->host_ = HostEnt(hostent);
+ if (verbose) std::cerr << "HostCallback(" << *result << ")" << std::endl;
+}
+
std::ostream& operator<<(std::ostream& os, const AddrInfoResult& result) {
os << '{';
if (result.done_ && result.ai_) {
@@ -638,135 +638,135 @@ void AddrInfoCallback(void *data, int status, int timeouts,
if (verbose) std::cerr << "AddrInfoCallback(" << *result << ")" << std::endl;
}
-std::ostream& operator<<(std::ostream& os, const SearchResult& result) {
- os << '{';
- if (result.done_) {
- os << StatusToString(result.status_) << " " << PacketToString(result.data_);
- } else {
- os << "(incomplete)";
- }
- os << '}';
- return os;
-}
-
-void SearchCallback(void *data, int status, int timeouts,
- unsigned char *abuf, int alen) {
- EXPECT_NE(nullptr, data);
- SearchResult* result = reinterpret_cast<SearchResult*>(data);
- result->done_ = true;
- result->status_ = status;
- result->timeouts_ = timeouts;
- result->data_.assign(abuf, abuf + alen);
- if (verbose) std::cerr << "SearchCallback(" << *result << ")" << std::endl;
-}
-
-std::ostream& operator<<(std::ostream& os, const NameInfoResult& result) {
- os << '{';
- if (result.done_) {
- os << StatusToString(result.status_) << " " << result.node_ << " " << result.service_;
- } else {
- os << "(incomplete)";
- }
- os << '}';
- return os;
-}
-
-void NameInfoCallback(void *data, int status, int timeouts,
- char *node, char *service) {
- EXPECT_NE(nullptr, data);
- NameInfoResult* result = reinterpret_cast<NameInfoResult*>(data);
- result->done_ = true;
- result->status_ = status;
- result->timeouts_ = timeouts;
- result->node_ = std::string(node ? node : "");
- result->service_ = std::string(service ? service : "");
- if (verbose) std::cerr << "NameInfoCallback(" << *result << ")" << std::endl;
-}
-
-std::vector<std::string> GetNameServers(ares_channel channel) {
- struct ares_addr_port_node* servers = nullptr;
- EXPECT_EQ(ARES_SUCCESS, ares_get_servers_ports(channel, &servers));
- struct ares_addr_port_node* server = servers;
- std::vector<std::string> results;
- while (server) {
- std::stringstream ss;
- switch (server->family) {
- case AF_INET:
- ss << AddressToString((char*)&server->addr.addr4, 4);
- break;
- case AF_INET6:
- if (server->udp_port != 0) {
- ss << '[';
- }
- ss << AddressToString((char*)&server->addr.addr6, 16);
- if (server->udp_port != 0) {
- ss << ']';
- }
- break;
- default:
- results.push_back("<unknown family>");
- break;
- }
- if (server->udp_port != 0) {
- ss << ":" << server->udp_port;
- }
- results.push_back(ss.str());
- server = server->next;
- }
- if (servers) ares_free_data(servers);
- return results;
-}
-
-TransientDir::TransientDir(const std::string& dirname) : dirname_(dirname) {
- if (mkdir_(dirname_.c_str(), 0755) != 0) {
- std::cerr << "Failed to create subdirectory '" << dirname_ << "'" << std::endl;
- }
-}
-
-TransientDir::~TransientDir() {
- rmdir(dirname_.c_str());
-}
-
-TransientFile::TransientFile(const std::string& filename,
- const std::string& contents)
- : filename_(filename) {
- FILE *f = fopen(filename.c_str(), "w");
- if (f == nullptr) {
- std::cerr << "Error: failed to create '" << filename << "'" << std::endl;
- return;
- }
- int rc = fwrite(contents.data(), 1, contents.size(), f);
- if (rc != (int)contents.size()) {
- std::cerr << "Error: failed to write contents of '" << filename << "'" << std::endl;
- }
- fclose(f);
-}
-
-TransientFile::~TransientFile() {
- unlink(filename_.c_str());
-}
-
-std::string TempNam(const char *dir, const char *prefix) {
- char *p = tempnam(dir, prefix);
- std::string result(p);
- free(p);
- return result;
-}
-
-TempFile::TempFile(const std::string& contents)
- : TransientFile(TempNam(nullptr, "ares"), contents) {
-
-}
-
-VirtualizeIO::VirtualizeIO(ares_channel c)
- : channel_(c)
-{
- ares_set_socket_functions(channel_, &default_functions, 0);
-}
-
-VirtualizeIO::~VirtualizeIO() {
- ares_set_socket_functions(channel_, 0, 0);
-}
-
-} // namespace test
-} // namespace ares
+std::ostream& operator<<(std::ostream& os, const SearchResult& result) {
+ os << '{';
+ if (result.done_) {
+ os << StatusToString(result.status_) << " " << PacketToString(result.data_);
+ } else {
+ os << "(incomplete)";
+ }
+ os << '}';
+ return os;
+}
+
+void SearchCallback(void *data, int status, int timeouts,
+ unsigned char *abuf, int alen) {
+ EXPECT_NE(nullptr, data);
+ SearchResult* result = reinterpret_cast<SearchResult*>(data);
+ result->done_ = true;
+ result->status_ = status;
+ result->timeouts_ = timeouts;
+ result->data_.assign(abuf, abuf + alen);
+ if (verbose) std::cerr << "SearchCallback(" << *result << ")" << std::endl;
+}
+
+std::ostream& operator<<(std::ostream& os, const NameInfoResult& result) {
+ os << '{';
+ if (result.done_) {
+ os << StatusToString(result.status_) << " " << result.node_ << " " << result.service_;
+ } else {
+ os << "(incomplete)";
+ }
+ os << '}';
+ return os;
+}
+
+void NameInfoCallback(void *data, int status, int timeouts,
+ char *node, char *service) {
+ EXPECT_NE(nullptr, data);
+ NameInfoResult* result = reinterpret_cast<NameInfoResult*>(data);
+ result->done_ = true;
+ result->status_ = status;
+ result->timeouts_ = timeouts;
+ result->node_ = std::string(node ? node : "");
+ result->service_ = std::string(service ? service : "");
+ if (verbose) std::cerr << "NameInfoCallback(" << *result << ")" << std::endl;
+}
+
+std::vector<std::string> GetNameServers(ares_channel channel) {
+ struct ares_addr_port_node* servers = nullptr;
+ EXPECT_EQ(ARES_SUCCESS, ares_get_servers_ports(channel, &servers));
+ struct ares_addr_port_node* server = servers;
+ std::vector<std::string> results;
+ while (server) {
+ std::stringstream ss;
+ switch (server->family) {
+ case AF_INET:
+ ss << AddressToString((char*)&server->addr.addr4, 4);
+ break;
+ case AF_INET6:
+ if (server->udp_port != 0) {
+ ss << '[';
+ }
+ ss << AddressToString((char*)&server->addr.addr6, 16);
+ if (server->udp_port != 0) {
+ ss << ']';
+ }
+ break;
+ default:
+ results.push_back("<unknown family>");
+ break;
+ }
+ if (server->udp_port != 0) {
+ ss << ":" << server->udp_port;
+ }
+ results.push_back(ss.str());
+ server = server->next;
+ }
+ if (servers) ares_free_data(servers);
+ return results;
+}
+
+TransientDir::TransientDir(const std::string& dirname) : dirname_(dirname) {
+ if (mkdir_(dirname_.c_str(), 0755) != 0) {
+ std::cerr << "Failed to create subdirectory '" << dirname_ << "'" << std::endl;
+ }
+}
+
+TransientDir::~TransientDir() {
+ rmdir(dirname_.c_str());
+}
+
+TransientFile::TransientFile(const std::string& filename,
+ const std::string& contents)
+ : filename_(filename) {
+ FILE *f = fopen(filename.c_str(), "w");
+ if (f == nullptr) {
+ std::cerr << "Error: failed to create '" << filename << "'" << std::endl;
+ return;
+ }
+ int rc = fwrite(contents.data(), 1, contents.size(), f);
+ if (rc != (int)contents.size()) {
+ std::cerr << "Error: failed to write contents of '" << filename << "'" << std::endl;
+ }
+ fclose(f);
+}
+
+TransientFile::~TransientFile() {
+ unlink(filename_.c_str());
+}
+
+std::string TempNam(const char *dir, const char *prefix) {
+ char *p = tempnam(dir, prefix);
+ std::string result(p);
+ free(p);
+ return result;
+}
+
+TempFile::TempFile(const std::string& contents)
+ : TransientFile(TempNam(nullptr, "ares"), contents) {
+
+}
+
+VirtualizeIO::VirtualizeIO(ares_channel c)
+ : channel_(c)
+{
+ ares_set_socket_functions(channel_, &default_functions, 0);
+}
+
+VirtualizeIO::~VirtualizeIO() {
+ ares_set_socket_functions(channel_, 0, 0);
+}
+
+} // namespace test
+} // namespace ares
diff --git a/contrib/libs/c-ares/test/ares-test.h b/contrib/libs/c-ares/test/ares-test.h
index a905702aef..fd3bc31c27 100644
--- a/contrib/libs/c-ares/test/ares-test.h
+++ b/contrib/libs/c-ares/test/ares-test.h
@@ -1,281 +1,281 @@
-// -*- mode: c++ -*-
-#ifndef ARES_TEST_H
-#define ARES_TEST_H
-
-#include "dns-proto.h"
-// Include ares internal file for DNS protocol constants
-#include "nameser.h"
-
-#include "ares_setup.h"
-#include "ares.h"
-
-#include "gtest/gtest.h"
-#include "gmock/gmock.h"
-
-#if defined(HAVE_USER_NAMESPACE) && defined(HAVE_UTS_NAMESPACE)
-#define HAVE_CONTAINER
-#endif
-
-#include <functional>
-#include <list>
-#include <map>
-#include <memory>
-#include <set>
-#include <string>
-#include <utility>
-#include <vector>
-
-namespace ares {
-
-typedef unsigned char byte;
-
-namespace test {
-
-extern bool verbose;
-extern int mock_port;
-extern const std::vector<int> both_families;
-extern const std::vector<int> ipv4_family;
-extern const std::vector<int> ipv6_family;
-
-extern const std::vector<std::pair<int, bool>> both_families_both_modes;
-extern const std::vector<std::pair<int, bool>> ipv4_family_both_modes;
-extern const std::vector<std::pair<int, bool>> ipv6_family_both_modes;
-
-// Which parameters to use in tests
-extern std::vector<int> families;
-extern std::vector<std::pair<int, bool>> families_modes;
-
-// Process all pending work on ares-owned file descriptors, plus
-// optionally the given set-of-FDs + work function.
-void ProcessWork(ares_channel channel,
- std::function<std::set<int>()> get_extrafds,
- std::function<void(int)> process_extra);
-std::set<int> NoExtraFDs();
-
-// Test fixture that ensures library initialization, and allows
-// memory allocations to be failed.
-class LibraryTest : public ::testing::Test {
- public:
- LibraryTest() {
- EXPECT_EQ(ARES_SUCCESS,
- ares_library_init_mem(ARES_LIB_INIT_ALL,
- &LibraryTest::amalloc,
- &LibraryTest::afree,
- &LibraryTest::arealloc));
- }
- ~LibraryTest() {
- ares_library_cleanup();
- ClearFails();
- }
- // Set the n-th malloc call (of any size) from the library to fail.
- // (nth == 1 means the next call)
- static void SetAllocFail(int nth);
- // Set the next malloc call for the given size to fail.
- static void SetAllocSizeFail(size_t size);
- // Remove any pending alloc failures.
- static void ClearFails();
-
- static void *amalloc(size_t size);
- static void* arealloc(void *ptr, size_t size);
- static void afree(void *ptr);
- private:
- static bool ShouldAllocFail(size_t size);
- static unsigned long long fails_;
- static std::map<size_t, int> size_fails_;
-};
-
-// Test fixture that uses a default channel.
-class DefaultChannelTest : public LibraryTest {
- public:
- DefaultChannelTest() : channel_(nullptr) {
- EXPECT_EQ(ARES_SUCCESS, ares_init(&channel_));
- EXPECT_NE(nullptr, channel_);
- }
-
- ~DefaultChannelTest() {
- ares_destroy(channel_);
- channel_ = nullptr;
- }
-
- // Process all pending work on ares-owned file descriptors.
- void Process();
-
- protected:
- ares_channel channel_;
-};
-
-// Test fixture that uses a default channel with the specified lookup mode.
-class DefaultChannelModeTest
- : public LibraryTest,
- public ::testing::WithParamInterface<std::string> {
- public:
- DefaultChannelModeTest() : channel_(nullptr) {
- struct ares_options opts = {0};
- opts.lookups = strdup(GetParam().c_str());
- int optmask = ARES_OPT_LOOKUPS;
- EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel_, &opts, optmask));
- EXPECT_NE(nullptr, channel_);
- free(opts.lookups);
- }
-
- ~DefaultChannelModeTest() {
- ares_destroy(channel_);
- channel_ = nullptr;
- }
-
- // Process all pending work on ares-owned file descriptors.
- void Process();
-
- protected:
- ares_channel channel_;
-};
-
-// Mock DNS server to allow responses to be scripted by tests.
-class MockServer {
- public:
- MockServer(int family, int port, int tcpport = 0);
- ~MockServer();
-
- // Mock method indicating the processing of a particular <name, RRtype>
- // request.
- MOCK_METHOD2(OnRequest, void(const std::string& name, int rrtype));
-
- // Set the reply to be sent next; the query ID field will be overwritten
- // with the value from the request.
- void SetReplyData(const std::vector<byte>& reply) { reply_ = reply; }
- void SetReply(const DNSPacket* reply) { SetReplyData(reply->data()); }
- void SetReplyQID(int qid) { qid_ = qid; }
-
- // The set of file descriptors that the server handles.
- std::set<int> fds() const;
-
- // Process activity on a file descriptor.
- void ProcessFD(int fd);
-
- // Ports the server is responding to
- int udpport() const { return udpport_; }
- int tcpport() const { return tcpport_; }
-
- private:
- void ProcessRequest(int fd, struct sockaddr_storage* addr, int addrlen,
- int qid, const std::string& name, int rrtype);
-
- int udpport_;
- int tcpport_;
- int udpfd_;
- int tcpfd_;
- std::set<int> connfds_;
- std::vector<byte> reply_;
- int qid_;
-};
-
-// Test fixture that uses a mock DNS server.
-class MockChannelOptsTest : public LibraryTest {
- public:
- MockChannelOptsTest(int count, int family, bool force_tcp, struct ares_options* givenopts, int optmask);
- ~MockChannelOptsTest();
-
- // Process all pending work on ares-owned and mock-server-owned file descriptors.
- void Process();
-
- protected:
- // NiceMockServer doesn't complain about uninteresting calls.
- typedef testing::NiceMock<MockServer> NiceMockServer;
- typedef std::vector< std::unique_ptr<NiceMockServer> > NiceMockServers;
-
- std::set<int> fds() const;
- void ProcessFD(int fd);
-
- static NiceMockServers BuildServers(int count, int family, int base_port);
-
- NiceMockServers servers_;
- // Convenience reference to first server.
- NiceMockServer& server_;
- ares_channel channel_;
-};
-
-class MockChannelTest
- : public MockChannelOptsTest,
- public ::testing::WithParamInterface< std::pair<int, bool> > {
- public:
- MockChannelTest() : MockChannelOptsTest(1, GetParam().first, GetParam().second, nullptr, 0) {}
-};
-
-class MockUDPChannelTest
- : public MockChannelOptsTest,
- public ::testing::WithParamInterface<int> {
- public:
- MockUDPChannelTest() : MockChannelOptsTest(1, GetParam(), false, nullptr, 0) {}
-};
-
-class MockTCPChannelTest
- : public MockChannelOptsTest,
- public ::testing::WithParamInterface<int> {
- public:
- MockTCPChannelTest() : MockChannelOptsTest(1, GetParam(), true, nullptr, 0) {}
-};
-
-// gMock action to set the reply for a mock server.
-ACTION_P2(SetReplyData, mockserver, data) {
- mockserver->SetReplyData(data);
-}
-ACTION_P2(SetReply, mockserver, reply) {
- mockserver->SetReply(reply);
-}
-ACTION_P2(SetReplyQID, mockserver, qid) {
- mockserver->SetReplyQID(qid);
-}
-// gMock action to cancel a channel.
-ACTION_P2(CancelChannel, mockserver, channel) {
- ares_cancel(channel);
-}
-
-// C++ wrapper for struct hostent.
-struct HostEnt {
- HostEnt() : addrtype_(-1) {}
- HostEnt(const struct hostent* hostent);
- std::string name_;
- std::vector<std::string> aliases_;
- int addrtype_; // AF_INET or AF_INET6
- std::vector<std::string> addrs_;
-};
-std::ostream& operator<<(std::ostream& os, const HostEnt& result);
-
-// Structure that describes the result of an ares_host_callback invocation.
-struct HostResult {
- // Whether the callback has been invoked.
- bool done_;
- // Explicitly provided result information.
- int status_;
- int timeouts_;
- // Contents of the hostent structure, if provided.
- HostEnt host_;
-};
-std::ostream& operator<<(std::ostream& os, const HostResult& result);
-
-// Structure that describes the result of an ares_callback invocation.
-struct SearchResult {
- // Whether the callback has been invoked.
- bool done_;
- // Explicitly provided result information.
- int status_;
- int timeouts_;
- std::vector<byte> data_;
-};
-std::ostream& operator<<(std::ostream& os, const SearchResult& result);
-
-// Structure that describes the result of an ares_nameinfo_callback invocation.
-struct NameInfoResult {
- // Whether the callback has been invoked.
- bool done_;
- // Explicitly provided result information.
- int status_;
- int timeouts_;
- std::string node_;
- std::string service_;
-};
-std::ostream& operator<<(std::ostream& os, const NameInfoResult& result);
-
+// -*- mode: c++ -*-
+#ifndef ARES_TEST_H
+#define ARES_TEST_H
+
+#include "dns-proto.h"
+// Include ares internal file for DNS protocol constants
+#include "nameser.h"
+
+#include "ares_setup.h"
+#include "ares.h"
+
+#include "gtest/gtest.h"
+#include "gmock/gmock.h"
+
+#if defined(HAVE_USER_NAMESPACE) && defined(HAVE_UTS_NAMESPACE)
+#define HAVE_CONTAINER
+#endif
+
+#include <functional>
+#include <list>
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace ares {
+
+typedef unsigned char byte;
+
+namespace test {
+
+extern bool verbose;
+extern int mock_port;
+extern const std::vector<int> both_families;
+extern const std::vector<int> ipv4_family;
+extern const std::vector<int> ipv6_family;
+
+extern const std::vector<std::pair<int, bool>> both_families_both_modes;
+extern const std::vector<std::pair<int, bool>> ipv4_family_both_modes;
+extern const std::vector<std::pair<int, bool>> ipv6_family_both_modes;
+
+// Which parameters to use in tests
+extern std::vector<int> families;
+extern std::vector<std::pair<int, bool>> families_modes;
+
+// Process all pending work on ares-owned file descriptors, plus
+// optionally the given set-of-FDs + work function.
+void ProcessWork(ares_channel channel,
+ std::function<std::set<int>()> get_extrafds,
+ std::function<void(int)> process_extra);
+std::set<int> NoExtraFDs();
+
+// Test fixture that ensures library initialization, and allows
+// memory allocations to be failed.
+class LibraryTest : public ::testing::Test {
+ public:
+ LibraryTest() {
+ EXPECT_EQ(ARES_SUCCESS,
+ ares_library_init_mem(ARES_LIB_INIT_ALL,
+ &LibraryTest::amalloc,
+ &LibraryTest::afree,
+ &LibraryTest::arealloc));
+ }
+ ~LibraryTest() {
+ ares_library_cleanup();
+ ClearFails();
+ }
+ // Set the n-th malloc call (of any size) from the library to fail.
+ // (nth == 1 means the next call)
+ static void SetAllocFail(int nth);
+ // Set the next malloc call for the given size to fail.
+ static void SetAllocSizeFail(size_t size);
+ // Remove any pending alloc failures.
+ static void ClearFails();
+
+ static void *amalloc(size_t size);
+ static void* arealloc(void *ptr, size_t size);
+ static void afree(void *ptr);
+ private:
+ static bool ShouldAllocFail(size_t size);
+ static unsigned long long fails_;
+ static std::map<size_t, int> size_fails_;
+};
+
+// Test fixture that uses a default channel.
+class DefaultChannelTest : public LibraryTest {
+ public:
+ DefaultChannelTest() : channel_(nullptr) {
+ EXPECT_EQ(ARES_SUCCESS, ares_init(&channel_));
+ EXPECT_NE(nullptr, channel_);
+ }
+
+ ~DefaultChannelTest() {
+ ares_destroy(channel_);
+ channel_ = nullptr;
+ }
+
+ // Process all pending work on ares-owned file descriptors.
+ void Process();
+
+ protected:
+ ares_channel channel_;
+};
+
+// Test fixture that uses a default channel with the specified lookup mode.
+class DefaultChannelModeTest
+ : public LibraryTest,
+ public ::testing::WithParamInterface<std::string> {
+ public:
+ DefaultChannelModeTest() : channel_(nullptr) {
+ struct ares_options opts = {0};
+ opts.lookups = strdup(GetParam().c_str());
+ int optmask = ARES_OPT_LOOKUPS;
+ EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel_, &opts, optmask));
+ EXPECT_NE(nullptr, channel_);
+ free(opts.lookups);
+ }
+
+ ~DefaultChannelModeTest() {
+ ares_destroy(channel_);
+ channel_ = nullptr;
+ }
+
+ // Process all pending work on ares-owned file descriptors.
+ void Process();
+
+ protected:
+ ares_channel channel_;
+};
+
+// Mock DNS server to allow responses to be scripted by tests.
+class MockServer {
+ public:
+ MockServer(int family, int port, int tcpport = 0);
+ ~MockServer();
+
+ // Mock method indicating the processing of a particular <name, RRtype>
+ // request.
+ MOCK_METHOD2(OnRequest, void(const std::string& name, int rrtype));
+
+ // Set the reply to be sent next; the query ID field will be overwritten
+ // with the value from the request.
+ void SetReplyData(const std::vector<byte>& reply) { reply_ = reply; }
+ void SetReply(const DNSPacket* reply) { SetReplyData(reply->data()); }
+ void SetReplyQID(int qid) { qid_ = qid; }
+
+ // The set of file descriptors that the server handles.
+ std::set<int> fds() const;
+
+ // Process activity on a file descriptor.
+ void ProcessFD(int fd);
+
+ // Ports the server is responding to
+ int udpport() const { return udpport_; }
+ int tcpport() const { return tcpport_; }
+
+ private:
+ void ProcessRequest(int fd, struct sockaddr_storage* addr, int addrlen,
+ int qid, const std::string& name, int rrtype);
+
+ int udpport_;
+ int tcpport_;
+ int udpfd_;
+ int tcpfd_;
+ std::set<int> connfds_;
+ std::vector<byte> reply_;
+ int qid_;
+};
+
+// Test fixture that uses a mock DNS server.
+class MockChannelOptsTest : public LibraryTest {
+ public:
+ MockChannelOptsTest(int count, int family, bool force_tcp, struct ares_options* givenopts, int optmask);
+ ~MockChannelOptsTest();
+
+ // Process all pending work on ares-owned and mock-server-owned file descriptors.
+ void Process();
+
+ protected:
+ // NiceMockServer doesn't complain about uninteresting calls.
+ typedef testing::NiceMock<MockServer> NiceMockServer;
+ typedef std::vector< std::unique_ptr<NiceMockServer> > NiceMockServers;
+
+ std::set<int> fds() const;
+ void ProcessFD(int fd);
+
+ static NiceMockServers BuildServers(int count, int family, int base_port);
+
+ NiceMockServers servers_;
+ // Convenience reference to first server.
+ NiceMockServer& server_;
+ ares_channel channel_;
+};
+
+class MockChannelTest
+ : public MockChannelOptsTest,
+ public ::testing::WithParamInterface< std::pair<int, bool> > {
+ public:
+ MockChannelTest() : MockChannelOptsTest(1, GetParam().first, GetParam().second, nullptr, 0) {}
+};
+
+class MockUDPChannelTest
+ : public MockChannelOptsTest,
+ public ::testing::WithParamInterface<int> {
+ public:
+ MockUDPChannelTest() : MockChannelOptsTest(1, GetParam(), false, nullptr, 0) {}
+};
+
+class MockTCPChannelTest
+ : public MockChannelOptsTest,
+ public ::testing::WithParamInterface<int> {
+ public:
+ MockTCPChannelTest() : MockChannelOptsTest(1, GetParam(), true, nullptr, 0) {}
+};
+
+// gMock action to set the reply for a mock server.
+ACTION_P2(SetReplyData, mockserver, data) {
+ mockserver->SetReplyData(data);
+}
+ACTION_P2(SetReply, mockserver, reply) {
+ mockserver->SetReply(reply);
+}
+ACTION_P2(SetReplyQID, mockserver, qid) {
+ mockserver->SetReplyQID(qid);
+}
+// gMock action to cancel a channel.
+ACTION_P2(CancelChannel, mockserver, channel) {
+ ares_cancel(channel);
+}
+
+// C++ wrapper for struct hostent.
+struct HostEnt {
+ HostEnt() : addrtype_(-1) {}
+ HostEnt(const struct hostent* hostent);
+ std::string name_;
+ std::vector<std::string> aliases_;
+ int addrtype_; // AF_INET or AF_INET6
+ std::vector<std::string> addrs_;
+};
+std::ostream& operator<<(std::ostream& os, const HostEnt& result);
+
+// Structure that describes the result of an ares_host_callback invocation.
+struct HostResult {
+ // Whether the callback has been invoked.
+ bool done_;
+ // Explicitly provided result information.
+ int status_;
+ int timeouts_;
+ // Contents of the hostent structure, if provided.
+ HostEnt host_;
+};
+std::ostream& operator<<(std::ostream& os, const HostResult& result);
+
+// Structure that describes the result of an ares_callback invocation.
+struct SearchResult {
+ // Whether the callback has been invoked.
+ bool done_;
+ // Explicitly provided result information.
+ int status_;
+ int timeouts_;
+ std::vector<byte> data_;
+};
+std::ostream& operator<<(std::ostream& os, const SearchResult& result);
+
+// Structure that describes the result of an ares_nameinfo_callback invocation.
+struct NameInfoResult {
+ // Whether the callback has been invoked.
+ bool done_;
+ // Explicitly provided result information.
+ int status_;
+ int timeouts_;
+ std::string node_;
+ std::string service_;
+};
+std::ostream& operator<<(std::ostream& os, const NameInfoResult& result);
+
struct AddrInfoDeleter {
void operator() (ares_addrinfo *ptr) {
if (ptr) ares_freeaddrinfo(ptr);
@@ -300,51 +300,51 @@ struct AddrInfoResult {
};
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,
- struct hostent *hostent);
-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);
+// Standard implementation of ares callbacks that fill out the corresponding
+// structures.
+void HostCallback(void *data, int status, int timeouts,
+ struct hostent *hostent);
+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);
-
-// Retrieve the name servers used by a channel.
-std::vector<std::string> GetNameServers(ares_channel channel);
-
-
-// RAII class to temporarily create a directory of a given name.
-class TransientDir {
- public:
- TransientDir(const std::string& dirname);
- ~TransientDir();
-
- private:
- std::string dirname_;
-};
-
-// C++ wrapper around tempnam()
-std::string TempNam(const char *dir, const char *prefix);
-
-// RAII class to temporarily create file of a given name and contents.
-class TransientFile {
- public:
- TransientFile(const std::string &filename, const std::string &contents);
- ~TransientFile();
-
- protected:
- std::string filename_;
-};
-
-// RAII class for a temporary file with the given contents.
-class TempFile : public TransientFile {
- public:
- TempFile(const std::string& contents);
- const char* filename() const { return filename_.c_str(); }
-};
-
+
+// Retrieve the name servers used by a channel.
+std::vector<std::string> GetNameServers(ares_channel channel);
+
+
+// RAII class to temporarily create a directory of a given name.
+class TransientDir {
+ public:
+ TransientDir(const std::string& dirname);
+ ~TransientDir();
+
+ private:
+ std::string dirname_;
+};
+
+// C++ wrapper around tempnam()
+std::string TempNam(const char *dir, const char *prefix);
+
+// RAII class to temporarily create file of a given name and contents.
+class TransientFile {
+ public:
+ TransientFile(const std::string &filename, const std::string &contents);
+ ~TransientFile();
+
+ protected:
+ std::string filename_;
+};
+
+// RAII class for a temporary file with the given contents.
+class TempFile : public TransientFile {
+ public:
+ TempFile(const std::string& contents);
+ const char* filename() const { return filename_.c_str(); }
+};
+
#ifdef _WIN32
extern "C" {
@@ -379,111 +379,111 @@ static int unsetenv(const char *name)
} /* extern "C" */
#endif
-// RAII class for a temporary environment variable value.
-class EnvValue {
- public:
- EnvValue(const char *name, const char *value) : name_(name), restore_(false) {
- char *original = getenv(name);
- if (original) {
- restore_ = true;
- original_ = original;
- }
- setenv(name_.c_str(), value, 1);
- }
- ~EnvValue() {
- if (restore_) {
- setenv(name_.c_str(), original_.c_str(), 1);
- } else {
- unsetenv(name_.c_str());
- }
- }
- private:
- std::string name_;
- bool restore_;
- std::string original_;
-};
-
-
-#ifdef HAVE_CONTAINER
-// Linux-specific functionality for running code in a container, implemented
-// in ares-test-ns.cc
-typedef std::function<int(void)> VoidToIntFn;
-typedef std::vector<std::pair<std::string, std::string>> NameContentList;
-
-class ContainerFilesystem {
- public:
- ContainerFilesystem(NameContentList files, const std::string& mountpt);
- ~ContainerFilesystem();
- std::string root() const { return rootdir_; };
- std::string mountpt() const { return mountpt_; };
- private:
- void EnsureDirExists(const std::string& dir);
- std::string rootdir_;
- std::string mountpt_;
- std::list<std::string> dirs_;
- std::vector<std::unique_ptr<TransientFile>> files_;
-};
-
-int RunInContainer(ContainerFilesystem* fs, const std::string& hostname,
- const std::string& domainname, VoidToIntFn fn);
-
-#define ICLASS_NAME(casename, testname) Contained##casename##_##testname
-#define CONTAINED_TEST_F(casename, testname, hostname, domainname, files) \
- class ICLASS_NAME(casename, testname) : public casename { \
- public: \
- ICLASS_NAME(casename, testname)() {} \
- static int InnerTestBody(); \
- }; \
- TEST_F(ICLASS_NAME(casename, testname), _) { \
- ContainerFilesystem chroot(files, ".."); \
- VoidToIntFn fn(ICLASS_NAME(casename, testname)::InnerTestBody); \
- EXPECT_EQ(0, RunInContainer(&chroot, hostname, domainname, fn)); \
- } \
- int ICLASS_NAME(casename, testname)::InnerTestBody()
-
-#endif
-
-/* Assigns virtual IO functions to a channel. These functions simply call
- * the actual system functions.
- */
-class VirtualizeIO {
-public:
- VirtualizeIO(ares_channel);
- ~VirtualizeIO();
-
- static const ares_socket_functions default_functions;
-private:
- ares_channel channel_;
-};
-
-/*
- * Slightly white-box macro to generate two runs for a given test case:
- * One with no modifications, and one with all IO functions set to use
- * the virtual io structure.
- * Since no magic socket setup or anything is done in the latter case
- * this should probably only be used for test with very vanilla IO
- * requirements.
- */
-#define VCLASS_NAME(casename, testname) Virt##casename##_##testname
-#define VIRT_NONVIRT_TEST_F(casename, testname) \
- class VCLASS_NAME(casename, testname) : public casename { \
- public: \
- VCLASS_NAME(casename, testname)() {} \
- void InnerTestBody(); \
- }; \
- GTEST_TEST_(casename, testname, VCLASS_NAME(casename, testname), \
- ::testing::internal::GetTypeId<casename>()) { \
- InnerTestBody(); \
- } \
- GTEST_TEST_(casename, testname##_virtualized, \
- VCLASS_NAME(casename, testname), \
- ::testing::internal::GetTypeId<casename>()) { \
- VirtualizeIO vio(channel_); \
- InnerTestBody(); \
- } \
- void VCLASS_NAME(casename, testname)::InnerTestBody()
-
-} // namespace test
-} // namespace ares
-
-#endif
+// RAII class for a temporary environment variable value.
+class EnvValue {
+ public:
+ EnvValue(const char *name, const char *value) : name_(name), restore_(false) {
+ char *original = getenv(name);
+ if (original) {
+ restore_ = true;
+ original_ = original;
+ }
+ setenv(name_.c_str(), value, 1);
+ }
+ ~EnvValue() {
+ if (restore_) {
+ setenv(name_.c_str(), original_.c_str(), 1);
+ } else {
+ unsetenv(name_.c_str());
+ }
+ }
+ private:
+ std::string name_;
+ bool restore_;
+ std::string original_;
+};
+
+
+#ifdef HAVE_CONTAINER
+// Linux-specific functionality for running code in a container, implemented
+// in ares-test-ns.cc
+typedef std::function<int(void)> VoidToIntFn;
+typedef std::vector<std::pair<std::string, std::string>> NameContentList;
+
+class ContainerFilesystem {
+ public:
+ ContainerFilesystem(NameContentList files, const std::string& mountpt);
+ ~ContainerFilesystem();
+ std::string root() const { return rootdir_; };
+ std::string mountpt() const { return mountpt_; };
+ private:
+ void EnsureDirExists(const std::string& dir);
+ std::string rootdir_;
+ std::string mountpt_;
+ std::list<std::string> dirs_;
+ std::vector<std::unique_ptr<TransientFile>> files_;
+};
+
+int RunInContainer(ContainerFilesystem* fs, const std::string& hostname,
+ const std::string& domainname, VoidToIntFn fn);
+
+#define ICLASS_NAME(casename, testname) Contained##casename##_##testname
+#define CONTAINED_TEST_F(casename, testname, hostname, domainname, files) \
+ class ICLASS_NAME(casename, testname) : public casename { \
+ public: \
+ ICLASS_NAME(casename, testname)() {} \
+ static int InnerTestBody(); \
+ }; \
+ TEST_F(ICLASS_NAME(casename, testname), _) { \
+ ContainerFilesystem chroot(files, ".."); \
+ VoidToIntFn fn(ICLASS_NAME(casename, testname)::InnerTestBody); \
+ EXPECT_EQ(0, RunInContainer(&chroot, hostname, domainname, fn)); \
+ } \
+ int ICLASS_NAME(casename, testname)::InnerTestBody()
+
+#endif
+
+/* Assigns virtual IO functions to a channel. These functions simply call
+ * the actual system functions.
+ */
+class VirtualizeIO {
+public:
+ VirtualizeIO(ares_channel);
+ ~VirtualizeIO();
+
+ static const ares_socket_functions default_functions;
+private:
+ ares_channel channel_;
+};
+
+/*
+ * Slightly white-box macro to generate two runs for a given test case:
+ * One with no modifications, and one with all IO functions set to use
+ * the virtual io structure.
+ * Since no magic socket setup or anything is done in the latter case
+ * this should probably only be used for test with very vanilla IO
+ * requirements.
+ */
+#define VCLASS_NAME(casename, testname) Virt##casename##_##testname
+#define VIRT_NONVIRT_TEST_F(casename, testname) \
+ class VCLASS_NAME(casename, testname) : public casename { \
+ public: \
+ VCLASS_NAME(casename, testname)() {} \
+ void InnerTestBody(); \
+ }; \
+ GTEST_TEST_(casename, testname, VCLASS_NAME(casename, testname), \
+ ::testing::internal::GetTypeId<casename>()) { \
+ InnerTestBody(); \
+ } \
+ GTEST_TEST_(casename, testname##_virtualized, \
+ VCLASS_NAME(casename, testname), \
+ ::testing::internal::GetTypeId<casename>()) { \
+ VirtualizeIO vio(channel_); \
+ InnerTestBody(); \
+ } \
+ void VCLASS_NAME(casename, testname)::InnerTestBody()
+
+} // namespace test
+} // namespace ares
+
+#endif
diff --git a/contrib/libs/c-ares/test/config.h b/contrib/libs/c-ares/test/config.h
index ce02fa3963..787575c8e0 100644
--- a/contrib/libs/c-ares/test/config.h
+++ b/contrib/libs/c-ares/test/config.h
@@ -1,81 +1,81 @@
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* define if the compiler supports basic C++11 syntax */
-/* #undef HAVE_CXX11 */
-
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the <netdb.h> header file. */
-#define HAVE_NETDB_H 1
-
-/* Define to 1 if you have the <netinet/tcp.h> header file. */
-#define HAVE_NETINET_TCP_H 1
-
-/* Define if you have POSIX threads libraries and header files. */
-#define HAVE_PTHREAD 1
-
-/* Have PTHREAD_PRIO_INHERIT. */
-#define HAVE_PTHREAD_PRIO_INHERIT 1
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
-
-/* Whether user namespaces are available */
-#define HAVE_USER_NAMESPACE 1
-
-/* Whether UTS namespaces are available */
-#define HAVE_UTS_NAMESPACE 1
-
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
-#define LT_OBJDIR ".libs/"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "-"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "c-ares-test"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "c-ares-test -"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "c-ares-test"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "-"
-
-/* Define to necessary symbol if this constant uses a non-standard name on
- your system. */
-/* #undef PTHREAD_CREATE_JOINABLE */
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* define if the compiler supports basic C++11 syntax */
+/* #undef HAVE_CXX11 */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+#define HAVE_NETINET_TCP_H 1
+
+/* Define if you have POSIX threads libraries and header files. */
+#define HAVE_PTHREAD 1
+
+/* Have PTHREAD_PRIO_INHERIT. */
+#define HAVE_PTHREAD_PRIO_INHERIT 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Whether user namespaces are available */
+#define HAVE_USER_NAMESPACE 1
+
+/* Whether UTS namespaces are available */
+#define HAVE_UTS_NAMESPACE 1
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#define LT_OBJDIR ".libs/"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "-"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "c-ares-test"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "c-ares-test -"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "c-ares-test"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "-"
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
+/* #undef PTHREAD_CREATE_JOINABLE */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
diff --git a/contrib/libs/c-ares/test/dns-proto-test.cc b/contrib/libs/c-ares/test/dns-proto-test.cc
index 2d9a9ec34d..0c36a0c922 100644
--- a/contrib/libs/c-ares/test/dns-proto-test.cc
+++ b/contrib/libs/c-ares/test/dns-proto-test.cc
@@ -1,131 +1,131 @@
-#include "ares-test.h"
-#include "dns-proto.h"
-
-#include <vector>
-
-namespace ares {
-namespace test {
-
-TEST(DNSProto, EncodeQuestions) {
- DNSPacket pkt;
- pkt.set_qid(0x1234).set_response().set_aa()
- .add_question(new DNSQuestion("example.com.", ns_t_a))
- .add_question(new DNSQuestion("www.example.com", ns_t_aaaa, ns_c_chaos));
-
- 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, 0x02, // num questions
- 0x00, 0x00, // num answer RRs
- 0x00, 0x00, // num authority RRs
- 0x00, 0x00, // num additional RRs
- // Question 1
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x01, // type A
- 0x00, 0x01, // class IN
- // Question 2
- 0x03, 'w', 'w', 'w',
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x1C, // type AAAA = 28
- 0x00, 0x03, // class CHAOS = 3
- };
- EXPECT_EQ(data, pkt.data());
-}
-
-TEST(DNSProto, EncodeSingleNameAnswers) {
- DNSPacket pkt;
- pkt.qid_ = 0x1234;
- pkt.response_ = true;
- pkt.aa_ = true;
- pkt.opcode_ = ns_o_query;
- pkt.add_answer(new DNSCnameRR("example.com", 0x01020304, "other.com."));
- pkt.add_auth(new DNSPtrRR("www.example.com", 0x01020304, "www.other.com"));
-
- 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, 0x00, // num questions
- 0x00, 0x01, // num answer RRs
- 0x00, 0x01, // num authority RRs
- 0x00, 0x00, // num additional RRs
- // Answer 1
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x05, // RR type
- 0x00, 0x01, // class IN
- 0x01, 0x02, 0x03, 0x04, // TTL
- 0x00, 0x0B, // rdata length
- 0x05, 'o', 't', 'h', 'e', 'r',
- 0x03, 'c', 'o', 'm',
- 0x00,
- // Authority 1
- 0x03, 'w', 'w', 'w',
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x0c, // RR type
- 0x00, 0x01, // class IN
- 0x01, 0x02, 0x03, 0x04, // TTL
- 0x00, 0x0F, // rdata length
- 0x03, 'w', 'w', 'w',
- 0x05, 'o', 't', 'h', 'e', 'r',
- 0x03, 'c', 'o', 'm',
- 0x00,
- };
- EXPECT_EQ(data, pkt.data());
-}
-
-TEST(DNSProto, EncodeAddressAnswers) {
- DNSPacket pkt;
- pkt.qid_ = 0x1234;
- pkt.response_ = true;
- pkt.aa_ = true;
- pkt.opcode_ = ns_o_query;
- std::vector<byte> addrv4 = {0x02, 0x03, 0x04, 0x05};
- pkt.add_answer(new DNSARR("example.com", 0x01020304, addrv4));
- byte addrv6[16] = {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
- 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04};
- pkt.add_additional(new DNSAaaaRR("www.example.com", 0x01020304, addrv6, 16));
-
- 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, 0x00, // num questions
- 0x00, 0x01, // num answer RRs
- 0x00, 0x00, // num authority RRs
- 0x00, 0x01, // num additional RRs
- // Answer 1
- 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
- 0x03, 'c', 'o', 'm',
- 0x00,
- 0x00, 0x01, // RR type
- 0x00, 0x01, // class IN
- 0x01, 0x02, 0x03, 0x04, // TTL
- 0x00, 0x04, // rdata length
- 0x02, 0x03, 0x04, 0x05,
- // Additional 1
- 0x03, 'w', 'w', 'w',
- 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
- 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
- 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04
- };
- EXPECT_EQ(data, pkt.data());
-}
-
-
-} // namespace test
-} // namespace ares
+#include "ares-test.h"
+#include "dns-proto.h"
+
+#include <vector>
+
+namespace ares {
+namespace test {
+
+TEST(DNSProto, EncodeQuestions) {
+ DNSPacket pkt;
+ pkt.set_qid(0x1234).set_response().set_aa()
+ .add_question(new DNSQuestion("example.com.", ns_t_a))
+ .add_question(new DNSQuestion("www.example.com", ns_t_aaaa, ns_c_chaos));
+
+ 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, 0x02, // num questions
+ 0x00, 0x00, // num answer RRs
+ 0x00, 0x00, // num authority RRs
+ 0x00, 0x00, // num additional RRs
+ // Question 1
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x01, // type A
+ 0x00, 0x01, // class IN
+ // Question 2
+ 0x03, 'w', 'w', 'w',
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x1C, // type AAAA = 28
+ 0x00, 0x03, // class CHAOS = 3
+ };
+ EXPECT_EQ(data, pkt.data());
+}
+
+TEST(DNSProto, EncodeSingleNameAnswers) {
+ DNSPacket pkt;
+ pkt.qid_ = 0x1234;
+ pkt.response_ = true;
+ pkt.aa_ = true;
+ pkt.opcode_ = ns_o_query;
+ pkt.add_answer(new DNSCnameRR("example.com", 0x01020304, "other.com."));
+ pkt.add_auth(new DNSPtrRR("www.example.com", 0x01020304, "www.other.com"));
+
+ 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, 0x00, // num questions
+ 0x00, 0x01, // num answer RRs
+ 0x00, 0x01, // num authority RRs
+ 0x00, 0x00, // num additional RRs
+ // Answer 1
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x05, // RR type
+ 0x00, 0x01, // class IN
+ 0x01, 0x02, 0x03, 0x04, // TTL
+ 0x00, 0x0B, // rdata length
+ 0x05, 'o', 't', 'h', 'e', 'r',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ // Authority 1
+ 0x03, 'w', 'w', 'w',
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x0c, // RR type
+ 0x00, 0x01, // class IN
+ 0x01, 0x02, 0x03, 0x04, // TTL
+ 0x00, 0x0F, // rdata length
+ 0x03, 'w', 'w', 'w',
+ 0x05, 'o', 't', 'h', 'e', 'r',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ };
+ EXPECT_EQ(data, pkt.data());
+}
+
+TEST(DNSProto, EncodeAddressAnswers) {
+ DNSPacket pkt;
+ pkt.qid_ = 0x1234;
+ pkt.response_ = true;
+ pkt.aa_ = true;
+ pkt.opcode_ = ns_o_query;
+ std::vector<byte> addrv4 = {0x02, 0x03, 0x04, 0x05};
+ pkt.add_answer(new DNSARR("example.com", 0x01020304, addrv4));
+ byte addrv6[16] = {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
+ 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04};
+ pkt.add_additional(new DNSAaaaRR("www.example.com", 0x01020304, addrv6, 16));
+
+ 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, 0x00, // num questions
+ 0x00, 0x01, // num answer RRs
+ 0x00, 0x00, // num authority RRs
+ 0x00, 0x01, // num additional RRs
+ // Answer 1
+ 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e',
+ 0x03, 'c', 'o', 'm',
+ 0x00,
+ 0x00, 0x01, // RR type
+ 0x00, 0x01, // class IN
+ 0x01, 0x02, 0x03, 0x04, // TTL
+ 0x00, 0x04, // rdata length
+ 0x02, 0x03, 0x04, 0x05,
+ // Additional 1
+ 0x03, 'w', 'w', 'w',
+ 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
+ 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
+ 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04
+ };
+ EXPECT_EQ(data, pkt.data());
+}
+
+
+} // namespace test
+} // namespace ares
diff --git a/contrib/libs/c-ares/test/dns-proto.cc b/contrib/libs/c-ares/test/dns-proto.cc
index 7f50be3534..d2fa8b15be 100644
--- a/contrib/libs/c-ares/test/dns-proto.cc
+++ b/contrib/libs/c-ares/test/dns-proto.cc
@@ -1,638 +1,638 @@
-#include "dns-proto.h"
-
-// Include ares internal file for DNS protocol details
-#include "ares_setup.h"
-#include "ares.h"
-#include "ares_dns.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <sstream>
-
-namespace ares {
-
-std::string HexDump(std::vector<byte> data) {
- std::stringstream ss;
- for (size_t ii = 0; ii < data.size(); ii++) {
- char buffer[2 + 1];
- sprintf(buffer, "%02x", data[ii]);
- ss << buffer;
- }
- return ss.str();
-}
-
-std::string HexDump(const byte *data, int len) {
- return HexDump(std::vector<byte>(data, data + len));
-}
-
-std::string HexDump(const char *data, int len) {
- return HexDump(reinterpret_cast<const byte*>(data), len);
-}
-
-std::string StatusToString(int status) {
- switch (status) {
- case ARES_SUCCESS: return "ARES_SUCCESS";
- case ARES_ENODATA: return "ARES_ENODATA";
- case ARES_EFORMERR: return "ARES_EFORMERR";
- case ARES_ESERVFAIL: return "ARES_ESERVFAIL";
- case ARES_ENOTFOUND: return "ARES_ENOTFOUND";
- case ARES_ENOTIMP: return "ARES_ENOTIMP";
- case ARES_EREFUSED: return "ARES_EREFUSED";
- case ARES_EBADQUERY: return "ARES_EBADQUERY";
- case ARES_EBADNAME: return "ARES_EBADNAME";
- case ARES_EBADFAMILY: return "ARES_EBADFAMILY";
- case ARES_EBADRESP: return "ARES_EBADRESP";
- case ARES_ECONNREFUSED: return "ARES_ECONNREFUSED";
- case ARES_ETIMEOUT: return "ARES_ETIMEOUT";
- case ARES_EOF: return "ARES_EOF";
- case ARES_EFILE: return "ARES_EFILE";
- case ARES_ENOMEM: return "ARES_ENOMEM";
- case ARES_EDESTRUCTION: return "ARES_EDESTRUCTION";
- case ARES_EBADSTR: return "ARES_EBADSTR";
- case ARES_EBADFLAGS: return "ARES_EBADFLAGS";
- case ARES_ENONAME: return "ARES_ENONAME";
- case ARES_EBADHINTS: return "ARES_EBADHINTS";
- case ARES_ENOTINITIALIZED: return "ARES_ENOTINITIALIZED";
- case ARES_ELOADIPHLPAPI: return "ARES_ELOADIPHLPAPI";
- case ARES_EADDRGETNETWORKPARAMS: return "ARES_EADDRGETNETWORKPARAMS";
- case ARES_ECANCELLED: return "ARES_ECANCELLED";
- default: return "UNKNOWN";
- }
-}
-
-std::string RcodeToString(int rcode) {
- switch (rcode) {
- case ns_r_noerror: return "NOERROR";
- case ns_r_formerr: return "FORMERR";
- case ns_r_servfail: return "SERVFAIL";
- case ns_r_nxdomain: return "NXDOMAIN";
- case ns_r_notimpl: return "NOTIMPL";
- case ns_r_refused: return "REFUSED";
- case ns_r_yxdomain: return "YXDOMAIN";
- case ns_r_yxrrset: return "YXRRSET";
- case ns_r_nxrrset: return "NXRRSET";
- case ns_r_notauth: return "NOTAUTH";
- case ns_r_notzone: return "NOTZONE";
- case ns_r_badsig: return "BADSIG";
- case ns_r_badkey: return "BADKEY";
- case ns_r_badtime: return "BADTIME";
- default: return "UNKNOWN";
- }
-}
-
-std::string RRTypeToString(int rrtype) {
- switch (rrtype) {
- case ns_t_a: return "A";
- case ns_t_ns: return "NS";
- case ns_t_md: return "MD";
- case ns_t_mf: return "MF";
- case ns_t_cname: return "CNAME";
- case ns_t_soa: return "SOA";
- case ns_t_mb: return "MB";
- case ns_t_mg: return "MG";
- case ns_t_mr: return "MR";
- case ns_t_null: return "NULL";
- case ns_t_wks: return "WKS";
- case ns_t_ptr: return "PTR";
- case ns_t_hinfo: return "HINFO";
- case ns_t_minfo: return "MINFO";
- case ns_t_mx: return "MX";
- case ns_t_txt: return "TXT";
- case ns_t_rp: return "RP";
- case ns_t_afsdb: return "AFSDB";
- case ns_t_x25: return "X25";
- case ns_t_isdn: return "ISDN";
- case ns_t_rt: return "RT";
- case ns_t_nsap: return "NSAP";
- case ns_t_nsap_ptr: return "NSAP_PTR";
- case ns_t_sig: return "SIG";
- case ns_t_key: return "KEY";
- case ns_t_px: return "PX";
- case ns_t_gpos: return "GPOS";
- case ns_t_aaaa: return "AAAA";
- case ns_t_loc: return "LOC";
- case ns_t_nxt: return "NXT";
- case ns_t_eid: return "EID";
- case ns_t_nimloc: return "NIMLOC";
- case ns_t_srv: return "SRV";
- case ns_t_atma: return "ATMA";
- case ns_t_naptr: return "NAPTR";
- case ns_t_kx: return "KX";
- case ns_t_cert: return "CERT";
- case ns_t_a6: return "A6";
- case ns_t_dname: return "DNAME";
- case ns_t_sink: return "SINK";
- case ns_t_opt: return "OPT";
- case ns_t_apl: return "APL";
- case ns_t_ds: return "DS";
- case ns_t_sshfp: return "SSHFP";
- case ns_t_rrsig: return "RRSIG";
- case ns_t_nsec: return "NSEC";
- case ns_t_dnskey: return "DNSKEY";
- case ns_t_tkey: return "TKEY";
- case ns_t_tsig: return "TSIG";
- case ns_t_ixfr: return "IXFR";
- case ns_t_axfr: return "AXFR";
- case ns_t_mailb: return "MAILB";
- case ns_t_maila: return "MAILA";
- case ns_t_any: return "ANY";
- case ns_t_zxfr: return "ZXFR";
- case ns_t_max: return "MAX";
- default: return "UNKNOWN";
- }
-}
-
-std::string ClassToString(int qclass) {
- switch (qclass) {
- case ns_c_in: return "IN";
- case ns_c_chaos: return "CHAOS";
- case ns_c_hs: return "HESIOD";
- case ns_c_none: return "NONE";
- case ns_c_any: return "ANY";
- default: return "UNKNOWN";
- }
-}
-
-std::string AddressToString(const void* vaddr, int len) {
- const byte* addr = reinterpret_cast<const byte*>(vaddr);
- std::stringstream ss;
- if (len == 4) {
- char buffer[4*4 + 3 + 1];
- sprintf(buffer, "%u.%u.%u.%u",
- (unsigned char)addr[0],
- (unsigned char)addr[1],
- (unsigned char)addr[2],
- (unsigned char)addr[3]);
- ss << buffer;
- } else if (len == 16) {
- for (int ii = 0; ii < 16; ii+=2) {
- if (ii > 0) ss << ':';
- char buffer[4 + 1];
- sprintf(buffer, "%02x%02x", (unsigned char)addr[ii], (unsigned char)addr[ii+1]);
- ss << buffer;
- }
- } else {
- ss << "!" << HexDump(addr, len) << "!";
- }
- return ss.str();
-}
-
-std::string PacketToString(const std::vector<byte>& packet) {
- const byte* data = packet.data();
- int len = packet.size();
- std::stringstream ss;
- if (len < NS_HFIXEDSZ) {
- ss << "(too short, len " << len << ")";
- return ss.str();
- }
- ss << ((DNS_HEADER_QR(data) == 0) ? "REQ " : "RSP ");
- switch (DNS_HEADER_OPCODE(data)) {
- case ns_o_query: ss << "QRY "; break;
- case ns_o_iquery: ss << "IQRY "; break;
- case ns_o_status: ss << "STATUS "; break;
- case ns_o_notify: ss << "NOTIFY "; break;
- case ns_o_update: ss << "UPDATE "; break;
- default: ss << "UNKNOWN(" << DNS_HEADER_OPCODE(data) << ") "; break;
- }
- if (DNS_HEADER_AA(data)) ss << "AA ";
- if (DNS_HEADER_TC(data)) ss << "TC ";
- if (DNS_HEADER_RD(data)) ss << "RD ";
- if (DNS_HEADER_RA(data)) ss << "RA ";
- if (DNS_HEADER_Z(data)) ss << "Z ";
- if (DNS_HEADER_QR(data) == 1) ss << RcodeToString(DNS_HEADER_RCODE(data));
-
- int nquestions = DNS_HEADER_QDCOUNT(data);
- int nanswers = DNS_HEADER_ANCOUNT(data);
- int nauths = DNS_HEADER_NSCOUNT(data);
- int nadds = DNS_HEADER_ARCOUNT(data);
-
- const byte* pq = data + NS_HFIXEDSZ;
- len -= NS_HFIXEDSZ;
- for (int ii = 0; ii < nquestions; ii++) {
- ss << " Q:" << QuestionToString(packet, &pq, &len);
- }
- const byte* prr = pq;
- for (int ii = 0; ii < nanswers; ii++) {
- ss << " A:" << RRToString(packet, &prr, &len);
- }
- for (int ii = 0; ii < nauths; ii++) {
- ss << " AUTH:" << RRToString(packet, &prr, &len);
- }
- for (int ii = 0; ii < nadds; ii++) {
- ss << " ADD:" << RRToString(packet, &prr, &len);
- }
- return ss.str();
-}
-
-std::string QuestionToString(const std::vector<byte>& packet,
- const byte** data, int* len) {
- std::stringstream ss;
- ss << "{";
- if (*len < NS_QFIXEDSZ) {
- ss << "(too short, len " << *len << ")";
- return ss.str();
- }
-
- char *name = nullptr;
- long enclen;
- int rc = ares_expand_name(*data, packet.data(), packet.size(), &name, &enclen);
- if (rc != ARES_SUCCESS) {
- ss << "(error from ares_expand_name)";
- return ss.str();
- }
- if (enclen > *len) {
- ss << "(error, encoded name len " << enclen << "bigger than remaining data " << *len << " bytes)";
- return ss.str();
- }
- *len -= enclen;
- *data += enclen;
- ss << "'" << name << "' ";
- ares_free_string(name);
- if (*len < NS_QFIXEDSZ) {
- ss << "(too short, len left " << *len << ")";
- return ss.str();
- }
- ss << ClassToString(DNS_QUESTION_CLASS(*data)) << " ";
- ss << RRTypeToString(DNS_QUESTION_TYPE(*data));
- *data += NS_QFIXEDSZ;
- *len -= NS_QFIXEDSZ;
- ss << "}";
- return ss.str();
-}
-
-std::string RRToString(const std::vector<byte>& packet,
- const byte** data, int* len) {
- std::stringstream ss;
- ss << "{";
- if (*len < NS_RRFIXEDSZ) {
- ss << "too short, len " << *len << ")";
- return ss.str();
- }
-
- char *name = nullptr;
- long enclen;
- int rc = ares_expand_name(*data, packet.data(), packet.size(), &name, &enclen);
- if (rc != ARES_SUCCESS) {
- ss << "(error from ares_expand_name)";
- return ss.str();
- }
- if (enclen > *len) {
- ss << "(error, encoded name len " << enclen << "bigger than remaining data " << *len << " bytes)";
- return ss.str();
- }
- *len -= enclen;
- *data += enclen;
- ss << "'" << name << "' ";
- ares_free_string(name);
- name = nullptr;
-
- if (*len < NS_RRFIXEDSZ) {
- ss << "(too short, len left " << *len << ")";
- return ss.str();
- }
- int rrtype = DNS_RR_TYPE(*data);
- if (rrtype == ns_t_opt) {
- ss << "MAXUDP=" << DNS_RR_CLASS(*data) << " ";
- ss << RRTypeToString(rrtype) << " ";
- ss << "RCODE2=" << DNS_RR_TTL(*data);
- } else {
- ss << ClassToString(DNS_RR_CLASS(*data)) << " ";
- ss << RRTypeToString(rrtype) << " ";
- ss << "TTL=" << DNS_RR_TTL(*data);
- }
- int rdatalen = DNS_RR_LEN(*data);
-
- *data += NS_RRFIXEDSZ;
- *len -= NS_RRFIXEDSZ;
- if (*len < rdatalen) {
- ss << "(RR too long at " << rdatalen << ", len left " << *len << ")";
- } else {
- switch (rrtype) {
- case ns_t_a:
- case ns_t_aaaa:
- ss << " " << AddressToString(*data, rdatalen);
- break;
- case ns_t_txt: {
- const byte* p = *data;
- while (p < (*data + rdatalen)) {
- int len = *p++;
- if ((p + len) <= (*data + rdatalen)) {
- std::string txt(p, p + len);
- ss << " " << len << ":'" << txt << "'";
- } else {
- ss << "(string too long)";
- }
- p += len;
- }
- break;
- }
- case ns_t_cname:
- case ns_t_ns:
- case ns_t_ptr: {
- int rc = ares_expand_name(*data, packet.data(), packet.size(), &name, &enclen);
- if (rc != ARES_SUCCESS) {
- ss << "(error from ares_expand_name)";
- break;
- }
- ss << " '" << name << "'";
- ares_free_string(name);
- break;
- }
- case ns_t_mx:
- if (rdatalen > 2) {
- int rc = ares_expand_name(*data + 2, packet.data(), packet.size(), &name, &enclen);
- if (rc != ARES_SUCCESS) {
- ss << "(error from ares_expand_name)";
- break;
- }
- ss << " " << DNS__16BIT(*data) << " '" << name << "'";
- ares_free_string(name);
- } else {
- ss << "(RR too short)";
- }
- break;
- case ns_t_srv: {
- if (rdatalen > 6) {
- const byte* p = *data;
- unsigned long prio = DNS__16BIT(p);
- unsigned long weight = DNS__16BIT(p + 2);
- unsigned long port = DNS__16BIT(p + 4);
- p += 6;
- int rc = ares_expand_name(p, packet.data(), packet.size(), &name, &enclen);
- if (rc != ARES_SUCCESS) {
- ss << "(error from ares_expand_name)";
- break;
- }
- ss << prio << " " << weight << " " << port << " '" << name << "'";
- ares_free_string(name);
- } else {
- ss << "(RR too short)";
- }
- break;
- }
- case ns_t_soa: {
- const byte* p = *data;
- int rc = ares_expand_name(p, packet.data(), packet.size(), &name, &enclen);
- if (rc != ARES_SUCCESS) {
- ss << "(error from ares_expand_name)";
- break;
- }
- ss << " '" << name << "'";
- ares_free_string(name);
- p += enclen;
- rc = ares_expand_name(p, packet.data(), packet.size(), &name, &enclen);
- if (rc != ARES_SUCCESS) {
- ss << "(error from ares_expand_name)";
- break;
- }
- ss << " '" << name << "'";
- ares_free_string(name);
- p += enclen;
- if ((p + 20) <= (*data + rdatalen)) {
- unsigned long serial = DNS__32BIT(p);
- unsigned long refresh = DNS__32BIT(p + 4);
- unsigned long retry = DNS__32BIT(p + 8);
- unsigned long expire = DNS__32BIT(p + 12);
- unsigned long minimum = DNS__32BIT(p + 16);
- ss << " " << serial << " " << refresh << " " << retry << " " << expire << " " << minimum;
- } else {
- ss << "(RR too short)";
- }
- break;
- }
- case ns_t_naptr: {
- if (rdatalen > 7) {
- const byte* p = *data;
- unsigned long order = DNS__16BIT(p);
- unsigned long pref = DNS__16BIT(p + 2);
- p += 4;
- ss << order << " " << pref;
-
- int len = *p++;
- std::string flags(p, p + len);
- ss << " " << flags;
- p += len;
-
- len = *p++;
- std::string service(p, p + len);
- ss << " '" << service << "'";
- p += len;
-
- len = *p++;
- std::string regexp(p, p + len);
- ss << " '" << regexp << "'";
- p += len;
-
- int rc = ares_expand_name(p, packet.data(), packet.size(), &name, &enclen);
- if (rc != ARES_SUCCESS) {
- ss << "(error from ares_expand_name)";
- break;
- }
- ss << " '" << name << "'";
- ares_free_string(name);
- } else {
- ss << "(RR too short)";
- }
- break;
- }
- default:
- ss << " " << HexDump(*data, rdatalen);
- break;
- }
- }
- *data += rdatalen;
- *len -= rdatalen;
-
- ss << "}";
- return ss.str();
-}
-
-void PushInt32(std::vector<byte>* data, int value) {
- data->push_back((value & 0xff000000) >> 24);
- data->push_back((value & 0x00ff0000) >> 16);
- data->push_back((value & 0x0000ff00) >> 8);
- data->push_back(value & 0x000000ff);
-}
-
-void PushInt16(std::vector<byte>* data, int value) {
- data->push_back((value & 0xff00) >> 8);
- data->push_back(value & 0x00ff);
-}
-
-std::vector<byte> EncodeString(const std::string& name) {
- std::vector<byte> data;
- std::stringstream ss(name);
- std::string label;
- // TODO: cope with escapes
- while (std::getline(ss, label, '.')) {
- data.push_back(label.length());
- data.insert(data.end(), label.begin(), label.end());
- }
- data.push_back(0);
- return data;
-}
-
-std::vector<byte> DNSQuestion::data() const {
- std::vector<byte> data;
- std::vector<byte> encname = EncodeString(name_);
- data.insert(data.end(), encname.begin(), encname.end());
- PushInt16(&data, rrtype_);
- PushInt16(&data, qclass_);
- return data;
-}
-
-std::vector<byte> DNSRR::data() const {
- std::vector<byte> data = DNSQuestion::data();
- PushInt32(&data, ttl_);
- return data;
-}
-
-std::vector<byte> DNSSingleNameRR::data() const {
- std::vector<byte> data = DNSRR::data();
- std::vector<byte> encname = EncodeString(other_);
- int len = encname.size();
- PushInt16(&data, len);
- data.insert(data.end(), encname.begin(), encname.end());
- return data;
-}
-
-std::vector<byte> DNSTxtRR::data() const {
- std::vector<byte> data = DNSRR::data();
- int len = 0;
- for (const std::string& txt : txt_) {
- len += (1 + txt.size());
- }
- PushInt16(&data, len);
- for (const std::string& txt : txt_) {
- data.push_back(txt.size());
- data.insert(data.end(), txt.begin(), txt.end());
- }
- return data;
-}
-
-std::vector<byte> DNSMxRR::data() const {
- std::vector<byte> data = DNSRR::data();
- std::vector<byte> encname = EncodeString(other_);
- int len = 2 + encname.size();
- PushInt16(&data, len);
- PushInt16(&data, pref_);
- data.insert(data.end(), encname.begin(), encname.end());
- return data;
-}
-
-std::vector<byte> DNSSrvRR::data() const {
- std::vector<byte> data = DNSRR::data();
- std::vector<byte> encname = EncodeString(target_);
- int len = 6 + encname.size();
- PushInt16(&data, len);
- PushInt16(&data, prio_);
- PushInt16(&data, weight_);
- PushInt16(&data, port_);
- data.insert(data.end(), encname.begin(), encname.end());
- return data;
-}
-
-std::vector<byte> DNSAddressRR::data() const {
- std::vector<byte> data = DNSRR::data();
- int len = addr_.size();
- PushInt16(&data, len);
- data.insert(data.end(), addr_.begin(), addr_.end());
- return data;
-}
-
-std::vector<byte> DNSSoaRR::data() const {
- std::vector<byte> data = DNSRR::data();
- std::vector<byte> encname1 = EncodeString(nsname_);
- std::vector<byte> encname2 = EncodeString(rname_);
- int len = encname1.size() + encname2.size() + 5*4;
- PushInt16(&data, len);
- data.insert(data.end(), encname1.begin(), encname1.end());
- data.insert(data.end(), encname2.begin(), encname2.end());
- PushInt32(&data, serial_);
- PushInt32(&data, refresh_);
- PushInt32(&data, retry_);
- PushInt32(&data, expire_);
- PushInt32(&data, minimum_);
- return data;
-}
-
-std::vector<byte> DNSOptRR::data() const {
- std::vector<byte> data = DNSRR::data();
- int len = 0;
- for (const DNSOption& opt : opts_) {
- len += (4 + opt.data_.size());
- }
- PushInt16(&data, len);
- for (const DNSOption& opt : opts_) {
- PushInt16(&data, opt.code_);
- PushInt16(&data, opt.data_.size());
- data.insert(data.end(), opt.data_.begin(), opt.data_.end());
- }
- return data;
-}
-
-std::vector<byte> DNSNaptrRR::data() const {
- std::vector<byte> data = DNSRR::data();
- std::vector<byte> encname = EncodeString(replacement_);
- int len = (4 + 1 + flags_.size() + 1 + service_.size() + 1 + regexp_.size() + encname.size());
- PushInt16(&data, len);
- PushInt16(&data, order_);
- PushInt16(&data, pref_);
- data.push_back(flags_.size());
- data.insert(data.end(), flags_.begin(), flags_.end());
- data.push_back(service_.size());
- data.insert(data.end(), service_.begin(), service_.end());
- data.push_back(regexp_.size());
- data.insert(data.end(), regexp_.begin(), regexp_.end());
- data.insert(data.end(), encname.begin(), encname.end());
- return data;
-}
-
-std::vector<byte> DNSPacket::data() const {
- std::vector<byte> data;
- PushInt16(&data, qid_);
- byte b = 0x00;
- if (response_) b |= 0x80;
- b |= ((opcode_ & 0x0f) << 3);
- if (aa_) b |= 0x04;
- if (tc_) b |= 0x02;
- if (rd_) b |= 0x01;
- data.push_back(b);
- b = 0x00;
- if (ra_) b |= 0x80;
- if (z_) b |= 0x40;
- if (ad_) b |= 0x20;
- if (cd_) b |= 0x10;
- b |= (rcode_ & 0x0f);
- data.push_back(b);
-
- int count = questions_.size();
- PushInt16(&data, count);
- count = answers_.size();
- PushInt16(&data, count);
- count = auths_.size();
- PushInt16(&data, count);
- count = adds_.size();
- PushInt16(&data, count);
-
- for (const std::unique_ptr<DNSQuestion>& question : questions_) {
- std::vector<byte> qdata = question->data();
- data.insert(data.end(), qdata.begin(), qdata.end());
- }
- for (const std::unique_ptr<DNSRR>& rr : answers_) {
- std::vector<byte> rrdata = rr->data();
- data.insert(data.end(), rrdata.begin(), rrdata.end());
- }
- for (const std::unique_ptr<DNSRR>& rr : auths_) {
- std::vector<byte> rrdata = rr->data();
- data.insert(data.end(), rrdata.begin(), rrdata.end());
- }
- for (const std::unique_ptr<DNSRR>& rr : adds_) {
- std::vector<byte> rrdata = rr->data();
- data.insert(data.end(), rrdata.begin(), rrdata.end());
- }
- return data;
-}
-
-} // namespace ares
+#include "dns-proto.h"
+
+// Include ares internal file for DNS protocol details
+#include "ares_setup.h"
+#include "ares.h"
+#include "ares_dns.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sstream>
+
+namespace ares {
+
+std::string HexDump(std::vector<byte> data) {
+ std::stringstream ss;
+ for (size_t ii = 0; ii < data.size(); ii++) {
+ char buffer[2 + 1];
+ sprintf(buffer, "%02x", data[ii]);
+ ss << buffer;
+ }
+ return ss.str();
+}
+
+std::string HexDump(const byte *data, int len) {
+ return HexDump(std::vector<byte>(data, data + len));
+}
+
+std::string HexDump(const char *data, int len) {
+ return HexDump(reinterpret_cast<const byte*>(data), len);
+}
+
+std::string StatusToString(int status) {
+ switch (status) {
+ case ARES_SUCCESS: return "ARES_SUCCESS";
+ case ARES_ENODATA: return "ARES_ENODATA";
+ case ARES_EFORMERR: return "ARES_EFORMERR";
+ case ARES_ESERVFAIL: return "ARES_ESERVFAIL";
+ case ARES_ENOTFOUND: return "ARES_ENOTFOUND";
+ case ARES_ENOTIMP: return "ARES_ENOTIMP";
+ case ARES_EREFUSED: return "ARES_EREFUSED";
+ case ARES_EBADQUERY: return "ARES_EBADQUERY";
+ case ARES_EBADNAME: return "ARES_EBADNAME";
+ case ARES_EBADFAMILY: return "ARES_EBADFAMILY";
+ case ARES_EBADRESP: return "ARES_EBADRESP";
+ case ARES_ECONNREFUSED: return "ARES_ECONNREFUSED";
+ case ARES_ETIMEOUT: return "ARES_ETIMEOUT";
+ case ARES_EOF: return "ARES_EOF";
+ case ARES_EFILE: return "ARES_EFILE";
+ case ARES_ENOMEM: return "ARES_ENOMEM";
+ case ARES_EDESTRUCTION: return "ARES_EDESTRUCTION";
+ case ARES_EBADSTR: return "ARES_EBADSTR";
+ case ARES_EBADFLAGS: return "ARES_EBADFLAGS";
+ case ARES_ENONAME: return "ARES_ENONAME";
+ case ARES_EBADHINTS: return "ARES_EBADHINTS";
+ case ARES_ENOTINITIALIZED: return "ARES_ENOTINITIALIZED";
+ case ARES_ELOADIPHLPAPI: return "ARES_ELOADIPHLPAPI";
+ case ARES_EADDRGETNETWORKPARAMS: return "ARES_EADDRGETNETWORKPARAMS";
+ case ARES_ECANCELLED: return "ARES_ECANCELLED";
+ default: return "UNKNOWN";
+ }
+}
+
+std::string RcodeToString(int rcode) {
+ switch (rcode) {
+ case ns_r_noerror: return "NOERROR";
+ case ns_r_formerr: return "FORMERR";
+ case ns_r_servfail: return "SERVFAIL";
+ case ns_r_nxdomain: return "NXDOMAIN";
+ case ns_r_notimpl: return "NOTIMPL";
+ case ns_r_refused: return "REFUSED";
+ case ns_r_yxdomain: return "YXDOMAIN";
+ case ns_r_yxrrset: return "YXRRSET";
+ case ns_r_nxrrset: return "NXRRSET";
+ case ns_r_notauth: return "NOTAUTH";
+ case ns_r_notzone: return "NOTZONE";
+ case ns_r_badsig: return "BADSIG";
+ case ns_r_badkey: return "BADKEY";
+ case ns_r_badtime: return "BADTIME";
+ default: return "UNKNOWN";
+ }
+}
+
+std::string RRTypeToString(int rrtype) {
+ switch (rrtype) {
+ case ns_t_a: return "A";
+ case ns_t_ns: return "NS";
+ case ns_t_md: return "MD";
+ case ns_t_mf: return "MF";
+ case ns_t_cname: return "CNAME";
+ case ns_t_soa: return "SOA";
+ case ns_t_mb: return "MB";
+ case ns_t_mg: return "MG";
+ case ns_t_mr: return "MR";
+ case ns_t_null: return "NULL";
+ case ns_t_wks: return "WKS";
+ case ns_t_ptr: return "PTR";
+ case ns_t_hinfo: return "HINFO";
+ case ns_t_minfo: return "MINFO";
+ case ns_t_mx: return "MX";
+ case ns_t_txt: return "TXT";
+ case ns_t_rp: return "RP";
+ case ns_t_afsdb: return "AFSDB";
+ case ns_t_x25: return "X25";
+ case ns_t_isdn: return "ISDN";
+ case ns_t_rt: return "RT";
+ case ns_t_nsap: return "NSAP";
+ case ns_t_nsap_ptr: return "NSAP_PTR";
+ case ns_t_sig: return "SIG";
+ case ns_t_key: return "KEY";
+ case ns_t_px: return "PX";
+ case ns_t_gpos: return "GPOS";
+ case ns_t_aaaa: return "AAAA";
+ case ns_t_loc: return "LOC";
+ case ns_t_nxt: return "NXT";
+ case ns_t_eid: return "EID";
+ case ns_t_nimloc: return "NIMLOC";
+ case ns_t_srv: return "SRV";
+ case ns_t_atma: return "ATMA";
+ case ns_t_naptr: return "NAPTR";
+ case ns_t_kx: return "KX";
+ case ns_t_cert: return "CERT";
+ case ns_t_a6: return "A6";
+ case ns_t_dname: return "DNAME";
+ case ns_t_sink: return "SINK";
+ case ns_t_opt: return "OPT";
+ case ns_t_apl: return "APL";
+ case ns_t_ds: return "DS";
+ case ns_t_sshfp: return "SSHFP";
+ case ns_t_rrsig: return "RRSIG";
+ case ns_t_nsec: return "NSEC";
+ case ns_t_dnskey: return "DNSKEY";
+ case ns_t_tkey: return "TKEY";
+ case ns_t_tsig: return "TSIG";
+ case ns_t_ixfr: return "IXFR";
+ case ns_t_axfr: return "AXFR";
+ case ns_t_mailb: return "MAILB";
+ case ns_t_maila: return "MAILA";
+ case ns_t_any: return "ANY";
+ case ns_t_zxfr: return "ZXFR";
+ case ns_t_max: return "MAX";
+ default: return "UNKNOWN";
+ }
+}
+
+std::string ClassToString(int qclass) {
+ switch (qclass) {
+ case ns_c_in: return "IN";
+ case ns_c_chaos: return "CHAOS";
+ case ns_c_hs: return "HESIOD";
+ case ns_c_none: return "NONE";
+ case ns_c_any: return "ANY";
+ default: return "UNKNOWN";
+ }
+}
+
+std::string AddressToString(const void* vaddr, int len) {
+ const byte* addr = reinterpret_cast<const byte*>(vaddr);
+ std::stringstream ss;
+ if (len == 4) {
+ char buffer[4*4 + 3 + 1];
+ sprintf(buffer, "%u.%u.%u.%u",
+ (unsigned char)addr[0],
+ (unsigned char)addr[1],
+ (unsigned char)addr[2],
+ (unsigned char)addr[3]);
+ ss << buffer;
+ } else if (len == 16) {
+ for (int ii = 0; ii < 16; ii+=2) {
+ if (ii > 0) ss << ':';
+ char buffer[4 + 1];
+ sprintf(buffer, "%02x%02x", (unsigned char)addr[ii], (unsigned char)addr[ii+1]);
+ ss << buffer;
+ }
+ } else {
+ ss << "!" << HexDump(addr, len) << "!";
+ }
+ return ss.str();
+}
+
+std::string PacketToString(const std::vector<byte>& packet) {
+ const byte* data = packet.data();
+ int len = packet.size();
+ std::stringstream ss;
+ if (len < NS_HFIXEDSZ) {
+ ss << "(too short, len " << len << ")";
+ return ss.str();
+ }
+ ss << ((DNS_HEADER_QR(data) == 0) ? "REQ " : "RSP ");
+ switch (DNS_HEADER_OPCODE(data)) {
+ case ns_o_query: ss << "QRY "; break;
+ case ns_o_iquery: ss << "IQRY "; break;
+ case ns_o_status: ss << "STATUS "; break;
+ case ns_o_notify: ss << "NOTIFY "; break;
+ case ns_o_update: ss << "UPDATE "; break;
+ default: ss << "UNKNOWN(" << DNS_HEADER_OPCODE(data) << ") "; break;
+ }
+ if (DNS_HEADER_AA(data)) ss << "AA ";
+ if (DNS_HEADER_TC(data)) ss << "TC ";
+ if (DNS_HEADER_RD(data)) ss << "RD ";
+ if (DNS_HEADER_RA(data)) ss << "RA ";
+ if (DNS_HEADER_Z(data)) ss << "Z ";
+ if (DNS_HEADER_QR(data) == 1) ss << RcodeToString(DNS_HEADER_RCODE(data));
+
+ int nquestions = DNS_HEADER_QDCOUNT(data);
+ int nanswers = DNS_HEADER_ANCOUNT(data);
+ int nauths = DNS_HEADER_NSCOUNT(data);
+ int nadds = DNS_HEADER_ARCOUNT(data);
+
+ const byte* pq = data + NS_HFIXEDSZ;
+ len -= NS_HFIXEDSZ;
+ for (int ii = 0; ii < nquestions; ii++) {
+ ss << " Q:" << QuestionToString(packet, &pq, &len);
+ }
+ const byte* prr = pq;
+ for (int ii = 0; ii < nanswers; ii++) {
+ ss << " A:" << RRToString(packet, &prr, &len);
+ }
+ for (int ii = 0; ii < nauths; ii++) {
+ ss << " AUTH:" << RRToString(packet, &prr, &len);
+ }
+ for (int ii = 0; ii < nadds; ii++) {
+ ss << " ADD:" << RRToString(packet, &prr, &len);
+ }
+ return ss.str();
+}
+
+std::string QuestionToString(const std::vector<byte>& packet,
+ const byte** data, int* len) {
+ std::stringstream ss;
+ ss << "{";
+ if (*len < NS_QFIXEDSZ) {
+ ss << "(too short, len " << *len << ")";
+ return ss.str();
+ }
+
+ char *name = nullptr;
+ long enclen;
+ int rc = ares_expand_name(*data, packet.data(), packet.size(), &name, &enclen);
+ if (rc != ARES_SUCCESS) {
+ ss << "(error from ares_expand_name)";
+ return ss.str();
+ }
+ if (enclen > *len) {
+ ss << "(error, encoded name len " << enclen << "bigger than remaining data " << *len << " bytes)";
+ return ss.str();
+ }
+ *len -= enclen;
+ *data += enclen;
+ ss << "'" << name << "' ";
+ ares_free_string(name);
+ if (*len < NS_QFIXEDSZ) {
+ ss << "(too short, len left " << *len << ")";
+ return ss.str();
+ }
+ ss << ClassToString(DNS_QUESTION_CLASS(*data)) << " ";
+ ss << RRTypeToString(DNS_QUESTION_TYPE(*data));
+ *data += NS_QFIXEDSZ;
+ *len -= NS_QFIXEDSZ;
+ ss << "}";
+ return ss.str();
+}
+
+std::string RRToString(const std::vector<byte>& packet,
+ const byte** data, int* len) {
+ std::stringstream ss;
+ ss << "{";
+ if (*len < NS_RRFIXEDSZ) {
+ ss << "too short, len " << *len << ")";
+ return ss.str();
+ }
+
+ char *name = nullptr;
+ long enclen;
+ int rc = ares_expand_name(*data, packet.data(), packet.size(), &name, &enclen);
+ if (rc != ARES_SUCCESS) {
+ ss << "(error from ares_expand_name)";
+ return ss.str();
+ }
+ if (enclen > *len) {
+ ss << "(error, encoded name len " << enclen << "bigger than remaining data " << *len << " bytes)";
+ return ss.str();
+ }
+ *len -= enclen;
+ *data += enclen;
+ ss << "'" << name << "' ";
+ ares_free_string(name);
+ name = nullptr;
+
+ if (*len < NS_RRFIXEDSZ) {
+ ss << "(too short, len left " << *len << ")";
+ return ss.str();
+ }
+ int rrtype = DNS_RR_TYPE(*data);
+ if (rrtype == ns_t_opt) {
+ ss << "MAXUDP=" << DNS_RR_CLASS(*data) << " ";
+ ss << RRTypeToString(rrtype) << " ";
+ ss << "RCODE2=" << DNS_RR_TTL(*data);
+ } else {
+ ss << ClassToString(DNS_RR_CLASS(*data)) << " ";
+ ss << RRTypeToString(rrtype) << " ";
+ ss << "TTL=" << DNS_RR_TTL(*data);
+ }
+ int rdatalen = DNS_RR_LEN(*data);
+
+ *data += NS_RRFIXEDSZ;
+ *len -= NS_RRFIXEDSZ;
+ if (*len < rdatalen) {
+ ss << "(RR too long at " << rdatalen << ", len left " << *len << ")";
+ } else {
+ switch (rrtype) {
+ case ns_t_a:
+ case ns_t_aaaa:
+ ss << " " << AddressToString(*data, rdatalen);
+ break;
+ case ns_t_txt: {
+ const byte* p = *data;
+ while (p < (*data + rdatalen)) {
+ int len = *p++;
+ if ((p + len) <= (*data + rdatalen)) {
+ std::string txt(p, p + len);
+ ss << " " << len << ":'" << txt << "'";
+ } else {
+ ss << "(string too long)";
+ }
+ p += len;
+ }
+ break;
+ }
+ case ns_t_cname:
+ case ns_t_ns:
+ case ns_t_ptr: {
+ int rc = ares_expand_name(*data, packet.data(), packet.size(), &name, &enclen);
+ if (rc != ARES_SUCCESS) {
+ ss << "(error from ares_expand_name)";
+ break;
+ }
+ ss << " '" << name << "'";
+ ares_free_string(name);
+ break;
+ }
+ case ns_t_mx:
+ if (rdatalen > 2) {
+ int rc = ares_expand_name(*data + 2, packet.data(), packet.size(), &name, &enclen);
+ if (rc != ARES_SUCCESS) {
+ ss << "(error from ares_expand_name)";
+ break;
+ }
+ ss << " " << DNS__16BIT(*data) << " '" << name << "'";
+ ares_free_string(name);
+ } else {
+ ss << "(RR too short)";
+ }
+ break;
+ case ns_t_srv: {
+ if (rdatalen > 6) {
+ const byte* p = *data;
+ unsigned long prio = DNS__16BIT(p);
+ unsigned long weight = DNS__16BIT(p + 2);
+ unsigned long port = DNS__16BIT(p + 4);
+ p += 6;
+ int rc = ares_expand_name(p, packet.data(), packet.size(), &name, &enclen);
+ if (rc != ARES_SUCCESS) {
+ ss << "(error from ares_expand_name)";
+ break;
+ }
+ ss << prio << " " << weight << " " << port << " '" << name << "'";
+ ares_free_string(name);
+ } else {
+ ss << "(RR too short)";
+ }
+ break;
+ }
+ case ns_t_soa: {
+ const byte* p = *data;
+ int rc = ares_expand_name(p, packet.data(), packet.size(), &name, &enclen);
+ if (rc != ARES_SUCCESS) {
+ ss << "(error from ares_expand_name)";
+ break;
+ }
+ ss << " '" << name << "'";
+ ares_free_string(name);
+ p += enclen;
+ rc = ares_expand_name(p, packet.data(), packet.size(), &name, &enclen);
+ if (rc != ARES_SUCCESS) {
+ ss << "(error from ares_expand_name)";
+ break;
+ }
+ ss << " '" << name << "'";
+ ares_free_string(name);
+ p += enclen;
+ if ((p + 20) <= (*data + rdatalen)) {
+ unsigned long serial = DNS__32BIT(p);
+ unsigned long refresh = DNS__32BIT(p + 4);
+ unsigned long retry = DNS__32BIT(p + 8);
+ unsigned long expire = DNS__32BIT(p + 12);
+ unsigned long minimum = DNS__32BIT(p + 16);
+ ss << " " << serial << " " << refresh << " " << retry << " " << expire << " " << minimum;
+ } else {
+ ss << "(RR too short)";
+ }
+ break;
+ }
+ case ns_t_naptr: {
+ if (rdatalen > 7) {
+ const byte* p = *data;
+ unsigned long order = DNS__16BIT(p);
+ unsigned long pref = DNS__16BIT(p + 2);
+ p += 4;
+ ss << order << " " << pref;
+
+ int len = *p++;
+ std::string flags(p, p + len);
+ ss << " " << flags;
+ p += len;
+
+ len = *p++;
+ std::string service(p, p + len);
+ ss << " '" << service << "'";
+ p += len;
+
+ len = *p++;
+ std::string regexp(p, p + len);
+ ss << " '" << regexp << "'";
+ p += len;
+
+ int rc = ares_expand_name(p, packet.data(), packet.size(), &name, &enclen);
+ if (rc != ARES_SUCCESS) {
+ ss << "(error from ares_expand_name)";
+ break;
+ }
+ ss << " '" << name << "'";
+ ares_free_string(name);
+ } else {
+ ss << "(RR too short)";
+ }
+ break;
+ }
+ default:
+ ss << " " << HexDump(*data, rdatalen);
+ break;
+ }
+ }
+ *data += rdatalen;
+ *len -= rdatalen;
+
+ ss << "}";
+ return ss.str();
+}
+
+void PushInt32(std::vector<byte>* data, int value) {
+ data->push_back((value & 0xff000000) >> 24);
+ data->push_back((value & 0x00ff0000) >> 16);
+ data->push_back((value & 0x0000ff00) >> 8);
+ data->push_back(value & 0x000000ff);
+}
+
+void PushInt16(std::vector<byte>* data, int value) {
+ data->push_back((value & 0xff00) >> 8);
+ data->push_back(value & 0x00ff);
+}
+
+std::vector<byte> EncodeString(const std::string& name) {
+ std::vector<byte> data;
+ std::stringstream ss(name);
+ std::string label;
+ // TODO: cope with escapes
+ while (std::getline(ss, label, '.')) {
+ data.push_back(label.length());
+ data.insert(data.end(), label.begin(), label.end());
+ }
+ data.push_back(0);
+ return data;
+}
+
+std::vector<byte> DNSQuestion::data() const {
+ std::vector<byte> data;
+ std::vector<byte> encname = EncodeString(name_);
+ data.insert(data.end(), encname.begin(), encname.end());
+ PushInt16(&data, rrtype_);
+ PushInt16(&data, qclass_);
+ return data;
+}
+
+std::vector<byte> DNSRR::data() const {
+ std::vector<byte> data = DNSQuestion::data();
+ PushInt32(&data, ttl_);
+ return data;
+}
+
+std::vector<byte> DNSSingleNameRR::data() const {
+ std::vector<byte> data = DNSRR::data();
+ std::vector<byte> encname = EncodeString(other_);
+ int len = encname.size();
+ PushInt16(&data, len);
+ data.insert(data.end(), encname.begin(), encname.end());
+ return data;
+}
+
+std::vector<byte> DNSTxtRR::data() const {
+ std::vector<byte> data = DNSRR::data();
+ int len = 0;
+ for (const std::string& txt : txt_) {
+ len += (1 + txt.size());
+ }
+ PushInt16(&data, len);
+ for (const std::string& txt : txt_) {
+ data.push_back(txt.size());
+ data.insert(data.end(), txt.begin(), txt.end());
+ }
+ return data;
+}
+
+std::vector<byte> DNSMxRR::data() const {
+ std::vector<byte> data = DNSRR::data();
+ std::vector<byte> encname = EncodeString(other_);
+ int len = 2 + encname.size();
+ PushInt16(&data, len);
+ PushInt16(&data, pref_);
+ data.insert(data.end(), encname.begin(), encname.end());
+ return data;
+}
+
+std::vector<byte> DNSSrvRR::data() const {
+ std::vector<byte> data = DNSRR::data();
+ std::vector<byte> encname = EncodeString(target_);
+ int len = 6 + encname.size();
+ PushInt16(&data, len);
+ PushInt16(&data, prio_);
+ PushInt16(&data, weight_);
+ PushInt16(&data, port_);
+ data.insert(data.end(), encname.begin(), encname.end());
+ return data;
+}
+
+std::vector<byte> DNSAddressRR::data() const {
+ std::vector<byte> data = DNSRR::data();
+ int len = addr_.size();
+ PushInt16(&data, len);
+ data.insert(data.end(), addr_.begin(), addr_.end());
+ return data;
+}
+
+std::vector<byte> DNSSoaRR::data() const {
+ std::vector<byte> data = DNSRR::data();
+ std::vector<byte> encname1 = EncodeString(nsname_);
+ std::vector<byte> encname2 = EncodeString(rname_);
+ int len = encname1.size() + encname2.size() + 5*4;
+ PushInt16(&data, len);
+ data.insert(data.end(), encname1.begin(), encname1.end());
+ data.insert(data.end(), encname2.begin(), encname2.end());
+ PushInt32(&data, serial_);
+ PushInt32(&data, refresh_);
+ PushInt32(&data, retry_);
+ PushInt32(&data, expire_);
+ PushInt32(&data, minimum_);
+ return data;
+}
+
+std::vector<byte> DNSOptRR::data() const {
+ std::vector<byte> data = DNSRR::data();
+ int len = 0;
+ for (const DNSOption& opt : opts_) {
+ len += (4 + opt.data_.size());
+ }
+ PushInt16(&data, len);
+ for (const DNSOption& opt : opts_) {
+ PushInt16(&data, opt.code_);
+ PushInt16(&data, opt.data_.size());
+ data.insert(data.end(), opt.data_.begin(), opt.data_.end());
+ }
+ return data;
+}
+
+std::vector<byte> DNSNaptrRR::data() const {
+ std::vector<byte> data = DNSRR::data();
+ std::vector<byte> encname = EncodeString(replacement_);
+ int len = (4 + 1 + flags_.size() + 1 + service_.size() + 1 + regexp_.size() + encname.size());
+ PushInt16(&data, len);
+ PushInt16(&data, order_);
+ PushInt16(&data, pref_);
+ data.push_back(flags_.size());
+ data.insert(data.end(), flags_.begin(), flags_.end());
+ data.push_back(service_.size());
+ data.insert(data.end(), service_.begin(), service_.end());
+ data.push_back(regexp_.size());
+ data.insert(data.end(), regexp_.begin(), regexp_.end());
+ data.insert(data.end(), encname.begin(), encname.end());
+ return data;
+}
+
+std::vector<byte> DNSPacket::data() const {
+ std::vector<byte> data;
+ PushInt16(&data, qid_);
+ byte b = 0x00;
+ if (response_) b |= 0x80;
+ b |= ((opcode_ & 0x0f) << 3);
+ if (aa_) b |= 0x04;
+ if (tc_) b |= 0x02;
+ if (rd_) b |= 0x01;
+ data.push_back(b);
+ b = 0x00;
+ if (ra_) b |= 0x80;
+ if (z_) b |= 0x40;
+ if (ad_) b |= 0x20;
+ if (cd_) b |= 0x10;
+ b |= (rcode_ & 0x0f);
+ data.push_back(b);
+
+ int count = questions_.size();
+ PushInt16(&data, count);
+ count = answers_.size();
+ PushInt16(&data, count);
+ count = auths_.size();
+ PushInt16(&data, count);
+ count = adds_.size();
+ PushInt16(&data, count);
+
+ for (const std::unique_ptr<DNSQuestion>& question : questions_) {
+ std::vector<byte> qdata = question->data();
+ data.insert(data.end(), qdata.begin(), qdata.end());
+ }
+ for (const std::unique_ptr<DNSRR>& rr : answers_) {
+ std::vector<byte> rrdata = rr->data();
+ data.insert(data.end(), rrdata.begin(), rrdata.end());
+ }
+ for (const std::unique_ptr<DNSRR>& rr : auths_) {
+ std::vector<byte> rrdata = rr->data();
+ data.insert(data.end(), rrdata.begin(), rrdata.end());
+ }
+ for (const std::unique_ptr<DNSRR>& rr : adds_) {
+ std::vector<byte> rrdata = rr->data();
+ data.insert(data.end(), rrdata.begin(), rrdata.end());
+ }
+ return data;
+}
+
+} // namespace ares
diff --git a/contrib/libs/c-ares/test/dns-proto.h b/contrib/libs/c-ares/test/dns-proto.h
index 9fcb850153..346711dfe9 100644
--- a/contrib/libs/c-ares/test/dns-proto.h
+++ b/contrib/libs/c-ares/test/dns-proto.h
@@ -1,242 +1,242 @@
-// -*- mode: c++ -*-
-#ifndef DNS_PROTO_H
-#define DNS_PROTO_H
-// Utilities for processing DNS packet contents
-
-// Include ares internal file for DNS protocol constants
-#include "nameser.h"
-
-#include <memory>
-#include <string>
-#include <vector>
-
-namespace ares {
-
-typedef unsigned char byte;
-
-std::string HexDump(std::vector<byte> data);
-std::string HexDump(const byte *data, int len);
-std::string HexDump(const char *data, int len);
-
-std::string StatusToString(int status);
-std::string RcodeToString(int rcode);
-std::string RRTypeToString(int rrtype);
-std::string ClassToString(int qclass);
-std::string AddressToString(const void* addr, int len);
-
-// Convert DNS protocol data to strings.
-// Note that these functions are not defensive; they assume
-// a validly formatted input, and so should not be used on
-// externally-determined inputs.
-std::string PacketToString(const std::vector<byte>& packet);
-std::string QuestionToString(const std::vector<byte>& packet,
- const byte** data, int* len);
-std::string RRToString(const std::vector<byte>& packet,
- const byte** data, int* len);
-
-
-// Manipulate DNS protocol data.
-void PushInt32(std::vector<byte>* data, int value);
-void PushInt16(std::vector<byte>* data, int value);
-std::vector<byte> EncodeString(const std::string& name);
-
-struct DNSQuestion {
- DNSQuestion(const std::string& name, ns_type rrtype, ns_class qclass)
- : name_(name), rrtype_(rrtype), qclass_(qclass) {}
- DNSQuestion(const std::string& name, ns_type rrtype)
- : name_(name), rrtype_(rrtype), qclass_(ns_c_in) {}
- virtual ~DNSQuestion() {}
- virtual std::vector<byte> data() const;
- std::string name_;
- ns_type rrtype_;
- ns_class qclass_;
-};
-
-struct DNSRR : public DNSQuestion {
- DNSRR(const std::string& name, ns_type rrtype, ns_class qclass, int ttl)
- : DNSQuestion(name, rrtype, qclass), ttl_(ttl) {}
- DNSRR(const std::string& name, ns_type rrtype, int ttl)
- : DNSQuestion(name, rrtype), ttl_(ttl) {}
- virtual ~DNSRR() {}
- virtual std::vector<byte> data() const = 0;
- int ttl_;
-};
-
-struct DNSAddressRR : public DNSRR {
- DNSAddressRR(const std::string& name, ns_type rrtype, int ttl,
- const byte* addr, int addrlen)
- : DNSRR(name, rrtype, ttl), addr_(addr, addr + addrlen) {}
- DNSAddressRR(const std::string& name, ns_type rrtype, int ttl,
- const std::vector<byte>& addr)
- : DNSRR(name, rrtype, ttl), addr_(addr) {}
- virtual std::vector<byte> data() const;
- std::vector<byte> addr_;
-};
-
-struct DNSARR : public DNSAddressRR {
- DNSARR(const std::string& name, int ttl, const byte* addr, int addrlen)
- : DNSAddressRR(name, ns_t_a, ttl, addr, addrlen) {}
- DNSARR(const std::string& name, int ttl, const std::vector<byte>& addr)
- : DNSAddressRR(name, ns_t_a, ttl, addr) {}
-};
-
-struct DNSAaaaRR : public DNSAddressRR {
- DNSAaaaRR(const std::string& name, int ttl, const byte* addr, int addrlen)
- : DNSAddressRR(name, ns_t_aaaa, ttl, addr, addrlen) {}
- DNSAaaaRR(const std::string& name, int ttl, const std::vector<byte>& addr)
- : DNSAddressRR(name, ns_t_aaaa, ttl, addr) {}
-};
-
-struct DNSSingleNameRR : public DNSRR {
- DNSSingleNameRR(const std::string& name, ns_type rrtype, int ttl,
- const std::string& other)
- : DNSRR(name, rrtype, ttl), other_(other) {}
- virtual std::vector<byte> data() const;
- std::string other_;
-};
-
-struct DNSCnameRR : public DNSSingleNameRR {
- DNSCnameRR(const std::string& name, int ttl, const std::string& other)
- : DNSSingleNameRR(name, ns_t_cname, ttl, other) {}
-};
-
-struct DNSNsRR : public DNSSingleNameRR {
- DNSNsRR(const std::string& name, int ttl, const std::string& other)
- : DNSSingleNameRR(name, ns_t_ns, ttl, other) {}
-};
-
-struct DNSPtrRR : public DNSSingleNameRR {
- DNSPtrRR(const std::string& name, int ttl, const std::string& other)
- : DNSSingleNameRR(name, ns_t_ptr, ttl, other) {}
-};
-
-struct DNSTxtRR : public DNSRR {
- DNSTxtRR(const std::string& name, int ttl, const std::vector<std::string>& txt)
- : DNSRR(name, ns_t_txt, ttl), txt_(txt) {}
- virtual std::vector<byte> data() const;
- std::vector<std::string> txt_;
-};
-
-struct DNSMxRR : public DNSRR {
- DNSMxRR(const std::string& name, int ttl, int pref, const std::string& other)
- : DNSRR(name, ns_t_mx, ttl), pref_(pref), other_(other) {}
- virtual std::vector<byte> data() const;
- int pref_;
- std::string other_;
-};
-
-struct DNSSrvRR : public DNSRR {
- DNSSrvRR(const std::string& name, int ttl,
- int prio, int weight, int port, const std::string& target)
- : DNSRR(name, ns_t_srv, ttl), prio_(prio), weight_(weight), port_(port), target_(target) {}
- virtual std::vector<byte> data() const;
- int prio_;
- int weight_;
- int port_;
- std::string target_;
-};
-
-struct DNSSoaRR : public DNSRR {
- DNSSoaRR(const std::string& name, int ttl,
- const std::string& nsname, const std::string& rname,
- int serial, int refresh, int retry, int expire, int minimum)
- : DNSRR(name, ns_t_soa, ttl), nsname_(nsname), rname_(rname),
- serial_(serial), refresh_(refresh), retry_(retry),
- expire_(expire), minimum_(minimum) {}
- virtual std::vector<byte> data() const;
- std::string nsname_;
- std::string rname_;
- int serial_;
- int refresh_;
- int retry_;
- int expire_;
- int minimum_;
-};
-
-struct DNSNaptrRR : public DNSRR {
- DNSNaptrRR(const std::string& name, int ttl,
- int order, int pref,
- const std::string& flags,
- const std::string& service,
- const std::string& regexp,
- const std::string& replacement)
- : DNSRR(name, ns_t_naptr, ttl), order_(order), pref_(pref),
- flags_(flags), service_(service), regexp_(regexp), replacement_(replacement) {}
- virtual std::vector<byte> data() const;
- int order_;
- int pref_;
- std::string flags_;
- std::string service_;
- std::string regexp_;
- std::string replacement_;
-};
-
-struct DNSOption {
- int code_;
- std::vector<byte> data_;
-};
-
-struct DNSOptRR : public DNSRR {
- DNSOptRR(int extrcode, int udpsize)
- : DNSRR("", ns_t_opt, static_cast<ns_class>(udpsize), extrcode) {}
- virtual std::vector<byte> data() const;
- std::vector<DNSOption> opts_;
-};
-
-struct DNSPacket {
- DNSPacket()
- : qid_(0), response_(false), opcode_(ns_o_query),
- aa_(false), tc_(false), rd_(false), ra_(false),
- z_(false), ad_(false), cd_(false), rcode_(ns_r_noerror) {}
- // Convenience functions that take ownership of given pointers.
- DNSPacket& add_question(DNSQuestion *q) {
- questions_.push_back(std::unique_ptr<DNSQuestion>(q));
- return *this;
- }
- DNSPacket& add_answer(DNSRR *q) {
- answers_.push_back(std::unique_ptr<DNSRR>(q));
- return *this;
- }
- DNSPacket& add_auth(DNSRR *q) {
- auths_.push_back(std::unique_ptr<DNSRR>(q));
- return *this;
- }
- DNSPacket& add_additional(DNSRR *q) {
- adds_.push_back(std::unique_ptr<DNSRR>(q));
- return *this;
- }
- // Chainable setters.
- DNSPacket& set_qid(int qid) { qid_ = qid; return *this; }
- DNSPacket& set_response(bool v = true) { response_ = v; return *this; }
- DNSPacket& set_aa(bool v = true) { aa_ = v; return *this; }
- DNSPacket& set_tc(bool v = true) { tc_ = v; return *this; }
- DNSPacket& set_rd(bool v = true) { rd_ = v; return *this; }
- DNSPacket& set_ra(bool v = true) { ra_ = v; return *this; }
- DNSPacket& set_z(bool v = true) { z_ = v; return *this; }
- DNSPacket& set_ad(bool v = true) { ad_ = v; return *this; }
- DNSPacket& set_cd(bool v = true) { cd_ = v; return *this; }
- DNSPacket& set_rcode(ns_rcode rcode) { rcode_ = rcode; return *this; }
-
- // Return the encoded packet.
- std::vector<byte> data() const;
-
- int qid_;
- bool response_;
- ns_opcode opcode_;
- bool aa_;
- bool tc_;
- bool rd_;
- bool ra_;
- bool z_;
- bool ad_;
- bool cd_;
- ns_rcode rcode_;
- std::vector<std::unique_ptr<DNSQuestion>> questions_;
- std::vector<std::unique_ptr<DNSRR>> answers_;
- std::vector<std::unique_ptr<DNSRR>> auths_;
- std::vector<std::unique_ptr<DNSRR>> adds_;
-};
-
-} // namespace ares
-
-#endif
+// -*- mode: c++ -*-
+#ifndef DNS_PROTO_H
+#define DNS_PROTO_H
+// Utilities for processing DNS packet contents
+
+// Include ares internal file for DNS protocol constants
+#include "nameser.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace ares {
+
+typedef unsigned char byte;
+
+std::string HexDump(std::vector<byte> data);
+std::string HexDump(const byte *data, int len);
+std::string HexDump(const char *data, int len);
+
+std::string StatusToString(int status);
+std::string RcodeToString(int rcode);
+std::string RRTypeToString(int rrtype);
+std::string ClassToString(int qclass);
+std::string AddressToString(const void* addr, int len);
+
+// Convert DNS protocol data to strings.
+// Note that these functions are not defensive; they assume
+// a validly formatted input, and so should not be used on
+// externally-determined inputs.
+std::string PacketToString(const std::vector<byte>& packet);
+std::string QuestionToString(const std::vector<byte>& packet,
+ const byte** data, int* len);
+std::string RRToString(const std::vector<byte>& packet,
+ const byte** data, int* len);
+
+
+// Manipulate DNS protocol data.
+void PushInt32(std::vector<byte>* data, int value);
+void PushInt16(std::vector<byte>* data, int value);
+std::vector<byte> EncodeString(const std::string& name);
+
+struct DNSQuestion {
+ DNSQuestion(const std::string& name, ns_type rrtype, ns_class qclass)
+ : name_(name), rrtype_(rrtype), qclass_(qclass) {}
+ DNSQuestion(const std::string& name, ns_type rrtype)
+ : name_(name), rrtype_(rrtype), qclass_(ns_c_in) {}
+ virtual ~DNSQuestion() {}
+ virtual std::vector<byte> data() const;
+ std::string name_;
+ ns_type rrtype_;
+ ns_class qclass_;
+};
+
+struct DNSRR : public DNSQuestion {
+ DNSRR(const std::string& name, ns_type rrtype, ns_class qclass, int ttl)
+ : DNSQuestion(name, rrtype, qclass), ttl_(ttl) {}
+ DNSRR(const std::string& name, ns_type rrtype, int ttl)
+ : DNSQuestion(name, rrtype), ttl_(ttl) {}
+ virtual ~DNSRR() {}
+ virtual std::vector<byte> data() const = 0;
+ int ttl_;
+};
+
+struct DNSAddressRR : public DNSRR {
+ DNSAddressRR(const std::string& name, ns_type rrtype, int ttl,
+ const byte* addr, int addrlen)
+ : DNSRR(name, rrtype, ttl), addr_(addr, addr + addrlen) {}
+ DNSAddressRR(const std::string& name, ns_type rrtype, int ttl,
+ const std::vector<byte>& addr)
+ : DNSRR(name, rrtype, ttl), addr_(addr) {}
+ virtual std::vector<byte> data() const;
+ std::vector<byte> addr_;
+};
+
+struct DNSARR : public DNSAddressRR {
+ DNSARR(const std::string& name, int ttl, const byte* addr, int addrlen)
+ : DNSAddressRR(name, ns_t_a, ttl, addr, addrlen) {}
+ DNSARR(const std::string& name, int ttl, const std::vector<byte>& addr)
+ : DNSAddressRR(name, ns_t_a, ttl, addr) {}
+};
+
+struct DNSAaaaRR : public DNSAddressRR {
+ DNSAaaaRR(const std::string& name, int ttl, const byte* addr, int addrlen)
+ : DNSAddressRR(name, ns_t_aaaa, ttl, addr, addrlen) {}
+ DNSAaaaRR(const std::string& name, int ttl, const std::vector<byte>& addr)
+ : DNSAddressRR(name, ns_t_aaaa, ttl, addr) {}
+};
+
+struct DNSSingleNameRR : public DNSRR {
+ DNSSingleNameRR(const std::string& name, ns_type rrtype, int ttl,
+ const std::string& other)
+ : DNSRR(name, rrtype, ttl), other_(other) {}
+ virtual std::vector<byte> data() const;
+ std::string other_;
+};
+
+struct DNSCnameRR : public DNSSingleNameRR {
+ DNSCnameRR(const std::string& name, int ttl, const std::string& other)
+ : DNSSingleNameRR(name, ns_t_cname, ttl, other) {}
+};
+
+struct DNSNsRR : public DNSSingleNameRR {
+ DNSNsRR(const std::string& name, int ttl, const std::string& other)
+ : DNSSingleNameRR(name, ns_t_ns, ttl, other) {}
+};
+
+struct DNSPtrRR : public DNSSingleNameRR {
+ DNSPtrRR(const std::string& name, int ttl, const std::string& other)
+ : DNSSingleNameRR(name, ns_t_ptr, ttl, other) {}
+};
+
+struct DNSTxtRR : public DNSRR {
+ DNSTxtRR(const std::string& name, int ttl, const std::vector<std::string>& txt)
+ : DNSRR(name, ns_t_txt, ttl), txt_(txt) {}
+ virtual std::vector<byte> data() const;
+ std::vector<std::string> txt_;
+};
+
+struct DNSMxRR : public DNSRR {
+ DNSMxRR(const std::string& name, int ttl, int pref, const std::string& other)
+ : DNSRR(name, ns_t_mx, ttl), pref_(pref), other_(other) {}
+ virtual std::vector<byte> data() const;
+ int pref_;
+ std::string other_;
+};
+
+struct DNSSrvRR : public DNSRR {
+ DNSSrvRR(const std::string& name, int ttl,
+ int prio, int weight, int port, const std::string& target)
+ : DNSRR(name, ns_t_srv, ttl), prio_(prio), weight_(weight), port_(port), target_(target) {}
+ virtual std::vector<byte> data() const;
+ int prio_;
+ int weight_;
+ int port_;
+ std::string target_;
+};
+
+struct DNSSoaRR : public DNSRR {
+ DNSSoaRR(const std::string& name, int ttl,
+ const std::string& nsname, const std::string& rname,
+ int serial, int refresh, int retry, int expire, int minimum)
+ : DNSRR(name, ns_t_soa, ttl), nsname_(nsname), rname_(rname),
+ serial_(serial), refresh_(refresh), retry_(retry),
+ expire_(expire), minimum_(minimum) {}
+ virtual std::vector<byte> data() const;
+ std::string nsname_;
+ std::string rname_;
+ int serial_;
+ int refresh_;
+ int retry_;
+ int expire_;
+ int minimum_;
+};
+
+struct DNSNaptrRR : public DNSRR {
+ DNSNaptrRR(const std::string& name, int ttl,
+ int order, int pref,
+ const std::string& flags,
+ const std::string& service,
+ const std::string& regexp,
+ const std::string& replacement)
+ : DNSRR(name, ns_t_naptr, ttl), order_(order), pref_(pref),
+ flags_(flags), service_(service), regexp_(regexp), replacement_(replacement) {}
+ virtual std::vector<byte> data() const;
+ int order_;
+ int pref_;
+ std::string flags_;
+ std::string service_;
+ std::string regexp_;
+ std::string replacement_;
+};
+
+struct DNSOption {
+ int code_;
+ std::vector<byte> data_;
+};
+
+struct DNSOptRR : public DNSRR {
+ DNSOptRR(int extrcode, int udpsize)
+ : DNSRR("", ns_t_opt, static_cast<ns_class>(udpsize), extrcode) {}
+ virtual std::vector<byte> data() const;
+ std::vector<DNSOption> opts_;
+};
+
+struct DNSPacket {
+ DNSPacket()
+ : qid_(0), response_(false), opcode_(ns_o_query),
+ aa_(false), tc_(false), rd_(false), ra_(false),
+ z_(false), ad_(false), cd_(false), rcode_(ns_r_noerror) {}
+ // Convenience functions that take ownership of given pointers.
+ DNSPacket& add_question(DNSQuestion *q) {
+ questions_.push_back(std::unique_ptr<DNSQuestion>(q));
+ return *this;
+ }
+ DNSPacket& add_answer(DNSRR *q) {
+ answers_.push_back(std::unique_ptr<DNSRR>(q));
+ return *this;
+ }
+ DNSPacket& add_auth(DNSRR *q) {
+ auths_.push_back(std::unique_ptr<DNSRR>(q));
+ return *this;
+ }
+ DNSPacket& add_additional(DNSRR *q) {
+ adds_.push_back(std::unique_ptr<DNSRR>(q));
+ return *this;
+ }
+ // Chainable setters.
+ DNSPacket& set_qid(int qid) { qid_ = qid; return *this; }
+ DNSPacket& set_response(bool v = true) { response_ = v; return *this; }
+ DNSPacket& set_aa(bool v = true) { aa_ = v; return *this; }
+ DNSPacket& set_tc(bool v = true) { tc_ = v; return *this; }
+ DNSPacket& set_rd(bool v = true) { rd_ = v; return *this; }
+ DNSPacket& set_ra(bool v = true) { ra_ = v; return *this; }
+ DNSPacket& set_z(bool v = true) { z_ = v; return *this; }
+ DNSPacket& set_ad(bool v = true) { ad_ = v; return *this; }
+ DNSPacket& set_cd(bool v = true) { cd_ = v; return *this; }
+ DNSPacket& set_rcode(ns_rcode rcode) { rcode_ = rcode; return *this; }
+
+ // Return the encoded packet.
+ std::vector<byte> data() const;
+
+ int qid_;
+ bool response_;
+ ns_opcode opcode_;
+ bool aa_;
+ bool tc_;
+ bool rd_;
+ bool ra_;
+ bool z_;
+ bool ad_;
+ bool cd_;
+ ns_rcode rcode_;
+ std::vector<std::unique_ptr<DNSQuestion>> questions_;
+ std::vector<std::unique_ptr<DNSRR>> answers_;
+ std::vector<std::unique_ptr<DNSRR>> auths_;
+ std::vector<std::unique_ptr<DNSRR>> adds_;
+};
+
+} // namespace ares
+
+#endif
diff --git a/contrib/libs/c-ares/test/ya.make b/contrib/libs/c-ares/test/ya.make
index fb81afa54e..ef42eab230 100644
--- a/contrib/libs/c-ares/test/ya.make
+++ b/contrib/libs/c-ares/test/ya.make
@@ -1,60 +1,60 @@
-# Generated by devtools/yamaker.
-
+# Generated by devtools/yamaker.
+
GTEST(arestest)
-
+
OWNER(max42 g:cpp-contrib)
-
-LICENSE(MIT)
-
-SIZE(MEDIUM)
-
-TAG(ya:external)
-
-REQUIREMENTS(network:full)
-
-PEERDIR(
- contrib/libs/c-ares
-)
-
-ADDINCL(
- contrib/libs/c-ares
- contrib/libs/c-ares/test
-)
-
-NO_COMPILER_WARNINGS()
-
+
+LICENSE(MIT)
+
+SIZE(MEDIUM)
+
+TAG(ya:external)
+
+REQUIREMENTS(network:full)
+
+PEERDIR(
+ contrib/libs/c-ares
+)
+
+ADDINCL(
+ contrib/libs/c-ares
+ contrib/libs/c-ares/test
+)
+
+NO_COMPILER_WARNINGS()
+
CFLAGS(
-DHAVE_CONFIG_H
)
-IF (NOT DLL_FOR)
- CFLAGS(
- -DCARES_STATICLIB
- )
-ENDIF()
-
-SRCS(
- ares-test-init.cc
- ares-test-internal.cc
- ares-test-live.cc
- ares-test-misc.cc
+IF (NOT DLL_FOR)
+ CFLAGS(
+ -DCARES_STATICLIB
+ )
+ENDIF()
+
+SRCS(
+ ares-test-init.cc
+ ares-test-internal.cc
+ ares-test-live.cc
+ ares-test-misc.cc
ares-test-mock-ai.cc
- ares-test-mock.cc
- ares-test-ns.cc
- ares-test-parse-a.cc
- ares-test-parse-aaaa.cc
- ares-test-parse-mx.cc
- ares-test-parse-naptr.cc
- ares-test-parse-ns.cc
- ares-test-parse-ptr.cc
+ ares-test-mock.cc
+ ares-test-ns.cc
+ ares-test-parse-a.cc
+ ares-test-parse-aaaa.cc
+ ares-test-parse-mx.cc
+ 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.cc
- ares-test-parse-srv.cc
- ares-test-parse-txt.cc
- ares-test-parse.cc
- ares-test.cc
- dns-proto-test.cc
- dns-proto.cc
-)
-
-END()
+ ares-test-parse-soa.cc
+ ares-test-parse-srv.cc
+ ares-test-parse-txt.cc
+ ares-test-parse.cc
+ ares-test.cc
+ dns-proto-test.cc
+ dns-proto.cc
+)
+
+END()