- use accept4 instead of paccept for everyone.
- add test for accept preserving non-block - comment on FreeBSD and Linux behavior.
This commit is contained in:
parent
c61fe20bc9
commit
a33f2da334
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: t_tcp.c,v 1.10 2018/02/16 22:20:18 christos Exp $ */
|
||||
/* $NetBSD: t_tcp.c,v 1.11 2019/10/26 23:08:27 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2013 The NetBSD Foundation, Inc.
|
||||
@ -33,22 +33,27 @@
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifdef __RCSID
|
||||
__RCSID("$Id: t_tcp.c,v 1.10 2018/02/16 22:20:18 christos Exp $");
|
||||
__RCSID("$Id: t_tcp.c,v 1.11 2019/10/26 23:08:27 christos Exp $");
|
||||
#endif
|
||||
|
||||
/* Example code. Should block; does with accept not paccept. */
|
||||
/* Example code. Should block; does with accept not accept4_. */
|
||||
/* Original by: Justin Cormack <justin@specialbusrvrervice.com> */
|
||||
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sched.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <err.h>
|
||||
@ -58,18 +63,14 @@ __RCSID("$Id: t_tcp.c,v 1.10 2018/02/16 22:20:18 christos Exp $");
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#define paccept(a, b, c, d, e) accept4((a), (b), (c), (e))
|
||||
#endif
|
||||
|
||||
static void
|
||||
ding(int al)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
paccept_block(sa_family_t sfamily, sa_family_t cfamily,
|
||||
bool pacceptblock, bool fcntlblock)
|
||||
accept_test(sa_family_t sfamily, sa_family_t cfamily,
|
||||
bool useaccept, bool accept4_block, bool fcntlblock)
|
||||
{
|
||||
int srvr = -1, clnt = -1, acpt = -1;
|
||||
int ok, fl;
|
||||
@ -152,9 +153,19 @@ paccept_block(sa_family_t sfamily, sa_family_t cfamily,
|
||||
|
||||
/* may not connect first time */
|
||||
ok = connect(clnt, (struct sockaddr *) &bs, addrlen);
|
||||
#ifndef __FreeBSD__
|
||||
/* FreeBSD: What's going on here, connect succeeds with no-one
|
||||
* accepting?
|
||||
*/
|
||||
if (ok != -1 || errno != EINPROGRESS)
|
||||
FAIL("expected connect to fail");
|
||||
acpt = paccept(srvr, NULL, NULL, NULL, pacceptblock ? 0 : SOCK_NONBLOCK);
|
||||
#endif
|
||||
if (useaccept) {
|
||||
acpt = accept(srvr, NULL, NULL);
|
||||
} else {
|
||||
acpt = accept4(srvr, NULL, NULL,
|
||||
accept4_block ? 0 : SOCK_NONBLOCK);
|
||||
}
|
||||
again:
|
||||
ok = connect(clnt, (struct sockaddr *) &bs, addrlen);
|
||||
if (ok == -1 && errno != EISCONN) {
|
||||
@ -183,28 +194,44 @@ again:
|
||||
#endif
|
||||
|
||||
if (acpt == -1) { /* not true under NetBSD */
|
||||
acpt = paccept(srvr, NULL, NULL, NULL,
|
||||
pacceptblock ? 0 : SOCK_NONBLOCK);
|
||||
if (useaccept) {
|
||||
acpt = accept(srvr, NULL, NULL);
|
||||
} else {
|
||||
acpt = accept4(srvr, NULL, NULL,
|
||||
accept4_block ? 0 : SOCK_NONBLOCK);
|
||||
}
|
||||
if (acpt == -1)
|
||||
FAIL("paccept");
|
||||
FAIL("accept4_");
|
||||
}
|
||||
/* This is supposed to only work on Unix sockets but returns garbage */
|
||||
#ifdef BSD4_4
|
||||
#ifndef __FreeBSD__
|
||||
/* NetBSD: This is supposed to only work on Unix sockets but returns
|
||||
* garbage
|
||||
* FreeBSD: fails with EISCONN
|
||||
*/
|
||||
|
||||
if (getpeereid(clnt, &euid, &egid) != -1)
|
||||
FAIL("getpeereid(clnt)");
|
||||
/* This is supposed to only work on Unix sockets but returns garbage */
|
||||
/* NetBSD: This is supposed to only work on Unix sockets but returns
|
||||
* garbage
|
||||
* FreeBSD: fails with EISCONN
|
||||
*/
|
||||
if (getpeereid(acpt, &euid, &egid) != -1)
|
||||
FAIL("getpeereid(srvr)");
|
||||
|
||||
if (fcntlblock) {
|
||||
#endif
|
||||
#endif
|
||||
if (fcntlblock || useaccept) {
|
||||
fl = fcntl(acpt, F_GETFL, 0);
|
||||
if (fl == -1)
|
||||
FAIL("fnctl");
|
||||
#ifndef __linux__
|
||||
/* Linux accept returns a blocking socket */
|
||||
if (fl != (O_RDWR|O_NONBLOCK))
|
||||
FAIL("fl 0x%x != 0x%x\n", fl, O_RDWR|O_NONBLOCK);
|
||||
ok = fcntl(acpt, F_SETFL, fl & ~O_NONBLOCK);
|
||||
if (ok == -1)
|
||||
FAIL("fnctl setfl");
|
||||
|
||||
#endif
|
||||
fl = fcntl(acpt, F_GETFL, 0);
|
||||
if (fl & O_NONBLOCK)
|
||||
FAIL("fl non blocking after reset");
|
||||
@ -216,7 +243,7 @@ again:
|
||||
alarm(1);
|
||||
n = read(acpt, buf, 10);
|
||||
|
||||
if (pacceptblock || fcntlblock) {
|
||||
if (useaccept || accept4_block || fcntlblock) {
|
||||
if (n == -1 && errno != EINTR)
|
||||
FAIL("read");
|
||||
} else {
|
||||
@ -232,17 +259,30 @@ fail:
|
||||
|
||||
#ifndef TEST
|
||||
|
||||
ATF_TC(paccept44_reset_nonblock);
|
||||
ATF_TC_HEAD(paccept44_reset_nonblock, tc)
|
||||
ATF_TC(accept_44_preserve_nonblock);
|
||||
ATF_TC_HEAD(accept_44_preserve_nonblock, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "Check that paccept(2) resets "
|
||||
atf_tc_set_md_var(tc, "descr", "Check that accept(2) preserves "
|
||||
"the non-blocking flag on non-blocking sockets (ipv4->ipv4)");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(paccept44_reset_nonblock, tc)
|
||||
ATF_TC_BODY(accept_44_preserve_nonblock, tc)
|
||||
{
|
||||
paccept_block(AF_INET, AF_INET, true, false);
|
||||
accept_test(AF_INET, AF_INET, true, false, false);
|
||||
}
|
||||
|
||||
ATF_TC(accept4_44_reset_nonblock);
|
||||
ATF_TC_HEAD(accept4_44_reset_nonblock, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "Check that accept4(2) resets "
|
||||
"the non-blocking flag on non-blocking sockets (ipv4->ipv4)");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(accept4_44_reset_nonblock, tc)
|
||||
{
|
||||
accept_test(AF_INET, AF_INET, false, true, false);
|
||||
}
|
||||
|
||||
ATF_TC(fcntl44_reset_nonblock);
|
||||
@ -255,33 +295,33 @@ ATF_TC_HEAD(fcntl44_reset_nonblock, tc)
|
||||
|
||||
ATF_TC_BODY(fcntl44_reset_nonblock, tc)
|
||||
{
|
||||
paccept_block(AF_INET, AF_INET, false, true);
|
||||
accept_test(AF_INET, AF_INET, false, false, true);
|
||||
}
|
||||
|
||||
ATF_TC(paccept44_nonblock);
|
||||
ATF_TC_HEAD(paccept44_nonblock, tc)
|
||||
ATF_TC(accept4_44_nonblock);
|
||||
ATF_TC_HEAD(accept4_44_nonblock, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "Check that fcntl(2) resets "
|
||||
"the non-blocking flag on non-blocking sockets (ipv4->ipv4)");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(paccept44_nonblock, tc)
|
||||
ATF_TC_BODY(accept4_44_nonblock, tc)
|
||||
{
|
||||
paccept_block(AF_INET, AF_INET, false, false);
|
||||
accept_test(AF_INET, AF_INET, false, false, false);
|
||||
}
|
||||
|
||||
ATF_TC(paccept66_reset_nonblock);
|
||||
ATF_TC_HEAD(paccept66_reset_nonblock, tc)
|
||||
ATF_TC(accept4_66_reset_nonblock);
|
||||
ATF_TC_HEAD(accept4_66_reset_nonblock, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "Check that paccept(2) resets "
|
||||
atf_tc_set_md_var(tc, "descr", "Check that accept4(2) resets "
|
||||
"the non-blocking flag on non-blocking sockets (ipv6->ipv6)");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(paccept66_reset_nonblock, tc)
|
||||
ATF_TC_BODY(accept4_66_reset_nonblock, tc)
|
||||
{
|
||||
paccept_block(AF_INET6, AF_INET6, true, false);
|
||||
accept_test(AF_INET6, AF_INET6, false, true, false);
|
||||
}
|
||||
|
||||
ATF_TC(fcntl66_reset_nonblock);
|
||||
@ -294,33 +334,33 @@ ATF_TC_HEAD(fcntl66_reset_nonblock, tc)
|
||||
|
||||
ATF_TC_BODY(fcntl66_reset_nonblock, tc)
|
||||
{
|
||||
paccept_block(AF_INET6, AF_INET6, false, true);
|
||||
accept_test(AF_INET6, AF_INET6, false, false, true);
|
||||
}
|
||||
|
||||
ATF_TC(paccept66_nonblock);
|
||||
ATF_TC_HEAD(paccept66_nonblock, tc)
|
||||
ATF_TC(accept4_66_nonblock);
|
||||
ATF_TC_HEAD(accept4_66_nonblock, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "Check that fcntl(2) resets "
|
||||
"the non-blocking flag on non-blocking sockets (ipv6->ipv6)");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(paccept66_nonblock, tc)
|
||||
ATF_TC_BODY(accept4_66_nonblock, tc)
|
||||
{
|
||||
paccept_block(AF_INET6, AF_INET6, false, false);
|
||||
accept_test(AF_INET6, AF_INET6, false, false, false);
|
||||
}
|
||||
|
||||
ATF_TC(paccept46_reset_nonblock);
|
||||
ATF_TC_HEAD(paccept46_reset_nonblock, tc)
|
||||
ATF_TC(accept4_46_reset_nonblock);
|
||||
ATF_TC_HEAD(accept4_46_reset_nonblock, tc)
|
||||
{
|
||||
|
||||
atf_tc_set_md_var(tc, "descr", "Check that paccept(2) resets "
|
||||
atf_tc_set_md_var(tc, "descr", "Check that accept4(2) resets "
|
||||
"the non-blocking flag on non-blocking sockets (ipv4->ipv6)");
|
||||
}
|
||||
|
||||
ATF_TC_BODY(paccept46_reset_nonblock, tc)
|
||||
ATF_TC_BODY(accept4_46_reset_nonblock, tc)
|
||||
{
|
||||
paccept_block(AF_INET6, AF_INET, true, false);
|
||||
accept_test(AF_INET6, AF_INET, false, true, false);
|
||||
}
|
||||
|
||||
ATF_TC(fcntl46_reset_nonblock);
|
||||
@ -333,42 +373,42 @@ ATF_TC_HEAD(fcntl46_reset_nonblock, tc)
|
||||
|
||||
ATF_TC_BODY(fcntl46_reset_nonblock, tc)
|
||||
{
|
||||
paccept_block(AF_INET6, AF_INET, false, true);
|
||||
accept_test(AF_INET6, AF_INET, false, false, true);
|
||||
}
|
||||
|
||||
ATF_TC(paccept46_nonblock);
|
||||
ATF_TC_HEAD(paccept46_nonblock, tc)
|
||||
ATF_TC(accept4_46_nonblock);
|
||||
ATF_TC_HEAD(accept4_46_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)
|
||||
ATF_TC_BODY(accept4_46_nonblock, tc)
|
||||
{
|
||||
paccept_block(AF_INET6, AF_INET, false, false);
|
||||
accept_test(AF_INET6, AF_INET, false, false, false);
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
|
||||
ATF_TP_ADD_TC(tp, paccept44_reset_nonblock);
|
||||
ATF_TP_ADD_TC(tp, accept_44_preserve_nonblock);
|
||||
ATF_TP_ADD_TC(tp, accept4_44_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, accept4_44_nonblock);
|
||||
ATF_TP_ADD_TC(tp, accept4_66_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, accept4_66_nonblock);
|
||||
ATF_TP_ADD_TC(tp, accept4_46_reset_nonblock);
|
||||
ATF_TP_ADD_TC(tp, fcntl46_reset_nonblock);
|
||||
ATF_TP_ADD_TC(tp, paccept46_nonblock);
|
||||
ATF_TP_ADD_TC(tp, accept4_46_nonblock);
|
||||
return atf_no_error();
|
||||
}
|
||||
#else
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
paccept_block(AF_INET, AF_INET, false, false);
|
||||
paccept_block(AF_INET, AF_INET, true, false);
|
||||
accept_test(AF_INET, AF_INET, true, true, false);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user