10 #include <sys/types.h>
11 #include <sys/socket.h>
12 #include <netinet/in.h>
13 #include <arpa/inet.h>
18 static int setup_echo_srv_tcp_ipv4(void **state)
20 torture_setup_echo_srv_tcp_ipv4(state);
21 setenv("SOCKET_WRAPPER_DEFAULT_IFACE", "20", 1);
26 static int teardown(void **state)
28 torture_teardown_echo_srv(state);
33 static void _assert_sockaddr_equal(struct torture_address *addr, const char *a,
34 const char * const file, const int line)
37 char ip[INET6_ADDRSTRLEN] = { 0 };
39 char ip[INET_ADDRSTRLEN] = { 0 };
44 p = inet_ntop(addr->sa.ss.ss_family,
45 addr->sa.ss.ss_family == AF_INET6 ?
46 (void *)&addr->sa.in6.sin6_addr :
47 (void *)&addr->sa.in.sin_addr,
51 p = inet_ntop(addr->sa.ss.ss_family,
52 (void *)&addr->sa.in.sin_addr,
56 _assert_true(cast_ptr_to_largest_integral_type(p),
57 "inet_ntop: Failed to convert IP address", file, line);
59 _assert_string_equal(ip, a, file, line);
62 #define assert_sockaddr_equal(ss, a) \
63 _assert_sockaddr_equal(ss, a, __FILE__, __LINE__)
65 static void _assert_sockaddr_port_equal(struct torture_address *addr,
68 const char * const file, const int line)
72 _assert_sockaddr_equal(addr, a, file, line);
74 switch(addr->sa.ss.ss_family) {
76 n_port = addr->sa.in.sin_port;
80 n_port = addr->sa.in6.sin6_port;
87 _assert_int_equal(ntohs(n_port), port, file, line);
90 #define assert_sockaddr_port_equal(ss, a, prt) \
91 _assert_sockaddr_port_equal(ss, a, prt, __FILE__, __LINE__)
93 static void _assert_sockaddr_port_range_equal(struct torture_address *addr,
95 uint16_t min_port, uint16_t max_port,
96 const char * const file, const int line)
100 _assert_sockaddr_equal(addr, a, file, line);
102 switch(addr->sa.ss.ss_family) {
104 n_port = addr->sa.in.sin_port;
108 n_port = addr->sa.in6.sin6_port;
115 _assert_in_range(ntohs(n_port),
122 #define assert_sockaddr_port_range_equal(ss, a, min_prt, max_prt) \
123 _assert_sockaddr_port_range_equal(ss, a, min_prt, max_prt, __FILE__, __LINE__)
125 static void test_connect_getsockname_getpeername(void **state)
127 struct torture_address addr = {
128 .sa_socklen = sizeof(struct sockaddr_in),
130 struct torture_address cli_addr = {
131 .sa_socklen = sizeof(struct sockaddr_storage),
133 struct torture_address srv_addr = {
134 .sa_socklen = sizeof(struct sockaddr_storage),
139 (void) state; /* unused */
141 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
142 assert_return_code(s, errno);
144 /* Bind client address to wildcard address */
145 addr.sa.in.sin_family = AF_INET;
147 rc = inet_pton(AF_INET, "127.0.0.20", &addr.sa.in.sin_addr);
148 assert_int_equal(rc, 1);
150 rc = bind(s, &addr.sa.s, addr.sa_socklen);
151 assert_return_code(rc, errno);
153 rc = getsockname(s, &cli_addr.sa.s, &cli_addr.sa_socklen);
154 assert_return_code(rc, errno);
155 assert_sockaddr_port_range_equal(&cli_addr, "127.0.0.20", 1024, 65535);
157 rc = getpeername(s, &addr.sa.s, &addr.sa_socklen);
158 assert_int_equal(rc, -1);
159 assert_int_equal(errno, ENOTCONN);
162 addr = (struct torture_address) {
163 .sa_socklen = sizeof(struct sockaddr_in),
164 .sa.in = (struct sockaddr_in) {
165 .sin_family = AF_INET,
166 .sin_port = htons(torture_server_port()),
169 rc = inet_pton(AF_INET,
170 torture_server_address(AF_INET),
171 &addr.sa.in.sin_addr);
172 assert_int_equal(rc, 1);
175 rc = connect(s, &addr.sa.s, addr.sa_socklen);
176 assert_return_code(rc, errno);
178 cli_addr = (struct torture_address) {
179 .sa_socklen = sizeof(struct sockaddr_storage),
182 rc = getsockname(s, &cli_addr.sa.s, &cli_addr.sa_socklen);
183 assert_return_code(rc, errno);
184 assert_sockaddr_port_range_equal(&cli_addr, "127.0.0.20", 1024, 65535);
186 srv_addr = (struct torture_address) {
187 .sa_socklen = sizeof(struct sockaddr_storage),
190 rc = getpeername(s, &srv_addr.sa.s, &srv_addr.sa_socklen);
191 assert_return_code(rc, errno);
192 assert_sockaddr_port_equal(&srv_addr, "127.0.0.10", 7);
197 static void test_connect_getsockname_getpeername_port(void **state)
199 struct torture_address addr = {
200 .sa_socklen = sizeof(struct sockaddr_in),
202 struct torture_address cli_addr = {
203 .sa_socklen = sizeof(struct sockaddr_storage),
205 struct torture_address srv_addr = {
206 .sa_socklen = sizeof(struct sockaddr_storage),
211 (void) state; /* unused */
213 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
214 assert_return_code(s, errno);
216 /* Bind client address to wildcard address */
217 addr.sa.in.sin_family = AF_INET;
219 rc = inet_pton(AF_INET, "127.0.0.20", &addr.sa.in.sin_addr);
220 assert_int_equal(rc, 1);
221 addr.sa.in.sin_port = htons(12345);
223 rc = bind(s, &addr.sa.s, addr.sa_socklen);
224 assert_return_code(rc, errno);
226 rc = getsockname(s, &cli_addr.sa.s, &cli_addr.sa_socklen);
227 assert_return_code(rc, errno);
228 assert_sockaddr_port_equal(&cli_addr, "127.0.0.20", 12345);
230 rc = getpeername(s, &srv_addr.sa.s, &srv_addr.sa_socklen);
231 assert_int_equal(rc, -1);
232 assert_int_equal(errno, ENOTCONN);
235 addr = (struct torture_address) {
236 .sa_socklen = sizeof(struct sockaddr_in),
237 .sa.in = (struct sockaddr_in) {
238 .sin_family = AF_INET,
239 .sin_port = htons(torture_server_port()),
243 rc = inet_pton(AF_INET,
244 torture_server_address(AF_INET),
245 &addr.sa.in.sin_addr);
246 assert_int_equal(rc, 1);
249 rc = connect(s, &addr.sa.s, addr.sa_socklen);
250 assert_return_code(rc, errno);
252 cli_addr = (struct torture_address) {
253 .sa_socklen = sizeof(struct sockaddr_storage),
256 rc = getsockname(s, &cli_addr.sa.s, &cli_addr.sa_socklen);
257 assert_return_code(rc, errno);
258 assert_sockaddr_port_equal(&cli_addr, "127.0.0.20", 12345);
260 srv_addr = (struct torture_address) {
261 .sa_socklen = sizeof(struct sockaddr_storage),
264 rc = getpeername(s, &srv_addr.sa.s, &srv_addr.sa_socklen);
265 assert_return_code(rc, errno);
266 assert_sockaddr_port_equal(&srv_addr, "127.0.0.10", 7);
271 static void test_connect_getsockname_getpeername_any(void **state)
273 struct torture_address addr = {
274 .sa_socklen = sizeof(struct sockaddr_in),
276 struct torture_address cli_addr = {
277 .sa_socklen = sizeof(struct sockaddr_storage),
279 struct torture_address srv_addr = {
280 .sa_socklen = sizeof(struct sockaddr_storage),
285 (void) state; /* unused */
287 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
288 assert_return_code(s, errno);
290 /* Bind client address to wildcard address */
291 addr.sa.in.sin_family = AF_INET;
292 addr.sa.in.sin_addr.s_addr = htonl(INADDR_ANY);
294 rc = bind(s, &addr.sa.s, addr.sa_socklen);
295 assert_return_code(rc, errno);
297 rc = getsockname(s, &cli_addr.sa.s, &cli_addr.sa_socklen);
298 assert_return_code(rc, errno);
299 assert_sockaddr_port_range_equal(&cli_addr, "0.0.0.0", 1024, 65535);
301 rc = getpeername(s, &srv_addr.sa.s, &srv_addr.sa_socklen);
302 assert_int_equal(rc, -1);
303 assert_int_equal(errno, ENOTCONN);
306 addr.sa.in.sin_family = AF_INET;
307 addr.sa.in.sin_port = htons(torture_server_port());
308 rc = inet_pton(AF_INET,
309 torture_server_address(AF_INET),
310 &addr.sa.in.sin_addr);
311 assert_int_equal(rc, 1);
314 rc = connect(s, &addr.sa.s, addr.sa_socklen);
315 assert_return_code(rc, errno);
317 cli_addr = (struct torture_address) {
318 .sa_socklen = sizeof(struct sockaddr_storage),
321 rc = getsockname(s, &cli_addr.sa.s, &cli_addr.sa_socklen);
322 assert_return_code(rc, errno);
323 assert_sockaddr_port_range_equal(&cli_addr, "127.0.0.20", 1024, 65535);
325 srv_addr = (struct torture_address) {
326 .sa_socklen = sizeof(struct sockaddr_storage),
329 rc = getpeername(s, &srv_addr.sa.s, &srv_addr.sa_socklen);
330 assert_return_code(rc, errno);
331 assert_sockaddr_port_equal(&srv_addr, "127.0.0.10", 7);
336 static void test_connect_getsockname_getpeername_any_port(void **state)
338 struct torture_address addr = {
339 .sa_socklen = sizeof(struct sockaddr_in),
341 struct torture_address cli_addr = {
342 .sa_socklen = sizeof(struct sockaddr_storage),
344 struct torture_address srv_addr = {
345 .sa_socklen = sizeof(struct sockaddr_storage),
350 (void) state; /* unused */
352 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
353 assert_return_code(s, errno);
355 /* Bind client address to wildcard address */
356 addr.sa.in.sin_family = AF_INET;
357 addr.sa.in.sin_addr.s_addr = htonl(INADDR_ANY);
358 addr.sa.in.sin_port = htons(12345);
360 rc = bind(s, &addr.sa.s, addr.sa_socklen);
361 assert_return_code(rc, errno);
363 rc = getsockname(s, &cli_addr.sa.s, &cli_addr.sa_socklen);
364 assert_return_code(rc, errno);
365 assert_sockaddr_port_equal(&cli_addr, "0.0.0.0", 12345);
367 rc = getpeername(s, &srv_addr.sa.s, &srv_addr.sa_socklen);
368 assert_int_equal(rc, -1);
369 assert_int_equal(errno, ENOTCONN);
372 addr.sa.in.sin_family = AF_INET;
373 addr.sa.in.sin_port = htons(torture_server_port());
374 rc = inet_pton(AF_INET,
375 torture_server_address(AF_INET),
376 &addr.sa.in.sin_addr);
377 assert_int_equal(rc, 1);
380 rc = connect(s, &addr.sa.s, addr.sa_socklen);
381 assert_return_code(rc, errno);
383 cli_addr = (struct torture_address) {
384 .sa_socklen = sizeof(struct sockaddr_storage),
387 rc = getsockname(s, &cli_addr.sa.s, &cli_addr.sa_socklen);
388 assert_return_code(rc, errno);
389 assert_sockaddr_port_equal(&cli_addr, "127.0.0.20", 12345);
391 srv_addr = (struct torture_address) {
392 .sa_socklen = sizeof(struct sockaddr_storage),
395 rc = getpeername(s, &srv_addr.sa.s, &srv_addr.sa_socklen);
396 assert_return_code(rc, errno);
397 assert_sockaddr_port_equal(&srv_addr, "127.0.0.10", 7);
402 static void test_connect_getsockname_getpeername_len(void **state)
404 struct torture_address addr = {
405 .sa_socklen = sizeof(struct sockaddr_in),
407 struct torture_address cli_addr = {
408 .sa_socklen = sizeof(struct sockaddr_storage),
410 struct torture_address srv_addr = {
411 .sa_socklen = sizeof(struct sockaddr_storage),
417 (void) state; /* unused */
419 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
420 assert_return_code(s, errno);
423 addr.sa.in.sin_family = AF_INET;
424 addr.sa.in.sin_port = htons(torture_server_port());
425 rc = inet_pton(AF_INET,
426 torture_server_address(AF_INET),
427 &addr.sa.in.sin_addr);
428 assert_int_equal(rc, 1);
431 rc = connect(s, &addr.sa.s, addr.sa_socklen);
432 assert_return_code(rc, errno);
434 /* Check with len=0 */
435 cli_addr.sa_socklen = 0;
436 rc = getsockname(s, &cli_addr.sa.s, &cli_addr.sa_socklen);
437 assert_return_code(rc, errno);
439 srv_addr.sa_socklen = 0;
440 rc = getpeername(s, &srv_addr.sa.s, &srv_addr.sa_socklen);
441 assert_return_code(rc, errno);
443 /* Check with len=too small */
444 cli_addr = (struct torture_address) {
445 .sa_socklen = sizeof(struct sockaddr_in) - 2,
448 tmp_len = cli_addr.sa_socklen;
449 rc = getsockname(s, &cli_addr.sa.s, &cli_addr.sa_socklen);
450 assert_return_code(rc, errno);
451 assert_int_equal(tmp_len + 2, cli_addr.sa_socklen);
453 srv_addr = (struct torture_address) {
454 .sa_socklen = sizeof(struct sockaddr_in) - 2,
457 tmp_len = srv_addr.sa_socklen;
458 rc = getpeername(s, &srv_addr.sa.s, &srv_addr.sa_socklen);
459 assert_return_code(rc, errno);
460 assert_int_equal(tmp_len + 2, srv_addr.sa_socklen);
468 const struct CMUnitTest sock_name_tests[] = {
469 cmocka_unit_test_setup_teardown(test_connect_getsockname_getpeername,
470 setup_echo_srv_tcp_ipv4,
472 cmocka_unit_test_setup_teardown(test_connect_getsockname_getpeername_port,
473 setup_echo_srv_tcp_ipv4,
475 cmocka_unit_test_setup_teardown(test_connect_getsockname_getpeername_any,
476 setup_echo_srv_tcp_ipv4,
478 cmocka_unit_test_setup_teardown(test_connect_getsockname_getpeername_any_port,
479 setup_echo_srv_tcp_ipv4,
481 cmocka_unit_test_setup_teardown(test_connect_getsockname_getpeername_len,
482 setup_echo_srv_tcp_ipv4,
486 rc = cmocka_run_group_tests(sock_name_tests,