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