1 | /* |
2 | Copyright (c) 2018 Contributors as noted in the AUTHORS file |
3 | |
4 | This file is part of 0MQ. |
5 | |
6 | 0MQ is free software; you can redistribute it and/or modify it under |
7 | the terms of the GNU Lesser General Public License as published by |
8 | the Free Software Foundation; either version 3 of the License, or |
9 | (at your option) any later version. |
10 | |
11 | 0MQ is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | GNU Lesser General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU Lesser General Public License |
17 | along with this program. If not, see <http://www.gnu.org/licenses/>. |
18 | */ |
19 | |
20 | #include <unity.h> |
21 | #include "../tests/testutil.hpp" |
22 | #include "../tests/testutil_unity.hpp" |
23 | #include "../unittests/unittest_resolver_common.hpp" |
24 | |
25 | #include <ip_resolver.hpp> |
26 | #include <ip.hpp> |
27 | |
28 | #ifndef _WIN32 |
29 | #include <sys/types.h> |
30 | #include <sys/socket.h> |
31 | #include <netdb.h> |
32 | #endif |
33 | |
34 | void setUp () |
35 | { |
36 | } |
37 | |
38 | void tearDown () |
39 | { |
40 | } |
41 | |
42 | class test_ip_resolver_t : public zmq::ip_resolver_t |
43 | { |
44 | public: |
45 | test_ip_resolver_t (zmq::ip_resolver_options_t opts_) : |
46 | ip_resolver_t (opts_) |
47 | { |
48 | } |
49 | |
50 | protected: |
51 | struct dns_lut_t |
52 | { |
53 | const char *hostname; |
54 | const char *ipv4; |
55 | const char *ipv6; |
56 | }; |
57 | |
58 | virtual int do_getaddrinfo (const char *node_, |
59 | const char *service_, |
60 | const struct addrinfo *hints_, |
61 | struct addrinfo **res_) |
62 | { |
63 | static const struct dns_lut_t dns_lut[] = { |
64 | {"ip.zeromq.org" , "10.100.0.1" , "fdf5:d058:d656::1" }, |
65 | {"ipv4only.zeromq.org" , "10.100.0.2" , "::ffff:10.100.0.2" }, |
66 | {"ipv6only.zeromq.org" , NULL, "fdf5:d058:d656::2" }, |
67 | }; |
68 | unsigned lut_len = sizeof (dns_lut) / sizeof (dns_lut[0]); |
69 | struct addrinfo ai; |
70 | |
71 | TEST_ASSERT_NULL (service_); |
72 | |
73 | bool ipv6 = (hints_->ai_family == AF_INET6); |
74 | bool no_dns = (hints_->ai_flags & AI_NUMERICHOST) != 0; |
75 | const char *ip = NULL; |
76 | |
77 | if (!no_dns) { |
78 | for (unsigned i = 0; i < lut_len; i++) { |
79 | if (strcmp (dns_lut[i].hostname, node_) == 0) { |
80 | if (ipv6) { |
81 | ip = dns_lut[i].ipv6; |
82 | } else { |
83 | ip = dns_lut[i].ipv4; |
84 | |
85 | if (ip == NULL) { |
86 | // No address associated with NAME |
87 | return EAI_NODATA; |
88 | } |
89 | } |
90 | } |
91 | } |
92 | } |
93 | |
94 | if (ip == NULL) { |
95 | // No entry for 'node_' found in the LUT (or DNS is |
96 | // forbidden), assume that it's a numeric IP address |
97 | ip = node_; |
98 | } |
99 | |
100 | // Call the real getaddrinfo implementation, making sure that it won't |
101 | // attempt to resolve using DNS |
102 | ai = *hints_; |
103 | ai.ai_flags |= AI_NUMERICHOST; |
104 | |
105 | return zmq::ip_resolver_t::do_getaddrinfo (ip, NULL, &ai, res_); |
106 | } |
107 | |
108 | virtual unsigned int do_if_nametoindex (const char *ifname_) |
109 | { |
110 | static const char *dummy_interfaces[] = { |
111 | "lo0" , |
112 | "eth0" , |
113 | "eth1" , |
114 | }; |
115 | unsigned lut_len = |
116 | sizeof (dummy_interfaces) / sizeof (dummy_interfaces[0]); |
117 | |
118 | for (unsigned i = 0; i < lut_len; i++) { |
119 | if (strcmp (dummy_interfaces[i], ifname_) == 0) { |
120 | // The dummy index will be the position in the array + 1 (0 is |
121 | // invalid) |
122 | return i + 1; |
123 | } |
124 | } |
125 | |
126 | // Not found |
127 | return 0; |
128 | } |
129 | }; |
130 | |
131 | // Attempt a resolution and test the results. If 'expected_addr_' is NULL |
132 | // assume that the resolution is meant to fail. |
133 | // |
134 | // On windows we can receive an IPv4 address even when an IPv6 is requested, if |
135 | // we're in this situation then we compare to 'expected_addr_v4_failover_' |
136 | // instead. |
137 | static void test_resolve (zmq::ip_resolver_options_t opts_, |
138 | const char *name_, |
139 | const char *expected_addr_, |
140 | uint16_t expected_port_ = 0, |
141 | uint16_t expected_zone_ = 0, |
142 | const char *expected_addr_v4_failover_ = NULL) |
143 | { |
144 | zmq::ip_addr_t addr; |
145 | int family = opts_.ipv6 () ? AF_INET6 : AF_INET; |
146 | |
147 | if (family == AF_INET6 && !is_ipv6_available ()) { |
148 | TEST_IGNORE_MESSAGE ("ipv6 is not available" ); |
149 | } |
150 | |
151 | // Generate an invalid but well-defined 'ip_addr_t'. Avoids testing |
152 | // uninitialized values if the code is buggy. |
153 | memset (&addr, 0xba, sizeof (addr)); |
154 | |
155 | test_ip_resolver_t resolver (opts_); |
156 | |
157 | int rc = resolver.resolve (&addr, name_); |
158 | |
159 | if (expected_addr_ == NULL) { |
160 | // TODO also check the expected errno |
161 | TEST_ASSERT_EQUAL (-1, rc); |
162 | return; |
163 | } |
164 | TEST_ASSERT_SUCCESS_ERRNO (rc); |
165 | |
166 | |
167 | validate_address (family, &addr, expected_addr_, expected_port_, |
168 | expected_zone_, expected_addr_v4_failover_); |
169 | } |
170 | |
171 | // Helper macro to define the v4/v6 function pairs |
172 | #define MAKE_TEST_V4V6(_test) \ |
173 | static void _test##_ipv4 () { _test (false); } \ |
174 | \ |
175 | static void _test##_ipv6 () { _test (true); } |
176 | |
177 | static void test_bind_any (bool ipv6_) |
178 | { |
179 | zmq::ip_resolver_options_t resolver_opts; |
180 | |
181 | resolver_opts.bindable (true).expect_port (true).ipv6 (ipv6_); |
182 | |
183 | const char *expected = ipv6_ ? "::" : "0.0.0.0" ; |
184 | test_resolve (resolver_opts, "*:*" , expected, 0); |
185 | } |
186 | MAKE_TEST_V4V6 (test_bind_any) |
187 | |
188 | static void test_bind_any_port0 (bool ipv6_) |
189 | { |
190 | zmq::ip_resolver_options_t resolver_opts; |
191 | |
192 | resolver_opts.bindable (true).expect_port (true).ipv6 (ipv6_); |
193 | |
194 | // Should be equivalent to "*:*" |
195 | const char *expected = ipv6_ ? "::" : "0.0.0.0" ; |
196 | test_resolve (resolver_opts, "*:0" , expected, 0); |
197 | } |
198 | MAKE_TEST_V4V6 (test_bind_any_port0) |
199 | |
200 | static void test_nobind_any (bool ipv6_) |
201 | { |
202 | zmq::ip_resolver_options_t resolver_opts; |
203 | |
204 | resolver_opts.expect_port (true).ipv6 (ipv6_); |
205 | |
206 | // Wildcard should be rejected if we're not looking for a |
207 | // bindable address |
208 | test_resolve (resolver_opts, "*:*" , NULL); |
209 | } |
210 | MAKE_TEST_V4V6 (test_nobind_any) |
211 | |
212 | static void test_nobind_any_port (bool ipv6_) |
213 | { |
214 | zmq::ip_resolver_options_t resolver_opts; |
215 | |
216 | resolver_opts.expect_port (true).ipv6 (ipv6_); |
217 | |
218 | // Wildcard should be rejected if we're not looking for a |
219 | // bindable address |
220 | test_resolve (resolver_opts, "*:1234" , NULL); |
221 | } |
222 | MAKE_TEST_V4V6 (test_nobind_any_port) |
223 | |
224 | static void test_nobind_addr_anyport (bool ipv6_) |
225 | { |
226 | zmq::ip_resolver_options_t resolver_opts; |
227 | |
228 | resolver_opts.expect_port (true).ipv6 (ipv6_); |
229 | |
230 | // Wildcard port should be rejected for non-bindable addresses |
231 | test_resolve (resolver_opts, "127.0.0.1:*" , NULL); |
232 | } |
233 | MAKE_TEST_V4V6 (test_nobind_addr_anyport) |
234 | |
235 | static void test_nobind_addr_port0 (bool ipv6_) |
236 | { |
237 | zmq::ip_resolver_options_t resolver_opts; |
238 | |
239 | resolver_opts.expect_port (true).ipv6 (ipv6_); |
240 | |
241 | // Connecting to port 0 is allowed, although it might not be massively |
242 | // useful |
243 | const char *expected = ipv6_ ? "::ffff:127.0.0.1" : "127.0.0.1" ; |
244 | const char *fallback = ipv6_ ? "127.0.0.1" : NULL; |
245 | test_resolve (resolver_opts, "127.0.0.1:0" , expected, 0, 0, fallback); |
246 | } |
247 | MAKE_TEST_V4V6 (test_nobind_addr_port0) |
248 | |
249 | static void test_parse_ipv4_simple () |
250 | { |
251 | zmq::ip_resolver_options_t resolver_opts; |
252 | |
253 | test_resolve (resolver_opts, "1.2.128.129" , "1.2.128.129" ); |
254 | } |
255 | |
256 | static void test_parse_ipv4_zero () |
257 | { |
258 | zmq::ip_resolver_options_t resolver_opts; |
259 | |
260 | test_resolve (resolver_opts, "0.0.0.0" , "0.0.0.0" ); |
261 | } |
262 | |
263 | static void test_parse_ipv4_max () |
264 | { |
265 | zmq::ip_resolver_options_t resolver_opts; |
266 | |
267 | test_resolve (resolver_opts, "255.255.255.255" , "255.255.255.255" ); |
268 | } |
269 | |
270 | static void test_parse_ipv4_brackets () |
271 | { |
272 | zmq::ip_resolver_options_t resolver_opts; |
273 | |
274 | // Not particularly useful, but valid |
275 | test_resolve (resolver_opts, "[1.2.128.129]" , "1.2.128.129" ); |
276 | } |
277 | |
278 | static void test_parse_ipv4_brackets_missingl () |
279 | { |
280 | zmq::ip_resolver_options_t resolver_opts; |
281 | |
282 | test_resolve (resolver_opts, "1.2.128.129]" , NULL); |
283 | } |
284 | |
285 | static void test_parse_ipv4_brackets_missingr () |
286 | { |
287 | zmq::ip_resolver_options_t resolver_opts; |
288 | |
289 | test_resolve (resolver_opts, "[1.2.128.129" , NULL); |
290 | } |
291 | |
292 | static void test_parse_ipv4_brackets_bad () |
293 | { |
294 | zmq::ip_resolver_options_t resolver_opts; |
295 | |
296 | test_resolve (resolver_opts, "[1.2.128].129" , NULL); |
297 | } |
298 | |
299 | static void test_parse_ipv4_reject_port () |
300 | { |
301 | zmq::ip_resolver_options_t resolver_opts; |
302 | |
303 | // No port expected, should be rejected |
304 | test_resolve (resolver_opts, "1.2.128.129:123" , NULL); |
305 | } |
306 | |
307 | static void test_parse_ipv4_reject_any () |
308 | { |
309 | zmq::ip_resolver_options_t resolver_opts; |
310 | |
311 | // No port expected, should be rejected |
312 | test_resolve (resolver_opts, "1.2.128.129:*" , NULL); |
313 | } |
314 | |
315 | static void test_parse_ipv4_reject_ipv6 () |
316 | { |
317 | zmq::ip_resolver_options_t resolver_opts; |
318 | |
319 | // No port expected, should be rejected |
320 | test_resolve (resolver_opts, "::1" , NULL); |
321 | } |
322 | |
323 | static void test_parse_ipv4_port () |
324 | { |
325 | zmq::ip_resolver_options_t resolver_opts; |
326 | |
327 | resolver_opts.expect_port (true); |
328 | |
329 | test_resolve (resolver_opts, "1.2.128.129:123" , "1.2.128.129" , 123); |
330 | } |
331 | |
332 | static void test_parse_ipv4_port0 () |
333 | { |
334 | zmq::ip_resolver_options_t resolver_opts; |
335 | |
336 | resolver_opts.expect_port (true); |
337 | |
338 | // Port 0 is accepted and is equivalent to * |
339 | test_resolve (resolver_opts, "1.2.128.129:0" , "1.2.128.129" , 0); |
340 | } |
341 | |
342 | static void test_parse_ipv4_port_garbage () |
343 | { |
344 | zmq::ip_resolver_options_t resolver_opts; |
345 | |
346 | resolver_opts.expect_port (true); |
347 | |
348 | // The code doesn't validate that the port doesn't contain garbage |
349 | test_resolve (resolver_opts, "1.2.3.4:567bad" , "1.2.3.4" , 567); |
350 | } |
351 | |
352 | static void test_parse_ipv4_port_missing () |
353 | { |
354 | zmq::ip_resolver_options_t resolver_opts; |
355 | |
356 | resolver_opts.expect_port (true); |
357 | |
358 | test_resolve (resolver_opts, "1.2.3.4" , NULL); |
359 | } |
360 | |
361 | static void test_parse_ipv4_port_bad () |
362 | { |
363 | zmq::ip_resolver_options_t resolver_opts; |
364 | |
365 | resolver_opts.expect_port (true); |
366 | |
367 | test_resolve (resolver_opts, "1.2.3.4:bad" , NULL); |
368 | } |
369 | |
370 | static void test_parse_ipv4_port_brackets () |
371 | { |
372 | zmq::ip_resolver_options_t resolver_opts; |
373 | |
374 | resolver_opts.expect_port (true); |
375 | |
376 | test_resolve (resolver_opts, "[192.168.1.1]:5555" , "192.168.1.1" , 5555); |
377 | } |
378 | |
379 | static void test_parse_ipv4_port_brackets_bad () |
380 | { |
381 | zmq::ip_resolver_options_t resolver_opts; |
382 | |
383 | resolver_opts.expect_port (true); |
384 | |
385 | test_resolve (resolver_opts, "[192.168.1.1:]5555" , NULL); |
386 | } |
387 | |
388 | static void test_parse_ipv4_port_brackets_bad2 () |
389 | { |
390 | zmq::ip_resolver_options_t resolver_opts; |
391 | |
392 | resolver_opts.expect_port (true); |
393 | |
394 | test_resolve (resolver_opts, "[192.168.1.1:5555]" , NULL); |
395 | } |
396 | |
397 | static void test_parse_ipv4_wild_brackets_bad () |
398 | { |
399 | zmq::ip_resolver_options_t resolver_opts; |
400 | |
401 | resolver_opts.expect_port (true); |
402 | |
403 | test_resolve (resolver_opts, "[192.168.1.1:*]" , NULL); |
404 | } |
405 | |
406 | static void test_parse_ipv4_port_ipv6_reject () |
407 | { |
408 | zmq::ip_resolver_options_t resolver_opts; |
409 | |
410 | resolver_opts.expect_port (true); |
411 | |
412 | test_resolve (resolver_opts, "[::1]:1234" , NULL); |
413 | } |
414 | |
415 | static void test_parse_ipv6_simple () |
416 | { |
417 | zmq::ip_resolver_options_t resolver_opts; |
418 | |
419 | resolver_opts.ipv6 (true); |
420 | |
421 | test_resolve (resolver_opts, "::1" , "::1" ); |
422 | } |
423 | |
424 | static void test_parse_ipv6_simple2 () |
425 | { |
426 | zmq::ip_resolver_options_t resolver_opts; |
427 | |
428 | resolver_opts.ipv6 (true); |
429 | |
430 | test_resolve (resolver_opts, "abcd:1234::1:0:234" , "abcd:1234::1:0:234" ); |
431 | } |
432 | |
433 | static void test_parse_ipv6_zero () |
434 | { |
435 | zmq::ip_resolver_options_t resolver_opts; |
436 | |
437 | resolver_opts.ipv6 (true); |
438 | |
439 | test_resolve (resolver_opts, "::" , "::" ); |
440 | } |
441 | |
442 | static void test_parse_ipv6_max () |
443 | { |
444 | zmq::ip_resolver_options_t resolver_opts; |
445 | |
446 | resolver_opts.ipv6 (true); |
447 | |
448 | test_resolve (resolver_opts, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" , |
449 | "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" ); |
450 | } |
451 | |
452 | static void test_parse_ipv6_brackets () |
453 | { |
454 | zmq::ip_resolver_options_t resolver_opts; |
455 | |
456 | resolver_opts.ipv6 (true); |
457 | |
458 | test_resolve (resolver_opts, "[::1]" , "::1" ); |
459 | } |
460 | |
461 | static void test_parse_ipv6_brackets_missingl () |
462 | { |
463 | zmq::ip_resolver_options_t resolver_opts; |
464 | |
465 | resolver_opts.ipv6 (true); |
466 | |
467 | test_resolve (resolver_opts, "::1]" , NULL); |
468 | } |
469 | |
470 | static void test_parse_ipv6_brackets_missingr () |
471 | { |
472 | zmq::ip_resolver_options_t resolver_opts; |
473 | |
474 | resolver_opts.ipv6 (true); |
475 | |
476 | test_resolve (resolver_opts, "[::1" , NULL); |
477 | } |
478 | |
479 | static void test_parse_ipv6_brackets_bad () |
480 | { |
481 | zmq::ip_resolver_options_t resolver_opts; |
482 | |
483 | resolver_opts.ipv6 (true); |
484 | |
485 | test_resolve (resolver_opts, "[abcd:1234::1:]0:234" , NULL); |
486 | } |
487 | |
488 | static void test_parse_ipv6_port () |
489 | { |
490 | zmq::ip_resolver_options_t resolver_opts; |
491 | |
492 | resolver_opts.ipv6 (true).expect_port (true); |
493 | |
494 | test_resolve (resolver_opts, "[1234::1]:80" , "1234::1" , 80); |
495 | } |
496 | |
497 | static void test_parse_ipv6_port_any () |
498 | { |
499 | zmq::ip_resolver_options_t resolver_opts; |
500 | |
501 | resolver_opts.ipv6 (true).expect_port (true).bindable (true); |
502 | |
503 | test_resolve (resolver_opts, "[1234::1]:*" , "1234::1" , 0); |
504 | } |
505 | |
506 | static void test_parse_ipv6_port_nobrackets () |
507 | { |
508 | zmq::ip_resolver_options_t resolver_opts; |
509 | |
510 | resolver_opts.ipv6 (true).expect_port (true); |
511 | |
512 | // Should this be allowed? Seems error-prone but so far ZMQ accepts it. |
513 | test_resolve (resolver_opts, "abcd:1234::1:0:234:123" , "abcd:1234::1:0:234" , |
514 | 123); |
515 | } |
516 | |
517 | static void test_parse_ipv4_in_ipv6 () |
518 | { |
519 | zmq::ip_resolver_options_t resolver_opts; |
520 | |
521 | resolver_opts.ipv6 (true); |
522 | |
523 | // Parsing IPv4 should also work if an IPv6 is requested, it returns an |
524 | // IPv6 with the IPv4 address embedded (except sometimes on Windows where |
525 | // we end up with an IPv4 anyway) |
526 | test_resolve (resolver_opts, "11.22.33.44" , "::ffff:11.22.33.44" , 0, 0, |
527 | "11.22.33.44" ); |
528 | } |
529 | |
530 | static void test_parse_ipv4_in_ipv6_port () |
531 | { |
532 | zmq::ip_resolver_options_t resolver_opts; |
533 | |
534 | resolver_opts.ipv6 (true).expect_port (true); |
535 | |
536 | test_resolve (resolver_opts, "11.22.33.44:55" , "::ffff:11.22.33.44" , 55, 0, |
537 | "11.22.33.44" ); |
538 | } |
539 | |
540 | static void test_parse_ipv6_scope_int () |
541 | { |
542 | zmq::ip_resolver_options_t resolver_opts; |
543 | |
544 | resolver_opts.ipv6 (true); |
545 | |
546 | test_resolve (resolver_opts, "3000:4:5::1:234%2" , "3000:4:5::1:234" , 0, 2); |
547 | } |
548 | |
549 | static void test_parse_ipv6_scope_zero () |
550 | { |
551 | zmq::ip_resolver_options_t resolver_opts; |
552 | |
553 | resolver_opts.ipv6 (true); |
554 | |
555 | test_resolve (resolver_opts, "3000:4:5::1:234%0" , NULL); |
556 | } |
557 | |
558 | static void test_parse_ipv6_scope_int_port () |
559 | { |
560 | zmq::ip_resolver_options_t resolver_opts; |
561 | |
562 | resolver_opts.expect_port (true).ipv6 (true); |
563 | |
564 | test_resolve (resolver_opts, "3000:4:5::1:234%2:1111" , "3000:4:5::1:234" , |
565 | 1111, 2); |
566 | } |
567 | |
568 | static void test_parse_ipv6_scope_if () |
569 | { |
570 | zmq::ip_resolver_options_t resolver_opts; |
571 | |
572 | resolver_opts.ipv6 (true); |
573 | |
574 | test_resolve (resolver_opts, "3000:4:5::1:234%eth1" , "3000:4:5::1:234" , 0, |
575 | 3); |
576 | } |
577 | |
578 | static void test_parse_ipv6_scope_if_port () |
579 | { |
580 | zmq::ip_resolver_options_t resolver_opts; |
581 | |
582 | resolver_opts.expect_port (true).ipv6 (true); |
583 | |
584 | test_resolve (resolver_opts, "3000:4:5::1:234%eth0:8080" , "3000:4:5::1:234" , |
585 | 8080, 2); |
586 | } |
587 | |
588 | static void test_parse_ipv6_scope_if_port_brackets () |
589 | { |
590 | zmq::ip_resolver_options_t resolver_opts; |
591 | |
592 | resolver_opts.expect_port (true).ipv6 (true); |
593 | |
594 | test_resolve (resolver_opts, "[3000:4:5::1:234%eth0]:8080" , |
595 | "3000:4:5::1:234" , 8080, 2); |
596 | } |
597 | |
598 | static void test_parse_ipv6_scope_badif () |
599 | { |
600 | zmq::ip_resolver_options_t resolver_opts; |
601 | |
602 | resolver_opts.ipv6 (true); |
603 | |
604 | test_resolve (resolver_opts, "3000:4:5::1:234%bad0" , NULL); |
605 | } |
606 | |
607 | static void test_dns_ipv4_simple () |
608 | { |
609 | zmq::ip_resolver_options_t resolver_opts; |
610 | |
611 | resolver_opts.allow_dns (true); |
612 | |
613 | test_resolve (resolver_opts, "ip.zeromq.org" , "10.100.0.1" ); |
614 | } |
615 | |
616 | static void test_dns_ipv4_only () |
617 | { |
618 | zmq::ip_resolver_options_t resolver_opts; |
619 | |
620 | resolver_opts.allow_dns (true); |
621 | |
622 | test_resolve (resolver_opts, "ipv4only.zeromq.org" , "10.100.0.2" ); |
623 | } |
624 | |
625 | static void test_dns_ipv4_invalid () |
626 | { |
627 | zmq::ip_resolver_options_t resolver_opts; |
628 | |
629 | resolver_opts.allow_dns (true); |
630 | |
631 | test_resolve (resolver_opts, "invalid.zeromq.org" , NULL); |
632 | } |
633 | |
634 | static void test_dns_ipv4_ipv6 () |
635 | { |
636 | zmq::ip_resolver_options_t resolver_opts; |
637 | |
638 | resolver_opts.allow_dns (true); |
639 | |
640 | test_resolve (resolver_opts, "ipv6only.zeromq.org" , NULL); |
641 | } |
642 | |
643 | static void test_dns_ipv4_numeric () |
644 | { |
645 | zmq::ip_resolver_options_t resolver_opts; |
646 | |
647 | resolver_opts.allow_dns (true); |
648 | |
649 | // Numeric IPs should still work |
650 | test_resolve (resolver_opts, "5.4.3.2" , "5.4.3.2" ); |
651 | } |
652 | |
653 | static void test_dns_ipv4_port () |
654 | { |
655 | zmq::ip_resolver_options_t resolver_opts; |
656 | |
657 | resolver_opts.expect_port (true).allow_dns (true); |
658 | |
659 | test_resolve (resolver_opts, "ip.zeromq.org:1234" , "10.100.0.1" , 1234); |
660 | } |
661 | |
662 | static void test_dns_ipv6_simple () |
663 | { |
664 | zmq::ip_resolver_options_t resolver_opts; |
665 | |
666 | resolver_opts.ipv6 (true).allow_dns (true); |
667 | |
668 | test_resolve (resolver_opts, "ip.zeromq.org" , "fdf5:d058:d656::1" ); |
669 | } |
670 | |
671 | static void test_dns_ipv6_only () |
672 | { |
673 | zmq::ip_resolver_options_t resolver_opts; |
674 | |
675 | resolver_opts.ipv6 (true).allow_dns (true); |
676 | |
677 | test_resolve (resolver_opts, "ipv6only.zeromq.org" , "fdf5:d058:d656::2" ); |
678 | } |
679 | |
680 | static void test_dns_ipv6_invalid () |
681 | { |
682 | zmq::ip_resolver_options_t resolver_opts; |
683 | |
684 | resolver_opts.ipv6 (true).allow_dns (true); |
685 | |
686 | test_resolve (resolver_opts, "invalid.zeromq.org" , NULL); |
687 | } |
688 | |
689 | static void test_dns_ipv6_ipv4 () |
690 | { |
691 | zmq::ip_resolver_options_t resolver_opts; |
692 | |
693 | resolver_opts.ipv6 (true).allow_dns (true); |
694 | |
695 | // If a host doesn't have an IPv6 then it should resolve as an embedded v4 |
696 | // address in an IPv6 |
697 | test_resolve (resolver_opts, "ipv4only.zeromq.org" , "::ffff:10.100.0.2" ); |
698 | } |
699 | |
700 | static void test_dns_ipv6_numeric () |
701 | { |
702 | zmq::ip_resolver_options_t resolver_opts; |
703 | |
704 | resolver_opts.ipv6 (true).allow_dns (true); |
705 | |
706 | // Numeric IPs should still work |
707 | test_resolve (resolver_opts, "fdf5:d058:d656::1" , "fdf5:d058:d656::1" ); |
708 | } |
709 | |
710 | static void test_dns_ipv6_port () |
711 | { |
712 | zmq::ip_resolver_options_t resolver_opts; |
713 | |
714 | resolver_opts.ipv6 (true).expect_port (true).allow_dns (true); |
715 | |
716 | test_resolve (resolver_opts, "ip.zeromq.org:1234" , "fdf5:d058:d656::1" , |
717 | 1234); |
718 | } |
719 | |
720 | void test_dns_brackets () |
721 | { |
722 | zmq::ip_resolver_options_t resolver_opts; |
723 | |
724 | resolver_opts.allow_dns (true); |
725 | |
726 | test_resolve (resolver_opts, "[ip.zeromq.org]" , "10.100.0.1" ); |
727 | } |
728 | |
729 | void test_dns_brackets_bad () |
730 | { |
731 | zmq::ip_resolver_options_t resolver_opts; |
732 | |
733 | resolver_opts.allow_dns (true); |
734 | |
735 | test_resolve (resolver_opts, "[ip.zeromq].org" , NULL); |
736 | } |
737 | |
738 | void test_dns_brackets_port () |
739 | { |
740 | zmq::ip_resolver_options_t resolver_opts; |
741 | |
742 | resolver_opts.allow_dns (true); |
743 | |
744 | test_resolve (resolver_opts, "[ip.zeromq.org]:22" , "10.100.0.1" , 22); |
745 | } |
746 | |
747 | void test_dns_brackets_port_bad () |
748 | { |
749 | zmq::ip_resolver_options_t resolver_opts; |
750 | |
751 | resolver_opts.allow_dns (true); |
752 | |
753 | test_resolve (resolver_opts, "[ip.zeromq.org:22]" , NULL); |
754 | } |
755 | |
756 | void test_dns_deny (bool ipv6_) |
757 | { |
758 | zmq::ip_resolver_options_t resolver_opts; |
759 | |
760 | resolver_opts.allow_dns (false).ipv6 (ipv6_); |
761 | |
762 | // DNS resolution shouldn't work when disallowed |
763 | test_resolve (resolver_opts, "ip.zeromq.org" , NULL); |
764 | } |
765 | MAKE_TEST_V4V6 (test_dns_deny) |
766 | |
767 | void test_dns_ipv6_scope () |
768 | { |
769 | zmq::ip_resolver_options_t resolver_opts; |
770 | |
771 | resolver_opts.allow_dns (true).ipv6 (true); |
772 | |
773 | // Not sure if that's very useful but you could technically add a scope |
774 | // identifier to a hostname |
775 | test_resolve (resolver_opts, "ip.zeromq.org%lo0" , "fdf5:d058:d656::1" , 0, |
776 | 1); |
777 | } |
778 | |
779 | void test_dns_ipv6_scope_port () |
780 | { |
781 | zmq::ip_resolver_options_t resolver_opts; |
782 | |
783 | resolver_opts.allow_dns (true).expect_port (true).ipv6 (true); |
784 | |
785 | // Not sure if that's very useful but you could technically add a scope |
786 | // identifier to a hostname |
787 | test_resolve (resolver_opts, "ip.zeromq.org%lo0:4444" , "fdf5:d058:d656::1" , |
788 | 4444, 1); |
789 | } |
790 | |
791 | void test_dns_ipv6_scope_port_brackets () |
792 | { |
793 | zmq::ip_resolver_options_t resolver_opts; |
794 | |
795 | resolver_opts.allow_dns (true).expect_port (true).ipv6 (true); |
796 | |
797 | test_resolve (resolver_opts, "[ip.zeromq.org%lo0]:4444" , |
798 | "fdf5:d058:d656::1" , 4444, 1); |
799 | } |
800 | |
801 | static void test_addr (int family_, const char *addr_, bool multicast_) |
802 | { |
803 | if (family_ == AF_INET6 && !is_ipv6_available ()) { |
804 | TEST_IGNORE_MESSAGE ("ipv6 is not available" ); |
805 | } |
806 | |
807 | zmq::ip_resolver_options_t resolver_opts; |
808 | |
809 | resolver_opts.ipv6 (family_ == AF_INET6); |
810 | |
811 | test_ip_resolver_t resolver (resolver_opts); |
812 | zmq::ip_addr_t addr; |
813 | |
814 | TEST_ASSERT_SUCCESS_ERRNO (resolver.resolve (&addr, addr_)); |
815 | |
816 | TEST_ASSERT_EQUAL (family_, addr.family ()); |
817 | TEST_ASSERT_EQUAL (multicast_, addr.is_multicast ()); |
818 | } |
819 | |
820 | static void test_addr_unicast_ipv4 () |
821 | { |
822 | test_addr (AF_INET, "1.2.3.4" , false); |
823 | } |
824 | |
825 | static void test_addr_unicast_ipv6 () |
826 | { |
827 | test_addr (AF_INET6, "abcd::1" , false); |
828 | } |
829 | |
830 | static void test_addr_multicast_ipv4 () |
831 | { |
832 | test_addr (AF_INET, "230.1.2.3" , true); |
833 | } |
834 | |
835 | static void test_addr_multicast_ipv6 () |
836 | { |
837 | test_addr (AF_INET6, "ffab::1234" , true); |
838 | } |
839 | |
840 | static void test_addr_multicast_ipv4_min () |
841 | { |
842 | test_addr (AF_INET, "224.0.0.0" , true); |
843 | } |
844 | |
845 | static void test_addr_multicast_ipv6_min () |
846 | { |
847 | test_addr (AF_INET6, "ff00::" , true); |
848 | } |
849 | |
850 | static void test_addr_multicast_ipv4_max () |
851 | { |
852 | test_addr (AF_INET, "239.255.255.255" , true); |
853 | } |
854 | |
855 | static void test_addr_multicast_ipv6_max () |
856 | { |
857 | test_addr (AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" , true); |
858 | } |
859 | |
860 | static void test_addr_multicast_ipv4_sub () |
861 | { |
862 | test_addr (AF_INET, "223.255.255.255" , false); |
863 | } |
864 | |
865 | static void test_addr_multicast_ipv6_sub () |
866 | { |
867 | test_addr (AF_INET6, "feff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" , false); |
868 | } |
869 | |
870 | static void test_addr_multicast_ipv4_over () |
871 | { |
872 | test_addr (AF_INET, "240.0.0.0" , false); |
873 | } |
874 | |
875 | int main (void) |
876 | { |
877 | zmq::initialize_network (); |
878 | setup_test_environment (); |
879 | |
880 | UNITY_BEGIN (); |
881 | |
882 | RUN_TEST (test_bind_any_ipv4); |
883 | RUN_TEST (test_bind_any_ipv6); |
884 | RUN_TEST (test_bind_any_port0_ipv4); |
885 | RUN_TEST (test_bind_any_port0_ipv6); |
886 | RUN_TEST (test_nobind_any_ipv4); |
887 | RUN_TEST (test_nobind_any_ipv6); |
888 | RUN_TEST (test_nobind_any_port_ipv4); |
889 | RUN_TEST (test_nobind_any_port_ipv6); |
890 | RUN_TEST (test_nobind_addr_anyport_ipv4); |
891 | RUN_TEST (test_nobind_addr_anyport_ipv6); |
892 | RUN_TEST (test_nobind_addr_port0_ipv4); |
893 | RUN_TEST (test_nobind_addr_port0_ipv6); |
894 | RUN_TEST (test_parse_ipv4_simple); |
895 | RUN_TEST (test_parse_ipv4_zero); |
896 | RUN_TEST (test_parse_ipv4_max); |
897 | RUN_TEST (test_parse_ipv4_brackets); |
898 | RUN_TEST (test_parse_ipv4_brackets_missingl); |
899 | RUN_TEST (test_parse_ipv4_brackets_missingr); |
900 | RUN_TEST (test_parse_ipv4_brackets_bad); |
901 | RUN_TEST (test_parse_ipv4_reject_port); |
902 | RUN_TEST (test_parse_ipv4_reject_any); |
903 | RUN_TEST (test_parse_ipv4_reject_ipv6); |
904 | RUN_TEST (test_parse_ipv4_port); |
905 | RUN_TEST (test_parse_ipv4_port0); |
906 | RUN_TEST (test_parse_ipv4_port_garbage); |
907 | RUN_TEST (test_parse_ipv4_port_missing); |
908 | RUN_TEST (test_parse_ipv4_port_bad); |
909 | RUN_TEST (test_parse_ipv4_port_brackets); |
910 | RUN_TEST (test_parse_ipv4_port_brackets_bad); |
911 | RUN_TEST (test_parse_ipv4_port_brackets_bad2); |
912 | RUN_TEST (test_parse_ipv4_wild_brackets_bad); |
913 | RUN_TEST (test_parse_ipv4_port_ipv6_reject); |
914 | RUN_TEST (test_parse_ipv6_simple); |
915 | RUN_TEST (test_parse_ipv6_simple2); |
916 | RUN_TEST (test_parse_ipv6_zero); |
917 | RUN_TEST (test_parse_ipv6_max); |
918 | RUN_TEST (test_parse_ipv6_brackets); |
919 | RUN_TEST (test_parse_ipv6_brackets_missingl); |
920 | RUN_TEST (test_parse_ipv6_brackets_missingr); |
921 | RUN_TEST (test_parse_ipv6_brackets_bad); |
922 | RUN_TEST (test_parse_ipv6_port); |
923 | RUN_TEST (test_parse_ipv6_port_any); |
924 | RUN_TEST (test_parse_ipv6_port_nobrackets); |
925 | RUN_TEST (test_parse_ipv4_in_ipv6); |
926 | RUN_TEST (test_parse_ipv4_in_ipv6_port); |
927 | RUN_TEST (test_parse_ipv6_scope_int); |
928 | RUN_TEST (test_parse_ipv6_scope_zero); |
929 | RUN_TEST (test_parse_ipv6_scope_int_port); |
930 | RUN_TEST (test_parse_ipv6_scope_if); |
931 | RUN_TEST (test_parse_ipv6_scope_if_port); |
932 | RUN_TEST (test_parse_ipv6_scope_if_port_brackets); |
933 | RUN_TEST (test_parse_ipv6_scope_badif); |
934 | RUN_TEST (test_dns_ipv4_simple); |
935 | RUN_TEST (test_dns_ipv4_only); |
936 | RUN_TEST (test_dns_ipv4_invalid); |
937 | RUN_TEST (test_dns_ipv4_ipv6); |
938 | RUN_TEST (test_dns_ipv4_numeric); |
939 | RUN_TEST (test_dns_ipv4_port); |
940 | RUN_TEST (test_dns_ipv6_simple); |
941 | RUN_TEST (test_dns_ipv6_only); |
942 | RUN_TEST (test_dns_ipv6_invalid); |
943 | RUN_TEST (test_dns_ipv6_ipv4); |
944 | RUN_TEST (test_dns_ipv6_numeric); |
945 | RUN_TEST (test_dns_ipv6_port); |
946 | RUN_TEST (test_dns_brackets); |
947 | RUN_TEST (test_dns_brackets_bad); |
948 | RUN_TEST (test_dns_deny_ipv4); |
949 | RUN_TEST (test_dns_deny_ipv6); |
950 | RUN_TEST (test_dns_ipv6_scope); |
951 | RUN_TEST (test_dns_ipv6_scope_port); |
952 | RUN_TEST (test_dns_ipv6_scope_port_brackets); |
953 | RUN_TEST (test_addr_unicast_ipv4); |
954 | RUN_TEST (test_addr_unicast_ipv6); |
955 | RUN_TEST (test_addr_multicast_ipv4); |
956 | RUN_TEST (test_addr_multicast_ipv6); |
957 | RUN_TEST (test_addr_multicast_ipv4_min); |
958 | RUN_TEST (test_addr_multicast_ipv6_min); |
959 | RUN_TEST (test_addr_multicast_ipv4_max); |
960 | RUN_TEST (test_addr_multicast_ipv6_max); |
961 | RUN_TEST (test_addr_multicast_ipv4_sub); |
962 | RUN_TEST (test_addr_multicast_ipv6_sub); |
963 | RUN_TEST (test_addr_multicast_ipv4_over); |
964 | |
965 | zmq::shutdown_network (); |
966 | |
967 | return UNITY_END (); |
968 | } |
969 | |