10 #include <sys/types.h>
11 #include <sys/socket.h>
13 #include <netinet/in.h>
14 #include <arpa/inet.h>
22 static int setup_echo_srv_tcp_ipv4(void **state)
24 torture_setup_echo_srv_tcp_ipv4(state);
30 static int setup_echo_srv_tcp_ipv6(void **state)
32 torture_setup_echo_srv_tcp_ipv6(state);
38 static int teardown(void **state)
40 torture_teardown_echo_srv(state);
45 static void test_bind_ipv4(void **state)
47 struct torture_address addr = {
48 .sa_socklen = sizeof(struct sockaddr_storage),
50 struct torture_address addr_in = {
51 .sa_socklen = sizeof(struct sockaddr_in),
53 struct torture_address addr_un = {
54 .sa_socklen = sizeof(struct sockaddr_un),
59 (void) state; /* unused */
61 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
62 assert_return_code(s, errno);
65 * Test various cases with family AF_UNSPEC
68 /* UNSPEC, len == 1: EINVAL */
70 addr_in.sa.in = (struct sockaddr_in) {
71 .sin_family = AF_UNSPEC,
73 rc = bind(s, &addr.sa.s, 1);
74 assert_int_equal(rc, -1);
75 assert_int_equal(errno, EINVAL);
77 /* UNSPEC: EAFNOSUPPORT */
79 addr_in.sa.in = (struct sockaddr_in) {
80 .sin_family = AF_UNSPEC,
82 rc = inet_pton(AF_INET, "127.0.0.20", &addr_in.sa.in.sin_addr);
83 assert_int_equal(rc, 1);
85 rc = bind(s, &addr_in.sa.s, addr_in.sa_socklen);
86 assert_int_equal(rc, -1);
87 /* FreeBSD uses EADDRNOTAVAIL here ... */
88 assert_true(errno == EAFNOSUPPORT || errno == EADDRNOTAVAIL);
90 /* special case: AF_UNSPEC with INADDR_ANY: success mapped to AF_INET */
92 addr_in.sa.in = (struct sockaddr_in) {
93 .sin_family = AF_UNSPEC,
95 assert_int_equal(addr_in.sa.in.sin_addr.s_addr, htonl(INADDR_ANY));
97 rc = bind(s, &addr_in.sa.s, addr_in.sa_socklen);
98 assert_return_code(rc, errno);
102 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
103 assert_return_code(s, errno);
106 * Test various cases with family AF_UNIX
107 * all fail with EAFNOSUPPORT
110 addr.sa.ss = (struct sockaddr_storage) {
111 .ss_family = AF_UNIX,
113 rc = bind(s, &addr.sa.s, addr.sa_socklen);
114 assert_int_equal(rc, -1);
115 assert_int_equal(errno, EAFNOSUPPORT);
117 addr_in.sa.in = (struct sockaddr_in) {
118 .sin_family = AF_UNIX,
120 rc = bind(s, &addr_in.sa.s, addr_in.sa_socklen);
121 assert_int_equal(rc, -1);
122 assert_int_equal(errno, EAFNOSUPPORT);
124 addr_un.sa.un = (struct sockaddr_un) {
125 .sun_family = AF_UNIX,
127 rc = bind(s, &addr_un.sa.s, addr_un.sa_socklen);
128 assert_int_equal(rc, -1);
129 assert_int_equal(errno, EAFNOSUPPORT);
133 * Test with family AF_INET6 - fail
136 addr_in.sa.in = (struct sockaddr_in) {
137 .sin_family = AF_INET6,
139 rc = bind(s, &addr_in.sa.s, addr_in.sa_socklen);
140 assert_int_equal(rc, -1);
141 assert_int_equal(errno, EAFNOSUPPORT);
145 * Finally, success binding a new IPv4 address.
147 addr_in = (struct torture_address) {
148 .sa_socklen = sizeof(struct sockaddr_in),
149 .sa.in = (struct sockaddr_in) {
150 .sin_family = AF_INET,
154 rc = inet_pton(AF_INET, "127.0.0.20", &addr_in.sa.in.sin_addr);
155 assert_int_equal(rc, 1);
157 rc = bind(s, &addr_in.sa.s, addr_in.sa_socklen);
158 assert_return_code(rc, errno);
160 addr_in = (struct torture_address) {
161 .sa_socklen = sizeof(struct sockaddr_in),
162 .sa.in = (struct sockaddr_in) {
163 .sin_family = AF_INET,
164 .sin_port = htons(torture_server_port()),
168 rc = inet_pton(AF_INET,
169 torture_server_address(AF_INET),
170 &addr_in.sa.in.sin_addr);
171 assert_int_equal(rc, 1);
173 rc = connect(s, &addr_in.sa.s, addr_in.sa_socklen);
174 assert_return_code(rc, errno);
180 static void test_bind_ipv4_addr_in_use(void **state)
182 struct sockaddr_in sin, sin2;
183 socklen_t slen = sizeof(struct sockaddr_in);
187 (void) state; /* unused */
189 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
190 assert_return_code(s, errno);
193 * Try to bind to the same address as already bound by a
197 /* Without specifying the port - success */
200 sin.sin_family = AF_INET;
201 rc = inet_pton(AF_INET, torture_server_address(AF_INET), &sin.sin_addr);
202 assert_int_equal(rc, 1);
203 rc = bind(s, (struct sockaddr *)&sin, slen);
204 assert_return_code(rc, errno);
208 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
209 assert_return_code(s, errno);
212 /* specify the same port - fail with EADDRINUSE. */
214 /* Not supported by socket_wrapper yet. ==> TODO! */
217 sin.sin_family = AF_INET,
218 sin.sin_port = htons(torture_server_port());
219 rc = inet_pton(AF_INET, torture_server_address(AF_INET), &sin.sin_addr);
220 assert_int_equal(rc, 1);
222 rc = bind(s, (struct sockaddr *)&sin, slen);
223 assert_int_equal(rc, -1);
224 assert_int_equal(errno, EADDRINUSE);
228 * Try double binding when the firs bind is with port == 0
232 sin.sin_family = AF_INET;
234 rc = inet_pton(AF_INET, "127.0.0.20", &sin.sin_addr);
235 assert_int_equal(rc, 1);
237 rc = bind(s, (struct sockaddr *)&sin, slen);
238 assert_return_code(rc, errno);
241 * Open a second socket locally and try to bind to the same address.
244 /* Succeeds with port == 0 */
246 s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
247 assert_return_code(s, errno);
250 sin2.sin_family = AF_INET;
252 rc = inet_pton(AF_INET, "127.0.0.20", &sin2.sin_addr);
253 assert_int_equal(rc, 1);
255 rc = bind(s2, (struct sockaddr *)&sin2, slen);
256 assert_return_code(rc, errno);
260 /* second bind with port != 0 - succeeds */
262 s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
263 assert_return_code(s, errno);
266 sin2.sin_family = AF_INET;
267 sin2.sin_port = htons(12345);
269 rc = inet_pton(AF_INET, "127.0.0.20", &sin2.sin_addr);
270 assert_int_equal(rc, 1);
272 rc = bind(s2, (struct sockaddr *)&sin2, slen);
273 assert_return_code(rc, errno);
279 * Try double binding when the first bind is with port != 0
282 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
283 assert_return_code(s, errno);
286 sin.sin_family = AF_INET;
287 sin.sin_port = htons(12345);
289 rc = inet_pton(AF_INET, "127.0.0.20", &sin.sin_addr);
290 assert_int_equal(rc, 1);
292 rc = bind(s, (struct sockaddr *)&sin, slen);
293 assert_return_code(rc, errno);
296 * Open a second socket locally and try to bind to the same address.
299 /* Succeeds with port == 0 */
301 s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
302 assert_return_code(s, errno);
305 sin2.sin_family = AF_INET;
307 rc = inet_pton(AF_INET, "127.0.0.20", &sin2.sin_addr);
308 assert_int_equal(rc, 1);
310 rc = bind(s2, (struct sockaddr *)&sin2, slen);
311 assert_return_code(rc, errno);
315 /* with same port as above - fail with EADDRINUSE */
317 s2 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
318 assert_return_code(s, errno);
321 sin2.sin_family = AF_INET;
322 sin2.sin_port = htons(12345);
324 rc = inet_pton(AF_INET, "127.0.0.20", &sin2.sin_addr);
325 assert_int_equal(rc, 1);
327 rc = bind(s2, (struct sockaddr *)&sin2, slen);
328 assert_int_equal(rc, -1);
329 assert_int_equal(errno, EADDRINUSE);
335 #ifdef HAVE_BINDRESVPORT
336 static void test_bindresvport_ipv4(void **state)
338 struct torture_address addr = {
339 .sa_socklen = sizeof(struct sockaddr_storage),
344 (void) state; /* unused */
346 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
347 assert_return_code(s, errno);
349 addr.sa.in.sin_family = AF_INET;
351 rc = inet_pton(AF_INET, "127.0.0.20", &addr.sa.in.sin_addr);
352 assert_int_equal(rc, 1);
354 rc = bindresvport(s, &addr.sa.in);
355 assert_return_code(rc, errno);
357 addr = (struct torture_address) {
358 .sa_socklen = sizeof(struct sockaddr_storage),
359 .sa.in = (struct sockaddr_in) {
360 .sin_family = AF_INET,
361 .sin_port = htons(torture_server_port()),
365 rc = inet_pton(AF_INET,
366 torture_server_address(AF_INET),
367 &addr.sa.in.sin_addr);
368 assert_int_equal(rc, 1);
370 rc = connect(s, &addr.sa.s, addr.sa_socklen);
371 assert_return_code(rc, errno);
376 static void test_bindresvport_ipv4_null(void **state)
378 struct torture_address addr = {
379 .sa_socklen = sizeof(struct sockaddr_in),
384 (void) state; /* unused */
386 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
387 assert_return_code(s, errno);
389 rc = bindresvport(s, NULL);
390 assert_return_code(rc, errno);
392 addr.sa.in.sin_family = AF_INET;
393 addr.sa.in.sin_port = htons(torture_server_port());
394 rc = inet_pton(AF_INET, torture_server_address(AF_INET), &addr.sa.in.sin_addr);
395 assert_int_equal(rc, 1);
397 rc = connect(s, &addr.sa.s, addr.sa_socklen);
398 assert_return_code(rc, errno);
402 #endif /* HAVE_BINDRESVPORT */
405 static void test_bind_on_ipv6_sock(void **state)
407 struct torture_address addr_in = {
408 .sa_socklen = sizeof(struct sockaddr_in),
410 struct torture_address addr_un = {
411 .sa_socklen = sizeof(struct sockaddr_un),
416 (void) state; /* unused */
418 s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
419 assert_return_code(s, errno);
421 addr_un.sa.un.sun_family = AF_UNIX;
422 rc = bind(s, &addr_un.sa.s, addr_un.sa_socklen);
423 assert_int_equal(rc, -1);
424 /* FreeBSD uses EINVAL here... */
425 assert_true(errno == EAFNOSUPPORT || errno == EINVAL);
427 addr_in.sa.in.sin_family = AF_INET;
428 rc = bind(s, &addr_in.sa.s, addr_in.sa_socklen);
429 assert_int_equal(rc, -1);
430 assert_int_equal(errno, EINVAL);
432 addr_in.sa.in = (struct sockaddr_in) {
433 .sin_family = AF_INET,
436 rc = inet_pton(AF_INET, "127.0.0.20", &addr_in.sa.in.sin_addr);
437 assert_int_equal(rc, 1);
439 rc = bind(s, &addr_in.sa.s, addr_in.sa_socklen);
440 assert_int_equal(rc, -1);
441 assert_int_equal(errno, EINVAL);
443 addr_in = (struct torture_address) {
444 .sa_socklen = sizeof(struct sockaddr_in6),
445 .sa.in = (struct sockaddr_in) {
446 .sin_family = AF_INET,
450 rc = bind(s, &addr_in.sa.s, addr_in.sa_socklen);
451 assert_int_equal(rc, -1);
452 assert_int_equal(errno, EAFNOSUPPORT);
457 #ifdef HAVE_BINDRESVPORT
458 static void test_bindresvport_on_ipv6_sock(void **state)
460 struct sockaddr_in sin;
464 (void) state; /* unused */
466 s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
467 assert_return_code(s, errno);
470 sin.sin_family = AF_INET;
472 rc = inet_pton(AF_INET, "127.0.0.20", &sin.sin_addr);
473 assert_int_equal(rc, 1);
475 rc = bindresvport(s, &sin);
476 assert_int_equal(rc, -1);
477 assert_int_equal(errno, EINVAL);
482 static void test_bindresvport_on_ipv6_sock_null(void **state)
487 (void) state; /* unused */
489 s = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
490 assert_return_code(s, errno);
492 rc = bindresvport(s, NULL);
493 assert_return_code(rc, errno);
497 #endif /* HAVE_BINDRESVPORT */
498 #endif /* HAVE_IPV6 */
503 const struct CMUnitTest tcp_bind_tests[] = {
504 cmocka_unit_test_setup_teardown(test_bind_ipv4,
505 setup_echo_srv_tcp_ipv4,
508 cmocka_unit_test_setup_teardown(test_bind_ipv4_addr_in_use,
509 setup_echo_srv_tcp_ipv4,
512 #ifdef HAVE_BINDRESVPORT
513 cmocka_unit_test_setup_teardown(test_bindresvport_ipv4,
514 setup_echo_srv_tcp_ipv4,
516 cmocka_unit_test_setup_teardown(test_bindresvport_ipv4_null,
517 setup_echo_srv_tcp_ipv4,
519 #endif /* HAVE_BINDRESVPORT */
521 cmocka_unit_test_setup_teardown(test_bind_on_ipv6_sock,
522 setup_echo_srv_tcp_ipv6,
524 #ifdef HAVE_BINDRESVPORT
525 cmocka_unit_test_setup_teardown(test_bindresvport_on_ipv6_sock,
526 setup_echo_srv_tcp_ipv6,
528 cmocka_unit_test_setup_teardown(test_bindresvport_on_ipv6_sock_null,
529 setup_echo_srv_tcp_ipv6,
531 #endif /* HAVE_BINDRESVPORT */
532 #endif /* HAVE_IPV6 */
535 rc = cmocka_run_group_tests(tcp_bind_tests, NULL, NULL);