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