add tests for 4->6 connections.
This commit is contained in:
parent
dc977faaf4
commit
64e9b5d330
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: t_tcp.c,v 1.5 2017/08/28 09:30:29 christos Exp $ */
|
||||
/* $NetBSD: t_tcp.c,v 1.6 2017/08/28 10:19:57 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2013 The NetBSD Foundation, Inc.
|
||||
|
@ -35,7 +35,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifdef __RCSID
|
||||
__RCSID("$Id: t_tcp.c,v 1.5 2017/08/28 09:30:29 christos Exp $");
|
||||
__RCSID("$Id: t_tcp.c,v 1.6 2017/08/28 10:19:57 christos Exp $");
|
||||
#endif
|
||||
|
||||
/* Example code. Should block; does with accept not paccept. */
|
||||
|
@ -46,6 +46,7 @@ __RCSID("$Id: t_tcp.c,v 1.5 2017/08/28 09:30:29 christos Exp $");
|
|||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <sched.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -55,10 +56,18 @@ __RCSID("$Id: t_tcp.c,v 1.5 2017/08/28 09:30:29 christos Exp $");
|
|||
#include <signal.h>
|
||||
|
||||
#ifdef TEST
|
||||
#define FAIL(msg, ...) err(EXIT_FAILURE, msg, ## __VA_ARGS__)
|
||||
#define FAIL(msg) err(EXIT_FAILURE, msg)
|
||||
#define FAILX(msg, ...) err(EXIT_FAILURE, msg, ## __VA_ARGS__)
|
||||
#else
|
||||
#include <atf-c.h>
|
||||
#define FAIL(msg, ...) ATF_CHECK_MSG(0, msg, ## __VA_ARGS__); goto fail
|
||||
#define FAIL(msg) do { \
|
||||
ATF_CHECK_MSG(0, msg " (%s)", strerror(errno)); \
|
||||
goto fail; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#define FAILX(msg, ...) do { \
|
||||
ATF_CHECK_MSG(0, msg, ## __VA_ARGS__); \
|
||||
goto fail; \
|
||||
} while (/*CONSTCOND*/0)
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
|
@ -71,10 +80,12 @@ ding(int al)
|
|||
}
|
||||
|
||||
static void
|
||||
paccept_block(sa_family_t family, bool pacceptblock, bool fcntlblock)
|
||||
paccept_block(sa_family_t sfamily, sa_family_t cfamily,
|
||||
bool pacceptblock, bool fcntlblock)
|
||||
{
|
||||
int srvr = -1, clnt = -1, as = -1;
|
||||
int ok, fl;
|
||||
int count = 5;
|
||||
ssize_t n;
|
||||
char buf[10];
|
||||
struct sockaddr_storage ss, bs;
|
||||
|
@ -83,12 +94,12 @@ paccept_block(sa_family_t family, bool pacceptblock, bool fcntlblock)
|
|||
struct sigaction sa;
|
||||
socklen_t slen;
|
||||
|
||||
srvr = socket(family, SOCK_STREAM | SOCK_NONBLOCK, 0);
|
||||
srvr = socket(sfamily, SOCK_STREAM | SOCK_NONBLOCK, 0);
|
||||
if (srvr == -1)
|
||||
FAIL("socket");
|
||||
|
||||
memset(&ss, 0, sizeof(ss));
|
||||
switch (ss.ss_family = family) {
|
||||
switch (ss.ss_family = sfamily) {
|
||||
case AF_INET:
|
||||
sin = (void *)&ss;
|
||||
slen = sizeof(*sin);
|
||||
|
@ -99,7 +110,11 @@ paccept_block(sa_family_t family, bool pacceptblock, bool fcntlblock)
|
|||
sin6 = (void *)&ss;
|
||||
slen = sizeof(*sin6);
|
||||
sin6->sin6_port = htons(0);
|
||||
sin6->sin6_addr = in6addr_loopback;
|
||||
if (sfamily == AF_INET6 && cfamily == AF_INET) {
|
||||
sin6->sin6_addr = in6addr_any;
|
||||
} else {
|
||||
sin6->sin6_addr = in6addr_loopback;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
|
@ -108,6 +123,12 @@ paccept_block(sa_family_t family, bool pacceptblock, bool fcntlblock)
|
|||
#ifdef BSD4_4
|
||||
ss.ss_len = slen;
|
||||
#endif
|
||||
if (sfamily == AF_INET6 && cfamily == AF_INET) {
|
||||
int off = 0;
|
||||
if (setsockopt(srvr, IPPROTO_IPV6, IPV6_V6ONLY,
|
||||
(void *)&off, sizeof(off)) == -1)
|
||||
FAIL("setsockopt IPV6_V6ONLY");
|
||||
}
|
||||
|
||||
ok = bind(srvr, (const struct sockaddr *)&ss, slen);
|
||||
if (ok == -1)
|
||||
|
@ -122,18 +143,44 @@ paccept_block(sa_family_t family, bool pacceptblock, bool fcntlblock)
|
|||
if (ok == -1)
|
||||
FAIL("listen");
|
||||
|
||||
clnt = socket(family, SOCK_STREAM | SOCK_NONBLOCK, 0);
|
||||
clnt = socket(cfamily, SOCK_STREAM | SOCK_NONBLOCK, 0);
|
||||
if (clnt == -1)
|
||||
FAIL("socket");
|
||||
|
||||
if (sfamily == AF_INET6 && cfamily == AF_INET) {
|
||||
ss = bs;
|
||||
sin6 = (void *)&ss;
|
||||
sin = (void *)&bs;
|
||||
addrlen = sizeof(*sin);
|
||||
#ifdef BSD4_4
|
||||
sin->sin_len = sizeof(*sin);
|
||||
#endif
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_port = sin6->sin6_port;
|
||||
sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
}
|
||||
|
||||
/* may not connect first time */
|
||||
ok = connect(clnt, (struct sockaddr *) &bs, addrlen);
|
||||
if (ok != -1 || errno != EINPROGRESS)
|
||||
FAIL("expected connect to fail");
|
||||
as = paccept(srvr, NULL, NULL, NULL, pacceptblock ? 0 : SOCK_NONBLOCK);
|
||||
again:
|
||||
ok = connect(clnt, (struct sockaddr *) &bs, addrlen);
|
||||
if (ok == -1 && errno != EISCONN)
|
||||
if (ok == -1 && errno != EISCONN) {
|
||||
if (count-- && errno == EALREADY) {
|
||||
fprintf(stderr, "retry\n");
|
||||
struct timespec ts;
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 1000000;
|
||||
nanosleep(&ts, NULL);
|
||||
#if 0
|
||||
sched_yield();
|
||||
#endif
|
||||
goto again;
|
||||
}
|
||||
FAIL("connect failed");
|
||||
}
|
||||
|
||||
#if 0
|
||||
fl = fcntl(srvr, F_GETFL, 0);
|
||||
|
@ -155,7 +202,7 @@ paccept_block(sa_family_t family, bool pacceptblock, bool fcntlblock)
|
|||
if (fl == -1)
|
||||
FAIL("fnctl");
|
||||
if (fl != (O_RDWR|O_NONBLOCK))
|
||||
FAIL("fl 0x%x != 0x%x\n", fl, O_RDWR|O_NONBLOCK);
|
||||
FAILX("fl 0x%x != 0x%x\n", fl, O_RDWR|O_NONBLOCK);
|
||||
ok = fcntl(as, F_SETFL, fl & ~O_NONBLOCK);
|
||||
if (ok == -1)
|
||||
FAIL("fnctl setfl");
|
||||
|
@ -187,101 +234,143 @@ fail:
|
|||
|
||||
#ifndef TEST
|
||||
|
||||
ATF_TC(paccept4_reset_nonblock);
|
||||
ATF_TC_HEAD(paccept4_reset_nonblock, tc)
|
||||
ATF_TC(paccept44_reset_nonblock);
|
||||
ATF_TC_HEAD(paccept44_reset_nonblock, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "Check that paccept(2) resets "
|
||||
"the non-blocking flag on non-blocking sockets (ipv4)");
|
||||
"the non-blocking flag on non-blocking sockets (ipv4->ipv4)");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(paccept4_reset_nonblock, tc)
|
||||
ATF_TC_BODY(paccept44_reset_nonblock, tc)
|
||||
{
|
||||
paccept_block(AF_INET, true, false);
|
||||
paccept_block(AF_INET, AF_INET, true, false);
|
||||
}
|
||||
|
||||
ATF_TC(fcntl4_reset_nonblock);
|
||||
ATF_TC_HEAD(fcntl4_reset_nonblock, tc)
|
||||
ATF_TC(fcntl44_reset_nonblock);
|
||||
ATF_TC_HEAD(fcntl44_reset_nonblock, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "Check that fcntl(2) resets "
|
||||
"the non-blocking flag on non-blocking sockets (ipv4)");
|
||||
"the non-blocking flag on non-blocking sockets (ipv4->ipv4)");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(fcntl4_reset_nonblock, tc)
|
||||
ATF_TC_BODY(fcntl44_reset_nonblock, tc)
|
||||
{
|
||||
paccept_block(AF_INET, false, true);
|
||||
paccept_block(AF_INET, AF_INET, false, true);
|
||||
}
|
||||
|
||||
ATF_TC(paccept4_nonblock);
|
||||
ATF_TC_HEAD(paccept4_nonblock, tc)
|
||||
ATF_TC(paccept44_nonblock);
|
||||
ATF_TC_HEAD(paccept44_nonblock, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "Check that fcntl(2) resets "
|
||||
"the non-blocking flag on non-blocking sockets (ipv4)");
|
||||
"the non-blocking flag on non-blocking sockets (ipv4->ipv4)");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(paccept4_nonblock, tc)
|
||||
ATF_TC_BODY(paccept44_nonblock, tc)
|
||||
{
|
||||
paccept_block(AF_INET, false, false);
|
||||
paccept_block(AF_INET, AF_INET, false, false);
|
||||
}
|
||||
|
||||
ATF_TC(paccept6_reset_nonblock);
|
||||
ATF_TC_HEAD(paccept6_reset_nonblock, tc)
|
||||
ATF_TC(paccept66_reset_nonblock);
|
||||
ATF_TC_HEAD(paccept66_reset_nonblock, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "Check that paccept(2) resets "
|
||||
"the non-blocking flag on non-blocking sockets (ipv6)");
|
||||
"the non-blocking flag on non-blocking sockets (ipv6->ipv6)");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(paccept6_reset_nonblock, tc)
|
||||
ATF_TC_BODY(paccept66_reset_nonblock, tc)
|
||||
{
|
||||
paccept_block(AF_INET6, true, false);
|
||||
paccept_block(AF_INET6, AF_INET6, true, false);
|
||||
}
|
||||
|
||||
ATF_TC(fcntl6_reset_nonblock);
|
||||
ATF_TC_HEAD(fcntl6_reset_nonblock, tc)
|
||||
ATF_TC(fcntl66_reset_nonblock);
|
||||
ATF_TC_HEAD(fcntl66_reset_nonblock, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "Check that fcntl(2) resets "
|
||||
"the non-blocking flag on non-blocking sockets (ipv6)");
|
||||
"the non-blocking flag on non-blocking sockets (ipv6->ipv6)");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(fcntl6_reset_nonblock, tc)
|
||||
ATF_TC_BODY(fcntl66_reset_nonblock, tc)
|
||||
{
|
||||
paccept_block(AF_INET6, false, true);
|
||||
paccept_block(AF_INET6, AF_INET6, false, true);
|
||||
}
|
||||
|
||||
ATF_TC(paccept6_nonblock);
|
||||
ATF_TC_HEAD(paccept6_nonblock, tc)
|
||||
ATF_TC(paccept66_nonblock);
|
||||
ATF_TC_HEAD(paccept66_nonblock, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "Check that fcntl(2) resets "
|
||||
"the non-blocking flag on non-blocking sockets (ipv6)");
|
||||
"the non-blocking flag on non-blocking sockets (ipv6->ipv6)");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(paccept6_nonblock, tc)
|
||||
ATF_TC_BODY(paccept66_nonblock, tc)
|
||||
{
|
||||
paccept_block(AF_INET6, false, false);
|
||||
paccept_block(AF_INET6, AF_INET6, false, false);
|
||||
}
|
||||
|
||||
ATF_TC(paccept46_reset_nonblock);
|
||||
ATF_TC_HEAD(paccept46_reset_nonblock, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "Check that paccept(2) resets "
|
||||
"the non-blocking flag on non-blocking sockets (ipv4->ipv6)");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(paccept46_reset_nonblock, tc)
|
||||
{
|
||||
paccept_block(AF_INET6, AF_INET, true, false);
|
||||
}
|
||||
|
||||
ATF_TC(fcntl46_reset_nonblock);
|
||||
ATF_TC_HEAD(fcntl46_reset_nonblock, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "Check that fcntl(2) resets "
|
||||
"the non-blocking flag on non-blocking sockets (ipv4->ipv6)");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(fcntl46_reset_nonblock, tc)
|
||||
{
|
||||
paccept_block(AF_INET6, AF_INET, false, true);
|
||||
}
|
||||
|
||||
ATF_TC(paccept46_nonblock);
|
||||
ATF_TC_HEAD(paccept46_nonblock, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "Check that fcntl(2) resets "
|
||||
"the non-blocking flag on non-blocking sockets (ipv4->ipv6)");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(paccept46_nonblock, tc)
|
||||
{
|
||||
paccept_block(AF_INET6, AF_INET, false, false);
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
|
||||
ATF_TP_ADD_TC(tp, paccept4_reset_nonblock);
|
||||
ATF_TP_ADD_TC(tp, fcntl4_reset_nonblock);
|
||||
ATF_TP_ADD_TC(tp, paccept4_nonblock);
|
||||
ATF_TP_ADD_TC(tp, paccept6_reset_nonblock);
|
||||
ATF_TP_ADD_TC(tp, fcntl6_reset_nonblock);
|
||||
ATF_TP_ADD_TC(tp, paccept6_nonblock);
|
||||
ATF_TP_ADD_TC(tp, paccept44_reset_nonblock);
|
||||
ATF_TP_ADD_TC(tp, fcntl44_reset_nonblock);
|
||||
ATF_TP_ADD_TC(tp, paccept44_nonblock);
|
||||
ATF_TP_ADD_TC(tp, paccept66_reset_nonblock);
|
||||
ATF_TP_ADD_TC(tp, fcntl66_reset_nonblock);
|
||||
ATF_TP_ADD_TC(tp, paccept66_nonblock);
|
||||
ATF_TP_ADD_TC(tp, paccept46_reset_nonblock);
|
||||
ATF_TP_ADD_TC(tp, fcntl46_reset_nonblock);
|
||||
ATF_TP_ADD_TC(tp, paccept46_nonblock);
|
||||
return atf_no_error();
|
||||
}
|
||||
#else
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
paccept_block(AF_INET, false, false);
|
||||
paccept_block(AF_INET, true, false);
|
||||
paccept_block(AF_INET, AF_INET, false, false);
|
||||
paccept_block(AF_INET, AF_INET, true, false);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue