1/*
2Copyright (c) 2018 Contributors as noted in the AUTHORS file
3
4This file is part of 0MQ.
5
60MQ is free software; you can redistribute it and/or modify it under
7the terms of the GNU Lesser General Public License as published by
8the Free Software Foundation; either version 3 of the License, or
9(at your option) any later version.
10
110MQ is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU Lesser General Public License for more details.
15
16You should have received a copy of the GNU Lesser General Public License
17along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#include <unity.h>
21#include "../tests/testutil.hpp"
22#include "../unittests/unittest_resolver_common.hpp"
23
24#include <ip.hpp>
25#include <udp_address.hpp>
26
27void setUp ()
28{
29}
30
31void tearDown ()
32{
33}
34
35// Test an UDP address resolution. If 'dest_addr_' is NULL assume the
36// resolution is supposed to fail.
37static void test_resolve (bool bind_,
38 int family_,
39 const char *name_,
40 const char *target_addr_,
41 uint16_t expected_port_,
42 const char *bind_addr_,
43 bool multicast_)
44{
45 if (family_ == AF_INET6 && !is_ipv6_available ()) {
46 TEST_IGNORE_MESSAGE ("ipv6 is not available");
47 }
48
49 zmq::udp_address_t addr;
50
51 int rc = addr.resolve (name_, bind_, family_ == AF_INET6);
52
53 if (target_addr_ == NULL) {
54 TEST_ASSERT_EQUAL (-1, rc);
55 TEST_ASSERT_EQUAL (EINVAL, errno);
56 return;
57 }
58 TEST_ASSERT_EQUAL (0, rc);
59
60
61 TEST_ASSERT_EQUAL (multicast_, addr.is_mcast ());
62
63 if (bind_addr_ == NULL) {
64 // Bind ANY
65 if (family_ == AF_INET) {
66 bind_addr_ = "0.0.0.0";
67 } else {
68 bind_addr_ = "::";
69 }
70 }
71
72 validate_address (family_, addr.target_addr (), target_addr_,
73 expected_port_);
74 validate_address (family_, addr.bind_addr (), bind_addr_, expected_port_);
75}
76
77static void test_resolve_bind (int family_,
78 const char *name_,
79 const char *dest_addr_,
80 uint16_t expected_port_ = 0,
81 const char *bind_addr_ = NULL,
82 bool multicast_ = false)
83{
84 test_resolve (true, family_, name_, dest_addr_, expected_port_, bind_addr_,
85 multicast_);
86}
87
88static void test_resolve_connect (int family_,
89 const char *name_,
90 const char *dest_addr_,
91 uint16_t expected_port_ = 0,
92 const char *bind_addr_ = NULL,
93 bool multicast_ = false)
94{
95 test_resolve (false, family_, name_, dest_addr_, expected_port_, bind_addr_,
96 multicast_);
97}
98
99static void test_resolve_ipv4_simple ()
100{
101 test_resolve_connect (AF_INET, "127.0.0.1:5555", "127.0.0.1", 5555);
102}
103
104static void test_resolve_ipv6_simple ()
105{
106 test_resolve_connect (AF_INET6, "[::1]:123", "::1", 123);
107}
108
109static void test_resolve_ipv4_bind ()
110{
111 test_resolve_bind (AF_INET, "127.0.0.1:5555", "127.0.0.1", 5555,
112 "127.0.0.1");
113}
114
115static void test_resolve_ipv6_bind ()
116{
117 test_resolve_bind (AF_INET6, "[abcd::1234:1]:5555", "abcd::1234:1", 5555,
118 "abcd::1234:1");
119}
120
121static void test_resolve_ipv4_bind_any ()
122{
123 test_resolve_bind (AF_INET, "*:*", "0.0.0.0", 0, "0.0.0.0");
124}
125
126static void test_resolve_ipv6_bind_any ()
127{
128 test_resolve_bind (AF_INET6, "*:*", "::", 0, "::");
129}
130
131static void test_resolve_ipv4_bind_anyport ()
132{
133 test_resolve_bind (AF_INET, "127.0.0.1:*", "127.0.0.1", 0, "127.0.0.1");
134}
135
136static void test_resolve_ipv6_bind_anyport ()
137{
138 test_resolve_bind (AF_INET6, "[1:2:3:4::5]:*", "1:2:3:4::5", 0,
139 "1:2:3:4::5");
140}
141
142static void test_resolve_ipv4_bind_any_port ()
143{
144 test_resolve_bind (AF_INET, "*:5555", "0.0.0.0", 5555, "0.0.0.0");
145}
146
147static void test_resolve_ipv6_bind_any_port ()
148{
149 test_resolve_bind (AF_INET6, "*:5555", "::", 5555, "::");
150}
151
152static void test_resolve_ipv4_connect_any ()
153{
154 // Cannot use wildcard for connection
155 test_resolve_connect (AF_INET, "*:5555", NULL);
156}
157
158static void test_resolve_ipv6_connect_any ()
159{
160 // Cannot use wildcard for connection
161 test_resolve_connect (AF_INET6, "*:5555", NULL);
162}
163
164static void test_resolve_ipv4_connect_anyport ()
165{
166 test_resolve_connect (AF_INET, "127.0.0.1:*", NULL);
167}
168
169static void test_resolve_ipv6_connect_anyport ()
170{
171 test_resolve_connect (AF_INET6, "[::1]:*", NULL);
172}
173
174static void test_resolve_ipv4_connect_port0 ()
175{
176 test_resolve_connect (AF_INET, "127.0.0.1:0", "127.0.0.1", 0);
177}
178
179static void test_resolve_ipv6_connect_port0 ()
180{
181 test_resolve_connect (AF_INET6, "[2000:abcd::1]:0", "2000:abcd::1", 0);
182}
183
184static void test_resolve_ipv4_bind_mcast ()
185{
186 test_resolve_bind (AF_INET, "239.0.0.1:1234", "239.0.0.1", 1234, "0.0.0.0",
187 true);
188}
189
190static void test_resolve_ipv6_bind_mcast ()
191{
192 test_resolve_bind (AF_INET6, "[ff00::1]:1234", "ff00::1", 1234, "::", true);
193}
194
195static void test_resolve_ipv4_connect_mcast ()
196{
197 test_resolve_connect (AF_INET, "239.0.0.1:2222", "239.0.0.1", 2222, NULL,
198 true);
199}
200
201static void test_resolve_ipv6_connect_mcast ()
202{
203 test_resolve_connect (AF_INET6, "[ff00::1]:2222", "ff00::1", 2222, NULL,
204 true);
205}
206
207static void test_resolve_ipv4_mcast_src_bind ()
208{
209 test_resolve_bind (AF_INET, "127.0.0.1;230.2.8.12:5555", "230.2.8.12", 5555,
210 "127.0.0.1", true);
211}
212
213static void test_resolve_ipv6_mcast_src_bind ()
214{
215 if (!is_ipv6_available ()) {
216 TEST_IGNORE_MESSAGE ("ipv6 is not available");
217 }
218
219 zmq::udp_address_t addr;
220 int rc = addr.resolve ("[::1];[ffab::4]:5555", true, true);
221
222 // For the time being this fails because we only support binding multicast
223 // by interface name, not interface IP
224 TEST_ASSERT_EQUAL (-1, rc);
225 TEST_ASSERT_EQUAL (ENODEV, errno);
226}
227
228static void test_resolve_ipv4_mcast_src_bind_any ()
229{
230 test_resolve_bind (AF_INET, "*;230.2.8.12:5555", "230.2.8.12", 5555,
231 "0.0.0.0", true);
232}
233
234static void test_resolve_ipv6_mcast_src_bind_any ()
235{
236 test_resolve_bind (AF_INET6, "*;[ffff::]:5555", "ffff::", 5555, "::", true);
237}
238
239static void test_resolve_ipv4_mcast_src_connect ()
240{
241 test_resolve_connect (AF_INET, "8.9.10.11;230.2.8.12:5555", "230.2.8.12",
242 5555, "8.9.10.11", true);
243}
244
245static void test_resolve_ipv6_mcast_src_connect ()
246{
247 if (!is_ipv6_available ()) {
248 TEST_IGNORE_MESSAGE ("ipv6 is not available");
249 }
250
251 zmq::udp_address_t addr;
252 int rc = addr.resolve ("[1:2:3::4];[ff01::1]:5555", false, true);
253
254 // For the time being this fails because we only support binding multicast
255 // by interface name, not interface IP
256 TEST_ASSERT_EQUAL (-1, rc);
257 TEST_ASSERT_EQUAL (ENODEV, errno);
258}
259
260static void test_resolve_ipv4_mcast_src_connect_any ()
261{
262 test_resolve_connect (AF_INET, "*;230.2.8.12:5555", "230.2.8.12", 5555,
263 "0.0.0.0", true);
264}
265
266static void test_resolve_ipv6_mcast_src_connect_any ()
267{
268 test_resolve_connect (AF_INET6, "*;[ff10::1]:5555", "ff10::1", 5555,
269 "::", true);
270}
271
272static void test_resolve_ipv4_mcast_src_bind_bad ()
273{
274 test_resolve_bind (AF_INET, "127.0.0.1;1.2.3.4:5555", NULL);
275}
276
277static void test_resolve_ipv6_mcast_src_bind_bad ()
278{
279 test_resolve_bind (AF_INET6, "[::1];[fe00::1]:5555", NULL);
280}
281
282static void test_resolve_ipv4_mcast_src_connect_bad ()
283{
284 test_resolve_connect (AF_INET, "127.0.0.1;1.2.3.4:5555", NULL);
285}
286
287static void test_resolve_ipv6_mcast_src_connect_bad ()
288{
289 test_resolve_connect (AF_INET6, "[::1];[fe00:1]:5555", NULL);
290}
291
292int main (void)
293{
294 zmq::initialize_network ();
295 setup_test_environment ();
296
297 UNITY_BEGIN ();
298
299 RUN_TEST (test_resolve_ipv4_simple);
300 RUN_TEST (test_resolve_ipv6_simple);
301 RUN_TEST (test_resolve_ipv4_bind);
302 RUN_TEST (test_resolve_ipv6_bind);
303 RUN_TEST (test_resolve_ipv4_bind_any);
304 RUN_TEST (test_resolve_ipv6_bind_any);
305 RUN_TEST (test_resolve_ipv4_bind_anyport);
306 RUN_TEST (test_resolve_ipv6_bind_anyport);
307 RUN_TEST (test_resolve_ipv4_bind_any_port);
308 RUN_TEST (test_resolve_ipv6_bind_any_port);
309 RUN_TEST (test_resolve_ipv4_connect_any);
310 RUN_TEST (test_resolve_ipv6_connect_any);
311 RUN_TEST (test_resolve_ipv4_connect_anyport);
312 RUN_TEST (test_resolve_ipv6_connect_anyport);
313 RUN_TEST (test_resolve_ipv4_connect_port0);
314 RUN_TEST (test_resolve_ipv6_connect_port0);
315 RUN_TEST (test_resolve_ipv4_bind_mcast);
316 RUN_TEST (test_resolve_ipv6_bind_mcast);
317 RUN_TEST (test_resolve_ipv4_connect_mcast);
318 RUN_TEST (test_resolve_ipv6_connect_mcast);
319 RUN_TEST (test_resolve_ipv4_mcast_src_bind);
320 RUN_TEST (test_resolve_ipv6_mcast_src_bind);
321 RUN_TEST (test_resolve_ipv4_mcast_src_bind_any);
322 RUN_TEST (test_resolve_ipv6_mcast_src_bind_any);
323 RUN_TEST (test_resolve_ipv4_mcast_src_connect);
324 RUN_TEST (test_resolve_ipv6_mcast_src_connect);
325 RUN_TEST (test_resolve_ipv4_mcast_src_connect_any);
326 RUN_TEST (test_resolve_ipv6_mcast_src_connect_any);
327 RUN_TEST (test_resolve_ipv4_mcast_src_bind_bad);
328 RUN_TEST (test_resolve_ipv6_mcast_src_bind_bad);
329 RUN_TEST (test_resolve_ipv4_mcast_src_connect_bad);
330 RUN_TEST (test_resolve_ipv6_mcast_src_connect_bad);
331
332 zmq::shutdown_network ();
333
334 return UNITY_END ();
335}
336