• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "ares-test.h"
2 #include "dns-proto.h"
3 
4 #include <stdio.h>
5 
6 #ifdef HAVE_UNISTD_H
7 #include <unistd.h>
8 #endif
9 #include <fcntl.h>
10 
11 extern "C" {
12 // Remove command-line defines of package variables for the test project...
13 #undef PACKAGE_NAME
14 #undef PACKAGE_BUGREPORT
15 #undef PACKAGE_STRING
16 #undef PACKAGE_TARNAME
17 // ... so we can include the library's config without symbol redefinitions.
18 #include "ares_setup.h"
19 #include "ares_nowarn.h"
20 #include "ares_inet_net_pton.h"
21 #include "ares_data.h"
22 #include "ares_private.h"
23 #include "bitncmp.h"
24 
25 #ifdef HAVE_ARPA_INET_H
26 #include <arpa/inet.h>
27 #endif
28 #ifdef HAVE_SYS_UIO_H
29 #  include <sys/uio.h>
30 #endif
31 }
32 
33 #include <string>
34 #include <vector>
35 
36 namespace ares {
37 namespace test {
38 
39 #ifndef CARES_SYMBOL_HIDING
CheckPtoN4(int size,unsigned int value,const char * input)40 void CheckPtoN4(int size, unsigned int value, const char *input) {
41   struct in_addr a4;
42   a4.s_addr = 0;
43   uint32_t expected = htonl(value);
44   EXPECT_EQ(size, ares_inet_net_pton(AF_INET, input, &a4, sizeof(a4)))
45     << " for input " << input;
46   EXPECT_EQ(expected, a4.s_addr) << " for input " << input;
47 }
48 #endif
49 
TEST_F(LibraryTest,InetPtoN)50 TEST_F(LibraryTest, InetPtoN) {
51   struct in_addr a4;
52   struct in6_addr a6;
53 
54 #ifndef CARES_SYMBOL_HIDING
55   uint32_t expected;
56 
57   CheckPtoN4(4 * 8, 0x01020304, "1.2.3.4");
58   CheckPtoN4(4 * 8, 0x81010101, "129.1.1.1");
59   CheckPtoN4(4 * 8, 0xC0010101, "192.1.1.1");
60   CheckPtoN4(4 * 8, 0xE0010101, "224.1.1.1");
61   CheckPtoN4(4 * 8, 0xE1010101, "225.1.1.1");
62   CheckPtoN4(4, 0xE0000000, "224");
63   CheckPtoN4(4 * 8, 0xFD000000, "253");
64   CheckPtoN4(4 * 8, 0xF0010101, "240.1.1.1");
65   CheckPtoN4(4 * 8, 0x02030405, "02.3.4.5");
66   CheckPtoN4(3 * 8, 0x01020304, "1.2.3.4/24");
67   CheckPtoN4(3 * 8, 0x01020300, "1.2.3/24");
68   CheckPtoN4(2 * 8, 0xa0000000, "0xa");
69   CheckPtoN4(0, 0x02030405, "2.3.4.5/000");
70   CheckPtoN4(1 * 8, 0x01020000, "1.2/8");
71   CheckPtoN4(2 * 8, 0x01020000, "0x0102/16");
72   CheckPtoN4(4 * 8, 0x02030405, "02.3.4.5");
73 
74   EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "::", &a6, sizeof(a6)));
75   EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "::1", &a6, sizeof(a6)));
76   EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "1234:5678::", &a6, sizeof(a6)));
77   EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "12:34::ff", &a6, sizeof(a6)));
78   EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.4", &a6, sizeof(a6)));
79   EXPECT_EQ(23, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.4/23", &a6, sizeof(a6)));
80   EXPECT_EQ(3 * 8, ares_inet_net_pton(AF_INET6, "12:34::ff/24", &a6, sizeof(a6)));
81   EXPECT_EQ(0, ares_inet_net_pton(AF_INET6, "12:34::ff/0", &a6, sizeof(a6)));
82   EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "12:34::ffff:0.2", &a6, sizeof(a6)));
83   EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234", &a6, sizeof(a6)));
84 
85   // Various malformed versions
86   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "", &a4, sizeof(a4)));
87   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, " ", &a4, sizeof(a4)));
88   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x", &a4, sizeof(a4)));
89   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x ", &a4, sizeof(a4)));
90   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "x0", &a4, sizeof(a4)));
91   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0xXYZZY", &a4, sizeof(a4)));
92   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "xyzzy", &a4, sizeof(a4)));
93   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET+AF_INET6, "1.2.3.4", &a4, sizeof(a4)));
94   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "257.2.3.4", &a4, sizeof(a4)));
95   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "002.3.4.x", &a4, sizeof(a4)));
96   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "00.3.4.x", &a4, sizeof(a4)));
97   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.x", &a4, sizeof(a4)));
98   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5.6", &a4, sizeof(a4)));
99   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5.6/12", &a4, sizeof(a4)));
100   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4:5", &a4, sizeof(a4)));
101   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5/120", &a4, sizeof(a4)));
102   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5/1x", &a4, sizeof(a4)));
103   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5/x", &a4, sizeof(a4)));
104   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/240", &a6, sizeof(a6)));
105   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/02", &a6, sizeof(a6)));
106   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/2y", &a6, sizeof(a6)));
107   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/y", &a6, sizeof(a6)));
108   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/", &a6, sizeof(a6)));
109   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "", &a6, sizeof(a6)));
110   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ":x", &a6, sizeof(a6)));
111   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ":", &a6, sizeof(a6)));
112   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ": :1234", &a6, sizeof(a6)));
113   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "::12345", &a6, sizeof(a6)));
114   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234::2345:3456::0011", &a6, sizeof(a6)));
115   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234:", &a6, sizeof(a6)));
116   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234::", &a6, sizeof(a6)));
117   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1.2.3.4", &a6, sizeof(a6)));
118   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ":1234:1234:1234:1234:1234:1234:1234:1234", &a6, sizeof(a6)));
119   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ":1234:1234:1234:1234:1234:1234:1234:1234:", &a6, sizeof(a6)));
120   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234:5678", &a6, sizeof(a6)));
121   // TODO(drysdale): check whether the next two tests should give -1.
122   EXPECT_EQ(0, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234:5678:5678", &a6, sizeof(a6)));
123   EXPECT_EQ(0, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234:5678:5678:5678", &a6, sizeof(a6)));
124   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:257.2.3.4", &a6, sizeof(a6)));
125   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:002.2.3.4", &a6, sizeof(a6)));
126   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.4.5.6", &a6, sizeof(a6)));
127   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.4.5", &a6, sizeof(a6)));
128   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.z", &a6, sizeof(a6)));
129   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3001.4", &a6, sizeof(a6)));
130   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3..4", &a6, sizeof(a6)));
131   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.", &a6, sizeof(a6)));
132 
133   // Hex constants are allowed.
134   EXPECT_EQ(4 * 8, ares_inet_net_pton(AF_INET, "0x01020304", &a4, sizeof(a4)));
135   expected = htonl(0x01020304);
136   EXPECT_EQ(expected, a4.s_addr);
137   EXPECT_EQ(4 * 8, ares_inet_net_pton(AF_INET, "0x0a0b0c0d", &a4, sizeof(a4)));
138   expected = htonl(0x0a0b0c0d);
139   EXPECT_EQ(expected, a4.s_addr);
140   EXPECT_EQ(4 * 8, ares_inet_net_pton(AF_INET, "0x0A0B0C0D", &a4, sizeof(a4)));
141   expected = htonl(0x0a0b0c0d);
142   EXPECT_EQ(expected, a4.s_addr);
143   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x0xyz", &a4, sizeof(a4)));
144   EXPECT_EQ(4 * 8, ares_inet_net_pton(AF_INET, "0x1122334", &a4, sizeof(a4)));
145   expected = htonl(0x11223340);
146   EXPECT_EQ(expected, a4.s_addr);  // huh?
147 
148   // No room, no room.
149   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "1.2.3.4", &a4, sizeof(a4) - 1));
150   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff", &a6, sizeof(a6) - 1));
151   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x01020304", &a4, 2));
152   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x01020304", &a4, 0));
153   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x0a0b0c0d", &a4, 0));
154   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x0xyz", &a4, 0));
155   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x1122334", &a4, sizeof(a4) - 1));
156   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "253", &a4, sizeof(a4) - 1));
157 #endif
158 
159   EXPECT_EQ(1, ares_inet_pton(AF_INET, "1.2.3.4", &a4));
160   EXPECT_EQ(1, ares_inet_pton(AF_INET6, "12:34::ff", &a6));
161   EXPECT_EQ(1, ares_inet_pton(AF_INET6, "12:34::ffff:1.2.3.4", &a6));
162   EXPECT_EQ(0, ares_inet_pton(AF_INET, "xyzzy", &a4));
163   EXPECT_EQ(-1, ares_inet_pton(AF_INET+AF_INET6, "1.2.3.4", &a4));
164 }
165 
TEST_F(LibraryTest,FreeCorruptData)166 TEST_F(LibraryTest, FreeCorruptData) {
167   // ares_free_data(p) expects that there is a type field and a marker
168   // field in the memory before p.  Feed it incorrect versions of each.
169   struct ares_data *data = (struct ares_data *)malloc(sizeof(struct ares_data));
170   void* p = &(data->data);
171 
172   // Invalid type
173   data->type = (ares_datatype)99;
174   data->mark = ARES_DATATYPE_MARK;
175   ares_free_data(p);
176 
177   // Invalid marker
178   data->type = (ares_datatype)ARES_DATATYPE_MX_REPLY;
179   data->mark = ARES_DATATYPE_MARK + 1;
180   ares_free_data(p);
181 
182   // Null pointer
183   ares_free_data(nullptr);
184 
185   free(data);
186 }
187 
188 #ifndef CARES_SYMBOL_HIDING
TEST_F(LibraryTest,FreeLongChain)189 TEST_F(LibraryTest, FreeLongChain) {
190   struct ares_addr_node *data = nullptr;
191   for (int ii = 0; ii < 100000; ii++) {
192     struct ares_addr_node *prev = (struct ares_addr_node*)ares_malloc_data(ARES_DATATYPE_ADDR_NODE);
193     prev->next = data;
194     data = prev;
195   }
196 
197   ares_free_data(data);
198 }
199 
TEST(LibraryInit,StrdupFailures)200 TEST(LibraryInit, StrdupFailures) {
201   EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
202   char* copy = ares_strdup("string");
203   EXPECT_NE(nullptr, copy);
204   ares_free(copy);
205   ares_library_cleanup();
206 }
207 
TEST_F(LibraryTest,StrdupFailures)208 TEST_F(LibraryTest, StrdupFailures) {
209   SetAllocFail(1);
210   char* copy = ares_strdup("string");
211   EXPECT_EQ(nullptr, copy);
212 }
213 
TEST_F(LibraryTest,MallocDataFail)214 TEST_F(LibraryTest, MallocDataFail) {
215   EXPECT_EQ(nullptr, ares_malloc_data((ares_datatype)99));
216   SetAllocSizeFail(sizeof(struct ares_data));
217   EXPECT_EQ(nullptr, ares_malloc_data(ARES_DATATYPE_MX_REPLY));
218 }
219 
TEST(Misc,Bitncmp)220 TEST(Misc, Bitncmp) {
221   byte a[4] = {0x80, 0x01, 0x02, 0x03};
222   byte b[4] = {0x80, 0x01, 0x02, 0x04};
223   byte c[4] = {0x01, 0xFF, 0x80, 0x02};
224   EXPECT_GT(0, ares__bitncmp(a, b, sizeof(a)*8));
225   EXPECT_LT(0, ares__bitncmp(b, a, sizeof(a)*8));
226   EXPECT_EQ(0, ares__bitncmp(a, a, sizeof(a)*8));
227 
228   for (int ii = 1; ii < (3*8+5); ii++) {
229     EXPECT_EQ(0, ares__bitncmp(a, b, ii));
230     EXPECT_EQ(0, ares__bitncmp(b, a, ii));
231     EXPECT_LT(0, ares__bitncmp(a, c, ii));
232     EXPECT_GT(0, ares__bitncmp(c, a, ii));
233   }
234 
235   // Last byte differs at 5th bit
236   EXPECT_EQ(0, ares__bitncmp(a, b, 3*8 + 3));
237   EXPECT_EQ(0, ares__bitncmp(a, b, 3*8 + 4));
238   EXPECT_EQ(0, ares__bitncmp(a, b, 3*8 + 5));
239   EXPECT_GT(0, ares__bitncmp(a, b, 3*8 + 6));
240   EXPECT_GT(0, ares__bitncmp(a, b, 3*8 + 7));
241 }
242 
TEST_F(LibraryTest,Casts)243 TEST_F(LibraryTest, Casts) {
244   ares_ssize_t ssz = 100;
245   unsigned int u = 100;
246   int i = 100;
247   long l = 100;
248 
249   unsigned int ru = aresx_sztoui(ssz);
250   EXPECT_EQ(u, ru);
251   int ri = aresx_sztosi(ssz);
252   EXPECT_EQ(i, ri);
253 
254   ri = aresx_sltosi(l);
255   EXPECT_EQ(l, (long)ri);
256 }
257 
TEST_F(LibraryTest,ReadLine)258 TEST_F(LibraryTest, ReadLine) {
259   TempFile temp("abcde\n0123456789\nXYZ\n012345678901234567890\n\n");
260   FILE *fp = fopen(temp.filename(), "r");
261   size_t bufsize = 4;
262   char *buf = (char *)ares_malloc(bufsize);
263 
264   EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
265   EXPECT_EQ("abcde", std::string(buf));
266   EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
267   EXPECT_EQ("0123456789", std::string(buf));
268   EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
269   EXPECT_EQ("XYZ", std::string(buf));
270   SetAllocFail(1);
271   EXPECT_EQ(ARES_ENOMEM, ares__read_line(fp, &buf, &bufsize));
272   EXPECT_EQ(nullptr, buf);
273 
274   fclose(fp);
275   ares_free(buf);
276 }
277 
TEST_F(LibraryTest,ReadLineNoBuf)278 TEST_F(LibraryTest, ReadLineNoBuf) {
279   TempFile temp("abcde\n0123456789\nXYZ\n012345678901234567890");
280   FILE *fp = fopen(temp.filename(), "r");
281   size_t bufsize = 0;
282   char *buf = nullptr;
283 
284   SetAllocFail(1);
285   EXPECT_EQ(ARES_ENOMEM, ares__read_line(fp, &buf, &bufsize));
286 
287   EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
288   EXPECT_EQ("abcde", std::string(buf));
289   EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
290   EXPECT_EQ("0123456789", std::string(buf));
291   EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
292   EXPECT_EQ("XYZ", std::string(buf));
293   EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize));
294   EXPECT_EQ("012345678901234567890", std::string(buf));
295 
296   fclose(fp);
297   ares_free(buf);
298 }
299 
TEST(Misc,GetHostent)300 TEST(Misc, GetHostent) {
301   TempFile hostsfile("1.2.3.4 example.com  \n"
302                      "  2.3.4.5\tgoogle.com   www.google.com\twww2.google.com\n"
303                      "#comment\n"
304                      "4.5.6.7\n"
305                      "1.3.5.7  \n"
306                      "::1    ipv6.com");
307   struct hostent *host = nullptr;
308   FILE *fp = fopen(hostsfile.filename(), "r");
309   ASSERT_NE(nullptr, fp);
310   EXPECT_EQ(ARES_EBADFAMILY, ares__get_hostent(fp, AF_INET+AF_INET6, &host));
311   rewind(fp);
312 
313   EXPECT_EQ(ARES_SUCCESS, ares__get_hostent(fp, AF_INET, &host));
314   ASSERT_NE(nullptr, host);
315   std::stringstream ss1;
316   ss1 << HostEnt(host);
317   EXPECT_EQ("{'example.com' aliases=[] addrs=[1.2.3.4]}", ss1.str());
318   ares_free_hostent(host);
319   host = nullptr;
320 
321   EXPECT_EQ(ARES_SUCCESS, ares__get_hostent(fp, AF_INET, &host));
322   ASSERT_NE(nullptr, host);
323   std::stringstream ss2;
324   ss2 << HostEnt(host);
325   EXPECT_EQ("{'google.com' aliases=[www.google.com, www2.google.com] addrs=[2.3.4.5]}", ss2.str());
326   ares_free_hostent(host);
327   host = nullptr;
328 
329   EXPECT_EQ(ARES_EOF, ares__get_hostent(fp, AF_INET, &host));
330 
331   rewind(fp);
332   EXPECT_EQ(ARES_SUCCESS, ares__get_hostent(fp, AF_INET6, &host));
333   ASSERT_NE(nullptr, host);
334   std::stringstream ss3;
335   ss3 << HostEnt(host);
336   EXPECT_EQ("{'ipv6.com' aliases=[] addrs=[0000:0000:0000:0000:0000:0000:0000:0001]}", ss3.str());
337   ares_free_hostent(host);
338   host = nullptr;
339   EXPECT_EQ(ARES_EOF, ares__get_hostent(fp, AF_INET6, &host));
340   fclose(fp);
341 }
342 
TEST_F(LibraryTest,GetHostentAllocFail)343 TEST_F(LibraryTest, GetHostentAllocFail) {
344   TempFile hostsfile("1.2.3.4 example.com alias1 alias2\n");
345   struct hostent *host = nullptr;
346   FILE *fp = fopen(hostsfile.filename(), "r");
347   ASSERT_NE(nullptr, fp);
348 
349   for (int ii = 1; ii <= 8; ii++) {
350     rewind(fp);
351     ClearFails();
352     SetAllocFail(ii);
353     host = nullptr;
354     EXPECT_EQ(ARES_ENOMEM, ares__get_hostent(fp, AF_INET, &host)) << ii;
355   }
356   fclose(fp);
357 }
358 
TEST_F(DefaultChannelTest,GetAddrInfoHostsPositive)359 TEST_F(DefaultChannelTest, GetAddrInfoHostsPositive) {
360   TempFile hostsfile("1.2.3.4 example.com  \n"
361                      "  2.3.4.5\tgoogle.com   www.google.com\twww2.google.com\n"
362                      "#comment\n"
363                      "4.5.6.7\n"
364                      "1.3.5.7  \n"
365                      "::1    ipv6.com");
366   EnvValue with_env("CARES_HOSTS", hostsfile.filename());
367   struct ares_addrinfo_hints hints = {};
368   AddrInfoResult result = {};
369   hints.ai_family = AF_INET;
370   hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT;
371   ares_getaddrinfo(channel_, "example.com", NULL, &hints, AddrInfoCallback, &result);
372   Process();
373   EXPECT_TRUE(result.done_);
374   std::stringstream ss;
375   ss << result.ai_;
376   EXPECT_EQ("{example.com addr=[1.2.3.4]}", ss.str());
377 }
378 
TEST_F(DefaultChannelTest,GetAddrInfoHostsSpaces)379 TEST_F(DefaultChannelTest, GetAddrInfoHostsSpaces) {
380   TempFile hostsfile("1.2.3.4 example.com  \n"
381                      "  2.3.4.5\tgoogle.com   www.google.com\twww2.google.com\n"
382                      "#comment\n"
383                      "4.5.6.7\n"
384                      "1.3.5.7  \n"
385                      "::1    ipv6.com");
386   EnvValue with_env("CARES_HOSTS", hostsfile.filename());
387   struct ares_addrinfo_hints hints = {};
388   AddrInfoResult result = {};
389   hints.ai_family = AF_INET;
390   hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT;
391   ares_getaddrinfo(channel_, "google.com", NULL, &hints, AddrInfoCallback, &result);
392   Process();
393   EXPECT_TRUE(result.done_);
394   std::stringstream ss;
395   ss << result.ai_;
396   EXPECT_EQ("{www.google.com->google.com, www2.google.com->google.com addr=[2.3.4.5]}", ss.str());
397 }
398 
TEST_F(DefaultChannelTest,GetAddrInfoHostsByALias)399 TEST_F(DefaultChannelTest, GetAddrInfoHostsByALias) {
400   TempFile hostsfile("1.2.3.4 example.com  \n"
401                      "  2.3.4.5\tgoogle.com   www.google.com\twww2.google.com\n"
402                      "#comment\n"
403                      "4.5.6.7\n"
404                      "1.3.5.7  \n"
405                      "::1    ipv6.com");
406   EnvValue with_env("CARES_HOSTS", hostsfile.filename());
407   struct ares_addrinfo_hints hints = {};
408   AddrInfoResult result = {};
409   hints.ai_family = AF_INET;
410   hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT;
411   ares_getaddrinfo(channel_, "www2.google.com", NULL, &hints, AddrInfoCallback, &result);
412   Process();
413   EXPECT_TRUE(result.done_);
414   std::stringstream ss;
415   ss << result.ai_;
416   EXPECT_EQ("{www.google.com->google.com, www2.google.com->google.com addr=[2.3.4.5]}", ss.str());
417 }
418 
TEST_F(DefaultChannelTest,GetAddrInfoHostsIPV6)419 TEST_F(DefaultChannelTest, GetAddrInfoHostsIPV6) {
420   TempFile hostsfile("1.2.3.4 example.com  \n"
421                      "  2.3.4.5\tgoogle.com   www.google.com\twww2.google.com\n"
422                      "#comment\n"
423                      "4.5.6.7\n"
424                      "1.3.5.7  \n"
425                      "::1    ipv6.com");
426   EnvValue with_env("CARES_HOSTS", hostsfile.filename());
427   struct ares_addrinfo_hints hints = {};
428   AddrInfoResult result = {};
429   hints.ai_family = AF_INET6;
430   hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT;
431   ares_getaddrinfo(channel_, "ipv6.com", NULL, &hints, AddrInfoCallback, &result);
432   Process();
433   EXPECT_TRUE(result.done_);
434   std::stringstream ss;
435   ss << result.ai_;
436   EXPECT_EQ("{ipv6.com addr=[[0000:0000:0000:0000:0000:0000:0000:0001]]}", ss.str());
437 }
438 
TEST_F(LibraryTest,GetAddrInfoAllocFail)439 TEST_F(LibraryTest, GetAddrInfoAllocFail) {
440   TempFile hostsfile("1.2.3.4 example.com alias1 alias2\n");
441   struct ares_addrinfo_hints hints;
442   unsigned short port = 80;
443 
444   memset(&hints, 0, sizeof(hints));
445   hints.ai_family = AF_INET;
446 
447   FILE *fp = fopen(hostsfile.filename(), "r");
448   ASSERT_NE(nullptr, fp);
449 
450   for (int ii = 1; ii <= 3; ii++) {
451     rewind(fp);
452     ClearFails();
453     SetAllocFail(ii);
454     struct ares_addrinfo ai;
455     EXPECT_EQ(ARES_ENOMEM, ares__readaddrinfo(fp, "example.com", port, &hints, &ai)) << ii;
456   }
457   fclose(fp);
458 }
459 
TEST(Misc,OnionDomain)460 TEST(Misc, OnionDomain) {
461   EXPECT_EQ(0, ares__is_onion_domain("onion.no"));
462   EXPECT_EQ(0, ares__is_onion_domain(".onion.no"));
463   EXPECT_EQ(1, ares__is_onion_domain(".onion"));
464   EXPECT_EQ(1, ares__is_onion_domain(".onion."));
465   EXPECT_EQ(1, ares__is_onion_domain("yes.onion"));
466   EXPECT_EQ(1, ares__is_onion_domain("yes.onion."));
467   EXPECT_EQ(1, ares__is_onion_domain("YES.ONION"));
468   EXPECT_EQ(1, ares__is_onion_domain("YES.ONION."));
469 }
470 #endif
471 
472 #ifdef CARES_EXPOSE_STATICS
473 // These tests access internal static functions from the library, which
474 // are only exposed when CARES_EXPOSE_STATICS has been configured. As such
475 // they are tightly couple to the internal library implementation details.
476 extern "C" char *ares_striendstr(const char*, const char*);
TEST_F(LibraryTest,Striendstr)477 TEST_F(LibraryTest, Striendstr) {
478   EXPECT_EQ(nullptr, ares_striendstr("abc", "12345"));
479   EXPECT_NE(nullptr, ares_striendstr("abc12345", "12345"));
480   EXPECT_NE(nullptr, ares_striendstr("abcxyzzy", "XYZZY"));
481   EXPECT_NE(nullptr, ares_striendstr("xyzzy", "XYZZY"));
482   EXPECT_EQ(nullptr, ares_striendstr("xyxzy", "XYZZY"));
483   EXPECT_NE(nullptr, ares_striendstr("", ""));
484   const char *str = "plugh";
485   EXPECT_NE(nullptr, ares_striendstr(str, str));
486 }
487 extern "C" int ares__single_domain(ares_channel, const char*, char**);
TEST_F(DefaultChannelTest,SingleDomain)488 TEST_F(DefaultChannelTest, SingleDomain) {
489   TempFile aliases("www www.google.com\n");
490   EnvValue with_env("HOSTALIASES", aliases.filename());
491 
492   SetAllocSizeFail(128);
493   char *ptr = nullptr;
494   EXPECT_EQ(ARES_ENOMEM, ares__single_domain(channel_, "www", &ptr));
495 
496   channel_->flags |= ARES_FLAG_NOSEARCH|ARES_FLAG_NOALIASES;
497   EXPECT_EQ(ARES_SUCCESS, ares__single_domain(channel_, "www", &ptr));
498   EXPECT_EQ("www", std::string(ptr));
499   ares_free(ptr);
500   ptr = nullptr;
501 
502   SetAllocFail(1);
503   EXPECT_EQ(ARES_ENOMEM, ares__single_domain(channel_, "www", &ptr));
504   EXPECT_EQ(nullptr, ptr);
505 }
506 #endif
507 
TEST_F(DefaultChannelTest,SaveInvalidChannel)508 TEST_F(DefaultChannelTest, SaveInvalidChannel) {
509   int saved = channel_->nservers;
510   channel_->nservers = -1;
511   struct ares_options opts;
512   int optmask = 0;
513   EXPECT_EQ(ARES_ENODATA, ares_save_options(channel_, &opts, &optmask));
514   channel_->nservers = saved;
515 }
516 
517 // Need to put this in own function due to nested lambda bug
518 // in VS2013. (C2888)
configure_socket(ares_socket_t s)519 static int configure_socket(ares_socket_t s) {
520   // transposed from ares-process, simplified non-block setter.
521 #if defined(USE_BLOCKING_SOCKETS)
522   return 0; /* returns success */
523 #elif defined(HAVE_FCNTL_O_NONBLOCK)
524   /* most recent unix versions */
525   int flags;
526   flags = fcntl(s, F_GETFL, 0);
527   return fcntl(s, F_SETFL, flags | O_NONBLOCK);
528 #elif defined(HAVE_IOCTL_FIONBIO)
529   /* older unix versions */
530   int flags = 1;
531   return ioctl(s, FIONBIO, &flags);
532 #elif defined(HAVE_IOCTLSOCKET_FIONBIO)
533 #ifdef WATT32
534   char flags = 1;
535 #else
536   /* Windows */
537   unsigned long flags = 1UL;
538 #endif
539   return ioctlsocket(s, FIONBIO, &flags);
540 #elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
541   /* Amiga */
542   long flags = 1L;
543   return IoctlSocket(s, FIONBIO, flags);
544 #elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
545   /* BeOS */
546   long b = 1L;
547   return setsockopt(s, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
548 #else
549 #  error "no non-blocking method was found/used/set"
550 #endif
551 }
552 
553 // TODO: This should not really be in this file, but we need ares config
554 // flags, and here they are available.
555 const struct ares_socket_functions VirtualizeIO::default_functions = {
__anon8e881cc90102(int af, int type, int protocol, void *) 556   [](int af, int type, int protocol, void *) -> ares_socket_t {
557     auto s = ::socket(af, type, protocol);
558     if (s == ARES_SOCKET_BAD) {
559       return s;
560     }
561     if (configure_socket(s) != 0) {
562       sclose(s);
563       return ares_socket_t(-1);
564     }
565     return s;
566   },
__anon8e881cc90202(ares_socket_t s, void * p) 567   [](ares_socket_t s, void * p) {
568     return :: sclose(s);
569   },
__anon8e881cc90302(ares_socket_t s, const struct sockaddr * addr, socklen_t len, void *) 570   [](ares_socket_t s, const struct sockaddr * addr, socklen_t len, void *) {
571     return ::connect(s, addr, len);
572   },
__anon8e881cc90402(ares_socket_t s, void * dst, size_t len, int flags, struct sockaddr * addr, socklen_t * alen, void *) 573   [](ares_socket_t s, void * dst, size_t len, int flags, struct sockaddr * addr, socklen_t * alen, void *) -> ares_ssize_t {
574 #ifdef HAVE_RECVFROM
575     return ::recvfrom(s, reinterpret_cast<RECV_TYPE_ARG2>(dst), len, flags, addr, alen);
576 #else
577     return sread(s, dst, len);
578 #endif
579   },
__anon8e881cc90502(ares_socket_t s, const struct iovec * vec, int len, void *) 580   [](ares_socket_t s, const struct iovec * vec, int len, void *) {
581 #ifdef _WIN32
582     return ares_writev(s, vec, len);
583 #else
584     return :: writev(s, vec, len);
585 #endif
586   }
587 };
588 
589 
590 }  // namespace test
591 }  // namespace ares
592