mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 07:22:34 +00:00
New address ACCEPT-FD
This commit is contained in:
parent
c311542e11
commit
ebacb7c4e8
10 changed files with 232 additions and 56 deletions
5
CHANGES
5
CHANGES
|
@ -117,6 +117,11 @@ Features:
|
|||
network namespace.
|
||||
Tests: NETNS NETNS_EXEC
|
||||
|
||||
New address ACCEPT-FD (ACCEPT) expects a listening file descriptor
|
||||
passed from parent, and accepts one or more connections for data
|
||||
transfer. This can be used with "inetd mode" of systemd.
|
||||
Test: ACCEPT_FD
|
||||
|
||||
Corrections:
|
||||
When a sub process (EXEC, SYSTEM) terminated with exit code other than
|
||||
0, its last sent data might have been lost depending on timing of read/
|
||||
|
|
29
doc/socat.yo
29
doc/socat.yo
|
@ -945,6 +945,18 @@ label(ADDRESS_SOCKET_SENDTO)dit(bf(tt(SOCKET-SENDTO:<domain>:<type>:<protocol>:<
|
|||
link(SOCKET-DATAGRAM)(ADDRESS_SOCKET_DATAGRAM),
|
||||
link(SOCKET-RECV)(ADDRESS_SOCKET_RECV)
|
||||
link(SOCKET-RECVFROM)(ADDRESS_SOCKET_RECVFROM)
|
||||
label(ADDRESS_ACCEPT_FD)dit(bf(tt(ACCEPT-FD:<fdnum>)))
|
||||
Expects a listening socket in <fdnum> and accepts one or (with option
|
||||
link(fork)(OPTION_FORK)) more connections. This address type is useful under
|
||||
systemd control with "inetd mode".nl()
|
||||
Example: (link(example)(EXAMPLE_ADDRESS_ACCEPT_FD))
|
||||
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET)link(TCP)(GROUP_TCP),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY) nl()
|
||||
Useful options:
|
||||
link(fork)(OPTION_FORK)),
|
||||
link(range)(OPTION_RANGE),
|
||||
link(sourceport)(OPTION_SOURCEPORT),
|
||||
link(lowport)(OPTION_LOWPORT),
|
||||
link(tcpwrap)(OPTION_TCPWRAPPERS),
|
||||
label(ADDRESS_SOCKS4)dit(bf(tt(SOCKS4:<socks-server>:<host>:<port>)))
|
||||
Connects via <socks-server> [link(IP address)(TYPE_IP_ADDRESS)]
|
||||
to <host> [link(IPv4 address)(TYPE_IPV4_ADDRESS)]
|
||||
|
@ -4140,6 +4152,23 @@ socat - \
|
|||
sends an SSDP (Simple Service Discovery Protocol) query to the local network
|
||||
and collects and outputs the answers received.
|
||||
|
||||
|
||||
label(EXAMPLE_ADDRESS_ACCEPT_FD)
|
||||
mancommand(\.LP)
|
||||
mancommand(\.nf)
|
||||
mancommand(\fBsystemd-socket-activate -l 1077 --inetd socat ACCEPT:0,fork PIPE\fP)
|
||||
mancommand(\.RE)
|
||||
mancommand(\.fi)
|
||||
|
||||
htmlcommand(<hr><div class="shell">systemd-socket-activate -l 1077 --inetd socat ACCEPT:0,fork PIPE</div>)
|
||||
|
||||
tt(systemd-socket-activate) is a program for testing tt(systemd) socket
|
||||
activation of daemons. With tt(--inetd) it waits for a connection on the
|
||||
specified port. It does not accept the connection but passes the listening file
|
||||
descriptor as FDs 0 and 1. Socat() accepts the waiting connection and starts
|
||||
data transfer.
|
||||
|
||||
|
||||
dit(bf(tt()))
|
||||
|
||||
|
||||
|
|
73
test.sh
73
test.sh
|
@ -6168,8 +6168,11 @@ if ! diff "$tref" "$tf" >"$tdiff"; then
|
|||
$PRINTF "$FAILED\n"
|
||||
echo "$CMD0 &"
|
||||
cat "${te}0" >&2
|
||||
echo "$CMD1"
|
||||
echo "$CMD1 &"
|
||||
cat "${te}1" >&2
|
||||
echo "$CMD1"
|
||||
cat "${te}2" >&2
|
||||
cat "$tdiff" >&2
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
else
|
||||
|
@ -6178,6 +6181,8 @@ else
|
|||
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
|
||||
if [ "$VERBOSE" ]; then echo "$CMD1"; fi
|
||||
if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
|
||||
if [ "$VERBOSE" ]; then echo "$CMD1"; fi
|
||||
if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
|
||||
numOK=$((numOK+1))
|
||||
fi # !(rc -ne 0)
|
||||
wait
|
||||
|
@ -16648,6 +16653,70 @@ PORT=$((PORT+1))
|
|||
N=$((N+1))
|
||||
|
||||
|
||||
# Test the ACCEPT-FD address
|
||||
NAME=ACCEPT_FD
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%bugs%*|*%socket%*|*%systemd%*|*%accept%*|*%$NAME%*)
|
||||
TEST="$NAME: ACCEPT-FD address"
|
||||
# Start Socat with address ACCEPT-FD via systemd-socket-activate for echoing
|
||||
# data.
|
||||
# Connect with a client; the test succeeds when the client gets its data back.
|
||||
if ! eval $NUMCOND; then :;
|
||||
elif ! $(type systemd-socket-activate >/dev/null 2>&1); then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}systemd-socket-activate not available${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif ! F=$(testfeats IP4 TCP LISTEN); then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif ! A=$(testaddrs ACCEPT-FD PIPE STDIO TCP4); then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif ! runsip4 >/dev/null; then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
else
|
||||
tf="$td/test$N.stdout"
|
||||
te="$td/test$N.stderr"
|
||||
tdiff="$td/test$N.diff"
|
||||
da="test$N $(date) $RANDOM"
|
||||
newport tcp4
|
||||
CMD0="systemd-socket-activate -l $PORT --inetd $TRACE $SOCAT $opts ACCEPT-FD:0 PIPE"
|
||||
CMD1="$TRACE $SOCAT $opts - TCP4:$LOCALHOST:$PORT"
|
||||
printf "test $F_n $TEST... " $N
|
||||
$CMD0 >/dev/null 2>"${te}0" &
|
||||
pid0=$!
|
||||
waittcp4port $PORT 1
|
||||
echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
|
||||
rc1=$?
|
||||
kill $pid0 2>/dev/null; wait
|
||||
if echo "$da" |diff "${tf}1" - >$tdiff; then
|
||||
$PRINTF "$OK\n"
|
||||
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
|
||||
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
|
||||
if [ "$VERBOSE" ]; then echo "$CMD1"; fi
|
||||
if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
|
||||
numOK=$((numOK+1))
|
||||
else
|
||||
$PRINTF "$FAILED\n"
|
||||
echo "$CMD0 &"
|
||||
cat "${te}0" >&2
|
||||
echo "$CMD1"
|
||||
cat "${te}1" >&2
|
||||
cat $tdiff >&2
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
namesFAIL="$namesFAIL $NAME"
|
||||
fi
|
||||
fi # NUMCOND
|
||||
;;
|
||||
esac
|
||||
N=$((N+1))
|
||||
|
||||
|
||||
# end of common tests
|
||||
|
||||
##################################################################################
|
||||
|
@ -16840,7 +16909,7 @@ wait<something>port $PORT 1
|
|||
echo "$da" |$CMD1 >"${tf}1" 2>"${te}1"
|
||||
rc1=$?
|
||||
kill $pid0 2>/dev/null; wait
|
||||
if [ !!! ]; then
|
||||
if echo "$da" |diff "${tf}1" - >$tdiff !!!; then
|
||||
$PRINTF "$OK\n"
|
||||
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
|
||||
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
|
||||
|
|
|
@ -35,7 +35,7 @@ static int xioopen_exec(int argc, const char *argv[], struct opt *opts,
|
|||
int duptostderr;
|
||||
|
||||
if (argc != 2) {
|
||||
Error3("\"%s:%s\": wrong number of parameters (%d instead of 1)", argv[0], argv[1], argc-1);
|
||||
Error2("\"%s\": wrong number of parameters (%d instead of 1)", argv[0], argc-1);
|
||||
}
|
||||
|
||||
retropt_bool(opts, OPT_DASH, &dash);
|
||||
|
|
57
xio-fdnum.c
57
xio-fdnum.c
|
@ -7,15 +7,21 @@
|
|||
#include "xiosysincludes.h"
|
||||
#include "xioopen.h"
|
||||
|
||||
#include "xio-listen.h"
|
||||
|
||||
#include "xio-fdnum.h"
|
||||
|
||||
|
||||
#if WITH_FDNUM
|
||||
|
||||
static int xioopen_fdnum(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3);
|
||||
static int xioopen_accept_fd(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3);
|
||||
|
||||
|
||||
const struct addrdesc xioaddr_fd = { "FD", 3, xioopen_fdnum, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_FILE|GROUP_SOCKET|GROUP_TERMIOS|GROUP_SOCK_UNIX|GROUP_SOCK_IP|GROUP_IPAPP, 0, 0, 0 HELP(":<num>") };
|
||||
const struct addrdesc xioaddr_fd = { "FD", 1+XIO_RDWR, xioopen_fdnum, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_FILE|GROUP_SOCKET|GROUP_TERMIOS|GROUP_SOCK_UNIX|GROUP_SOCK_IP|GROUP_IPAPP, 0, 0, 0 HELP(":<fdnum>") };
|
||||
#if WITH_LISTEN
|
||||
const struct addrdesc xioaddr_accept_fd = { "ACCEPT-FD", 1+XIO_RDWR, xioopen_accept_fd, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_SOCK_IP|GROUP_IPAPP|GROUP_CHILD|GROUP_RANGE|GROUP_RETRY, 0, 0, 0 HELP(":<fdnum>") };
|
||||
#endif /* WITH_LISTEN */
|
||||
|
||||
|
||||
/* use some file descriptor and apply the options. Set the FD_CLOEXEC flag. */
|
||||
|
@ -28,7 +34,7 @@ static int xioopen_fdnum(int argc, const char *argv[], struct opt *opts,
|
|||
int result;
|
||||
|
||||
if (argc != 2) {
|
||||
Error3("%s:%s: wrong number of parameters (%d instead of 1)", argv[0], argv[1], argc-1);
|
||||
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
|
||||
}
|
||||
|
||||
numfd = strtoul(argv[1], &a1, 0);
|
||||
|
@ -46,8 +52,55 @@ static int xioopen_fdnum(int argc, const char *argv[], struct opt *opts,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if WITH_LISTEN
|
||||
|
||||
/* Use some file descriptor and apply the options. Set the FD_CLOEXEC flag. */
|
||||
static int xioopen_accept_fd(
|
||||
int argc,
|
||||
const char *argv[],
|
||||
struct opt *opts,
|
||||
int xioflags,
|
||||
xiofile_t *xfd,
|
||||
groups_t groups,
|
||||
int dummy1,
|
||||
int dummy2,
|
||||
int dummy3)
|
||||
{
|
||||
char *a1;
|
||||
int rw = (xioflags&XIO_ACCMODE);
|
||||
int numfd;
|
||||
union sockaddr_union us;
|
||||
socklen_t uslen = sizeof(union sockaddr_union);
|
||||
int result;
|
||||
|
||||
if (argc != 2) {
|
||||
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
|
||||
}
|
||||
|
||||
numfd = strtoul(argv[1], &a1, 0);
|
||||
if (*a1 != '\0') {
|
||||
Error1("error in FD number \"%s\"", argv[1]);
|
||||
}
|
||||
/* we dont want to see these fds in child processes */
|
||||
if (Fcntl_l(numfd, F_SETFD, FD_CLOEXEC) < 0) {
|
||||
Warn2("fcntl(%d, F_SETFD, FD_CLOEXEC): %s", numfd, strerror(errno));
|
||||
}
|
||||
|
||||
if (Getsockname(numfd, (struct sockaddr *)&us, &uslen) < 0) {
|
||||
Warn2("getsockname(fd=%d, ...): %s", numfd, strerror(errno));
|
||||
}
|
||||
Notice2("using file descriptor %d accepting a connection for %s", numfd, ddirection[rw]);
|
||||
xfd->stream.fd = numfd;
|
||||
if ((result = _xioopen_accept_fd(&xfd->stream, xioflags, (struct sockaddr *)&us, uslen, opts, us.soa.sa_family, 0, 0)) < 0) {
|
||||
return result;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* WITH_LISTEN */
|
||||
#endif /* WITH_FDNUM */
|
||||
|
||||
|
||||
#if WITH_FD
|
||||
|
||||
/* retrieve and apply options to a standard file descriptor.
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#define __xio_fdnum_h_included 1
|
||||
|
||||
extern const struct addrdesc xioaddr_fd;
|
||||
extern const struct addrdesc xioaddr_accept_fd;
|
||||
|
||||
extern int xioopen_fd(struct opt *opts, int rw, xiosingle_t *xfd, int numfd, int dummy2, int dummy3);
|
||||
|
||||
|
|
114
xio-listen.c
114
xio-listen.c
|
@ -27,7 +27,6 @@ const struct optdesc opt_range = { "range", NULL, OPT_RANGE, GROUP_R
|
|||
#endif
|
||||
const struct optdesc opt_accept_timeout = { "accept-timeout", "listen-timeout", OPT_ACCEPT_TIMEOUT, GROUP_LISTEN, PH_LISTEN, TYPE_TIMEVAL, OFUNC_OFFSET, XIO_OFFSETOF(para.socket.accept_timeout) };
|
||||
|
||||
|
||||
/*
|
||||
applies and consumes the following option:
|
||||
PH_INIT, PH_PASTSOCKET, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_EARLY,
|
||||
|
@ -106,45 +105,11 @@ int
|
|||
*/
|
||||
int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, socklen_t uslen,
|
||||
struct opt *opts, int pf, int socktype, int proto, int level) {
|
||||
struct sockaddr sa;
|
||||
socklen_t salen;
|
||||
int backlog = 5; /* why? 1 seems to cause problems under some load */
|
||||
char *rangename;
|
||||
bool dofork = false;
|
||||
int maxchildren = 0;
|
||||
char infobuff[256];
|
||||
char lisname[256];
|
||||
union sockaddr_union _peername;
|
||||
union sockaddr_union _sockname;
|
||||
union sockaddr_union *pa = &_peername; /* peer address */
|
||||
union sockaddr_union *la = &_sockname; /* local address */
|
||||
socklen_t pas = sizeof(_peername); /* peer address size */
|
||||
socklen_t las = sizeof(_sockname); /* local address size */
|
||||
int result;
|
||||
|
||||
retropt_bool(opts, OPT_FORK, &dofork);
|
||||
|
||||
if (dofork) {
|
||||
if (!(xioflags & XIO_MAYFORK)) {
|
||||
Error("option fork not allowed here");
|
||||
return STAT_NORETRY;
|
||||
}
|
||||
xfd->flags |= XIO_DOESFORK;
|
||||
}
|
||||
|
||||
retropt_int(opts, OPT_MAX_CHILDREN, &maxchildren);
|
||||
|
||||
if (! dofork && maxchildren) {
|
||||
Error("option max-children not allowed without option fork");
|
||||
return STAT_NORETRY;
|
||||
}
|
||||
|
||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
||||
|
||||
if (dofork) {
|
||||
xiosetchilddied(); /* set SIGCHLD handler */
|
||||
}
|
||||
|
||||
if ((xfd->fd = xiosocket(opts, pf?pf:us->sa_family, socktype, proto, level)) < 0) {
|
||||
return STAT_RETRYLATER;
|
||||
}
|
||||
|
@ -175,13 +140,6 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl
|
|||
}
|
||||
}
|
||||
#endif
|
||||
/* under some circumstances (e.g., TCP listen on port 0) bind() fills empty
|
||||
fields that we want to know. */
|
||||
salen = sizeof(sa);
|
||||
if (Getsockname(xfd->fd, us, &uslen) < 0) {
|
||||
Warn4("getsockname(%d, %p, {%d}): %s",
|
||||
xfd->fd, &us, uslen, strerror(errno));
|
||||
}
|
||||
|
||||
applyopts(xfd->fd, opts, PH_PASTBIND);
|
||||
#if WITH_UNIX
|
||||
|
@ -197,6 +155,70 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl
|
|||
}
|
||||
#endif /* WITH_UNIX */
|
||||
|
||||
applyopts(xfd->fd, opts, PH_PRELISTEN);
|
||||
retropt_int(opts, OPT_BACKLOG, &backlog);
|
||||
applyopts(xfd->fd, opts, PH_LISTEN);
|
||||
if (Listen(xfd->fd, backlog) < 0) {
|
||||
Error3("listen(%d, %d): %s", xfd->fd, backlog, strerror(errno));
|
||||
return STAT_RETRYLATER;
|
||||
}
|
||||
return _xioopen_accept_fd(xfd, xioflags, us, uslen, opts, pf, proto,level);
|
||||
}
|
||||
|
||||
int _xioopen_accept_fd(
|
||||
struct single *xfd,
|
||||
int xioflags,
|
||||
struct sockaddr *us,
|
||||
socklen_t uslen,
|
||||
struct opt *opts,
|
||||
int pf,
|
||||
int proto,
|
||||
int level)
|
||||
{
|
||||
struct sockaddr sa;
|
||||
socklen_t salen;
|
||||
char *rangename;
|
||||
bool dofork = false;
|
||||
int maxchildren = 0;
|
||||
char infobuff[256];
|
||||
char lisname[256];
|
||||
union sockaddr_union _peername;
|
||||
union sockaddr_union _sockname;
|
||||
union sockaddr_union *pa = &_peername; /* peer address */
|
||||
union sockaddr_union *la = &_sockname; /* local address */
|
||||
socklen_t pas = sizeof(_peername); /* peer address size */
|
||||
socklen_t las = sizeof(_sockname); /* local address size */
|
||||
int result;
|
||||
|
||||
retropt_bool(opts, OPT_FORK, &dofork);
|
||||
|
||||
if (dofork) {
|
||||
if (!(xioflags & XIO_MAYFORK)) {
|
||||
Error("option fork not allowed here");
|
||||
return STAT_NORETRY;
|
||||
}
|
||||
xfd->flags |= XIO_DOESFORK;
|
||||
}
|
||||
|
||||
retropt_int(opts, OPT_MAX_CHILDREN, &maxchildren);
|
||||
|
||||
if (! dofork && maxchildren) {
|
||||
Error("option max-children not allowed without option fork");
|
||||
return STAT_NORETRY;
|
||||
}
|
||||
|
||||
if (dofork) {
|
||||
xiosetchilddied(); /* set SIGCHLD handler */
|
||||
}
|
||||
|
||||
/* Under some circumstances (e.g., TCP listen on port 0) bind() fills empty
|
||||
fields that we want to know. */
|
||||
salen = sizeof(sa);
|
||||
if (Getsockname(xfd->fd, us, &uslen) < 0) {
|
||||
Warn4("getsockname(%d, %p, {%d}): %s",
|
||||
xfd->fd, &us, uslen, strerror(errno));
|
||||
}
|
||||
|
||||
#if WITH_IP4 /*|| WITH_IP6*/
|
||||
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
||||
if (xioparserange(rangename, pf, &xfd->para.socket.range,
|
||||
|
@ -221,14 +243,6 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl
|
|||
retropt_bool(opts, OPT_LOWPORT, &xfd->para.socket.ip.lowport);
|
||||
#endif /* WITH_TCP || WITH_UDP */
|
||||
|
||||
applyopts(xfd->fd, opts, PH_PRELISTEN);
|
||||
retropt_int(opts, OPT_BACKLOG, &backlog);
|
||||
applyopts(xfd->fd, opts, PH_LISTEN);
|
||||
if (Listen(xfd->fd, backlog) < 0) {
|
||||
Error3("listen(%d, %d): %s", xfd->fd, backlog, strerror(errno));
|
||||
return STAT_RETRYLATER;
|
||||
}
|
||||
|
||||
if (xioparms.logopt == 'm') {
|
||||
Info("starting accept loop, switching to syslog");
|
||||
diag_set('y', xioparms.syslogfac); xioparms.logopt = 'y';
|
||||
|
|
|
@ -20,5 +20,6 @@ int
|
|||
int _xioopen_listen(struct single *fd, int xioflags,
|
||||
struct sockaddr *us, socklen_t uslen,
|
||||
struct opt *opts, int pf, int socktype, int proto, int level);
|
||||
extern int _xioopen_accept_fd(struct single *xfd, int xioflags, struct sockaddr *us, socklen_t uslen, struct opt *opts, int pf, int proto, int level);
|
||||
|
||||
#endif /* !defined(__xio_listen_h_included) */
|
||||
|
|
|
@ -1847,7 +1847,7 @@ int xioparsenetwork(
|
|||
char *addrname;
|
||||
const char *maskname;
|
||||
if ((maskname = strchr(rangename, ':')) == NULL) {
|
||||
Error1("syntax error in range \"%s\": use <addr>:<mask>", rangename);
|
||||
Error1("syntax error in range \"%s\" of unspecified address family: use <addr>:<mask>", rangename);
|
||||
return STAT_NORETRY;
|
||||
}
|
||||
++maskname; /* skip ':' */
|
||||
|
|
|
@ -33,6 +33,10 @@ const struct addrname addressnames[] = {
|
|||
{ "ABSTRACT-RECVFROM", &xioaddr_abstract_recvfrom },
|
||||
{ "ABSTRACT-SENDTO", &xioaddr_abstract_sendto },
|
||||
#endif /* defined(WITH_UNIX) && defined(WITH_ABSTRACT_UNIXSOCKET) */
|
||||
#if WITH_LISTEN
|
||||
{ "ACCEPT", &xioaddr_accept_fd },
|
||||
{ "ACCEPT-FD", &xioaddr_accept_fd },
|
||||
#endif
|
||||
#if WITH_CREAT
|
||||
{ "CREAT", &xioaddr_creat },
|
||||
{ "CREATE", &xioaddr_creat },
|
||||
|
|
Loading…
Reference in a new issue