• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* MIT License
2  *
3  * Copyright (c) The c-ares project and its contributors
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights
8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the next
13  * paragraph) shall be included in all copies or substantial portions of the
14  * Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  *
24  * SPDX-License-Identifier: MIT
25  */
26 #include "ares-test.h"
27 #include "dns-proto.h"
28 
29 #include <string>
30 #include <vector>
31 
32 namespace ares {
33 namespace test {
34 
TEST_F(DefaultChannelTest,GetServers)35 TEST_F(DefaultChannelTest, GetServers) {
36   std::string servers = GetNameServers(channel_);
37   if (verbose) {
38     std::cerr << "Nameserver: " << servers << std::endl;
39   }
40 }
41 
TEST_F(DefaultChannelTest,GetServersFailures)42 TEST_F(DefaultChannelTest, GetServersFailures) {
43   EXPECT_EQ(ARES_SUCCESS,
44             ares_set_servers_csv(channel_, "1.2.3.4,2.3.4.5"));
45   struct ares_addr_node* servers = nullptr;
46   SetAllocFail(1);
47   EXPECT_EQ(ARES_ENOMEM, ares_get_servers(channel_, &servers));
48   SetAllocFail(2);
49   EXPECT_EQ(ARES_ENOMEM, ares_get_servers(channel_, &servers));
50   EXPECT_EQ(ARES_ENODATA, ares_get_servers(nullptr, &servers));
51 }
52 
TEST_F(DefaultChannelTest,SetServers)53 TEST_F(DefaultChannelTest, SetServers) {
54   /* NOTE: This test is because we have actual external users doing test case
55    *       simulation and removing all servers to generate various error
56    *       conditions in their own code.  It would make more sense to return
57    *       ARES_ENODATA, but due to historical users, we can't break them.
58    *       See: https://github.com/nodejs/node/pull/50800
59    */
60   EXPECT_EQ(ARES_SUCCESS, ares_set_servers(channel_, nullptr));
61   std::string expected_empty = "";
62   EXPECT_EQ(expected_empty, GetNameServers(channel_));
63   HostResult result;
64   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
65   Process();
66   EXPECT_TRUE(result.done_);
67   EXPECT_EQ(ARES_ENOSERVER, result.status_);
68 
69 
70   struct ares_addr_node server1;
71   struct ares_addr_node server2;
72   server1.next = &server2;
73   server1.family = AF_INET;
74   server1.addr.addr4.s_addr = htonl(0x01020304);
75   server2.next = nullptr;
76   server2.family = AF_INET;
77   server2.addr.addr4.s_addr = htonl(0x02030405);
78   EXPECT_EQ(ARES_ENODATA, ares_set_servers(nullptr, &server1));
79 
80   EXPECT_EQ(ARES_SUCCESS, ares_set_servers(channel_, &server1));
81   std::string expected = "1.2.3.4:53,2.3.4.5:53";
82   EXPECT_EQ(expected, GetNameServers(channel_));
83 }
84 
TEST_F(DefaultChannelTest,SetServersPorts)85 TEST_F(DefaultChannelTest, SetServersPorts) {
86   /* NOTE: This test is because we have actual external users doing test case
87    *       simulation and removing all servers to generate various error
88    *       conditions in their own code.  It would make more sense to return
89    *       ARES_ENODATA, but due to historical users, we can't break them.
90    *       See: https://github.com/nodejs/node/pull/50800
91    */
92   EXPECT_EQ(ARES_SUCCESS, ares_set_servers_ports(channel_, nullptr));
93   std::string expected_empty = "";
94   EXPECT_EQ(expected_empty, GetNameServers(channel_));
95 
96   struct ares_addr_port_node server1;
97   struct ares_addr_port_node server2;
98   server1.next = &server2;
99   server1.family = AF_INET;
100   server1.addr.addr4.s_addr = htonl(0x01020304);
101   server1.udp_port = 111;
102   server1.tcp_port = 111;
103   server2.next = nullptr;
104   server2.family = AF_INET;
105   server2.addr.addr4.s_addr = htonl(0x02030405);
106   server2.udp_port = 0;
107   server2.tcp_port = 0;
108   EXPECT_EQ(ARES_ENODATA, ares_set_servers_ports(nullptr, &server1));
109 
110   EXPECT_EQ(ARES_SUCCESS, ares_set_servers_ports(channel_, &server1));
111   std::string expected = "1.2.3.4:111,2.3.4.5:53";
112   EXPECT_EQ(expected, GetNameServers(channel_));
113 }
114 
TEST_F(DefaultChannelTest,SetServersCSV)115 TEST_F(DefaultChannelTest, SetServersCSV) {
116   EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "1.2.3.4"));
117   EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "xyzzy,plugh"));
118   EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "256.1.2.3"));
119   EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "1.2.3.4.5"));
120   EXPECT_EQ(ARES_ENODATA, ares_set_servers_csv(nullptr, "1:2:3:4:5"));
121 
122   /* NOTE: This test is because we have actual external users doing test case
123    *       simulation and removing all servers to generate various error
124    *       conditions in their own code.  It would make more sense to return
125    *       ARES_ENODATA, but due to historical users, we can't break them.
126    *       See: https://github.com/nodejs/node/pull/50800
127    */
128   EXPECT_EQ(ARES_SUCCESS, ares_set_servers_csv(channel_, NULL));
129   std::string expected_empty = "";
130   EXPECT_EQ(expected_empty, GetNameServers(channel_));
131   EXPECT_EQ(ARES_SUCCESS, ares_set_servers_csv(channel_, ""));
132   EXPECT_EQ(expected_empty, GetNameServers(channel_));
133 
134 
135   EXPECT_EQ(ARES_SUCCESS,
136             ares_set_servers_csv(channel_, "1.2.3.4,0102:0304:0506:0708:0910:1112:1314:1516,2.3.4.5"));
137   std::string expected = "1.2.3.4:53,[102:304:506:708:910:1112:1314:1516]:53,2.3.4.5:53";
138   EXPECT_EQ(expected, GetNameServers(channel_));
139 
140   // Same, with spaces
141   EXPECT_EQ(ARES_SUCCESS,
142             ares_set_servers_csv(channel_, "1.2.3.4 , [0102:0304:0506:0708:0910:1112:1314:1516]:53, 2.3.4.5"));
143   EXPECT_EQ(expected, GetNameServers(channel_));
144 
145   // Ignore invalid link-local interface, keep rest.
146   EXPECT_EQ(ARES_SUCCESS,
147             ares_set_servers_csv(channel_, "1.2.3.4 , [0102:0304:0506:0708:0910:1112:1314:1516]:53, [fe80::1]:53%iface0, 2.3.4.5"));
148   EXPECT_EQ(expected, GetNameServers(channel_));
149 
150   // Same, with ports
151   EXPECT_EQ(ARES_SUCCESS,
152             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"));
153   std::string expected2 = {"1.2.3.4:54,[102:304:506:708:910:1112:1314:1516]:80,2.3.4.5:55"};
154   EXPECT_EQ(expected2, GetNameServers(channel_));
155 
156   // Should survive duplication
157   ares_channel_t *channel2;
158   EXPECT_EQ(ARES_SUCCESS, ares_dup(&channel2, channel_));
159   EXPECT_EQ(expected2, GetNameServers(channel2));
160   ares_destroy(channel2);
161 
162   // Allocation failure cases
163   for (int fail = 1; fail <= 5; fail++) {
164     SetAllocFail(fail);
165     EXPECT_EQ(ARES_ENOMEM,
166               ares_set_servers_csv(channel_, "1.2.3.4,0102:0304:0506:0708:0910:1112:1314:1516,2.3.4.5"));
167   }
168 
169   EXPECT_EQ(ARES_EBADSTR, ares_set_servers_csv(channel_, "2.3.4.5,1.2.3.4:,3.4.5.6"));
170   EXPECT_EQ(ARES_EBADSTR, ares_set_servers_csv(channel_, "2.3.4.5,1.2.3.4:Z,3.4.5.6"));
171 }
172 
TEST_F(DefaultChannelTest,TimeoutValue)173 TEST_F(DefaultChannelTest, TimeoutValue) {
174   struct timeval tinfo;
175   tinfo.tv_sec = 0;
176   tinfo.tv_usec = 0;
177   struct timeval tmax;
178   tmax.tv_sec = 0;
179   tmax.tv_usec = 10;
180   struct timeval* pt;
181 
182   // No timers => get max back.
183   pt = ares_timeout(channel_, &tmax, &tinfo);
184   EXPECT_EQ(&tmax, pt);
185   EXPECT_EQ(0, pt->tv_sec);
186   EXPECT_EQ(10, pt->tv_usec);
187 
188   pt = ares_timeout(channel_, nullptr, &tinfo);
189   EXPECT_EQ(nullptr, pt);
190 
191   HostResult result;
192   ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result);
193 
194   // Now there's a timer running.
195   pt = ares_timeout(channel_, &tmax, &tinfo);
196   EXPECT_EQ(&tmax, pt);
197   EXPECT_EQ(0, pt->tv_sec);
198   EXPECT_EQ(10, pt->tv_usec);
199 
200   tmax.tv_sec = 100;
201   pt = ares_timeout(channel_, &tmax, &tinfo);
202   EXPECT_EQ(&tinfo, pt);
203 
204   pt = ares_timeout(channel_, nullptr, &tinfo);
205   EXPECT_EQ(&tinfo, pt);
206 
207   Process();
208 }
209 
TEST_F(LibraryTest,InetNtoP)210 TEST_F(LibraryTest, InetNtoP) {
211   struct in_addr addr;
212   addr.s_addr = htonl(0x01020304);
213   char buffer[256];
214   EXPECT_EQ(buffer, ares_inet_ntop(AF_INET, &addr, buffer, sizeof(buffer)));
215   EXPECT_EQ("1.2.3.4", std::string(buffer));
216 }
217 
TEST_F(LibraryTest,Mkquery)218 TEST_F(LibraryTest, Mkquery) {
219   byte* p;
220   int len;
221   ares_mkquery("example.com", C_IN, T_A, 0x1234, 0, &p, &len);
222   std::vector<byte> data(p, p + len);
223   ares_free_string(p);
224 
225   std::string actual = PacketToString(data);
226   DNSPacket pkt;
227   pkt.set_qid(0x1234).add_question(new DNSQuestion("example.com", T_A));
228   std::string expected = PacketToString(pkt.data());
229   EXPECT_EQ(expected, actual);
230 }
231 
TEST_F(LibraryTest,CreateQuery)232 TEST_F(LibraryTest, CreateQuery) {
233   byte* p;
234   int len;
235   // This is hard to really test with escaping since DNS names don't allow
236   // bad characters.  So we'll escape good characters.
237   EXPECT_EQ(ARES_SUCCESS,
238             ares_create_query("ex\\097m\\ple.com", C_IN, T_A, 0x1234, 0,
239                               &p, &len, 0));
240   std::vector<byte> data(p, p + len);
241   ares_free_string(p);
242 
243   std::string actual = PacketToString(data);
244   DNSPacket pkt;
245   pkt.set_qid(0x1234).add_question(new DNSQuestion("example.com", T_A));
246   std::string expected = PacketToString(pkt.data());
247   EXPECT_EQ(expected, actual);
248 }
249 
TEST_F(LibraryTest,CreateQueryTrailingEscapedDot)250 TEST_F(LibraryTest, CreateQueryTrailingEscapedDot) {
251   byte* p;
252   int len;
253   EXPECT_EQ(ARES_SUCCESS,
254             ares_create_query("example.com\\.", C_IN, T_A, 0x1234, 0,
255                               &p, &len, 0));
256   std::vector<byte> data(p, p + len);
257   ares_free_string(p);
258 
259   std::string actual = PacketToString(data);
260   EXPECT_EQ("REQ QRY  Q:{'example.com\\.' IN A}", actual);
261 }
262 
TEST_F(LibraryTest,CreateQueryNameTooLong)263 TEST_F(LibraryTest, CreateQueryNameTooLong) {
264   byte* p;
265   int len;
266   EXPECT_EQ(ARES_EBADNAME,
267             ares_create_query(
268               "a1234567890123456789.b1234567890123456789.c1234567890123456789.d1234567890123456789."
269               "a1234567890123456789.b1234567890123456789.c1234567890123456789.d1234567890123456789."
270               "a1234567890123456789.b1234567890123456789.c1234567890123456789.d1234567890123456789."
271               "x1234567890123456789.y1234567890123456789.",
272               C_IN, T_A, 0x1234, 0, &p, &len, 0));
273 }
274 
TEST_F(LibraryTest,CreateQueryFailures)275 TEST_F(LibraryTest, CreateQueryFailures) {
276   byte* p;
277   int len;
278   // RC1035 has a 255 byte limit on names.
279   std::string longname;
280   for (int ii = 0; ii < 17; ii++) {
281     longname += "fedcba9876543210";
282   }
283   p = nullptr;
284   EXPECT_EQ(ARES_EBADNAME,
285             ares_create_query(longname.c_str(), C_IN, T_A, 0x1234, 0,
286                     &p, &len, 0));
287   if (p) ares_free_string(p);
288 
289   SetAllocFail(1);
290 
291   p = nullptr;
292   EXPECT_EQ(ARES_ENOMEM,
293             ares_create_query("example.com", C_IN, T_A, 0x1234, 0,
294                     &p, &len, 0));
295   if (p) ares_free_string(p);
296 
297   // 63-char limit on a single label
298   std::string longlabel = "a.a123456789b123456789c123456789d123456789e123456789f123456789g123456789.org";
299   p = nullptr;
300   EXPECT_EQ(ARES_EBADNAME,
301             ares_create_query(longlabel.c_str(), C_IN, T_A, 0x1234, 0,
302                     &p, &len, 0));
303   if (p) ares_free_string(p);
304 
305   // Empty non-terminal label
306   p = nullptr;
307   EXPECT_EQ(ARES_EBADNAME,
308             ares_create_query("example..com", C_IN, T_A, 0x1234, 0,
309                     &p, &len, 0));
310   if (p) ares_free_string(p);
311 
312   EXPECT_EQ(ARES_EFORMERR,
313             ares_create_query(NULL, C_IN, T_A, 0x1234, 0, NULL, NULL, 0));
314 }
315 
TEST_F(LibraryTest,CreateQueryOnionDomain)316 TEST_F(LibraryTest, CreateQueryOnionDomain) {
317   byte* p;
318   int len;
319   EXPECT_EQ(ARES_ENOTFOUND,
320             ares_create_query("dontleak.onion", C_IN, T_A, 0x1234, 0,
321                               &p, &len, 0));
322 }
323 
TEST_F(DefaultChannelTest,HostByNameOnionDomain)324 TEST_F(DefaultChannelTest, HostByNameOnionDomain) {
325   HostResult result;
326   ares_gethostbyname(channel_, "dontleak.onion", AF_INET, HostCallback, &result);
327   EXPECT_TRUE(result.done_);
328   EXPECT_EQ(ARES_ENOTFOUND, result.status_);
329 }
330 
TEST_F(DefaultChannelTest,HostByNameFileOnionDomain)331 TEST_F(DefaultChannelTest, HostByNameFileOnionDomain) {
332   struct hostent *h;
333   EXPECT_EQ(ARES_ENOTFOUND,
334             ares_gethostbyname_file(channel_, "dontleak.onion", AF_INET, &h));
335 }
336 
TEST_F(DefaultChannelTest,GetAddrinfoOnionDomain)337 TEST_F(DefaultChannelTest, GetAddrinfoOnionDomain) {
338   AddrInfoResult result;
339   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
340   hints.ai_family = AF_UNSPEC;
341   ares_getaddrinfo(channel_, "dontleak.onion", NULL, &hints, AddrInfoCallback, &result);
342   EXPECT_TRUE(result.done_);
343   EXPECT_EQ(ARES_ENOTFOUND, result.status_);
344 }
345 
346 // Interesting question: should tacking on a search domain let the query
347 // through? It seems safer to reject it because "supersecret.onion.search"
348 // still leaks information about the query to malicious resolvers.
TEST_F(DefaultChannelTest,SearchOnionDomain)349 TEST_F(DefaultChannelTest, SearchOnionDomain) {
350   SearchResult result;
351   ares_search(channel_, "dontleak.onion", C_IN, T_A,
352               SearchCallback, &result);
353   EXPECT_TRUE(result.done_);
354   EXPECT_EQ(ARES_ENOTFOUND, result.status_);
355 }
356 
TEST_F(DefaultChannelTest,SendFailure)357 TEST_F(DefaultChannelTest, SendFailure) {
358   unsigned char buf[2] = {};
359   SearchResult result;
360   ares_send(channel_, buf, sizeof(buf), SearchCallback, &result);
361   EXPECT_TRUE(result.done_);
362   EXPECT_EQ(ARES_EBADQUERY, result.status_);
363 }
364 
ExpandName(const std::vector<byte> & data,int offset,long * enclen)365 static std::string ExpandName(const std::vector<byte>& data, int offset,
366                               long *enclen) {
367   char *name = nullptr;
368   int rc = ares_expand_name(data.data() + offset, data.data(), (int)data.size(),
369                             &name, enclen);
370   EXPECT_EQ(ARES_SUCCESS, rc);
371   std::string result;
372   if (rc == ARES_SUCCESS) {
373     result = name;
374   } else {
375     result = "<error>";
376   }
377   ares_free_string(name);
378   return result;
379 }
380 
TEST_F(LibraryTest,ExpandName)381 TEST_F(LibraryTest, ExpandName) {
382   long enclen;
383   std::vector<byte> data1 = {1, 'a', 2, 'b', 'c', 3, 'd', 'e', 'f', 0};
384   EXPECT_EQ("a.bc.def", ExpandName(data1, 0, &enclen));
385   EXPECT_EQ(data1.size(), (size_t)enclen);
386 
387   std::vector<byte> data2 = {0};
388   EXPECT_EQ("", ExpandName(data2, 0, &enclen));
389   EXPECT_EQ(1, enclen);
390 
391   // Complete name indirection
392   std::vector<byte> data3 = {0x12, 0x23,
393                              3, 'd', 'e', 'f', 0,
394                              0xC0, 2};
395   EXPECT_EQ("def", ExpandName(data3, 2, &enclen));
396   EXPECT_EQ(5, enclen);
397   EXPECT_EQ("def", ExpandName(data3, 7, &enclen));
398   EXPECT_EQ(2, enclen);
399 
400   // One label then indirection
401   std::vector<byte> data4 = {0x12, 0x23,
402                              3, 'd', 'e', 'f', 0,
403                              1, 'a', 0xC0, 2};
404   EXPECT_EQ("def", ExpandName(data4, 2, &enclen));
405   EXPECT_EQ(5, enclen);
406   EXPECT_EQ("a.def", ExpandName(data4, 7, &enclen));
407   EXPECT_EQ(4, enclen);
408 
409   // Two labels then indirection
410   std::vector<byte> data5 = {0x12, 0x23,
411                              3, 'd', 'e', 'f', 0,
412                              1, 'a', 1, 'b', 0xC0, 2};
413   EXPECT_EQ("def", ExpandName(data5, 2, &enclen));
414   EXPECT_EQ(5, enclen);
415   EXPECT_EQ("a.b.def", ExpandName(data5, 7, &enclen));
416   EXPECT_EQ(6, enclen);
417 
418   // Empty name, indirection to empty name
419   std::vector<byte> data6 = {0x12, 0x23,
420                              0,
421                              0xC0, 2};
422   EXPECT_EQ("", ExpandName(data6, 2, &enclen));
423   EXPECT_EQ(1, enclen);
424   EXPECT_EQ("", ExpandName(data6, 3, &enclen));
425   EXPECT_EQ(2, enclen);
426 }
427 
TEST_F(LibraryTest,ExpandNameFailure)428 TEST_F(LibraryTest, ExpandNameFailure) {
429   std::vector<byte> data1 = {0x03, 'c', 'o', 'm', 0x00};
430   char *name = nullptr;
431   long enclen;
432   SetAllocFail(1);
433   EXPECT_EQ(ARES_ENOMEM,
434             ares_expand_name(data1.data(), data1.data(), (int)data1.size(),
435                              &name, &enclen));
436 
437   // Empty packet
438   EXPECT_EQ(ARES_EBADNAME,
439             ares_expand_name(data1.data(), data1.data(), 0, &name, &enclen));
440 
441   // Start beyond enclosing data
442   EXPECT_EQ(ARES_EBADNAME,
443             ares_expand_name(data1.data() + data1.size(), data1.data(), (int)data1.size(),
444                              &name, &enclen));
445 
446   // Length beyond size of enclosing data
447   std::vector<byte> data2a = {0x13, 'c', 'o', 'm', 0x00};
448   EXPECT_EQ(ARES_EBADNAME,
449             ares_expand_name(data2a.data(), data2a.data(), (int)data2a.size(),
450                              &name, &enclen));
451   std::vector<byte> data2b = {0x1};
452   EXPECT_EQ(ARES_EBADNAME,
453             ares_expand_name(data2b.data(), data2b.data(), (int)data2b.size(),
454                              &name, &enclen));
455   std::vector<byte> data2c = {0xC0};
456   EXPECT_EQ(ARES_EBADNAME,
457             ares_expand_name(data2c.data(), data2c.data(), (int)data2c.size(),
458                              &name, &enclen));
459 
460   // Indirection beyond enclosing data
461   std::vector<byte> data3a = {0xC0, 0x02};
462   EXPECT_EQ(ARES_EBADNAME,
463             ares_expand_name(data3a.data(), data3a.data(), (int)data3a.size(),
464                              &name, &enclen));
465   std::vector<byte> data3b = {0xC0, 0x0A, 'c', 'o', 'm', 0x00};
466   EXPECT_EQ(ARES_EBADNAME,
467             ares_expand_name(data3b.data(), data3b.data(), (int)data3b.size(),
468                              &name, &enclen));
469 
470   // Invalid top bits in label length
471   std::vector<byte> data4 = {0x03, 'c', 'o', 'm', 0x00, 0x80, 0x00};
472   EXPECT_EQ(ARES_EBADNAME,
473             ares_expand_name(data4.data() + 5, data4.data(), (int)data4.size(),
474                              &name, &enclen));
475 
476   // Label too long: 64-byte label, with invalid top 2 bits of length (01).
477   std::vector<byte> data5 = {0x40,
478                              '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
479                              '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
480                              '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
481                              '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f',
482                              0x00};
483   EXPECT_EQ(ARES_EBADNAME,
484             ares_expand_name(data5.data(), data5.data(), (int)data5.size(),
485                              &name, &enclen)) << name;
486 
487   // Incomplete indirect length
488   std::vector<byte> data6 = {0x03, 'c', 'o', 'm', 0x00, 0xC0};
489   EXPECT_EQ(ARES_EBADNAME,
490             ares_expand_name(data6.data() + 5, data6.data(), (int)data6.size(),
491                              &name, &enclen));
492 
493   // Indirection loops
494   std::vector<byte> data7 = {0xC0, 0x02, 0xC0, 0x00};
495   EXPECT_EQ(ARES_EBADNAME,
496             ares_expand_name(data7.data(), data7.data(), (int)data7.size(),
497                              &name, &enclen));
498   std::vector<byte> data8 = {3, 'd', 'e', 'f', 0xC0, 0x08, 0x00, 0x00,
499                              3, 'a', 'b', 'c', 0xC0, 0x00};
500   EXPECT_EQ(ARES_EBADNAME,
501             ares_expand_name(data8.data(), data8.data(), (int)data8.size(),
502                              &name, &enclen));
503   std::vector<byte> data9 = {0x12, 0x23,  // start 2 bytes in
504                              3, 'd', 'e', 'f', 0xC0, 0x02};
505   EXPECT_EQ(ARES_EBADNAME,
506             ares_expand_name(data9.data() + 2, data9.data(), (int)data9.size(),
507                              &name, &enclen));
508 }
509 
TEST_F(LibraryTest,CreateEDNSQuery)510 TEST_F(LibraryTest, CreateEDNSQuery) {
511   byte* p;
512   int len;
513   EXPECT_EQ(ARES_SUCCESS,
514             ares_create_query("example.com", C_IN, T_A, 0x1234, 0,
515                               &p, &len, 1280));
516   std::vector<byte> data(p, p + len);
517   ares_free_string(p);
518 
519   std::string actual = PacketToString(data);
520   DNSPacket pkt;
521   pkt.set_qid(0x1234).add_question(new DNSQuestion("example.com", T_A))
522     .add_additional(new DNSOptRR(0, 0, 0, 1280, { }, { } /* No server cookie */, false));
523   std::string expected = PacketToString(pkt.data());
524   EXPECT_EQ(expected, actual);
525 }
526 
TEST_F(LibraryTest,CreateRootQuery)527 TEST_F(LibraryTest, CreateRootQuery) {
528   byte* p;
529   int len;
530   ares_create_query(".", C_IN, T_A, 0x1234, 0, &p, &len, 0);
531   std::vector<byte> data(p, p + len);
532   ares_free_string(p);
533 
534   std::string actual = PacketToString(data);
535   DNSPacket pkt;
536   pkt.set_qid(0x1234).add_question(new DNSQuestion("", T_A));
537   std::string expected = PacketToString(pkt.data());
538   EXPECT_EQ(expected, actual);
539 }
540 
TEST_F(LibraryTest,Version)541 TEST_F(LibraryTest, Version) {
542   // Assume linked to same version
543   EXPECT_EQ(std::string(ARES_VERSION_STR),
544             std::string(ares_version(nullptr)));
545   int version;
546   ares_version(&version);
547   EXPECT_EQ(ARES_VERSION, version);
548 }
549 
TEST_F(LibraryTest,ExpandString)550 TEST_F(LibraryTest, ExpandString) {
551   std::vector<byte> s1 = { 3, 'a', 'b', 'c'};
552   char* result = nullptr;
553   long len;
554   EXPECT_EQ(ARES_SUCCESS,
555             ares_expand_string(s1.data(), s1.data(), (int)s1.size(),
556                                (unsigned char**)&result, &len));
557   EXPECT_EQ("abc", std::string(result));
558   EXPECT_EQ(1 + 3, len);  // amount of data consumed includes 1 byte len
559   ares_free_string(result);
560   result = nullptr;
561   EXPECT_EQ(ARES_EBADSTR,
562             ares_expand_string(s1.data() + 1, s1.data(), (int)s1.size(),
563                                (unsigned char**)&result, &len));
564   EXPECT_EQ(ARES_EBADSTR,
565             ares_expand_string(s1.data() + 4, s1.data(), (int)s1.size(),
566                                (unsigned char**)&result, &len));
567   SetAllocFail(1);
568   EXPECT_EQ(ARES_ENOMEM,
569             ares_expand_string(s1.data(), s1.data(), (int)s1.size(),
570                                (unsigned char**)&result, &len));
571 }
572 
TEST_F(LibraryTest,DNSMapping)573 TEST_F(LibraryTest, DNSMapping) {
574   ares_dns_rec_type_t types[] = {
575     ARES_REC_TYPE_A,
576     ARES_REC_TYPE_NS,
577     ARES_REC_TYPE_CNAME,
578     ARES_REC_TYPE_SOA,
579     ARES_REC_TYPE_PTR,
580     ARES_REC_TYPE_HINFO,
581     ARES_REC_TYPE_MX,
582     ARES_REC_TYPE_TXT,
583     ARES_REC_TYPE_SIG,
584     ARES_REC_TYPE_AAAA,
585     ARES_REC_TYPE_SRV,
586     ARES_REC_TYPE_NAPTR,
587     ARES_REC_TYPE_OPT,
588     ARES_REC_TYPE_TLSA,
589     ARES_REC_TYPE_SVCB,
590     ARES_REC_TYPE_HTTPS,
591     ARES_REC_TYPE_ANY,
592     ARES_REC_TYPE_URI,
593     ARES_REC_TYPE_CAA
594   };
595 
596   for (size_t i=0; i<sizeof(types) / sizeof(*types); i++) {
597     ares_dns_rec_type_t type;
598     EXPECT_TRUE(ares_dns_rec_type_fromstr(&type, ares_dns_rec_type_tostr(types[i])));
599     EXPECT_EQ(types[i], type);
600     size_t cnt;
601     const ares_dns_rr_key_t *keys = ares_dns_rr_get_keys(type, &cnt);
602     for (size_t j=0; j<cnt; j++) {
603       const char *name = ares_dns_rr_key_tostr(keys[j]);
604       EXPECT_NE(nullptr, name);
605       EXPECT_NE("UNKNOWN", std::string(name));
606       EXPECT_EQ(type, ares_dns_rr_key_to_rec_type(keys[j]));
607       EXPECT_NE(0, (int)ares_dns_rr_key_datatype(keys[j]));
608     }
609   }
610 }
611 
TEST_F(LibraryTest,StrError)612 TEST_F(LibraryTest, StrError) {
613   ares_status_t status[] = {
614     ARES_SUCCESS, ARES_ENODATA, ARES_EFORMERR, ARES_ESERVFAIL, ARES_ENOTFOUND,
615     ARES_ENOTIMP, ARES_EREFUSED, ARES_EBADQUERY, ARES_EBADNAME, ARES_EBADFAMILY,
616     ARES_EBADRESP, ARES_ECONNREFUSED, ARES_ETIMEOUT, ARES_EOF, ARES_EFILE,
617     ARES_ENOMEM, ARES_EDESTRUCTION, ARES_EBADSTR, ARES_EBADFLAGS, ARES_ENONAME,
618     ARES_EBADHINTS, ARES_ENOTINITIALIZED, ARES_ELOADIPHLPAPI,
619     ARES_EADDRGETNETWORKPARAMS, ARES_ECANCELLED, ARES_ESERVICE, ARES_ENOSERVER
620   };
621   size_t i;
622   const char *str = nullptr;
623 
624   for (i=0; i < sizeof(status) / sizeof(*status); i++) {
625     str = ares_strerror((int)status[i]);
626     EXPECT_NE(nullptr, str);
627     EXPECT_NE("unknown", std::string(str));
628   }
629 
630   /* unknown value */
631   str = ares_strerror(0x12345678);
632   EXPECT_NE(nullptr, str);
633   EXPECT_EQ("unknown", std::string(str));
634 }
635 
TEST_F(LibraryTest,UsageErrors)636 TEST_F(LibraryTest, UsageErrors) {
637   ares_cancel(NULL);
638   ares_set_socket_callback(NULL, NULL, NULL);
639   ares_set_socket_configure_callback(NULL, NULL, NULL);
640   ares_set_socket_functions(NULL, NULL, NULL);
641   ares_destroy(NULL);
642   ares_expand_name(NULL, NULL, 0, NULL, NULL);
643   ares_expand_string(NULL, NULL, 0, NULL, NULL);
644   ares_fds(NULL, NULL, NULL);
645   ares_getaddrinfo(NULL, NULL, NULL, NULL, NULL, NULL);
646   ares_gethostbyaddr(NULL, NULL, 0, 0, NULL, NULL);
647   ares_getnameinfo(NULL, NULL, 0, 0, NULL, NULL);
648   ares_reinit(NULL);
649   ares_dup(NULL, NULL);
650   ares_set_local_ip4(NULL, 0);
651   ares_set_local_ip6(NULL, NULL);
652   ares_set_local_dev(NULL, NULL);
653   ares_query_dnsrec(NULL, NULL, ARES_CLASS_IN, ARES_REC_TYPE_A, NULL, NULL, NULL);
654   ares_query(NULL, NULL, ARES_CLASS_IN, ARES_REC_TYPE_A, NULL, NULL);
655 }
656 
657 
658 }  // namespace test
659 }  // namespace ares
660