• 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 <stdio.h>
30 
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34 #include <fcntl.h>
35 #ifdef HAVE_SYS_IOCTL_H
36 #  include <sys/ioctl.h>
37 #endif
38 extern "C" {
39 // Remove command-line defines of package variables for the test project...
40 #undef PACKAGE_NAME
41 #undef PACKAGE_BUGREPORT
42 #undef PACKAGE_STRING
43 #undef PACKAGE_TARNAME
44 // ... so we can include the library's config without symbol redefinitions.
45 #include "ares_private.h"
46 #include "ares_inet_net_pton.h"
47 #include "ares_data.h"
48 #include "str/ares_strsplit.h"
49 #include "dsa/ares_htable.h"
50 
51 #ifdef HAVE_ARPA_INET_H
52 #include <arpa/inet.h>
53 #endif
54 #ifdef HAVE_SYS_UIO_H
55 #  include <sys/uio.h>
56 #endif
57 }
58 
59 #include <string>
60 #include <vector>
61 
62 namespace ares {
63 namespace test {
64 
65 #ifndef CARES_SYMBOL_HIDING
TEST_F(LibraryTest,StringLength)66 TEST_F(LibraryTest, StringLength) {
67   const char data[] = "test\0test";
68   size_t n = sizeof data;
69   for(size_t i = 0; i < n; ++i) {
70     EXPECT_EQ(ares_strlen(&data[i]), ares_strnlen(&data[i], n - i));
71   }
72 }
73 
TEST_F(LibraryTest,StringLengthNullPointer)74 TEST_F(LibraryTest, StringLengthNullPointer) {
75   EXPECT_EQ(ares_strlen(NULL), 0);
76   EXPECT_EQ(ares_strnlen(NULL, 0), 0);
77   EXPECT_EQ(ares_strnlen(NULL, 1), 0);
78   EXPECT_EQ(ares_strnlen(NULL, 42), 0);
79 }
80 
TEST_F(LibraryTest,StringLengthWithoutNullTerminator)81 TEST_F(LibraryTest, StringLengthWithoutNullTerminator) {
82   std::string data = "test";
83   for(size_t i = 0; i < data.length(); ++i) {
84     EXPECT_EQ(ares_strnlen(data.c_str(), i), i);
85   }
86 }
87 
CheckPtoN4(int size,unsigned int value,const char * input)88 void CheckPtoN4(int size, unsigned int value, const char *input) {
89   struct in_addr a4;
90   a4.s_addr = 0;
91   uint32_t expected = htonl(value);
92   EXPECT_EQ(size, ares_inet_net_pton(AF_INET, input, &a4, sizeof(a4)))
93     << " for input " << input;
94   EXPECT_EQ(expected, a4.s_addr) << " for input " << input;
95 }
96 
TEST_F(LibraryTest,Strsplit)97 TEST_F(LibraryTest, Strsplit) {
98   using std::vector;
99   using std::string;
100   size_t n;
101   struct {
102     vector<string> inputs;
103     vector<string> delimiters;
104     vector<vector<string>> expected;
105   } data = {
106     {
107       "",
108       " ",
109       "             ",
110       "example.com, example.co",
111       "        a, b, A,c,     d, e,,,D,e,e,E",
112     },
113     { ", ", ", ", ", ", ", ", ", " },
114     {
115       {}, {}, {},
116       { "example.com", "example.co" },
117       { "a", "b", "c", "d", "e" },
118     },
119   };
120   for(size_t i = 0; i < data.inputs.size(); i++) {
121     char **out = ares_strsplit(data.inputs.at(i).c_str(),
122                                data.delimiters.at(i).c_str(), &n);
123     if(data.expected.at(i).size() == 0) {
124       EXPECT_EQ(out, nullptr);
125     }
126     else {
127       EXPECT_EQ(n, data.expected.at(i).size());
128       for(size_t j = 0; j < n && j < data.expected.at(i).size(); j++) {
129         EXPECT_STREQ(out[j], data.expected.at(i).at(j).c_str());
130       }
131     }
132     ares_strsplit_free(out, n);
133   }
134 }
135 
TEST_F(LibraryTest,InetNetPtoN)136 TEST_F(LibraryTest, InetNetPtoN) {
137   uint32_t expected;
138   struct in_addr a4;
139   struct in6_addr a6;
140   CheckPtoN4(4 * 8, 0x01020304, "1.2.3.4");
141   CheckPtoN4(4 * 8, 0x81010101, "129.1.1.1");
142   CheckPtoN4(4 * 8, 0xC0010101, "192.1.1.1");
143   CheckPtoN4(4 * 8, 0xE0010101, "224.1.1.1");
144   CheckPtoN4(4 * 8, 0xE1010101, "225.1.1.1");
145   CheckPtoN4(4, 0xE0000000, "224");
146   CheckPtoN4(4 * 8, 0xFD000000, "253");
147   CheckPtoN4(4 * 8, 0xF0010101, "240.1.1.1");
148   CheckPtoN4(4 * 8, 0x02030405, "02.3.4.5");
149   CheckPtoN4(3 * 8, 0x01020304, "1.2.3.4/24");
150   CheckPtoN4(3 * 8, 0x01020300, "1.2.3/24");
151   CheckPtoN4(2 * 8, 0xa0000000, "0xa");
152   CheckPtoN4(0, 0x02030405, "2.3.4.5/000");
153   CheckPtoN4(1 * 8, 0x01020000, "1.2/8");
154   CheckPtoN4(2 * 8, 0x01020000, "0x0102/16");
155   CheckPtoN4(4 * 8, 0x02030405, "02.3.4.5");
156 
157   EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "::", &a6, sizeof(a6)));
158   EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "::1", &a6, sizeof(a6)));
159   EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "1234:5678::", &a6, sizeof(a6)));
160   EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "12:34::ff", &a6, sizeof(a6)));
161   EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.4", &a6, sizeof(a6)));
162   EXPECT_EQ(23, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.4/23", &a6, sizeof(a6)));
163   EXPECT_EQ(3 * 8, ares_inet_net_pton(AF_INET6, "12:34::ff/24", &a6, sizeof(a6)));
164   EXPECT_EQ(0, ares_inet_net_pton(AF_INET6, "12:34::ff/0", &a6, sizeof(a6)));
165   EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "12:34::ffff:0.2", &a6, sizeof(a6)));
166   EXPECT_EQ(16 * 8, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234", &a6, sizeof(a6)));
167   EXPECT_EQ(2, ares_inet_net_pton(AF_INET6, "0::00:00:00/2", &a6, sizeof(a6)));
168 
169   // Various malformed versions
170   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "", &a4, sizeof(a4)));
171   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, " ", &a4, sizeof(a4)));
172   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x", &a4, sizeof(a4)));
173   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x ", &a4, sizeof(a4)));
174   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "x0", &a4, sizeof(a4)));
175   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0xXYZZY", &a4, sizeof(a4)));
176   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "xyzzy", &a4, sizeof(a4)));
177   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET+AF_INET6, "1.2.3.4", &a4, sizeof(a4)));
178   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "257.2.3.4", &a4, sizeof(a4)));
179   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "002.3.4.x", &a4, sizeof(a4)));
180   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "00.3.4.x", &a4, sizeof(a4)));
181   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.x", &a4, sizeof(a4)));
182   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5.6", &a4, sizeof(a4)));
183   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5.6/12", &a4, sizeof(a4)));
184   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4:5", &a4, sizeof(a4)));
185   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5/120", &a4, sizeof(a4)));
186   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5/1x", &a4, sizeof(a4)));
187   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "2.3.4.5/x", &a4, sizeof(a4)));
188   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/240", &a6, sizeof(a6)));
189   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/02", &a6, sizeof(a6)));
190   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/2y", &a6, sizeof(a6)));
191   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/y", &a6, sizeof(a6)));
192   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff/", &a6, sizeof(a6)));
193   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "", &a6, sizeof(a6)));
194   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ":x", &a6, sizeof(a6)));
195   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ":", &a6, sizeof(a6)));
196   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ": :1234", &a6, sizeof(a6)));
197   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "::12345", &a6, sizeof(a6)));
198   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234::2345:3456::0011", &a6, sizeof(a6)));
199   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234:", &a6, sizeof(a6)));
200   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234::", &a6, sizeof(a6)));
201   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1.2.3.4", &a6, sizeof(a6)));
202   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ":1234:1234:1234:1234:1234:1234:1234:1234", &a6, sizeof(a6)));
203   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, ":1234:1234:1234:1234:1234:1234:1234:1234:", &a6, sizeof(a6)));
204   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234:5678", &a6, sizeof(a6)));
205   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234:5678:5678", &a6, sizeof(a6)));
206   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "1234:1234:1234:1234:1234:1234:1234:1234:5678:5678:5678", &a6, sizeof(a6)));
207   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:257.2.3.4", &a6, sizeof(a6)));
208   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.4.5.6", &a6, sizeof(a6)));
209   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.4.5", &a6, sizeof(a6)));
210   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.z", &a6, sizeof(a6)));
211   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3001.4", &a6, sizeof(a6)));
212   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3..4", &a6, sizeof(a6)));
213   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ffff:1.2.3.", &a6, sizeof(a6)));
214 
215   // Hex constants are allowed.
216   EXPECT_EQ(4 * 8, ares_inet_net_pton(AF_INET, "0x01020304", &a4, sizeof(a4)));
217   expected = htonl(0x01020304);
218   EXPECT_EQ(expected, a4.s_addr);
219   EXPECT_EQ(4 * 8, ares_inet_net_pton(AF_INET, "0x0a0b0c0d", &a4, sizeof(a4)));
220   expected = htonl(0x0a0b0c0d);
221   EXPECT_EQ(expected, a4.s_addr);
222   EXPECT_EQ(4 * 8, ares_inet_net_pton(AF_INET, "0x0A0B0C0D", &a4, sizeof(a4)));
223   expected = htonl(0x0a0b0c0d);
224   EXPECT_EQ(expected, a4.s_addr);
225   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x0xyz", &a4, sizeof(a4)));
226   EXPECT_EQ(4 * 8, ares_inet_net_pton(AF_INET, "0x1122334", &a4, sizeof(a4)));
227   expected = htonl(0x11223340);
228   EXPECT_EQ(expected, a4.s_addr);  // huh?
229 
230   // No room, no room.
231   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "1.2.3.4", &a4, sizeof(a4) - 1));
232   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET6, "12:34::ff", &a6, sizeof(a6) - 1));
233   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x01020304", &a4, 2));
234   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x01020304", &a4, 0));
235   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x0a0b0c0d", &a4, 0));
236   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x0xyz", &a4, 0));
237   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "0x1122334", &a4, sizeof(a4) - 1));
238   EXPECT_EQ(-1, ares_inet_net_pton(AF_INET, "253", &a4, sizeof(a4) - 1));
239 }
240 
TEST_F(LibraryTest,FreeLongChain)241 TEST_F(LibraryTest, FreeLongChain) {
242   struct ares_addr_node *data = nullptr;
243   for (int ii = 0; ii < 100000; ii++) {
244     struct ares_addr_node *prev = (struct ares_addr_node*)ares_malloc_data(ARES_DATATYPE_ADDR_NODE);
245     prev->next = data;
246     data = prev;
247   }
248 
249   ares_free_data(data);
250 }
251 
TEST_F(LibraryTest,MallocDataFail)252 TEST_F(LibraryTest, MallocDataFail) {
253   EXPECT_EQ(nullptr, ares_malloc_data((ares_datatype)99));
254   SetAllocSizeFail(sizeof(struct ares_data));
255   EXPECT_EQ(nullptr, ares_malloc_data(ARES_DATATYPE_MX_REPLY));
256 }
257 
TEST(Misc,OnionDomain)258 TEST(Misc, OnionDomain) {
259   EXPECT_EQ(0, ares_is_onion_domain("onion.no"));
260   EXPECT_EQ(0, ares_is_onion_domain(".onion.no"));
261   EXPECT_EQ(1, ares_is_onion_domain(".onion"));
262   EXPECT_EQ(1, ares_is_onion_domain(".onion."));
263   EXPECT_EQ(1, ares_is_onion_domain("yes.onion"));
264   EXPECT_EQ(1, ares_is_onion_domain("yes.onion."));
265   EXPECT_EQ(1, ares_is_onion_domain("YES.ONION"));
266   EXPECT_EQ(1, ares_is_onion_domain("YES.ONION."));
267 }
268 
TEST_F(LibraryTest,CatDomain)269 TEST_F(LibraryTest, CatDomain) {
270   char *s;
271 
272   ares_cat_domain("foo", "example.net", &s);
273   EXPECT_STREQ("foo.example.net", s);
274   ares_free(s);
275 
276   ares_cat_domain("foo", ".", &s);
277   EXPECT_STREQ("foo.", s);
278   ares_free(s);
279 
280   ares_cat_domain("foo", "example.net.", &s);
281   EXPECT_STREQ("foo.example.net.", s);
282   ares_free(s);
283 }
284 
TEST_F(LibraryTest,SlistMisuse)285 TEST_F(LibraryTest, SlistMisuse) {
286   EXPECT_EQ(NULL, ares_slist_create(NULL, NULL, NULL));
287   ares_slist_replace_destructor(NULL, NULL);
288   EXPECT_EQ(NULL, ares_slist_insert(NULL, NULL));
289   EXPECT_EQ(NULL, ares_slist_node_find(NULL, NULL));
290   EXPECT_EQ(NULL, ares_slist_node_first(NULL));
291   EXPECT_EQ(NULL, ares_slist_node_last(NULL));
292   EXPECT_EQ(NULL, ares_slist_node_next(NULL));
293   EXPECT_EQ(NULL, ares_slist_node_prev(NULL));
294   EXPECT_EQ(NULL, ares_slist_node_val(NULL));
295   EXPECT_EQ((size_t)0, ares_slist_len(NULL));
296   EXPECT_EQ(NULL, ares_slist_node_parent(NULL));
297   EXPECT_EQ(NULL, ares_slist_first_val(NULL));
298   EXPECT_EQ(NULL, ares_slist_last_val(NULL));
299   EXPECT_EQ(NULL, ares_slist_node_claim(NULL));
300 }
301 
302 #if !defined(_WIN32) || _WIN32_WINNT >= 0x0600
TEST_F(LibraryTest,IfaceIPs)303 TEST_F(LibraryTest, IfaceIPs) {
304   ares_status_t      status;
305   ares_iface_ips_t *ips = NULL;
306   size_t             i;
307 
308   status = ares_iface_ips(&ips, ARES_IFACE_IP_DEFAULT, NULL);
309   EXPECT_TRUE(status == ARES_SUCCESS || status == ARES_ENOTIMP);
310 
311   /* Not implemented, can't run tests */
312   if (status == ARES_ENOTIMP)
313     return;
314 
315   EXPECT_NE(nullptr, ips);
316 
317   for (i=0; i<ares_iface_ips_cnt(ips); i++) {
318     const char *name = ares_iface_ips_get_name(ips, i);
319     EXPECT_NE(nullptr, name);
320     int flags = (int)ares_iface_ips_get_flags(ips, i);
321     EXPECT_NE(0, (int)flags);
322     EXPECT_NE(nullptr, ares_iface_ips_get_addr(ips, i));
323     EXPECT_NE(0, ares_iface_ips_get_netmask(ips, i));
324     if (flags & ARES_IFACE_IP_LINKLOCAL && flags & ARES_IFACE_IP_V6) {
325       /* Hmm, seems not to work at least on MacOS
326        * EXPECT_NE(0, ares_iface_ips_get_ll_scope(ips, i));
327        */
328     } else {
329       EXPECT_EQ(0, ares_iface_ips_get_ll_scope(ips, i));
330     }
331     unsigned int idx = ares_os_if_nametoindex(name);
332     EXPECT_NE(0, idx);
333     char namebuf[256];
334     EXPECT_EQ(std::string(ares_os_if_indextoname(idx, namebuf, sizeof(namebuf))), std::string(name));
335   }
336 
337 
338   /* Negative checking */
339   ares_iface_ips_get_name(ips, ares_iface_ips_cnt(ips));
340   ares_iface_ips_get_flags(ips, ares_iface_ips_cnt(ips));
341   ares_iface_ips_get_addr(ips, ares_iface_ips_cnt(ips));
342   ares_iface_ips_get_netmask(ips, ares_iface_ips_cnt(ips));
343   ares_iface_ips_get_ll_scope(ips, ares_iface_ips_cnt(ips));
344 
345   ares_iface_ips(NULL, ARES_IFACE_IP_DEFAULT, NULL);
346   ares_iface_ips_cnt(NULL);
347   ares_iface_ips_get_name(NULL, 0);
348   ares_iface_ips_get_flags(NULL, 0);
349   ares_iface_ips_get_addr(NULL, 0);
350   ares_iface_ips_get_netmask(NULL, 0);
351   ares_iface_ips_get_ll_scope(NULL, 0);
352   ares_iface_ips_destroy(NULL);
353   ares_os_if_nametoindex(NULL);
354   ares_os_if_indextoname(0, NULL, 0);
355 
356   ares_iface_ips_destroy(ips);
357 }
358 #endif
359 
TEST_F(LibraryTest,HtableMisuse)360 TEST_F(LibraryTest, HtableMisuse) {
361   EXPECT_EQ(NULL, ares_htable_create(NULL, NULL, NULL, NULL));
362   EXPECT_EQ(ARES_FALSE, ares_htable_insert(NULL, NULL));
363   EXPECT_EQ(NULL, ares_htable_get(NULL, NULL));
364   EXPECT_EQ(ARES_FALSE, ares_htable_remove(NULL, NULL));
365   EXPECT_EQ((size_t)0, ares_htable_num_keys(NULL));
366 }
367 
TEST_F(LibraryTest,URI)368 TEST_F(LibraryTest, URI) {
369   struct {
370     ares_bool_t success;
371     const char *uri;
372     const char *alt_match_uri;
373   } tests[] = {
374     { ARES_TRUE,  "https://www.example.com",                                                               NULL },
375     { ARES_TRUE,  "https://www.example.com:8443",                                                          NULL },
376     { ARES_TRUE,  "https://user:password@www.example.com",                                                 NULL },
377     { ARES_TRUE,  "https://user%25:password@www.example.com",                                              NULL },
378     { ARES_TRUE,  "https://user:password%25@www.example.com",                                              NULL },
379     { ARES_TRUE,  "https://user@www.example.com",                                                          NULL },
380     { ARES_TRUE,  "https://www.example.com/path",                                                          NULL },
381     { ARES_TRUE,  "https://www.example.com/path/",                                                         NULL },
382     { ARES_TRUE,  "https://www.example.com/a/../",                                                         "https://www.example.com/" },
383     { ARES_TRUE,  "https://www.example.com/../a/",                                                         "https://www.example.com/a/" },
384     { ARES_TRUE,  "https://www.example.com/.././../a/",                                                    "https://www.example.com/a/" },
385     { ARES_TRUE,  "https://www.example.com/.././../a//b/c/d/../../",                                       "https://www.example.com/a/b/" },
386     { ARES_TRUE,  "https://www.example.com?key=val",                                                       NULL },
387     { ARES_TRUE,  "https://www.example.com?key",                                                           NULL },
388     { ARES_TRUE,  "https://www.example.com?key=",                                                          "https://www.example.com?key" },
389     { ARES_TRUE,  "https://www.example.com#fragment",                                                      NULL },
390     { ARES_TRUE,  "https://user:password@www.example.com/path",                                            NULL },
391     { ARES_TRUE,  "https://user:password@www.example.com/path#fragment",                                   NULL },
392     { ARES_TRUE,  "https://user:password@www.example.com/path?key=val",                                    NULL },
393     { ARES_TRUE,  "https://user:password@www.example.com/path?key=val#fragment",                           NULL },
394     { ARES_TRUE,  "https://user:password@www.example.com/path?key=val#fragment/with?chars",                NULL },
395     { ARES_TRUE,  "HTTPS://www.example.com",                                                               "https://www.example.com" },
396     { ARES_TRUE,  "https://www.example.com?key=hello+world",                                               "https://www.example.com?key=hello%20world" },
397     { ARES_TRUE,  "https://www.example.com?key=val%26",                                                    NULL },
398     { ARES_TRUE,  "https://www.example.com?key%26=val",                                                    NULL },
399     { ARES_TRUE,  "https://www.example.com?key=Aa2-._~/?!$'()*,;:@",                                       NULL },
400     { ARES_TRUE,  "https://www.example.com?key1=val1&key2=val2&key3=val3&key4=val4",                       "ignore" }, /* keys get randomized, can't match */
401     { ARES_TRUE,  "https://www.example.com?key=%41%61%32%2D%2E%5f%7e%2F%3F%21%24%27%28%29%2a%2C%3b%3a%40", "https://www.example.com?key=Aa2-._~/?!$'()*,;:@" },
402     { ARES_TRUE,  "dns+tls://192.168.1.1:53",                                                              NULL },
403     { ARES_TRUE,  "dns+tls://[fe80::1]:53",                                                                NULL },
404     { ARES_TRUE,  "dns://[fe80::b542:84df:1719:65e3%en0]",                                                 NULL },
405     { ARES_TRUE,  "dns+tls://[fe80:00::00:1]:53",                                                          "dns+tls://[fe80::1]:53" },
406     { ARES_TRUE,  "d.n+s-tls://www.example.com",                                                           NULL },
407     { ARES_FALSE, "dns*tls://www.example.com",                                                             NULL }, /* invalid scheme character */
408     { ARES_FALSE, "0dns://www.example.com",                                                                NULL }, /* dns can't start with digits */
409     { ARES_FALSE, "https://www.example.com?key=val%01",                                                    NULL }, /* non-printable character */
410     { ARES_FALSE, "abcdef0123456789://www.example.com",                                                    NULL }, /* scheme too long */
411     { ARES_FALSE, "www.example.com",                                                                       NULL }, /* missing scheme */
412     { ARES_FALSE, "https://www.example.com?key=val%0",                                                     NULL }, /* truncated uri-encoding */
413     { ARES_FALSE, "https://www.example.com?key=val%AZ",                                                    NULL }, /* invalid uri-encoding sequence */
414     { ARES_FALSE, "https://www.example.com?key=hello world",                                               NULL }, /* invalid character in query value */
415     { ARES_FALSE, "https://:password@www.example.com",                                                     NULL }, /* can't have password without username */
416     { ARES_FALSE, "dns+tls://[fe8G::1]",                                                                   NULL }, /* invalid ipv6 address */
417 
418     { ARES_FALSE, NULL, NULL }
419   };
420   size_t i;
421 
422   for (i=0; tests[i].uri != NULL; i++) {
423     ares_uri_t *uri = NULL;
424     ares_status_t status;
425 
426     if (verbose) std::cerr << "Testing " << tests[i].uri << std::endl;
427     status = ares_uri_parse(&uri, tests[i].uri);
428     if (tests[i].success) {
429       EXPECT_EQ(ARES_SUCCESS, status);
430     } else {
431       EXPECT_NE(ARES_SUCCESS, status);
432     }
433 
434     if (status == ARES_SUCCESS) {
435       char *out = NULL;
436       EXPECT_EQ(ARES_SUCCESS, ares_uri_write(&out, uri));
437       if (tests[i].alt_match_uri == NULL || strcmp(tests[i].alt_match_uri, "ignore") != 0) {
438         EXPECT_STRCASEEQ(tests[i].alt_match_uri == NULL?tests[i].uri:tests[i].alt_match_uri, out);
439       }
440       ares_free(out);
441     }
442     ares_uri_destroy(uri);
443   }
444 
445   /* Invalid tests  */
446   EXPECT_NE(ARES_SUCCESS, ares_uri_set_scheme(NULL, NULL));
447   EXPECT_EQ(nullptr, ares_uri_get_scheme(NULL));
448   EXPECT_NE(ARES_SUCCESS, ares_uri_set_username(NULL, NULL));
449   EXPECT_EQ(nullptr, ares_uri_get_username(NULL));
450   EXPECT_NE(ARES_SUCCESS, ares_uri_set_password(NULL, NULL));
451   EXPECT_EQ(nullptr, ares_uri_get_password(NULL));
452   EXPECT_NE(ARES_SUCCESS, ares_uri_set_host(NULL, NULL));
453   EXPECT_EQ(nullptr, ares_uri_get_host(NULL));
454   EXPECT_NE(ARES_SUCCESS, ares_uri_set_port(NULL, 0));
455   EXPECT_EQ(0, ares_uri_get_port(NULL));
456   EXPECT_NE(ARES_SUCCESS, ares_uri_set_path(NULL, NULL));
457   EXPECT_EQ(nullptr, ares_uri_get_path(NULL));
458   EXPECT_NE(ARES_SUCCESS, ares_uri_set_query_key(NULL, NULL, NULL));
459   EXPECT_NE(ARES_SUCCESS, ares_uri_del_query_key(NULL, NULL));
460   EXPECT_EQ(nullptr, ares_uri_get_query_key(NULL, NULL));
461   EXPECT_EQ(nullptr, ares_uri_get_query_keys(NULL, NULL));
462   EXPECT_NE(ARES_SUCCESS, ares_uri_set_fragment(NULL, NULL));
463   EXPECT_EQ(nullptr, ares_uri_get_fragment(NULL));
464   EXPECT_NE(ARES_SUCCESS, ares_uri_write_buf(NULL, NULL));
465   EXPECT_NE(ARES_SUCCESS, ares_uri_write(NULL, NULL));
466   EXPECT_NE(ARES_SUCCESS, ares_uri_parse_buf(NULL, NULL));
467   EXPECT_NE(ARES_SUCCESS, ares_uri_parse_buf(NULL, NULL));
468 }
469 #endif /* !CARES_SYMBOL_HIDING */
470 
TEST_F(LibraryTest,InetPtoN)471 TEST_F(LibraryTest, InetPtoN) {
472   struct in_addr a4;
473   struct in6_addr a6;
474   EXPECT_EQ(1, ares_inet_pton(AF_INET, "1.2.3.4", &a4));
475   EXPECT_EQ(1, ares_inet_pton(AF_INET6, "12:34::ff", &a6));
476   EXPECT_EQ(1, ares_inet_pton(AF_INET6, "12:34::ffff:1.2.3.4", &a6));
477   EXPECT_EQ(0, ares_inet_pton(AF_INET, "xyzzy", &a4));
478   EXPECT_EQ(-1, ares_inet_pton(AF_INET+AF_INET6, "1.2.3.4", &a4));
479 }
480 
TEST_F(LibraryTest,FreeCorruptData)481 TEST_F(LibraryTest, FreeCorruptData) {
482   // ares_free_data(p) expects that there is a type field and a marker
483   // field in the memory before p.  Feed it incorrect versions of each.
484   struct ares_data *data = (struct ares_data *)malloc(sizeof(struct ares_data));
485   void* p = &(data->data);
486 
487   // Invalid type
488   data->type = (ares_datatype)ARES_DATATYPE_LAST;
489   data->mark = ARES_DATATYPE_MARK;
490   ares_free_data(p);
491 
492   // Invalid marker
493   data->type = (ares_datatype)ARES_DATATYPE_MX_REPLY;
494   data->mark = ARES_DATATYPE_MARK + 1;
495   ares_free_data(p);
496 
497   // Null pointer
498   ares_free_data(nullptr);
499 
500   free(data);
501 }
502 
TEST(LibraryInit,StrdupFailures)503 TEST(LibraryInit, StrdupFailures) {
504   EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL));
505   char* copy = ares_strdup("string");
506   EXPECT_NE(nullptr, copy);
507   ares_free(copy);
508   ares_library_cleanup();
509 }
510 
TEST_F(LibraryTest,StrdupFailures)511 TEST_F(LibraryTest, StrdupFailures) {
512   SetAllocFail(1);
513   char* copy = ares_strdup("string");
514   EXPECT_EQ(nullptr, copy);
515 }
516 
TEST_F(FileChannelTest,GetAddrInfoHostsPositive)517 TEST_F(FileChannelTest, GetAddrInfoHostsPositive) {
518   TempFile hostsfile("1.2.3.4 example.com  \n"
519                      "  2.3.4.5\tgoogle.com   www.google.com\twww2.google.com\n"
520                      "#comment\n"
521                      "4.5.6.7\n"
522                      "1.3.5.7  \n"
523                      "::1    ipv6.com");
524   EnvValue with_env("CARES_HOSTS", hostsfile.filename());
525   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
526   AddrInfoResult result = {};
527   hints.ai_family = AF_INET;
528   hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT;
529   ares_getaddrinfo(channel_, "example.com", NULL, &hints, AddrInfoCallback, &result);
530   Process();
531   EXPECT_TRUE(result.done_);
532   std::stringstream ss;
533   ss << result.ai_;
534   EXPECT_EQ("{example.com addr=[1.2.3.4]}", ss.str());
535 }
536 
TEST_F(FileChannelTest,GetAddrInfoHostsSpaces)537 TEST_F(FileChannelTest, GetAddrInfoHostsSpaces) {
538   TempFile hostsfile("1.2.3.4 example.com  \n"
539                      "  2.3.4.5\tgoogle.com   www.google.com\twww2.google.com\n"
540                      "#comment\n"
541                      "4.5.6.7\n"
542                      "1.3.5.7  \n"
543                      "::1    ipv6.com");
544   EnvValue with_env("CARES_HOSTS", hostsfile.filename());
545   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
546   AddrInfoResult result = {};
547   hints.ai_family = AF_INET;
548   hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT;
549   ares_getaddrinfo(channel_, "google.com", NULL, &hints, AddrInfoCallback, &result);
550   Process();
551   EXPECT_TRUE(result.done_);
552   std::stringstream ss;
553   ss << result.ai_;
554   EXPECT_EQ("{www.google.com->google.com, www2.google.com->google.com addr=[2.3.4.5]}", ss.str());
555 }
556 
TEST_F(FileChannelTest,GetAddrInfoHostsByALias)557 TEST_F(FileChannelTest, GetAddrInfoHostsByALias) {
558   TempFile hostsfile("1.2.3.4 example.com  \n"
559                      "  2.3.4.5\tgoogle.com   www.google.com\twww2.google.com\n"
560                      "#comment\n"
561                      "4.5.6.7\n"
562                      "1.3.5.7  \n"
563                      "::1    ipv6.com");
564   EnvValue with_env("CARES_HOSTS", hostsfile.filename());
565   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
566   AddrInfoResult result = {};
567   hints.ai_family = AF_INET;
568   hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT;
569   ares_getaddrinfo(channel_, "www2.google.com", NULL, &hints, AddrInfoCallback, &result);
570   Process();
571   EXPECT_TRUE(result.done_);
572   std::stringstream ss;
573   ss << result.ai_;
574   EXPECT_EQ("{www.google.com->google.com, www2.google.com->google.com addr=[2.3.4.5]}", ss.str());
575 }
576 
TEST_F(FileChannelTest,GetAddrInfoHostsIPV6)577 TEST_F(FileChannelTest, GetAddrInfoHostsIPV6) {
578   TempFile hostsfile("1.2.3.4 example.com  \n"
579                      "  2.3.4.5\tgoogle.com   www.google.com\twww2.google.com\n"
580                      "#comment\n"
581                      "4.5.6.7\n"
582                      "1.3.5.7  \n"
583                      "::1    ipv6.com");
584   EnvValue with_env("CARES_HOSTS", hostsfile.filename());
585   struct ares_addrinfo_hints hints = {0, 0, 0, 0};
586   AddrInfoResult result = {};
587   hints.ai_family = AF_INET6;
588   hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT;
589   ares_getaddrinfo(channel_, "ipv6.com", NULL, &hints, AddrInfoCallback, &result);
590   Process();
591   EXPECT_TRUE(result.done_);
592   std::stringstream ss;
593   ss << result.ai_;
594   EXPECT_EQ("{ipv6.com addr=[[0000:0000:0000:0000:0000:0000:0000:0001]]}", ss.str());
595 }
596 
597 
TEST_F(FileChannelTest,GetAddrInfoAllocFail)598 TEST_F(FileChannelTest, GetAddrInfoAllocFail) {
599   TempFile hostsfile("1.2.3.4 example.com alias1 alias2\n");
600   EnvValue with_env("CARES_HOSTS", hostsfile.filename());
601   struct ares_addrinfo_hints hints;
602 
603   memset(&hints, 0, sizeof(hints));
604   hints.ai_family = AF_INET;
605 
606   // Fail a variety of different memory allocations, and confirm
607   // that the operation either fails with ENOMEM or succeeds
608   // with the expected result.
609   const int kCount = 34;
610   AddrInfoResult results[kCount];
611   for (int ii = 1; ii <= kCount; ii++) {
612     AddrInfoResult* result = &(results[ii - 1]);
613     ClearFails();
614     SetAllocFail(ii);
615     ares_getaddrinfo(channel_, "example.com", NULL, &hints, AddrInfoCallback, result);
616     Process();
617     EXPECT_TRUE(result->done_);
618     if (result->status_ == ARES_SUCCESS) {
619       std::stringstream ss;
620       ss << result->ai_;
621       EXPECT_EQ("{alias1->example.com, alias2->example.com addr=[1.2.3.4]}", ss.str()) << " failed alloc #" << ii;
622       if (verbose) std::cerr << "Succeeded despite failure of alloc #" << ii << std::endl;
623     }
624   }
625 }
626 
TEST_F(LibraryTest,DNSRecord)627 TEST_F(LibraryTest, DNSRecord) {
628   ares_dns_record_t   *dnsrec = NULL;
629   ares_dns_rr_t       *rr     = NULL;
630   struct in_addr       addr;
631   struct ares_in6_addr addr6;
632   unsigned char       *msg    = NULL;
633   size_t               msglen = 0;
634   size_t               qdcount = 0;
635   size_t               ancount = 0;
636   size_t               nscount = 0;
637   size_t               arcount = 0;
638 
639   EXPECT_EQ(ARES_SUCCESS,
640     ares_dns_record_create(&dnsrec, 0x1234,
641       ARES_FLAG_QR|ARES_FLAG_AA|ARES_FLAG_RD|ARES_FLAG_RA,
642       ARES_OPCODE_QUERY, ARES_RCODE_NOERROR));
643 
644   /* == Question == */
645   EXPECT_EQ(ARES_SUCCESS,
646     ares_dns_record_query_add(dnsrec, "example.com",
647       ARES_REC_TYPE_ANY,
648       ARES_CLASS_IN));
649 
650   /* == Answer == */
651   /* A */
652   EXPECT_EQ(ARES_SUCCESS,
653     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ANSWER, "example.com",
654       ARES_REC_TYPE_A, ARES_CLASS_IN, 300));
655   EXPECT_LT(0, ares_inet_pton(AF_INET, "1.1.1.1", &addr));
656   EXPECT_EQ(ARES_SUCCESS,
657     ares_dns_rr_set_addr(rr, ARES_RR_A_ADDR, &addr));
658   /* AAAA */
659   EXPECT_EQ(ARES_SUCCESS,
660     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ANSWER, "example.com",
661       ARES_REC_TYPE_AAAA, ARES_CLASS_IN, 300));
662   EXPECT_LT(0, ares_inet_pton(AF_INET6, "2600::4", &addr6));
663   EXPECT_EQ(ARES_SUCCESS,
664     ares_dns_rr_set_addr6(rr, ARES_RR_AAAA_ADDR, &addr6));
665   /* MX */
666   EXPECT_EQ(ARES_SUCCESS,
667     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ANSWER, "example.com",
668       ARES_REC_TYPE_MX, ARES_CLASS_IN, 3600));
669   EXPECT_EQ(ARES_SUCCESS,
670     ares_dns_rr_set_u16(rr, ARES_RR_MX_PREFERENCE, 10));
671   EXPECT_EQ(ARES_SUCCESS,
672     ares_dns_rr_set_str(rr, ARES_RR_MX_EXCHANGE, "mail.example.com"));
673   /* CNAME */
674   EXPECT_EQ(ARES_SUCCESS,
675     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ANSWER, "example.com",
676       ARES_REC_TYPE_CNAME, ARES_CLASS_IN, 3600));
677   EXPECT_EQ(ARES_SUCCESS,
678     ares_dns_rr_set_str(rr, ARES_RR_CNAME_CNAME, "b.example.com"));
679   /* TXT */
680   EXPECT_EQ(ARES_SUCCESS,
681     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ANSWER, "example.com",
682       ARES_REC_TYPE_TXT, ARES_CLASS_IN, 3600));
683   const char txt1[] = "blah=here blah=there anywhere";
684   const char txt2[] = "some other record";
685   EXPECT_EQ(ARES_SUCCESS,
686     ares_dns_rr_add_abin(rr, ARES_RR_TXT_DATA, (unsigned char *)txt1,
687       sizeof(txt1)-1));
688    EXPECT_EQ(ARES_SUCCESS,
689     ares_dns_rr_add_abin(rr, ARES_RR_TXT_DATA, (unsigned char *)txt2,
690       sizeof(txt2)-1));
691   /* SIG */
692   EXPECT_EQ(ARES_SUCCESS,
693     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ANSWER, "example.com",
694       ARES_REC_TYPE_SIG, ARES_CLASS_ANY, 0));
695   EXPECT_EQ(ARES_SUCCESS,
696     ares_dns_rr_set_u16(rr, ARES_RR_SIG_TYPE_COVERED, ARES_REC_TYPE_TXT));
697   EXPECT_EQ(ARES_SUCCESS,
698     ares_dns_rr_set_u8(rr, ARES_RR_SIG_ALGORITHM, 1));
699   EXPECT_EQ(ARES_SUCCESS,
700     ares_dns_rr_set_u8(rr, ARES_RR_SIG_LABELS, 1));
701   EXPECT_EQ(ARES_SUCCESS,
702     ares_dns_rr_set_u32(rr, ARES_RR_SIG_ORIGINAL_TTL, 3200));
703   EXPECT_EQ(ARES_SUCCESS,
704     ares_dns_rr_set_u32(rr, ARES_RR_SIG_EXPIRATION, (unsigned int)time(NULL)));
705   EXPECT_EQ(ARES_SUCCESS,
706     ares_dns_rr_set_u32(rr, ARES_RR_SIG_INCEPTION, (unsigned int)time(NULL) - (86400 * 365)));
707   EXPECT_EQ(ARES_SUCCESS,
708     ares_dns_rr_set_u16(rr, ARES_RR_SIG_KEY_TAG, 0x1234));
709   EXPECT_EQ(ARES_SUCCESS,
710     ares_dns_rr_set_str(rr, ARES_RR_SIG_SIGNERS_NAME, "signer.example.com"));
711   const unsigned char sig[] = {
712     0xd2, 0xab, 0xde, 0x24, 0x0d, 0x7c, 0xd3, 0xee, 0x6b, 0x4b, 0x28, 0xc5,
713     0x4d, 0xf0, 0x34, 0xb9, 0x79, 0x83, 0xa1, 0xd1, 0x6e, 0x8a, 0x41, 0x0e,
714     0x45, 0x61, 0xcb, 0x10, 0x66, 0x18, 0xe9, 0x71 };
715   EXPECT_EQ(ARES_SUCCESS,
716     ares_dns_rr_set_bin(rr, ARES_RR_SIG_SIGNATURE, sig, sizeof(sig)));
717 
718 
719   /* == Authority == */
720   /* NS */
721   EXPECT_EQ(ARES_SUCCESS,
722     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_AUTHORITY, "example.com",
723       ARES_REC_TYPE_NS, ARES_CLASS_IN, 38400));
724   EXPECT_EQ(ARES_SUCCESS,
725     ares_dns_rr_set_str(rr, ARES_RR_NS_NSDNAME, "ns1.example.com"));
726   EXPECT_EQ(ARES_SUCCESS,
727     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_AUTHORITY, "example.com",
728       ARES_REC_TYPE_NS, ARES_CLASS_IN, 38400));
729   EXPECT_EQ(ARES_SUCCESS,
730     ares_dns_rr_set_str(rr, ARES_RR_NS_NSDNAME, "ns2.example.com"));
731   /* SOA */
732   EXPECT_EQ(ARES_SUCCESS,
733     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_AUTHORITY, "example.com",
734       ARES_REC_TYPE_SOA, ARES_CLASS_IN, 86400));
735   EXPECT_EQ(ARES_SUCCESS,
736     ares_dns_rr_set_str(rr, ARES_RR_SOA_MNAME, "ns1.example.com"));
737   EXPECT_EQ(ARES_SUCCESS,
738     ares_dns_rr_set_str(rr, ARES_RR_SOA_RNAME, "tech\\.support.example.com"));
739   EXPECT_EQ(ARES_SUCCESS,
740     ares_dns_rr_set_u32(rr, ARES_RR_SOA_SERIAL, 2023110701));
741   EXPECT_EQ(ARES_SUCCESS,
742     ares_dns_rr_set_u32(rr, ARES_RR_SOA_REFRESH, 28800));
743   EXPECT_EQ(ARES_SUCCESS,
744     ares_dns_rr_set_u32(rr, ARES_RR_SOA_RETRY, 7200));
745   EXPECT_EQ(ARES_SUCCESS,
746     ares_dns_rr_set_u32(rr, ARES_RR_SOA_EXPIRE, 604800));
747   EXPECT_EQ(ARES_SUCCESS,
748     ares_dns_rr_set_u32(rr, ARES_RR_SOA_MINIMUM, 86400));
749 
750   /* == Additional */
751   /* OPT */
752   EXPECT_EQ(ARES_SUCCESS,
753     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ADDITIONAL, "",
754       ARES_REC_TYPE_OPT, ARES_CLASS_IN, 0));
755   EXPECT_EQ(ARES_SUCCESS,
756     ares_dns_rr_set_u16(rr, ARES_RR_OPT_UDP_SIZE, 1280));
757   EXPECT_EQ(ARES_SUCCESS,
758     ares_dns_rr_set_u8(rr, ARES_RR_OPT_VERSION, 0));
759   EXPECT_EQ(ARES_SUCCESS,
760     ares_dns_rr_set_u16(rr, ARES_RR_OPT_FLAGS, 0));
761   unsigned char optval[] = { 'c', '-', 'a', 'r', 'e', 's' };
762   EXPECT_EQ(ARES_SUCCESS,
763     ares_dns_rr_set_opt(rr, ARES_RR_OPT_OPTIONS, 3 /* NSID */, optval, sizeof(optval)));
764   /* PTR -- doesn't make sense, but ok */
765   EXPECT_EQ(ARES_SUCCESS,
766     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ADDITIONAL, "example.com",
767       ARES_REC_TYPE_PTR, ARES_CLASS_IN, 300));
768   EXPECT_EQ(ARES_SUCCESS,
769     ares_dns_rr_set_str(rr, ARES_RR_PTR_DNAME, "b.example.com"));
770   /* HINFO */
771   EXPECT_EQ(ARES_SUCCESS,
772     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ADDITIONAL, "example.com",
773       ARES_REC_TYPE_HINFO, ARES_CLASS_IN, 300));
774   EXPECT_EQ(ARES_SUCCESS,
775     ares_dns_rr_set_str(rr, ARES_RR_HINFO_CPU, "Virtual"));
776   EXPECT_EQ(ARES_SUCCESS,
777     ares_dns_rr_set_str(rr, ARES_RR_HINFO_OS, "Linux"));
778   /* SRV */
779   EXPECT_EQ(ARES_SUCCESS,
780     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ADDITIONAL,
781       "_ldap.example.com", ARES_REC_TYPE_SRV, ARES_CLASS_IN, 300));
782   EXPECT_EQ(ARES_SUCCESS,
783     ares_dns_rr_set_u16(rr, ARES_RR_SRV_PRIORITY, 100));
784   EXPECT_EQ(ARES_SUCCESS,
785     ares_dns_rr_set_u16(rr, ARES_RR_SRV_WEIGHT, 1));
786   EXPECT_EQ(ARES_SUCCESS,
787     ares_dns_rr_set_u16(rr, ARES_RR_SRV_PORT, 389));
788   EXPECT_EQ(ARES_SUCCESS,
789     ares_dns_rr_set_str(rr, ARES_RR_SRV_TARGET, "ldap.example.com"));
790   /* TLSA */
791   EXPECT_EQ(ARES_SUCCESS,
792     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ADDITIONAL,
793       "_443._tcp.example.com", ARES_REC_TYPE_TLSA, ARES_CLASS_IN, 86400));
794   EXPECT_EQ(ARES_SUCCESS,
795     ares_dns_rr_set_u8(rr, ARES_RR_TLSA_CERT_USAGE, ARES_TLSA_USAGE_CA));
796   EXPECT_EQ(ARES_SUCCESS,
797     ares_dns_rr_set_u8(rr, ARES_RR_TLSA_SELECTOR, ARES_TLSA_SELECTOR_FULL));
798   EXPECT_EQ(ARES_SUCCESS,
799     ares_dns_rr_set_u8(rr, ARES_RR_TLSA_MATCH, ARES_TLSA_MATCH_SHA256));
800   const unsigned char tlsa[] = {
801     0xd2, 0xab, 0xde, 0x24, 0x0d, 0x7c, 0xd3, 0xee, 0x6b, 0x4b, 0x28, 0xc5,
802     0x4d, 0xf0, 0x34, 0xb9, 0x79, 0x83, 0xa1, 0xd1, 0x6e, 0x8a, 0x41, 0x0e,
803     0x45, 0x61, 0xcb, 0x10, 0x66, 0x18, 0xe9, 0x71 };
804   EXPECT_EQ(ARES_SUCCESS,
805     ares_dns_rr_set_bin(rr, ARES_RR_TLSA_DATA, tlsa, sizeof(tlsa)));
806   /* SVCB */
807   EXPECT_EQ(ARES_SUCCESS,
808     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ADDITIONAL,
809       "_1234._bar.example.com", ARES_REC_TYPE_SVCB, ARES_CLASS_IN, 300));
810   EXPECT_EQ(ARES_SUCCESS,
811     ares_dns_rr_set_u16(rr, ARES_RR_SVCB_PRIORITY, 1));
812   EXPECT_EQ(ARES_SUCCESS,
813     ares_dns_rr_set_str(rr, ARES_RR_SVCB_TARGET, "svc1.example.net"));
814   /* IPV6 hint is a list of IPV6 addresses in network byte order, concatenated */
815   struct ares_addr svcb_addr;
816   svcb_addr.family = AF_UNSPEC;
817   size_t               svcb_ipv6hint_len = 0;
818   const unsigned char *svcb_ipv6hint = (const unsigned char *)ares_dns_pton("2001:db8::1", &svcb_addr, &svcb_ipv6hint_len);
819   EXPECT_EQ(ARES_SUCCESS,
820     ares_dns_rr_set_opt(rr, ARES_RR_SVCB_PARAMS, ARES_SVCB_PARAM_IPV6HINT,
821       svcb_ipv6hint, svcb_ipv6hint_len));
822   /* Port is 16bit big endian format */
823   unsigned short svcb_port = htons(1234);
824   EXPECT_EQ(ARES_SUCCESS,
825     ares_dns_rr_set_opt(rr, ARES_RR_SVCB_PARAMS, ARES_SVCB_PARAM_PORT,
826       (const unsigned char *)&svcb_port, sizeof(svcb_port)));
827   /* HTTPS */
828   EXPECT_EQ(ARES_SUCCESS,
829     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ADDITIONAL,
830       "example.com", ARES_REC_TYPE_HTTPS, ARES_CLASS_IN, 300));
831   EXPECT_EQ(ARES_SUCCESS,
832     ares_dns_rr_set_u16(rr, ARES_RR_HTTPS_PRIORITY, 1));
833   EXPECT_EQ(ARES_SUCCESS,
834     ares_dns_rr_set_str(rr, ARES_RR_HTTPS_TARGET, ""));
835 
836   /* In DNS string format which is 1 octet length indicator followed by string */
837   const unsigned char https_alpn[] = { 0x02, 'h', '3' };
838   EXPECT_EQ(ARES_SUCCESS,
839     ares_dns_rr_set_opt(rr, ARES_RR_HTTPS_PARAMS, ARES_SVCB_PARAM_ALPN,
840       https_alpn, sizeof(https_alpn)));
841   /* URI */
842   EXPECT_EQ(ARES_SUCCESS,
843     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ADDITIONAL,
844       "_ftp._tcp.example.com", ARES_REC_TYPE_URI, ARES_CLASS_IN, 3600));
845   EXPECT_EQ(ARES_SUCCESS,
846     ares_dns_rr_set_u16(rr, ARES_RR_URI_PRIORITY, 10));
847   EXPECT_EQ(ARES_SUCCESS,
848     ares_dns_rr_set_u16(rr, ARES_RR_URI_WEIGHT, 1));
849   EXPECT_EQ(ARES_SUCCESS,
850     ares_dns_rr_set_str(rr, ARES_RR_URI_TARGET, "ftp://ftp.example.com/public"));
851   /* CAA */
852   EXPECT_EQ(ARES_SUCCESS,
853     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ADDITIONAL,
854       "example.com", ARES_REC_TYPE_CAA, ARES_CLASS_IN, 86400));
855   EXPECT_EQ(ARES_SUCCESS,
856     ares_dns_rr_set_u8(rr, ARES_RR_CAA_CRITICAL, 0));
857   EXPECT_EQ(ARES_SUCCESS,
858     ares_dns_rr_set_str(rr, ARES_RR_CAA_TAG, "issue"));
859   unsigned char caa[] = "letsencrypt.org";
860   EXPECT_EQ(ARES_SUCCESS,
861     ares_dns_rr_set_bin(rr, ARES_RR_CAA_VALUE, caa, sizeof(caa)));
862   /* NAPTR */
863   EXPECT_EQ(ARES_SUCCESS,
864     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ADDITIONAL,
865       "example.com", ARES_REC_TYPE_NAPTR, ARES_CLASS_IN, 86400));
866   EXPECT_EQ(ARES_SUCCESS,
867     ares_dns_rr_set_u16(rr, ARES_RR_NAPTR_ORDER, 100));
868   EXPECT_EQ(ARES_SUCCESS,
869     ares_dns_rr_set_u16(rr, ARES_RR_NAPTR_PREFERENCE, 10));
870   EXPECT_EQ(ARES_SUCCESS,
871     ares_dns_rr_set_str(rr, ARES_RR_NAPTR_FLAGS, "S"));
872   EXPECT_EQ(ARES_SUCCESS,
873     ares_dns_rr_set_str(rr, ARES_RR_NAPTR_SERVICES, "SIP+D2U"));
874   EXPECT_EQ(ARES_SUCCESS,
875     ares_dns_rr_set_str(rr, ARES_RR_NAPTR_REGEXP,
876       "!^.*$!sip:customer-service@example.com!"));
877   EXPECT_EQ(ARES_SUCCESS,
878     ares_dns_rr_set_str(rr, ARES_RR_NAPTR_REPLACEMENT,
879       "_sip._udp.example.com."));
880   /* RAW_RR */
881   EXPECT_EQ(ARES_SUCCESS,
882     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ADDITIONAL, "",
883       ARES_REC_TYPE_RAW_RR, ARES_CLASS_IN, 0));
884   EXPECT_EQ(ARES_SUCCESS,
885     ares_dns_rr_set_u16(rr, ARES_RR_RAW_RR_TYPE, 65432));
886   unsigned char data[] = { 0x00 };
887   EXPECT_EQ(ARES_SUCCESS,
888     ares_dns_rr_set_bin(rr, ARES_RR_RAW_RR_DATA, data, sizeof(data)));
889 
890   qdcount = ares_dns_record_query_cnt(dnsrec);
891   ancount = ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER);
892   nscount = ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_AUTHORITY);
893   arcount = ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ADDITIONAL);
894 
895   /* Write */
896   EXPECT_EQ(ARES_SUCCESS, ares_dns_write(dnsrec, &msg, &msglen));
897 
898   ares_buf_t *hexdump = ares_buf_create();
899   EXPECT_EQ(ARES_SUCCESS, ares_buf_hexdump(hexdump, msg, msglen));
900   char *hexdata = ares_buf_finish_str(hexdump, NULL);
901   //printf("HEXDUMP\n%s", hexdata);
902   ares_free(hexdata);
903 
904   ares_dns_record_destroy(dnsrec); dnsrec = NULL;
905 
906   /* Parse */
907   EXPECT_EQ(ARES_SUCCESS, ares_dns_parse(msg, msglen, 0, &dnsrec));
908   ares_free_string(msg); msg = NULL;
909 
910   /* Re-write */
911   EXPECT_EQ(ARES_SUCCESS, ares_dns_write(dnsrec, &msg, &msglen));
912 
913   EXPECT_EQ(qdcount, ares_dns_record_query_cnt(dnsrec));
914   EXPECT_EQ(ancount, ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER));
915   EXPECT_EQ(nscount, ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_AUTHORITY));
916   EXPECT_EQ(arcount, ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ADDITIONAL));
917 
918   /* Iterate and print */
919   ares_buf_t *printmsg = ares_buf_create();
920   ares_buf_append_str(printmsg, ";; ->>HEADER<<- opcode: ");
921   ares_buf_append_str(printmsg, ares_dns_opcode_tostr(ares_dns_record_get_opcode(dnsrec)));
922   ares_buf_append_str(printmsg, ", status: ");
923   ares_buf_append_str(printmsg, ares_dns_rcode_tostr(ares_dns_record_get_rcode(dnsrec)));
924   ares_buf_append_str(printmsg, ", id: ");
925   ares_buf_append_num_dec(printmsg, (size_t)ares_dns_record_get_id(dnsrec), 0);
926   ares_buf_append_str(printmsg, "\n;; flags: ");
927   ares_buf_append_num_hex(printmsg, (size_t)ares_dns_record_get_flags(dnsrec), 0);
928   ares_buf_append_str(printmsg, "; QUERY: ");
929   ares_buf_append_num_dec(printmsg, ares_dns_record_query_cnt(dnsrec), 0);
930   ares_buf_append_str(printmsg, ", ANSWER: ");
931   ares_buf_append_num_dec(printmsg, ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER), 0);
932   ares_buf_append_str(printmsg, ", AUTHORITY: ");
933   ares_buf_append_num_dec(printmsg, ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_AUTHORITY), 0);
934   ares_buf_append_str(printmsg, ", ADDITIONAL: ");
935   ares_buf_append_num_dec(printmsg, ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ADDITIONAL), 0);
936   ares_buf_append_str(printmsg, "\n\n");
937   ares_buf_append_str(printmsg, ";; QUESTION SECTION:\n");
938   for (size_t i = 0; i < ares_dns_record_query_cnt(dnsrec); i++) {
939     const char         *name;
940     ares_dns_rec_type_t qtype;
941     ares_dns_class_t    qclass;
942     ares_dns_record_query_get(dnsrec, i, &name, &qtype, &qclass);
943     ares_buf_append_str(printmsg, ";");
944     ares_buf_append_str(printmsg, name);
945     ares_buf_append_str(printmsg, ".\t\t\t");
946     ares_buf_append_str(printmsg, ares_dns_class_tostr(qclass));
947     ares_buf_append_str(printmsg, "\t");
948     ares_buf_append_str(printmsg, ares_dns_rec_type_tostr(qtype));
949     ares_buf_append_str(printmsg, "\n");
950   }
951   ares_buf_append_str(printmsg, "\n");
952   for (size_t i = ARES_SECTION_ANSWER; i < ARES_SECTION_ADDITIONAL + 1; i++) {
953     ares_buf_append_str(printmsg, ";; ");
954     ares_buf_append_str(printmsg, ares_dns_section_tostr((ares_dns_section_t)i));
955     ares_buf_append_str(printmsg, " SECTION:\n");
956     for (size_t j = 0; j < ares_dns_record_rr_cnt(dnsrec, (ares_dns_section_t)i); j++) {
957       rr = ares_dns_record_rr_get(dnsrec, (ares_dns_section_t)i, j);
958       ares_buf_append_str(printmsg, ares_dns_rr_get_name(rr));
959       ares_buf_append_str(printmsg, ".\t\t\t");
960       ares_buf_append_str(printmsg, ares_dns_class_tostr(ares_dns_rr_get_class(rr)));
961       ares_buf_append_str(printmsg, "\t");
962       ares_buf_append_str(printmsg, ares_dns_rec_type_tostr(ares_dns_rr_get_type(rr)));
963       ares_buf_append_str(printmsg, "\t");
964       ares_buf_append_num_dec(printmsg, ares_dns_rr_get_ttl(rr), 0);
965       ares_buf_append_str(printmsg, "\t");
966 
967       size_t keys_cnt;
968       const ares_dns_rr_key_t *keys = ares_dns_rr_get_keys(ares_dns_rr_get_type(rr), &keys_cnt);
969       for (size_t k = 0; k<keys_cnt; k++) {
970         char buf[256] = "";
971         ares_buf_append_str(printmsg, ares_dns_rr_key_tostr(keys[k]));
972         ares_buf_append_str(printmsg, "=");
973         switch (ares_dns_rr_key_datatype(keys[k])) {
974           case ARES_DATATYPE_INADDR:
975             ares_inet_ntop(AF_INET, ares_dns_rr_get_addr(rr, keys[k]), buf, sizeof(buf));
976             ares_buf_append_str(printmsg, buf);
977             break;
978           case ARES_DATATYPE_INADDR6:
979             ares_inet_ntop(AF_INET6, ares_dns_rr_get_addr6(rr, keys[k]), buf, sizeof(buf));
980             ares_buf_append_str(printmsg, buf);
981             break;
982           case ARES_DATATYPE_U8:
983             ares_buf_append_num_dec(printmsg, ares_dns_rr_get_u8(rr, keys[k]), 0);
984             break;
985           case ARES_DATATYPE_U16:
986             ares_buf_append_num_dec(printmsg, ares_dns_rr_get_u16(rr, keys[k]), 0);
987             break;
988           case ARES_DATATYPE_U32:
989             ares_buf_append_num_dec(printmsg, ares_dns_rr_get_u32(rr, keys[k]), 0);
990             break;
991           case ARES_DATATYPE_NAME:
992           case ARES_DATATYPE_STR:
993             ares_buf_append_byte(printmsg, '"');
994             ares_buf_append_str(printmsg, ares_dns_rr_get_str(rr, keys[k]));
995             ares_buf_append_byte(printmsg, '"');
996             break;
997           case ARES_DATATYPE_BIN:
998             /* TODO */
999             break;
1000           case ARES_DATATYPE_BINP:
1001             {
1002               ares_buf_append_byte(printmsg, '"');
1003               size_t templen;
1004               ares_buf_append_str(printmsg, (const char *)ares_dns_rr_get_bin(rr, keys[k], &templen));
1005               ares_buf_append_byte(printmsg, '"');
1006             }
1007             break;
1008           case ARES_DATATYPE_ABINP:
1009             for (size_t a=0; a<ares_dns_rr_get_abin_cnt(rr, keys[k]); a++) {
1010               if (a != 0) {
1011                 ares_buf_append_byte(printmsg, ' ');
1012               }
1013               ares_buf_append_byte(printmsg, '"');
1014               size_t templen;
1015               ares_buf_append_str(printmsg, (const char *)ares_dns_rr_get_abin(rr, keys[k], a, &templen));
1016               ares_buf_append_byte(printmsg, '"');
1017             }
1018             break;
1019           case ARES_DATATYPE_OPT:
1020             /* TODO */
1021             break;
1022         }
1023         ares_buf_append_str(printmsg, " ");
1024       }
1025       ares_buf_append_str(printmsg, "\n");
1026     }
1027   }
1028   ares_buf_append_str(printmsg, ";; SIZE: ");
1029   ares_buf_append_num_dec(printmsg, msglen, 0);
1030   ares_buf_append_str(printmsg, "\n\n");
1031 
1032   char *printdata = ares_buf_finish_str(printmsg, NULL);
1033   //printf("%s", printdata);
1034   ares_free(printdata);
1035 
1036   ares_dns_record_destroy(dnsrec);
1037   ares_free_string(msg);
1038 
1039   // Invalid
1040   EXPECT_NE(ARES_SUCCESS, ares_dns_parse(NULL, 0, 0, NULL));
1041   EXPECT_NE(ARES_SUCCESS, ares_dns_record_create(NULL, 0, 0, ARES_OPCODE_QUERY, ARES_RCODE_NOERROR));
1042   EXPECT_EQ(0, ares_dns_record_get_id(NULL));
1043   EXPECT_EQ(0, ares_dns_record_get_flags(NULL));
1044   EXPECT_EQ(0, (int)ares_dns_record_get_opcode(NULL));
1045   EXPECT_EQ(0, (int)ares_dns_record_get_rcode(NULL));
1046   EXPECT_EQ(0, (int)ares_dns_record_query_cnt(NULL));
1047   EXPECT_NE(ARES_SUCCESS, ares_dns_record_query_set_name(NULL, 0, NULL));
1048   EXPECT_NE(ARES_SUCCESS, ares_dns_record_query_set_type(NULL, 0, ARES_REC_TYPE_A));
1049   EXPECT_NE(ARES_SUCCESS, ares_dns_record_query_get(NULL, 0, NULL, NULL, NULL));
1050   EXPECT_EQ(0, ares_dns_record_rr_cnt(NULL, ARES_SECTION_ANSWER));
1051   EXPECT_NE(ARES_SUCCESS, ares_dns_record_rr_add(NULL, NULL, ARES_SECTION_ANSWER, NULL, ARES_REC_TYPE_A, ARES_CLASS_IN, 0));
1052   EXPECT_NE(ARES_SUCCESS, ares_dns_record_rr_del(NULL, ARES_SECTION_ANSWER, 0));
1053   EXPECT_EQ(nullptr, ares_dns_record_rr_get(NULL, ARES_SECTION_ANSWER, 0));
1054   EXPECT_EQ(nullptr, ares_dns_rr_get_name(NULL));
1055   EXPECT_EQ(0, (int)ares_dns_rr_get_type(NULL));
1056   EXPECT_EQ(0, (int)ares_dns_rr_get_class(NULL));
1057   EXPECT_EQ(0, ares_dns_rr_get_ttl(NULL));
1058   EXPECT_NE(ARES_SUCCESS, ares_dns_write(NULL, NULL, NULL));
1059 #ifndef CARES_SYMBOL_HIDING
1060   ares_dns_record_ttl_decrement(NULL, 0);
1061 #endif
1062   EXPECT_EQ(nullptr, ares_dns_rr_get_addr(NULL, ARES_RR_A_ADDR));
1063   EXPECT_EQ(nullptr, ares_dns_rr_get_addr(NULL, ARES_RR_NS_NSDNAME));
1064   EXPECT_EQ(nullptr, ares_dns_rr_get_addr6(NULL, ARES_RR_AAAA_ADDR));
1065   EXPECT_EQ(nullptr, ares_dns_rr_get_addr6(NULL, ARES_RR_NS_NSDNAME));
1066   EXPECT_EQ(0, ares_dns_rr_get_u8(NULL, ARES_RR_SIG_ALGORITHM));
1067   EXPECT_EQ(0, ares_dns_rr_get_u8(NULL, ARES_RR_NS_NSDNAME));
1068   EXPECT_EQ(0, ares_dns_rr_get_u16(NULL, ARES_RR_MX_PREFERENCE));
1069   EXPECT_EQ(0, ares_dns_rr_get_u16(NULL, ARES_RR_NS_NSDNAME));
1070   EXPECT_EQ(0, ares_dns_rr_get_u32(NULL, ARES_RR_SOA_SERIAL));
1071   EXPECT_EQ(0, ares_dns_rr_get_u32(NULL, ARES_RR_NS_NSDNAME));
1072   EXPECT_EQ(nullptr, ares_dns_rr_get_bin(NULL, ARES_RR_TXT_DATA, NULL));
1073   EXPECT_EQ(nullptr, ares_dns_rr_get_bin(NULL, ARES_RR_NS_NSDNAME, NULL));
1074   EXPECT_EQ(nullptr, ares_dns_rr_get_str(NULL, ARES_RR_NS_NSDNAME));
1075   EXPECT_EQ(nullptr, ares_dns_rr_get_str(NULL, ARES_RR_MX_PREFERENCE));
1076   EXPECT_EQ(0, ares_dns_rr_get_opt_cnt(NULL, ARES_RR_OPT_OPTIONS));
1077   EXPECT_EQ(0, ares_dns_rr_get_opt_cnt(NULL, ARES_RR_A_ADDR));
1078   EXPECT_EQ(65535, ares_dns_rr_get_opt(NULL, ARES_RR_OPT_OPTIONS, 0, NULL, NULL));
1079   EXPECT_EQ(65535, ares_dns_rr_get_opt(NULL, ARES_RR_A_ADDR, 0, NULL, NULL));
1080   EXPECT_EQ(ARES_FALSE, ares_dns_rr_get_opt_byid(NULL, ARES_RR_OPT_OPTIONS, 1, NULL, NULL));
1081   EXPECT_EQ(ARES_FALSE, ares_dns_rr_get_opt_byid(NULL, ARES_RR_A_ADDR, 1, NULL, NULL));
1082 }
1083 
TEST_F(LibraryTest,DNSParseFlags)1084 TEST_F(LibraryTest, DNSParseFlags) {
1085   ares_dns_record_t   *dnsrec = NULL;
1086   ares_dns_rr_t       *rr     = NULL;
1087   struct in_addr       addr;
1088   unsigned char       *msg    = NULL;
1089   size_t               msglen = 0;
1090 
1091   EXPECT_EQ(ARES_SUCCESS,
1092     ares_dns_record_create(&dnsrec, 0x1234,
1093       ARES_FLAG_QR|ARES_FLAG_AA|ARES_FLAG_RD|ARES_FLAG_RA,
1094       ARES_OPCODE_QUERY, ARES_RCODE_NOERROR));
1095 
1096   /* == Question == */
1097   EXPECT_EQ(ARES_SUCCESS,
1098     ares_dns_record_query_add(dnsrec, "example.com",
1099       ARES_REC_TYPE_ANY,
1100       ARES_CLASS_IN));
1101 
1102   /* == Answer == */
1103   /* A */
1104   EXPECT_EQ(ARES_SUCCESS,
1105     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ANSWER, "example.com",
1106       ARES_REC_TYPE_A, ARES_CLASS_IN, 300));
1107   EXPECT_LT(0, ares_inet_pton(AF_INET, "1.1.1.1", &addr));
1108   EXPECT_EQ(ARES_SUCCESS,
1109     ares_dns_rr_set_addr(rr, ARES_RR_A_ADDR, &addr));
1110   /* TLSA */
1111   EXPECT_EQ(ARES_SUCCESS,
1112     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ANSWER,
1113       "_443._tcp.example.com", ARES_REC_TYPE_TLSA, ARES_CLASS_IN, 86400));
1114   EXPECT_EQ(ARES_SUCCESS,
1115     ares_dns_rr_set_u8(rr, ARES_RR_TLSA_CERT_USAGE, ARES_TLSA_USAGE_CA));
1116   EXPECT_EQ(ARES_SUCCESS,
1117     ares_dns_rr_set_u8(rr, ARES_RR_TLSA_SELECTOR, ARES_TLSA_SELECTOR_FULL));
1118   EXPECT_EQ(ARES_SUCCESS,
1119     ares_dns_rr_set_u8(rr, ARES_RR_TLSA_MATCH, ARES_TLSA_MATCH_SHA256));
1120   const unsigned char tlsa[] = {
1121     0xd2, 0xab, 0xde, 0x24, 0x0d, 0x7c, 0xd3, 0xee, 0x6b, 0x4b, 0x28, 0xc5,
1122     0x4d, 0xf0, 0x34, 0xb9, 0x79, 0x83, 0xa1, 0xd1, 0x6e, 0x8a, 0x41, 0x0e,
1123     0x45, 0x61, 0xcb, 0x10, 0x66, 0x18, 0xe9, 0x71 };
1124   EXPECT_EQ(ARES_SUCCESS,
1125     ares_dns_rr_set_bin(rr, ARES_RR_TLSA_DATA, tlsa, sizeof(tlsa)));
1126 
1127   /* == Authority == */
1128   /* NS */
1129   EXPECT_EQ(ARES_SUCCESS,
1130     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_AUTHORITY, "example.com",
1131       ARES_REC_TYPE_NS, ARES_CLASS_IN, 38400));
1132   EXPECT_EQ(ARES_SUCCESS,
1133     ares_dns_rr_set_str(rr, ARES_RR_NS_NSDNAME, "ns1.example.com"));
1134 
1135   /* == Additional */
1136   /* PTR -- doesn't make sense, but ok */
1137   EXPECT_EQ(ARES_SUCCESS,
1138     ares_dns_record_rr_add(&rr, dnsrec, ARES_SECTION_ADDITIONAL, "example.com",
1139       ARES_REC_TYPE_PTR, ARES_CLASS_IN, 300));
1140   EXPECT_EQ(ARES_SUCCESS,
1141     ares_dns_rr_set_str(rr, ARES_RR_PTR_DNAME, "b.example.com"));
1142 
1143   /* Write */
1144   EXPECT_EQ(ARES_SUCCESS, ares_dns_write(dnsrec, &msg, &msglen));
1145 
1146   /* Cleanup - before reuse */
1147   ares_dns_record_destroy(dnsrec);
1148 
1149   /* Parse "base" type records (1035) */
1150   EXPECT_EQ(ARES_SUCCESS, ares_dns_parse(msg, msglen, ARES_DNS_PARSE_AN_BASE_RAW |
1151     ARES_DNS_PARSE_NS_BASE_RAW | ARES_DNS_PARSE_AR_BASE_RAW, &dnsrec));
1152 
1153   EXPECT_EQ(1, ares_dns_record_query_cnt(dnsrec));
1154   EXPECT_EQ(2, ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER));
1155   EXPECT_EQ(1, ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_AUTHORITY));
1156   EXPECT_EQ(1, ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ADDITIONAL));
1157 
1158   rr = ares_dns_record_rr_get(dnsrec, ARES_SECTION_ANSWER, 0);
1159   EXPECT_EQ(ARES_REC_TYPE_RAW_RR, ares_dns_rr_get_type(rr));
1160 
1161   rr = ares_dns_record_rr_get(dnsrec, ARES_SECTION_ANSWER, 1);
1162   EXPECT_EQ(ARES_REC_TYPE_TLSA, ares_dns_rr_get_type(rr));
1163 
1164   rr = ares_dns_record_rr_get(dnsrec, ARES_SECTION_AUTHORITY, 0);
1165   EXPECT_EQ(ARES_REC_TYPE_RAW_RR, ares_dns_rr_get_type(rr));
1166 
1167   rr = ares_dns_record_rr_get(dnsrec, ARES_SECTION_ADDITIONAL, 0);
1168   EXPECT_EQ(ARES_REC_TYPE_RAW_RR, ares_dns_rr_get_type(rr));
1169 
1170   /* Cleanup - before reuse */
1171 
1172   ares_dns_record_destroy(dnsrec);
1173 
1174   /* Parse later RFCs (no name compression) type records */
1175 
1176   EXPECT_EQ(ARES_SUCCESS, ares_dns_parse(msg, msglen, ARES_DNS_PARSE_AN_EXT_RAW |
1177     ARES_DNS_PARSE_NS_EXT_RAW | ARES_DNS_PARSE_AR_EXT_RAW, &dnsrec));
1178 
1179   EXPECT_EQ(1, ares_dns_record_query_cnt(dnsrec));
1180   EXPECT_EQ(2, ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER));
1181   EXPECT_EQ(1, ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_AUTHORITY));
1182   EXPECT_EQ(1, ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ADDITIONAL));
1183 
1184   rr = ares_dns_record_rr_get(dnsrec, ARES_SECTION_ANSWER, 0);
1185   EXPECT_EQ(ARES_REC_TYPE_A, ares_dns_rr_get_type(rr));
1186 
1187   rr = ares_dns_record_rr_get(dnsrec, ARES_SECTION_ANSWER, 1);
1188   EXPECT_EQ(ARES_REC_TYPE_RAW_RR, ares_dns_rr_get_type(rr));
1189 
1190   rr = ares_dns_record_rr_get(dnsrec, ARES_SECTION_AUTHORITY, 0);
1191   EXPECT_EQ(ARES_REC_TYPE_NS, ares_dns_rr_get_type(rr));
1192 
1193   rr = ares_dns_record_rr_get(dnsrec, ARES_SECTION_ADDITIONAL, 0);
1194   EXPECT_EQ(ARES_REC_TYPE_PTR, ares_dns_rr_get_type(rr));
1195 
1196   ares_dns_record_destroy(dnsrec);
1197   ares_free_string(msg); msg = NULL;
1198 }
1199 
TEST_F(LibraryTest,ArrayMisuse)1200 TEST_F(LibraryTest, ArrayMisuse) {
1201   EXPECT_EQ(NULL, ares_array_create(0, NULL));
1202   ares_array_destroy(NULL);
1203   EXPECT_EQ(NULL, ares_array_finish(NULL, NULL));
1204   EXPECT_EQ(0, ares_array_len(NULL));
1205   EXPECT_NE(ARES_SUCCESS, ares_array_insert_at(NULL, NULL, 0));
1206   EXPECT_NE(ARES_SUCCESS, ares_array_insertdata_at(NULL, 0, NULL));
1207   EXPECT_NE(ARES_SUCCESS, ares_array_insert_last(NULL, NULL));
1208   EXPECT_NE(ARES_SUCCESS, ares_array_insertdata_last(NULL, NULL));
1209   EXPECT_NE(ARES_SUCCESS, ares_array_insert_first(NULL, NULL));
1210   EXPECT_NE(ARES_SUCCESS, ares_array_insertdata_first(NULL, NULL));
1211   EXPECT_EQ(NULL, ares_array_at(NULL, 0));
1212   EXPECT_EQ(NULL, ares_array_first(NULL));
1213   EXPECT_EQ(NULL, ares_array_last(NULL));
1214   EXPECT_NE(ARES_SUCCESS, ares_array_claim_at(NULL, 0, NULL, 0));
1215   EXPECT_NE(ARES_SUCCESS, ares_array_remove_at(NULL, 0));
1216   EXPECT_NE(ARES_SUCCESS, ares_array_remove_first(NULL));
1217   EXPECT_NE(ARES_SUCCESS, ares_array_remove_last(NULL));
1218   EXPECT_NE(ARES_SUCCESS, ares_array_sort(NULL, NULL));
1219   EXPECT_NE(ARES_SUCCESS, ares_array_set_size(NULL, 0));
1220 }
1221 
TEST_F(LibraryTest,BufMisuse)1222 TEST_F(LibraryTest, BufMisuse) {
1223   EXPECT_EQ(NULL, ares_buf_create_const(NULL, 0));
1224   ares_buf_reclaim(NULL);
1225   EXPECT_NE(ARES_SUCCESS, ares_buf_append(NULL, NULL, 55));
1226   size_t len = 10;
1227   EXPECT_EQ(NULL, ares_buf_append_start(NULL, &len));
1228   EXPECT_EQ(NULL, ares_buf_append_start(NULL, NULL));
1229   ares_buf_append_finish(NULL, 0);
1230   EXPECT_EQ(NULL, ares_buf_finish_bin(NULL, NULL));
1231   EXPECT_EQ(NULL, ares_buf_finish_str(NULL, NULL));
1232   ares_buf_tag(NULL);
1233   EXPECT_NE(ARES_SUCCESS, ares_buf_tag_rollback(NULL));
1234   EXPECT_NE(ARES_SUCCESS, ares_buf_tag_clear(NULL));
1235   EXPECT_EQ(NULL, ares_buf_tag_fetch(NULL, NULL));
1236   EXPECT_EQ((size_t)0, ares_buf_tag_length(NULL));
1237   EXPECT_NE(ARES_SUCCESS, ares_buf_tag_fetch_bytes(NULL, NULL, NULL));
1238   EXPECT_NE(ARES_SUCCESS, ares_buf_tag_fetch_string(NULL, NULL, 0));
1239   EXPECT_NE(ARES_SUCCESS, ares_buf_fetch_bytes_dup(NULL, 0, ARES_FALSE, NULL));
1240   EXPECT_NE(ARES_SUCCESS, ares_buf_fetch_str_dup(NULL, 0, NULL));
1241   EXPECT_EQ((size_t)0, ares_buf_consume_whitespace(NULL, ARES_FALSE));
1242   EXPECT_EQ((size_t)0, ares_buf_consume_nonwhitespace(NULL));
1243   EXPECT_EQ((size_t)0, ares_buf_consume_line(NULL, ARES_FALSE));
1244   EXPECT_EQ(ARES_FALSE, ares_buf_begins_with(NULL, NULL, 0));
1245   EXPECT_EQ((size_t)0, ares_buf_get_position(NULL));
1246   EXPECT_NE(ARES_SUCCESS, ares_buf_set_position(NULL, 0));
1247   EXPECT_NE(ARES_SUCCESS, ares_buf_parse_dns_binstr(NULL, 0, NULL, NULL));
1248 }
1249 
TEST_F(LibraryTest,HtableAsvpMisuse)1250 TEST_F(LibraryTest, HtableAsvpMisuse) {
1251   EXPECT_EQ(ARES_FALSE, ares_htable_asvp_insert(NULL, ARES_SOCKET_BAD, NULL));
1252   EXPECT_EQ(ARES_FALSE, ares_htable_asvp_get(NULL, ARES_SOCKET_BAD, NULL));
1253   EXPECT_EQ(ARES_FALSE, ares_htable_asvp_remove(NULL, ARES_SOCKET_BAD));
1254   EXPECT_EQ((size_t)0, ares_htable_asvp_num_keys(NULL));
1255 }
1256 
TEST_F(LibraryTest,HtableStrvpMisuse)1257 TEST_F(LibraryTest, HtableStrvpMisuse) {
1258   EXPECT_EQ(ARES_FALSE, ares_htable_strvp_insert(NULL, NULL, NULL));
1259   EXPECT_EQ(ARES_FALSE, ares_htable_strvp_get(NULL, NULL, NULL));
1260   EXPECT_EQ(ARES_FALSE, ares_htable_strvp_remove(NULL, NULL));
1261   EXPECT_EQ((size_t)0, ares_htable_strvp_num_keys(NULL));
1262 }
1263 
TEST_F(LibraryTest,HtableVpStrMisuse)1264 TEST_F(LibraryTest, HtableVpStrMisuse) {
1265   EXPECT_EQ(ARES_FALSE, ares_htable_vpstr_insert(NULL, NULL, NULL));
1266   EXPECT_EQ(ARES_FALSE, ares_htable_vpstr_get(NULL, NULL, NULL));
1267   EXPECT_EQ(ARES_FALSE, ares_htable_vpstr_remove(NULL, NULL));
1268   EXPECT_EQ((size_t)0, ares_htable_vpstr_num_keys(NULL));
1269 }
1270 
TEST_F(LibraryTest,HtableDictMisuse)1271 TEST_F(LibraryTest, HtableDictMisuse) {
1272   EXPECT_EQ(ARES_FALSE, ares_htable_dict_insert(NULL, NULL, NULL));
1273   EXPECT_EQ(ARES_FALSE, ares_htable_dict_get(NULL, NULL, NULL));
1274   EXPECT_EQ(ARES_FALSE, ares_htable_dict_remove(NULL, NULL));
1275   EXPECT_EQ((size_t)0, ares_htable_dict_num_keys(NULL));
1276 }
1277 
TEST_F(LibraryTest,HtableSzvpMisuse)1278 TEST_F(LibraryTest, HtableSzvpMisuse) {
1279   EXPECT_EQ(ARES_FALSE, ares_htable_szvp_insert(NULL, 0, NULL));
1280   EXPECT_EQ(ARES_FALSE, ares_htable_szvp_get(NULL, 0, NULL));
1281   EXPECT_EQ(ARES_FALSE, ares_htable_szvp_remove(NULL, 0));
1282   EXPECT_EQ((size_t)0, ares_htable_szvp_num_keys(NULL));
1283 }
1284 
TEST_F(LibraryTest,HtableVpvpMisuse)1285 TEST_F(LibraryTest, HtableVpvpMisuse) {
1286   EXPECT_EQ(ARES_FALSE, ares_htable_vpvp_insert(NULL, NULL, NULL));
1287   EXPECT_EQ(ARES_FALSE, ares_htable_vpvp_get(NULL, NULL, NULL));
1288   EXPECT_EQ(ARES_FALSE, ares_htable_vpvp_remove(NULL, NULL));
1289   EXPECT_EQ((size_t)0, ares_htable_vpvp_num_keys(NULL));
1290 }
1291 
TEST_F(LibraryTest,LlistMisuse)1292 TEST_F(LibraryTest, LlistMisuse) {
1293   ares_llist_replace_destructor(NULL, NULL);
1294   EXPECT_EQ(NULL, ares_llist_insert_before(NULL, NULL));
1295   EXPECT_EQ(NULL, ares_llist_insert_after(NULL, NULL));
1296   EXPECT_EQ(NULL, ares_llist_node_last(NULL));
1297   EXPECT_EQ(NULL, ares_llist_node_next(NULL));
1298   EXPECT_EQ(NULL, ares_llist_node_prev(NULL));
1299   EXPECT_EQ((size_t)0, ares_llist_len(NULL));
1300   EXPECT_EQ(NULL, ares_llist_node_parent(NULL));
1301   EXPECT_EQ(NULL, ares_llist_node_claim(NULL));
1302   ares_llist_node_replace(NULL, NULL);
1303 }
1304 
1305 typedef struct {
1306   unsigned int id;
1307   ares_buf_t *buf;
1308 } array_member_t;
1309 
array_member_init(void * mb,unsigned int id)1310 static void array_member_init(void *mb, unsigned int id)
1311 {
1312   array_member_t *m = (array_member_t *)mb;
1313   m->id             = id;
1314   m->buf            = ares_buf_create();
1315   ares_buf_append_be32(m->buf, id);
1316 }
1317 
array_member_destroy(void * mb)1318 static void array_member_destroy(void *mb)
1319 {
1320   array_member_t *m = (array_member_t *)mb;
1321   ares_buf_destroy(m->buf);
1322 }
1323 
array_sort_cmp(const void * data1,const void * data2)1324 static int array_sort_cmp(const void *data1, const void *data2)
1325 {
1326   const array_member_t *m1 = (const array_member_t *)data1;
1327   const array_member_t *m2 = (const array_member_t *)data2;
1328   if (m1->id > m2->id)
1329     return 1;
1330   if (m1->id < m2->id)
1331     return -1;
1332   return 0;
1333 }
1334 
TEST_F(LibraryTest,Array)1335 TEST_F(LibraryTest, Array) {
1336   ares_array_t   *a       = NULL;
1337   array_member_t *m       = NULL;
1338   array_member_t  mbuf;
1339   unsigned int    cnt     = 0;
1340   unsigned int    removed = 0;
1341   void           *ptr     = NULL;
1342   size_t          i;
1343 
1344   a = ares_array_create(sizeof(array_member_t), array_member_destroy);
1345   EXPECT_NE(nullptr, a);
1346 
1347   /* Try to sort with no elements, should break out */
1348   EXPECT_EQ(ARES_SUCCESS, ares_array_sort(a, array_sort_cmp));
1349 
1350   /* Add 8 elements */
1351   for ( ; cnt < 8 ; cnt++) {
1352     EXPECT_EQ(ARES_SUCCESS, ares_array_insert_last(&ptr, a));
1353     array_member_init(ptr, cnt+1);
1354   }
1355 
1356   /* Insert at invalid index */
1357   EXPECT_NE(ARES_SUCCESS, ares_array_insert_at(&ptr, a, 12345678));
1358 
1359   /* Verify count */
1360   EXPECT_EQ(cnt, ares_array_len(a));
1361 
1362   /* Remove the first 2 elements */
1363   EXPECT_EQ(ARES_SUCCESS, ares_array_remove_first(a));
1364   EXPECT_EQ(ARES_SUCCESS, ares_array_remove_first(a));
1365   removed += 2;
1366 
1367   /* Verify count */
1368   EXPECT_EQ(cnt-removed, ares_array_len(a));
1369 
1370   /* Verify id of first element */
1371   m = (array_member_t *)ares_array_first(a);
1372   EXPECT_NE(nullptr, m);
1373   EXPECT_EQ(3, m->id);
1374 
1375 
1376   /* Add 100 total elements, this should force a shift of memory at some
1377    * to make sure moves are working */
1378   for ( ; cnt < 100 ; cnt++) {
1379     EXPECT_EQ(ARES_SUCCESS, ares_array_insert_last(&ptr, a));
1380     array_member_init(ptr, cnt+1);
1381   }
1382 
1383   /* Verify count */
1384   EXPECT_EQ(cnt-removed, ares_array_len(a));
1385 
1386   /* Remove 2 from the end */
1387   EXPECT_EQ(ARES_SUCCESS, ares_array_remove_last(a));
1388   EXPECT_EQ(ARES_SUCCESS, ares_array_remove_last(a));
1389   removed += 2;
1390 
1391   /* Verify count */
1392   EXPECT_EQ(cnt-removed, ares_array_len(a));
1393 
1394   /* Verify expected id of last member */
1395   m = (array_member_t *)ares_array_last(a);
1396   EXPECT_NE(nullptr, m);
1397   EXPECT_EQ(cnt-2, m->id);
1398 
1399   /* Remove 3 middle members */
1400   EXPECT_EQ(ARES_SUCCESS, ares_array_remove_at(a, ares_array_len(a)/2));
1401   EXPECT_EQ(ARES_SUCCESS, ares_array_remove_at(a, ares_array_len(a)/2));
1402   EXPECT_EQ(ARES_SUCCESS, ares_array_remove_at(a, ares_array_len(a)/2));
1403   removed += 3;
1404 
1405   /* Verify count */
1406   EXPECT_EQ(cnt-removed, ares_array_len(a));
1407 
1408   /* Claim a middle member then re-add it at the same position */
1409   i = ares_array_len(a) / 2;
1410   EXPECT_EQ(ARES_SUCCESS, ares_array_claim_at(&mbuf, sizeof(mbuf), a, i));
1411   EXPECT_EQ(ARES_SUCCESS, ares_array_insert_at(&ptr, a, i));
1412   array_member_init(ptr, mbuf.id);
1413   array_member_destroy((void *)&mbuf);
1414   /* Verify count */
1415   EXPECT_EQ(cnt-removed, ares_array_len(a));
1416 
1417   /* Iterate across the array, make sure each entry is greater than the last and
1418    * the data in the buffer matches the id in the array */
1419   unsigned int last_id = 0;
1420   for (i=0; i<ares_array_len(a); i++) {
1421     m = (array_member_t *)ares_array_at(a, i);
1422     EXPECT_NE(nullptr, m);
1423     EXPECT_GT(m->id, last_id);
1424     last_id = m->id;
1425 
1426     unsigned int bufval = 0;
1427     ares_buf_tag(m->buf);
1428     EXPECT_EQ(ARES_SUCCESS, ares_buf_fetch_be32(m->buf, &bufval));
1429     ares_buf_tag_rollback(m->buf);
1430     EXPECT_EQ(bufval, m->id);
1431   }
1432 
1433   /* add a new element in the middle to the beginning with a high id */
1434   EXPECT_EQ(ARES_SUCCESS, ares_array_insert_at(&ptr, a, ares_array_len(a)/2));
1435   array_member_init(ptr, 100000);
1436 
1437   /* Sort the array */
1438   EXPECT_EQ(ARES_SUCCESS, ares_array_sort(a, array_sort_cmp));
1439 
1440   /* Iterate across the array, make sure each entry is greater than the last and
1441    * the data in the buffer matches the id in the array */
1442   last_id = 0;
1443   for (i=0; i<ares_array_len(a); i++) {
1444     m = (array_member_t *)ares_array_at(a, i);
1445     EXPECT_NE(nullptr, m);
1446     EXPECT_GT(m->id, last_id);
1447     last_id = m->id;
1448 
1449     unsigned int bufval = 0;
1450     ares_buf_tag(m->buf);
1451     EXPECT_EQ(ARES_SUCCESS, ares_buf_fetch_be32(m->buf, &bufval));
1452     ares_buf_tag_rollback(m->buf);
1453     EXPECT_EQ(bufval, m->id);
1454   }
1455 
1456   ares_array_destroy(a);
1457 }
1458 
TEST_F(LibraryTest,HtableVpvp)1459 TEST_F(LibraryTest, HtableVpvp) {
1460   ares_llist_t       *l = NULL;
1461   ares_htable_vpvp_t *h = NULL;
1462   ares_llist_node_t  *n = NULL;
1463   size_t               i;
1464 
1465 #define VPVP_TABLE_SIZE 1000
1466 
1467   l = ares_llist_create(NULL);
1468   EXPECT_NE((void *)NULL, l);
1469 
1470   h = ares_htable_vpvp_create(NULL, ares_free);
1471   EXPECT_NE((void *)NULL, h);
1472 
1473   for (i=0; i<VPVP_TABLE_SIZE; i++) {
1474     void *p = ares_malloc_zero(4);
1475     EXPECT_NE((void *)NULL, p);
1476     EXPECT_NE((void *)NULL, ares_llist_insert_last(l, p));
1477     EXPECT_TRUE(ares_htable_vpvp_insert(h, p, p));
1478   }
1479 
1480   EXPECT_EQ(VPVP_TABLE_SIZE, ares_llist_len(l));
1481   EXPECT_EQ(VPVP_TABLE_SIZE, ares_htable_vpvp_num_keys(h));
1482 
1483   n = ares_llist_node_first(l);
1484   EXPECT_NE((void *)NULL, n);
1485   while (n != NULL) {
1486     ares_llist_node_t *next = ares_llist_node_next(n);
1487     void               *p    = ares_llist_node_val(n);
1488     EXPECT_NE((void *)NULL, p);
1489     EXPECT_EQ(p, ares_htable_vpvp_get_direct(h, p));
1490     EXPECT_TRUE(ares_htable_vpvp_get(h, p, NULL));
1491     EXPECT_TRUE(ares_htable_vpvp_remove(h, p));
1492     ares_llist_node_destroy(n);
1493     n = next;
1494   }
1495 
1496   EXPECT_EQ(0, ares_llist_len(l));
1497   EXPECT_EQ(0, ares_htable_vpvp_num_keys(h));
1498 
1499   ares_llist_destroy(l);
1500   ares_htable_vpvp_destroy(h);
1501 }
1502 
TEST_F(LibraryTest,BufSplitStr)1503 TEST_F(LibraryTest, BufSplitStr) {
1504   ares_buf_t  *buf   = NULL;
1505   char        **strs  = NULL;
1506   size_t        nstrs = 0;
1507 
1508   buf = ares_buf_create();
1509   ares_buf_append_str(buf, "string1\nstring2 string3\t   \nstring4");
1510   ares_buf_split_str(buf, (const unsigned char *)"\n \t", 2, ARES_BUF_SPLIT_TRIM, 0, &strs, &nstrs);
1511   ares_buf_destroy(buf);
1512 
1513   EXPECT_EQ(4, nstrs);
1514   EXPECT_TRUE(ares_streq(strs[0], "string1"));
1515   EXPECT_TRUE(ares_streq(strs[1], "string2"));
1516   EXPECT_TRUE(ares_streq(strs[2], "string3"));
1517   EXPECT_TRUE(ares_streq(strs[3], "string4"));
1518   ares_free_array(strs, nstrs, ares_free);
1519 }
1520 
TEST_F(LibraryTest,BufReplace)1521 TEST_F(LibraryTest, BufReplace) {
1522   ares_buf_t  *buf = NULL;
1523   size_t       i;
1524   struct {
1525     const char *input;
1526     const char *srch;
1527     const char *rplc;
1528     const char *output;
1529   } tests[] = {
1530     /* Same size */
1531     { "nameserver_1.2.3.4\nnameserver_2.3.4.5\n", "_", " ", "nameserver 1.2.3.4\nnameserver 2.3.4.5\n" },
1532     /* Longer */
1533     { "nameserver_1.2.3.4\nnameserver_2.3.4.5\n", "_", "|||", "nameserver|||1.2.3.4\nnameserver|||2.3.4.5\n" },
1534     /* Shorter */
1535     { "nameserver_1.2.3.4\nnameserver_2.3.4.5\n", "_", "", "nameserver1.2.3.4\nnameserver2.3.4.5\n" }
1536   };
1537   char        *str = NULL;
1538 
1539   for (i=0; i<sizeof(tests)/sizeof(*tests); i++) {
1540     buf = ares_buf_create();
1541     EXPECT_EQ(ARES_SUCCESS, ares_buf_append_str(buf, tests[i].input));
1542     EXPECT_EQ(ARES_SUCCESS, ares_buf_replace(buf, (const unsigned char *)tests[i].srch, ares_strlen(tests[i].srch), (const unsigned char *)tests[i].rplc, ares_strlen(tests[i].rplc)));
1543     str = ares_buf_finish_str(buf, NULL);
1544     EXPECT_STREQ(str, tests[i].output);
1545     ares_free(str);
1546   }
1547 }
1548 
1549 typedef struct {
1550   ares_socket_t s;
1551 } test_htable_asvp_t;
1552 
TEST_F(LibraryTest,HtableAsvp)1553 TEST_F(LibraryTest, HtableAsvp) {
1554   ares_llist_t       *l = NULL;
1555   ares_htable_asvp_t *h = NULL;
1556   ares_llist_node_t  *n = NULL;
1557   size_t               i;
1558 
1559 #define ASVP_TABLE_SIZE 1000
1560 
1561   l = ares_llist_create(NULL);
1562   EXPECT_NE((void *)NULL, l);
1563 
1564   h = ares_htable_asvp_create(ares_free);
1565   EXPECT_NE((void *)NULL, h);
1566 
1567   for (i=0; i<ASVP_TABLE_SIZE; i++) {
1568     test_htable_asvp_t *a = (test_htable_asvp_t *)ares_malloc_zero(sizeof(*a));
1569     EXPECT_NE((void *)NULL, a);
1570     a->s = (ares_socket_t)i+1;
1571     EXPECT_NE((void *)NULL, ares_llist_insert_last(l, a));
1572     EXPECT_TRUE(ares_htable_asvp_insert(h, a->s, a));
1573   }
1574 
1575   EXPECT_EQ(ASVP_TABLE_SIZE, ares_llist_len(l));
1576   EXPECT_EQ(ASVP_TABLE_SIZE, ares_htable_asvp_num_keys(h));
1577 
1578   n = ares_llist_node_first(l);
1579   EXPECT_NE((void *)NULL, n);
1580   while (n != NULL) {
1581     ares_llist_node_t *next = ares_llist_node_next(n);
1582     test_htable_asvp_t *a    = (test_htable_asvp_t *)ares_llist_node_val(n);
1583     EXPECT_NE((void *)NULL, a);
1584     EXPECT_EQ(a, ares_htable_asvp_get_direct(h, a->s));
1585     EXPECT_TRUE(ares_htable_asvp_get(h, a->s, NULL));
1586     EXPECT_TRUE(ares_htable_asvp_remove(h, a->s));
1587     ares_llist_node_destroy(n);
1588     n = next;
1589   }
1590 
1591   EXPECT_EQ(0, ares_llist_len(l));
1592   EXPECT_EQ(0, ares_htable_asvp_num_keys(h));
1593 
1594   ares_llist_destroy(l);
1595   ares_htable_asvp_destroy(h);
1596 }
1597 
1598 
1599 typedef struct {
1600   size_t s;
1601 } test_htable_szvp_t;
1602 
TEST_F(LibraryTest,HtableSzvp)1603 TEST_F(LibraryTest, HtableSzvp) {
1604   ares_llist_t       *l = NULL;
1605   ares_htable_szvp_t *h = NULL;
1606   ares_llist_node_t  *n = NULL;
1607   size_t               i;
1608 
1609 #define SZVP_TABLE_SIZE 1000
1610 
1611   l = ares_llist_create(NULL);
1612   EXPECT_NE((void *)NULL, l);
1613 
1614   h = ares_htable_szvp_create(ares_free);
1615   EXPECT_NE((void *)NULL, h);
1616 
1617   for (i=0; i<SZVP_TABLE_SIZE; i++) {
1618     test_htable_szvp_t *s = (test_htable_szvp_t *)ares_malloc_zero(sizeof(*s));
1619     EXPECT_NE((void *)NULL, s);
1620     s->s = i+1;
1621     EXPECT_NE((void *)NULL, ares_llist_insert_last(l, s));
1622     EXPECT_TRUE(ares_htable_szvp_insert(h, s->s, s));
1623   }
1624 
1625   EXPECT_EQ(SZVP_TABLE_SIZE, ares_llist_len(l));
1626   EXPECT_EQ(SZVP_TABLE_SIZE, ares_htable_szvp_num_keys(h));
1627 
1628   n = ares_llist_node_first(l);
1629   EXPECT_NE((void *)NULL, n);
1630   while (n != NULL) {
1631     ares_llist_node_t *next = ares_llist_node_next(n);
1632     test_htable_szvp_t *s    = (test_htable_szvp_t *)ares_llist_node_val(n);
1633     EXPECT_NE((void *)NULL, s);
1634     EXPECT_EQ(s, ares_htable_szvp_get_direct(h, s->s));
1635     EXPECT_TRUE(ares_htable_szvp_get(h, s->s, NULL));
1636     EXPECT_TRUE(ares_htable_szvp_remove(h, s->s));
1637     ares_llist_node_destroy(n);
1638     n = next;
1639   }
1640 
1641   EXPECT_EQ(0, ares_llist_len(l));
1642   EXPECT_EQ(0, ares_htable_szvp_num_keys(h));
1643 
1644   ares_llist_destroy(l);
1645   ares_htable_szvp_destroy(h);
1646 }
1647 
1648 typedef struct {
1649   char s[32];
1650 } test_htable_vpstr_t;
1651 
TEST_F(LibraryTest,HtableVpstr)1652 TEST_F(LibraryTest, HtableVpstr) {
1653   ares_llist_t        *l = NULL;
1654   ares_htable_vpstr_t *h = NULL;
1655   ares_llist_node_t   *n = NULL;
1656   size_t                i;
1657 
1658 #define VPSTR_TABLE_SIZE 1000
1659 
1660   l = ares_llist_create(ares_free);
1661   EXPECT_NE((void *)NULL, l);
1662 
1663   h = ares_htable_vpstr_create();
1664   EXPECT_NE((void *)NULL, h);
1665 
1666   for (i=0; i<VPSTR_TABLE_SIZE; i++) {
1667     test_htable_vpstr_t *s = (test_htable_vpstr_t *)ares_malloc_zero(sizeof(*s));
1668     EXPECT_NE((void *)NULL, s);
1669     snprintf(s->s, sizeof(s->s), "%d", (int)i);
1670     EXPECT_NE((void *)NULL, ares_llist_insert_last(l, s));
1671     EXPECT_TRUE(ares_htable_vpstr_insert(h, s, s->s));
1672   }
1673 
1674   EXPECT_EQ(VPSTR_TABLE_SIZE, ares_llist_len(l));
1675   EXPECT_EQ(VPSTR_TABLE_SIZE, ares_htable_vpstr_num_keys(h));
1676 
1677   n = ares_llist_node_first(l);
1678   EXPECT_NE((void *)NULL, n);
1679   while (n != NULL) {
1680     ares_llist_node_t *next = ares_llist_node_next(n);
1681     test_htable_vpstr_t *s   = (test_htable_vpstr_t *)ares_llist_node_val(n);
1682     EXPECT_NE((void *)NULL, s);
1683     EXPECT_STREQ(s->s, ares_htable_vpstr_get_direct(h, s));
1684     EXPECT_TRUE(ares_htable_vpstr_get(h, s, NULL));
1685     EXPECT_TRUE(ares_htable_vpstr_remove(h, s));
1686     ares_llist_node_destroy(n);
1687     n = next;
1688   }
1689 
1690   EXPECT_EQ(0, ares_llist_len(l));
1691   EXPECT_EQ(0, ares_htable_vpstr_num_keys(h));
1692 
1693   ares_llist_destroy(l);
1694   ares_htable_vpstr_destroy(h);
1695 }
1696 
1697 
1698 typedef struct {
1699   char s[32];
1700 } test_htable_strvp_t;
1701 
TEST_F(LibraryTest,HtableStrvp)1702 TEST_F(LibraryTest, HtableStrvp) {
1703   ares_llist_t        *l = NULL;
1704   ares_htable_strvp_t *h = NULL;
1705   ares_llist_node_t   *n = NULL;
1706   size_t                i;
1707 
1708 #define STRVP_TABLE_SIZE 1000
1709 
1710   l = ares_llist_create(NULL);
1711   EXPECT_NE((void *)NULL, l);
1712 
1713   h = ares_htable_strvp_create(ares_free);
1714   EXPECT_NE((void *)NULL, h);
1715 
1716   for (i=0; i<STRVP_TABLE_SIZE; i++) {
1717     test_htable_strvp_t *s = (test_htable_strvp_t *)ares_malloc_zero(sizeof(*s));
1718     EXPECT_NE((void *)NULL, s);
1719     snprintf(s->s, sizeof(s->s), "%d", (int)i);
1720     EXPECT_NE((void *)NULL, ares_llist_insert_last(l, s));
1721     EXPECT_TRUE(ares_htable_strvp_insert(h, s->s, s));
1722   }
1723 
1724   EXPECT_EQ(STRVP_TABLE_SIZE, ares_llist_len(l));
1725   EXPECT_EQ(STRVP_TABLE_SIZE, ares_htable_strvp_num_keys(h));
1726 
1727   n = ares_llist_node_first(l);
1728   EXPECT_NE((void *)NULL, n);
1729   while (n != NULL) {
1730     ares_llist_node_t *next = ares_llist_node_next(n);
1731     test_htable_strvp_t *s   = (test_htable_strvp_t *)ares_llist_node_val(n);
1732     EXPECT_NE((void *)NULL, s);
1733     EXPECT_EQ(s, ares_htable_strvp_get_direct(h, s->s));
1734     EXPECT_TRUE(ares_htable_strvp_get(h, s->s, NULL));
1735     EXPECT_TRUE(ares_htable_strvp_remove(h, s->s));
1736     ares_llist_node_destroy(n);
1737     n = next;
1738   }
1739 
1740   EXPECT_EQ(0, ares_llist_len(l));
1741   EXPECT_EQ(0, ares_htable_strvp_num_keys(h));
1742 
1743   ares_llist_destroy(l);
1744   ares_htable_strvp_destroy(h);
1745 }
1746 
TEST_F(LibraryTest,HtableDict)1747 TEST_F(LibraryTest, HtableDict) {
1748   ares_htable_dict_t  *h = NULL;
1749   size_t               i;
1750   char               **keys;
1751   size_t               nkeys;
1752 
1753 #define DICT_TABLE_SIZE 1000
1754 
1755   h = ares_htable_dict_create();
1756   EXPECT_NE((void *)NULL, h);
1757 
1758   for (i=0; i<DICT_TABLE_SIZE; i++) {
1759     char key[32];
1760     char val[32];
1761     snprintf(key, sizeof(key), "%d", (int)i);
1762     snprintf(val, sizeof(val), "val%d", (int)i);
1763     EXPECT_TRUE(ares_htable_dict_insert(h, key, val));
1764   }
1765 
1766   EXPECT_EQ(DICT_TABLE_SIZE, ares_htable_dict_num_keys(h));
1767 
1768   keys = ares_htable_dict_keys(h, &nkeys);
1769   for (i=0; i<nkeys; i++) {
1770     char val[32];
1771     snprintf(val, sizeof(val), "val%s", keys[i]);
1772     EXPECT_STREQ(val, ares_htable_dict_get_direct(h, keys[i]));
1773     EXPECT_TRUE(ares_htable_dict_get(h, keys[i], NULL));
1774     EXPECT_TRUE(ares_htable_dict_remove(h, keys[i]));
1775   }
1776   ares_free_array(keys, nkeys, ares_free);
1777 
1778   EXPECT_EQ(0, ares_htable_dict_num_keys(h));
1779 
1780   ares_htable_dict_destroy(h);
1781 }
1782 
TEST_F(DefaultChannelTest,SaveInvalidChannel)1783 TEST_F(DefaultChannelTest, SaveInvalidChannel) {
1784   ares_slist_t *saved = channel_->servers;
1785   channel_->servers = NULL;
1786   struct ares_options opts;
1787   int optmask = 0;
1788   EXPECT_EQ(ARES_ENODATA, ares_save_options(channel_, &opts, &optmask));
1789   channel_->servers = saved;
1790 }
1791 
1792 // Need to put this in own function due to nested lambda bug
1793 // in VS2013. (C2888)
configure_socket(ares_socket_t s)1794 static int configure_socket(ares_socket_t s) {
1795   // transposed from ares-process, simplified non-block setter.
1796 #if defined(USE_BLOCKING_SOCKETS)
1797   return 0; /* returns success */
1798 #elif defined(HAVE_FCNTL_O_NONBLOCK)
1799   /* most recent unix versions */
1800   int flags;
1801   flags = fcntl(s, F_GETFL, 0);
1802   return fcntl(s, F_SETFL, flags | O_NONBLOCK);
1803 #elif defined(HAVE_IOCTL_FIONBIO)
1804   /* older unix versions */
1805   int flags = 1;
1806   return ioctl(s, FIONBIO, &flags);
1807 #elif defined(HAVE_IOCTLSOCKET_FIONBIO)
1808 #ifdef WATT32
1809   char flags = 1;
1810 #else
1811   /* Windows */
1812   unsigned long flags = 1UL;
1813 #endif
1814   return ioctlsocket(s, (long)FIONBIO, &flags);
1815 #elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO)
1816   /* Amiga */
1817   long flags = 1L;
1818   return IoctlSocket(s, FIONBIO, flags);
1819 #elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK)
1820   /* BeOS */
1821   long b = 1L;
1822   return setsockopt(s, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
1823 #else
1824 #  error "no non-blocking method was found/used/set"
1825 #endif
1826 }
1827 
1828 // TODO: This should not really be in this file, but we need ares config
1829 // flags, and here they are available.
1830 const struct ares_socket_functions VirtualizeIO::default_functions = {
__anon6cf070860902(int af, int type, int protocol, void *) 1831   [](int af, int type, int protocol, void *) -> ares_socket_t {
1832     auto s = ::socket(af, type, protocol);
1833     if (s == ARES_SOCKET_BAD) {
1834       return s;
1835     }
1836     if (configure_socket(s) != 0) {
1837       sclose(s);
1838       return ares_socket_t(-1);
1839     }
1840     return s;
1841   },
1842   NULL,
1843   NULL,
1844   NULL,
1845   NULL
1846 };
1847 
1848 
1849 }  // namespace test
1850 }  // namespace ares
1851