mirror of
https://github.com/moparisthebest/socat
synced 2024-12-21 14:38:48 -05:00
merged feature protocol-type
This commit is contained in:
commit
86c596bd51
6
CHANGES
6
CHANGES
@ -31,6 +31,10 @@ new features:
|
|||||||
new address options ipv6-tclass and ipv6-unicast-hops set the related
|
new address options ipv6-tclass and ipv6-unicast-hops set the related
|
||||||
socket options.
|
socket options.
|
||||||
|
|
||||||
|
so-type now only affect the socket() and socketpair() calls, not the
|
||||||
|
name resolution. so-type and so-prototype can be applied to all socket
|
||||||
|
based addresses.
|
||||||
|
|
||||||
corrections:
|
corrections:
|
||||||
some raw IP and UNIX datagram modes failed on BSD systems
|
some raw IP and UNIX datagram modes failed on BSD systems
|
||||||
|
|
||||||
@ -78,6 +82,8 @@ further changes:
|
|||||||
Makefile now supports datarootdir (thanks to Camillo Lugaresi for
|
Makefile now supports datarootdir (thanks to Camillo Lugaresi for
|
||||||
providing the patch)
|
providing the patch)
|
||||||
|
|
||||||
|
cleanup in xio-unix.c
|
||||||
|
|
||||||
####################### V 1.6.0.1:
|
####################### V 1.6.0.1:
|
||||||
|
|
||||||
new features:
|
new features:
|
||||||
|
2
VERSION
2
VERSION
@ -1 +1 @@
|
|||||||
"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock+escape+timestamp+ancillary+envvar"
|
"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock+escape+timestamp+ancillary+envvar+protocol"
|
||||||
|
23
doc/socat.yo
23
doc/socat.yo
@ -1590,11 +1590,23 @@ label(OPTION_SNDLOWAT)dit(bf(tt(sndlowat=<bytes>)))
|
|||||||
layer will send the data to <bytes> [link(int)(TYPE_INT)].
|
layer will send the data to <bytes> [link(int)(TYPE_INT)].
|
||||||
label(OPTION_SNDTIMEO)dit(bf(tt(sndtimeo=<seconds>)))
|
label(OPTION_SNDTIMEO)dit(bf(tt(sndtimeo=<seconds>)))
|
||||||
Sets the send timeout to seconds [link(timeval)(TYPE_TIMEVAL)].
|
Sets the send timeout to seconds [link(timeval)(TYPE_TIMEVAL)].
|
||||||
label(OPTION_TYPE)dit(bf(tt(type=<type>)))
|
label(OPTION_PROTOCOL_FAMILY)dit(bf(tt(pf=<string>)))
|
||||||
Sets the type of the socket, usually as argument to the code(socket()) or
|
Forces the use of the specified IP version or protocol. <string> can be
|
||||||
code(socketpair()) call, to <type> [link(int)(TYPE_INT)].
|
something like "ip4" or "ip6". The resulting value is
|
||||||
|
used as first argument to the code(socket()) or code(socketpair()) calls.
|
||||||
|
This option affects address resolution and the required syntax of bind and
|
||||||
|
range options.
|
||||||
|
label(OPTION_SO_TYPE)dit(bf(tt(type=<type>)))
|
||||||
|
Sets the type of the socket, specified as second argument to the
|
||||||
|
code(socket()) or code(socketpair()) calls, to <type>
|
||||||
|
[link(int)(TYPE_INT)]. Address resolution is not affected by this option.
|
||||||
Under Linux, 1 means stream oriented socket, 2 means datagram socket, and 3
|
Under Linux, 1 means stream oriented socket, 2 means datagram socket, and 3
|
||||||
means raw socket.
|
means raw socket.
|
||||||
|
label(OPTION_SO_PROTOTYPE)dit(bf(tt(prototype)))
|
||||||
|
Sets the protocol of the socket, specified as third argument to the
|
||||||
|
code(socket()) or code(socketpair()) calls, to <prototype>
|
||||||
|
[link(int)(TYPE_INT)]. Address resolution is not affected by this option.
|
||||||
|
6 means TCP, 17 means UDP.
|
||||||
COMMENT(label(OPTION_USELOOPBACK)dit(bf(tt(useloopback)))
|
COMMENT(label(OPTION_USELOOPBACK)dit(bf(tt(useloopback)))
|
||||||
Sets the code(SO_USELOOPBACK) socket option.)
|
Sets the code(SO_USELOOPBACK) socket option.)
|
||||||
COMMENT(label(OPTION_ACCEPTCONN)dit(bf(tt(acceptconn)))
|
COMMENT(label(OPTION_ACCEPTCONN)dit(bf(tt(acceptconn)))
|
||||||
@ -1623,8 +1635,6 @@ COMMENT(label(OPTION_PASSCRED)dit(bf(tt(passcred)))
|
|||||||
Set the code(SO_PASSCRED) socket option.)
|
Set the code(SO_PASSCRED) socket option.)
|
||||||
COMMENT(label(OPTION_PEERCRED)dit(bf(tt(peercred)))
|
COMMENT(label(OPTION_PEERCRED)dit(bf(tt(peercred)))
|
||||||
This is a read-only socket option.)
|
This is a read-only socket option.)
|
||||||
COMMENT(label(OPTION_PROTOTYPE)dit(bf(tt(prototype)))
|
|
||||||
Tries to set the code(SO_PROTOTYPE) socket option.)
|
|
||||||
COMMENT(label(OPTION_REUSEPORT)dit(bf(tt(reuseport)))
|
COMMENT(label(OPTION_REUSEPORT)dit(bf(tt(reuseport)))
|
||||||
Set the code(SO_REUSEPORT) socket option.)
|
Set the code(SO_REUSEPORT) socket option.)
|
||||||
COMMENT(label(OPTION_SECUTIYAUTHENTICATION)dit(bf(tt(securityauthentication)))
|
COMMENT(label(OPTION_SECUTIYAUTHENTICATION)dit(bf(tt(securityauthentication)))
|
||||||
@ -1637,9 +1647,6 @@ COMMENT(label(OPTION_SIOCSPGRP)dit(bf(tt(siocspgrp=<pid_t>)))
|
|||||||
Set the SIOCSPGRP with code(ioclt()) to enable SIGIO.)
|
Set the SIOCSPGRP with code(ioclt()) to enable SIGIO.)
|
||||||
COMMENT(label(OPTION_USEIFBUFS)dit(bf(tt(useifbufs)))
|
COMMENT(label(OPTION_USEIFBUFS)dit(bf(tt(useifbufs)))
|
||||||
Set the code(SO_USE_IFBUFS) socket option.)
|
Set the code(SO_USE_IFBUFS) socket option.)
|
||||||
label(OPTION_PROTOCOL_FAMILY)dit(bf(tt(pf=<string>)))
|
|
||||||
Forces the use of the specified IP version. <string> can be
|
|
||||||
something like "ip4" or "ip6".
|
|
||||||
label(OPTION_SO_TIMESTAMP)dit(bf(tt(so-timestamp)))
|
label(OPTION_SO_TIMESTAMP)dit(bf(tt(so-timestamp)))
|
||||||
Sets the SO_TIMESTAMP socket option. This enables receiving and logging of
|
Sets the SO_TIMESTAMP socket option. This enables receiving and logging of
|
||||||
timestamp ancillary messages.
|
timestamp ancillary messages.
|
||||||
|
3
filan.c
3
filan.c
@ -479,6 +479,9 @@ int sockan(int fd, FILE *outfile) {
|
|||||||
{SO_REUSEADDR, "REUSEADDR"},
|
{SO_REUSEADDR, "REUSEADDR"},
|
||||||
{SO_TYPE, "TYPE"},
|
{SO_TYPE, "TYPE"},
|
||||||
{SO_ERROR, "ERROR"},
|
{SO_ERROR, "ERROR"},
|
||||||
|
#ifdef SO_PROTOTYPE
|
||||||
|
{SO_PROTOTYPE, "PROTOTYPE"},
|
||||||
|
#endif
|
||||||
{SO_DONTROUTE, "DONTROUTE"},
|
{SO_DONTROUTE, "DONTROUTE"},
|
||||||
{SO_BROADCAST, "BROADCAST"},
|
{SO_BROADCAST, "BROADCAST"},
|
||||||
{SO_SNDBUF, "SNDBUF"},
|
{SO_SNDBUF, "SNDBUF"},
|
||||||
|
82
test.sh
82
test.sh
@ -2374,9 +2374,9 @@ N=$((N+1))
|
|||||||
#}
|
#}
|
||||||
|
|
||||||
|
|
||||||
NAME=UNIXSOCKET
|
NAME=UNIXSTREAM
|
||||||
case "$TESTS" in
|
case "$TESTS" in
|
||||||
*%functions%*|*%$NAME%*)
|
*%functions%*|*%unix%*|*%$NAME%*)
|
||||||
TEST="$NAME: echo via connection to UNIX domain socket"
|
TEST="$NAME: echo via connection to UNIX domain socket"
|
||||||
tf="$td/test$N.stdout"
|
tf="$td/test$N.stdout"
|
||||||
te="$td/test$N.stderr"
|
te="$td/test$N.stderr"
|
||||||
@ -2384,7 +2384,7 @@ ts="$td/test$N.socket"
|
|||||||
tdiff="$td/test$N.diff"
|
tdiff="$td/test$N.diff"
|
||||||
da="test$N $(date) $RANDOM"
|
da="test$N $(date) $RANDOM"
|
||||||
CMD1="$SOCAT $opts UNIX-LISTEN:$ts PIPE"
|
CMD1="$SOCAT $opts UNIX-LISTEN:$ts PIPE"
|
||||||
CMD2="$SOCAT $opts -!!- UNIX:$ts"
|
CMD2="$SOCAT $opts -!!- UNIX-CONNECT:$ts"
|
||||||
printf "test $F_n $TEST... " $N
|
printf "test $F_n $TEST... " $N
|
||||||
$CMD1 </dev/null >$tf 2>"${te}1" &
|
$CMD1 </dev/null >$tf 2>"${te}1" &
|
||||||
bg=$! # background process id
|
bg=$! # background process id
|
||||||
@ -8520,82 +8520,6 @@ esac
|
|||||||
N=$((N+1))
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
while read SCM_ENABLE SCM_RECV SCM_TYPE SCM_NAME SCM_VALUE
|
|
||||||
do
|
|
||||||
|
|
||||||
# test: logging of ancillary message with ip-recvopt
|
|
||||||
NAME=UDP4SCM_$SCM_TYPE
|
|
||||||
case "$TESTS" in
|
|
||||||
*%functions%*|*%ip4%*|*%dgram%*|*%udp%*|*%udp4%*|*%recv%*|*%ancillary%*|*%$NAME%*)
|
|
||||||
#set -vx
|
|
||||||
TEST="$NAME: IPv4 ancillary messages"
|
|
||||||
# idea: start a socat process with udp4-recv:..,ip-recvopts and send it a packet
|
|
||||||
# with IP options (ip-options). check the info log for the appropriate output.
|
|
||||||
tf="$td/test$N.stdout"
|
|
||||||
te="$td/test$N.stderr"
|
|
||||||
ts1p=$PORT; PORT=$((PORT+1))
|
|
||||||
ts1a="127.0.0.1"
|
|
||||||
ts1="$ts1a:$ts1p"
|
|
||||||
CMD0="$SOCAT $opts -d -d -d -u UDP4-RECV:$ts1p,reuseaddr,$SCM_RECV -"
|
|
||||||
CMD1="$SOCAT $opts -u - UDP4-SENDTO:$ts1,$SCM_ENABLE"
|
|
||||||
printf "test $F_n $TEST... " $N
|
|
||||||
# is this option supported?
|
|
||||||
if $SOCAT -hhh |grep "[[:space:]]$SCM_RECV[[:space:]]" >/dev/null; then
|
|
||||||
$CMD0 >"$tf" 2>"${te}0" &
|
|
||||||
pid0="$!"
|
|
||||||
waitudp4port $ts1p 1
|
|
||||||
echo "XYZ" |$CMD1 2>>"${te}1"
|
|
||||||
rc1="$?"
|
|
||||||
sleep 1
|
|
||||||
i=0; while [ ! -s "${te}0" -a "$i" -lt 10 ]; do usleep 100000; i=$((i+1)); done
|
|
||||||
kill "$pid0" 2>/dev/null; wait
|
|
||||||
# do not show more messages than requested
|
|
||||||
case "$opts" in
|
|
||||||
*-d*-d*-d*-d*) LEVELS="[EWNID]" ;;
|
|
||||||
*-d*-d*-d*) LEVELS="[EWNI]" ;;
|
|
||||||
*-d*-d*) LEVELS="[EWN]" ;;
|
|
||||||
*-d*) LEVELS="[EW]" ;;
|
|
||||||
*) LEVELS="[E]" ;;
|
|
||||||
esac
|
|
||||||
if [ "$rc1" -ne 0 ]; then
|
|
||||||
$PRINTF "$FAILED: $SOCAT:\n"
|
|
||||||
echo "$CMD0 &"
|
|
||||||
echo "$CMD1"
|
|
||||||
grep " $LEVELS " "${te}0"
|
|
||||||
grep " $LEVELS " "${te}1"
|
|
||||||
numFAIL=$((numFAIL+1))
|
|
||||||
elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=$SCM_VALUE" ${te}0 >/dev/null; then
|
|
||||||
$PRINTF "$FAILED\n"
|
|
||||||
echo "$CMD0 &"
|
|
||||||
echo "$CMD1"
|
|
||||||
grep " $LEVELS " "${te}0"
|
|
||||||
grep " $LEVELS " "${te}1"
|
|
||||||
numFAIL=$((numFAIL+1))
|
|
||||||
else
|
|
||||||
$PRINTF "$OK\n"
|
|
||||||
if [ -n "$debug" ]; then
|
|
||||||
grep " $LEVELS " "${te}0"; echo; grep " $LEVELS " "${te}1";
|
|
||||||
fi
|
|
||||||
numOK=$((numOK+1))
|
|
||||||
fi
|
|
||||||
else # option is not supported
|
|
||||||
$PRINTF "${YELLOW}$SCM_RECV not available${NORMAL}\n"
|
|
||||||
numCANT=$((numCANT+1))
|
|
||||||
fi # option is not supported
|
|
||||||
set +vx
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
N=$((N+1))
|
|
||||||
|
|
||||||
done <<<"ip-options=x01000000 ip-recvopts IP_OPTIONS options x01000000
|
|
||||||
, so-timestamp SCM_TIMESTAMP timestamp $(date '+%a %b %e %H:%M:.. %Y')
|
|
||||||
ip-ttl=53 ip-recvttl IP_TTL ttl 53
|
|
||||||
ip-tos=7 ip-recvtos IP_TOS tos 7
|
|
||||||
, ip-pktinfo IP_PKTINFO locaddr 127.0.0.1
|
|
||||||
, ip-recvif IP_RECVIF if lo
|
|
||||||
, ip-recvdstaddr IP_RECVDSTADDR dstaddr 127.0.0.1"
|
|
||||||
|
|
||||||
|
|
||||||
# test: logging of ancillary message
|
# test: logging of ancillary message
|
||||||
while read PF KEYW ADDR IPPORT SCM_ENABLE SCM_RECV SCM_TYPE SCM_NAME ROOT SCM_VALUE
|
while read PF KEYW ADDR IPPORT SCM_ENABLE SCM_RECV SCM_TYPE SCM_NAME ROOT SCM_VALUE
|
||||||
do
|
do
|
||||||
|
113
xio-gopen.c
113
xio-gopen.c
@ -45,113 +45,17 @@ static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xio
|
|||||||
/* note: when S_ISSOCK was undefined, it always gives 0 */
|
/* note: when S_ISSOCK was undefined, it always gives 0 */
|
||||||
if (exists && S_ISSOCK(st_mode)) {
|
if (exists && S_ISSOCK(st_mode)) {
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
int socktype = SOCK_STREAM;
|
union sockaddr_union us;
|
||||||
int optsotype = -1;
|
socklen_t uslen;
|
||||||
struct sockaddr_un sa, us;
|
|
||||||
socklen_t salen, uslen = sizeof(us);
|
|
||||||
bool needbind = false;
|
|
||||||
char infobuff[256];
|
char infobuff[256];
|
||||||
struct opt *opts2;
|
|
||||||
|
|
||||||
socket_un_init(&sa);
|
|
||||||
socket_un_init(&us);
|
|
||||||
|
|
||||||
Info1("\"%s\" is a socket, connecting to it", filename);
|
Info1("\"%s\" is a socket, connecting to it", filename);
|
||||||
if (retropt_int(opts, OPT_SO_TYPE, &optsotype) == 0) {
|
|
||||||
socktype = optsotype;
|
result =
|
||||||
|
_xioopen_unix_client(&fd->stream, xioflags, groups, 0, opts, filename);
|
||||||
|
if (result < 0) {
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (retropt_bind(opts, AF_UNIX, socktype, 0, (struct sockaddr *)&us, &uslen, 0, 0, 0) != STAT_NOACTION) {
|
|
||||||
needbind = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
|
||||||
if (opt_unlink_close) {
|
|
||||||
if ((fd->stream.unlink_close = strdup(filename)) == NULL) {
|
|
||||||
Error1("strdup(\"%s\"): out of memory", filename);
|
|
||||||
}
|
|
||||||
fd->stream.opt_unlink_close = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* save options, because we might have to start again with Socket() */
|
|
||||||
opts2 = copyopts(opts, GROUP_ALL);
|
|
||||||
|
|
||||||
if ((fd->stream.fd = Socket(PF_UNIX, socktype, 0)) < 0) {
|
|
||||||
Error2("socket(PF_UNIX, %d, 0): %s", socktype, strerror(errno));
|
|
||||||
return STAT_RETRYLATER;
|
|
||||||
}
|
|
||||||
/*0 Info2("socket(PF_UNIX, %d, 0) -> %d", socktype, fd->stream.fd);*/
|
|
||||||
applyopts(fd->stream.fd, opts, PH_PASTSOCKET);
|
|
||||||
applyopts(fd->stream.fd, opts, PH_FD);
|
|
||||||
|
|
||||||
applyopts_cloexec(fd->stream.fd, opts);
|
|
||||||
|
|
||||||
sa.sun_family = AF_UNIX;
|
|
||||||
salen = xiosetunix(&sa, filename, false, false);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
applyopts(fd->stream.fd, opts, PH_PREBIND);
|
|
||||||
applyopts(fd->stream.fd, opts, PH_BIND);
|
|
||||||
if (us) {
|
|
||||||
if (Bind(fd->stream.fd, us, uslen) < 0) {
|
|
||||||
Error4("bind(%d, {%s}, "F_Zd"): %s",
|
|
||||||
fd->fd, sockaddr_info(us, infobuff, sizeof(infobuff)),
|
|
||||||
uslen, strerror(errno));
|
|
||||||
if (fd->forever || --fd->retry) {
|
|
||||||
Nanosleep(&fd->intervall, NULL);
|
|
||||||
continue;
|
|
||||||
} else
|
|
||||||
return STAT_RETRYLATER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
applyopts(fd->stream.fd, opts, PH_PASTBIND);
|
|
||||||
#endif /* 0 */
|
|
||||||
|
|
||||||
applyopts(fd->stream.fd, opts, PH_CONNECT);
|
|
||||||
if ((result = Connect(fd->stream.fd, (struct sockaddr *)&sa, salen)) < 0) {
|
|
||||||
if (errno == EINPROGRESS) {
|
|
||||||
Warn4("connect(%d, %s, "F_Zd"): %s",
|
|
||||||
fd->stream.fd, sockaddr_unix_info(&sa, salen, infobuff, sizeof(infobuff)),
|
|
||||||
sizeof(sa), strerror(errno));
|
|
||||||
} else if (errno == EPROTOTYPE && optsotype != SOCK_STREAM) {
|
|
||||||
Warn4("connect(%d, %s, "F_Zd"): %s",
|
|
||||||
fd->stream.fd, sockaddr_unix_info(&sa, salen, infobuff, sizeof(infobuff)),
|
|
||||||
sizeof(sa), strerror(errno));
|
|
||||||
Info("assuming datagram socket");
|
|
||||||
Close(fd->stream.fd);
|
|
||||||
|
|
||||||
opts = opts2;
|
|
||||||
if ((fd->stream.fd = Socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) {
|
|
||||||
Error1("socket(PF_UNIX, SOCK_DGRAM, 0): %s", strerror(errno));
|
|
||||||
return STAT_RETRYLATER;
|
|
||||||
}
|
|
||||||
/*0 Info1("socket(PF_UNIX, SOCK_DGRAM, 0) -> %d", fd->stream.fd);*/
|
|
||||||
|
|
||||||
applyopts(fd->stream.fd, opts, PH_PASTSOCKET);
|
|
||||||
applyopts(fd->stream.fd, opts, PH_FD);
|
|
||||||
|
|
||||||
applyopts_cloexec(fd->stream.fd, opts);
|
|
||||||
|
|
||||||
sa.sun_family = AF_UNIX;
|
|
||||||
strncpy(sa.sun_path, filename, sizeof(sa.sun_path));
|
|
||||||
|
|
||||||
fd->stream.dtype = XIODATA_RECVFROM;
|
|
||||||
fd->stream.salen = sizeof(sa);
|
|
||||||
memcpy(&fd->stream.peersa.soa, &sa, fd->stream.salen);
|
|
||||||
} else {
|
|
||||||
Error4("connect(%d, %s, "F_Zd"): %s",
|
|
||||||
fd->stream.fd, sockaddr_unix_info(&sa, fd->stream.salen, infobuff, sizeof(infobuff)),
|
|
||||||
sizeof(sa), strerror(errno));
|
|
||||||
return STAT_RETRYLATER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fd->stream.howtoend == END_UNSPEC) {
|
|
||||||
fd->stream.howtoend = END_SHUTDOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
applyopts_fchown(fd->stream.fd, opts);
|
|
||||||
applyopts(fd->stream.fd, opts, PH_CONNECTED);
|
|
||||||
applyopts(fd->stream.fd, opts, PH_LATE);
|
|
||||||
applyopts_named(filename, opts, PH_PASTOPEN); /* unlink-late */
|
applyopts_named(filename, opts, PH_PASTOPEN); /* unlink-late */
|
||||||
|
|
||||||
if (Getsockname(fd->stream.fd, (struct sockaddr *)&us, &uslen) < 0) {
|
if (Getsockname(fd->stream.fd, (struct sockaddr *)&us, &uslen) < 0) {
|
||||||
@ -159,7 +63,8 @@ static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xio
|
|||||||
fd->stream.fd, &us, uslen, strerror(errno));
|
fd->stream.fd, &us, uslen, strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
Notice1("successfully connected via %s",
|
Notice1("successfully connected via %s",
|
||||||
sockaddr_unix_info(&us, uslen, infobuff, sizeof(infobuff)));
|
sockaddr_unix_info(&us.un, uslen,
|
||||||
|
infobuff, sizeof(infobuff)));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
Error("\"%s\" is a socket, but UNIX socket support is not compiled in");
|
Error("\"%s\" is a socket, but UNIX socket support is not compiled in");
|
||||||
|
12
xio-ip.c
12
xio-ip.c
@ -213,6 +213,18 @@ int xiogetaddrinfo(const char *node, const char *service,
|
|||||||
if (node != NULL || service != NULL) {
|
if (node != NULL || service != NULL) {
|
||||||
struct addrinfo *record;
|
struct addrinfo *record;
|
||||||
|
|
||||||
|
if (socktype != SOCK_STREAM && socktype != SOCK_DGRAM) {
|
||||||
|
/* actual socket type value is not supported - fallback to a good one */
|
||||||
|
socktype = SOCK_DGRAM;
|
||||||
|
}
|
||||||
|
if (protocol != IPPROTO_TCP && protocol != IPPROTO_UDP) {
|
||||||
|
/* actual protocol value is not supported - fallback to a good one */
|
||||||
|
if (socktype == SOCK_DGRAM) {
|
||||||
|
protocol = IPPROTO_UDP;
|
||||||
|
} else {
|
||||||
|
protocol = IPPROTO_TCP;
|
||||||
|
}
|
||||||
|
}
|
||||||
hints.ai_flags |= AI_PASSIVE;
|
hints.ai_flags |= AI_PASSIVE;
|
||||||
hints.ai_family = family;
|
hints.ai_family = family;
|
||||||
hints.ai_socktype = socktype;
|
hints.ai_socktype = socktype;
|
||||||
|
29
xio-ipapp.c
29
xio-ipapp.c
@ -52,8 +52,8 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts,
|
|||||||
if (_xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto,
|
if (_xioopen_ipapp_prepare(opts, &opts0, hostname, portname, &pf, ipproto,
|
||||||
xfd->para.socket.ip.res_opts[1],
|
xfd->para.socket.ip.res_opts[1],
|
||||||
xfd->para.socket.ip.res_opts[0],
|
xfd->para.socket.ip.res_opts[0],
|
||||||
them, &themlen, us, &uslen, &needbind, &lowport,
|
them, &themlen, us, &uslen, &needbind, &lowport,
|
||||||
&socktype) != STAT_OK) {
|
socktype) != STAT_OK) {
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,7 +142,11 @@ int xioopen_ipapp_connect(int argc, const char *argv[], struct opt *opts,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* returns STAT_OK on success or some other value on failure */
|
/* returns STAT_OK on success or some other value on failure
|
||||||
|
applies and consumes the following options:
|
||||||
|
PH_EARLY
|
||||||
|
OPT_PROTOCOL_FAMILY, OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
_xioopen_ipapp_prepare(struct opt *opts, struct opt **opts0,
|
_xioopen_ipapp_prepare(struct opt *opts, struct opt **opts0,
|
||||||
const char *hostname,
|
const char *hostname,
|
||||||
@ -153,7 +157,7 @@ int
|
|||||||
union sockaddr_union *them, socklen_t *themlen,
|
union sockaddr_union *them, socklen_t *themlen,
|
||||||
union sockaddr_union *us, socklen_t *uslen,
|
union sockaddr_union *us, socklen_t *uslen,
|
||||||
bool *needbind, bool *lowport,
|
bool *needbind, bool *lowport,
|
||||||
int *socktype) {
|
int socktype) {
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
char infobuff[256];
|
char infobuff[256];
|
||||||
int result;
|
int result;
|
||||||
@ -162,7 +166,7 @@ int
|
|||||||
|
|
||||||
if ((result =
|
if ((result =
|
||||||
xiogetaddrinfo(hostname, portname,
|
xiogetaddrinfo(hostname, portname,
|
||||||
*pf, *socktype, protocol,
|
*pf, socktype, protocol,
|
||||||
(union sockaddr_union *)them, themlen,
|
(union sockaddr_union *)them, themlen,
|
||||||
res_opts0, res_opts1
|
res_opts0, res_opts1
|
||||||
))
|
))
|
||||||
@ -176,7 +180,7 @@ int
|
|||||||
applyopts(-1, opts, PH_EARLY);
|
applyopts(-1, opts, PH_EARLY);
|
||||||
|
|
||||||
/* 3 means: IP address AND port accepted */
|
/* 3 means: IP address AND port accepted */
|
||||||
if (retropt_bind(opts, *pf, *socktype, protocol, (struct sockaddr *)us, uslen, 3,
|
if (retropt_bind(opts, *pf, socktype, protocol, (struct sockaddr *)us, uslen, 3,
|
||||||
res_opts0, res_opts1)
|
res_opts0, res_opts1)
|
||||||
!= STAT_NOACTION) {
|
!= STAT_NOACTION) {
|
||||||
*needbind = true;
|
*needbind = true;
|
||||||
@ -205,7 +209,6 @@ int
|
|||||||
}
|
}
|
||||||
|
|
||||||
retropt_bool(opts, OPT_LOWPORT, lowport);
|
retropt_bool(opts, OPT_LOWPORT, lowport);
|
||||||
retropt_int(opts, OPT_SO_TYPE, socktype);
|
|
||||||
|
|
||||||
*opts0 = copyopts(opts, GROUP_ALL);
|
*opts0 = copyopts(opts, GROUP_ALL);
|
||||||
|
|
||||||
@ -217,22 +220,24 @@ int
|
|||||||
|
|
||||||
|
|
||||||
#if WITH_TCP && WITH_LISTEN
|
#if WITH_TCP && WITH_LISTEN
|
||||||
|
/*
|
||||||
|
applies and consumes the following options:
|
||||||
|
OPT_PROTOCOL_FAMILY, OPT_BIND
|
||||||
|
*/
|
||||||
int _xioopen_ipapp_listen_prepare(struct opt *opts, struct opt **opts0,
|
int _xioopen_ipapp_listen_prepare(struct opt *opts, struct opt **opts0,
|
||||||
const char *portname, int *pf, int ipproto,
|
const char *portname, int *pf, int ipproto,
|
||||||
unsigned long res_opts0,
|
unsigned long res_opts0,
|
||||||
unsigned long res_opts1,
|
unsigned long res_opts1,
|
||||||
union sockaddr_union *us, socklen_t *uslen,
|
union sockaddr_union *us, socklen_t *uslen,
|
||||||
int *socktype) {
|
int socktype) {
|
||||||
char *bindname = NULL;
|
char *bindname = NULL;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, socktype);
|
|
||||||
|
|
||||||
retropt_socket_pf(opts, pf);
|
retropt_socket_pf(opts, pf);
|
||||||
|
|
||||||
retropt_string(opts, OPT_BIND, &bindname);
|
retropt_string(opts, OPT_BIND, &bindname);
|
||||||
if ((result =
|
if ((result =
|
||||||
xiogetaddrinfo(bindname, portname, *pf, *socktype, ipproto,
|
xiogetaddrinfo(bindname, portname, *pf, socktype, ipproto,
|
||||||
(union sockaddr_union *)us, uslen,
|
(union sockaddr_union *)us, uslen,
|
||||||
res_opts0, res_opts1))
|
res_opts0, res_opts1))
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
@ -279,7 +284,7 @@ int xioopen_ipapp_listen(int argc, const char *argv[], struct opt *opts,
|
|||||||
if (_xioopen_ipapp_listen_prepare(opts, &opts0, argv[1], &pf, ipproto,
|
if (_xioopen_ipapp_listen_prepare(opts, &opts0, argv[1], &pf, ipproto,
|
||||||
fd->stream.para.socket.ip.res_opts[1],
|
fd->stream.para.socket.ip.res_opts[1],
|
||||||
fd->stream.para.socket.ip.res_opts[0],
|
fd->stream.para.socket.ip.res_opts[0],
|
||||||
us, &uslen, &socktype)
|
us, &uslen, socktype)
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* source: xio-ipapp.h */
|
/* source: xio-ipapp.h */
|
||||||
/* Copyright Gerhard Rieger 2001-2006 */
|
/* Copyright Gerhard Rieger 2001-2008 */
|
||||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||||
|
|
||||||
#ifndef __xio_ipapp_h_included
|
#ifndef __xio_ipapp_h_included
|
||||||
@ -25,7 +25,7 @@ extern int
|
|||||||
union sockaddr_union *them, socklen_t *themlen,
|
union sockaddr_union *them, socklen_t *themlen,
|
||||||
union sockaddr_union *us, socklen_t *uslen,
|
union sockaddr_union *us, socklen_t *uslen,
|
||||||
bool *needbind, bool *lowport,
|
bool *needbind, bool *lowport,
|
||||||
int *socktype);
|
int socktype);
|
||||||
extern int _xioopen_ip4app_connect(const char *hostname, const char *portname,
|
extern int _xioopen_ip4app_connect(const char *hostname, const char *portname,
|
||||||
struct single *xfd,
|
struct single *xfd,
|
||||||
int socktype, int ipproto, void *protname,
|
int socktype, int ipproto, void *protname,
|
||||||
@ -39,7 +39,7 @@ extern int _xioopen_ipapp_listen_prepare(struct opt *opts, struct opt **opts0,
|
|||||||
unsigned long res_opts0,
|
unsigned long res_opts0,
|
||||||
unsigned long res_opts1,
|
unsigned long res_opts1,
|
||||||
union sockaddr_union *us, socklen_t *uslen,
|
union sockaddr_union *us, socklen_t *uslen,
|
||||||
int *socktype);
|
int socktype);
|
||||||
extern int xioopen_ip6app_connect(int argc, const char *argv[], struct opt *opts,
|
extern int xioopen_ip6app_connect(int argc, const char *argv[], struct opt *opts,
|
||||||
int rw, xiofile_t *fd,
|
int rw, xiofile_t *fd,
|
||||||
unsigned groups, int socktype, int ipproto,
|
unsigned groups, int socktype, int ipproto,
|
||||||
|
25
xio-listen.c
25
xio-listen.c
@ -25,6 +25,13 @@ const struct optdesc opt_range = { "range", NULL, OPT_RANGE, GROUP_R
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
applies and consumes the following option:
|
||||||
|
PH_INIT, PH_PASTSOCKET, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_EARLY,
|
||||||
|
PH_PREOPEN, PH_FD, PH_CONNECTED, PH_LATE, PH_LATE2
|
||||||
|
OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_BACKLOG, OPT_RANGE, tcpwrap,
|
||||||
|
OPT_SOURCEPORT, OPT_LOWPORT, cloexec
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
xioopen_listen(struct single *xfd, int xioflags,
|
xioopen_listen(struct single *xfd, int xioflags,
|
||||||
struct sockaddr *us, socklen_t uslen,
|
struct sockaddr *us, socklen_t uslen,
|
||||||
@ -81,15 +88,21 @@ int
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* waits for incoming connection, checks its source address and port. Depending
|
/* creates the listening socket, bind, applies options; waits for incoming
|
||||||
on fork option, it may fork a subprocess.
|
connection, checks its source address and port. Depending on fork option, it
|
||||||
|
may fork a subprocess.
|
||||||
Returns 0 if a connection was accepted; with fork option, this is always in
|
Returns 0 if a connection was accepted; with fork option, this is always in
|
||||||
a subprocess!
|
a subprocess!
|
||||||
Other return values indicate a problem; this can happen in the master
|
Other return values indicate a problem; this can happen in the master
|
||||||
process or in a subprocess.
|
process or in a subprocess.
|
||||||
This function does not retry. If you need retries, handle this is a
|
This function does not retry. If you need retries, handle this in a
|
||||||
loop in the calling function.
|
loop in the calling function (and always provide the options...)
|
||||||
after fork, we set the forever/retry of the child process to 0
|
after fork, we set the forever/retry of the child process to 0
|
||||||
|
applies and consumes the following option:
|
||||||
|
PH_INIT, PH_PASTSOCKET, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_EARLY,
|
||||||
|
PH_PREOPEN, PH_FD, PH_CONNECTED, PH_LATE, PH_LATE2
|
||||||
|
OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_BACKLOG, OPT_RANGE, tcpwrap,
|
||||||
|
OPT_SOURCEPORT, OPT_LOWPORT, cloexec
|
||||||
*/
|
*/
|
||||||
int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, socklen_t uslen,
|
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 opt *opts, int pf, int socktype, int proto, int level) {
|
||||||
@ -124,9 +137,7 @@ int _xioopen_listen(struct single *xfd, int xioflags, struct sockaddr *us, sockl
|
|||||||
xiosetchilddied(); /* set SIGCHLD handler */
|
xiosetchilddied(); /* set SIGCHLD handler */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((xfd->fd = Socket(pf, socktype, proto)) < 0) {
|
if ((xfd->fd = xiosocket(opts, pf, socktype, proto, level)) < 0) {
|
||||||
Msg4(level,
|
|
||||||
"socket(%d, %d, %d): %s", pf, socktype, proto, strerror(errno));
|
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ static int
|
|||||||
xfd->para.socket.ip.res_opts[1],
|
xfd->para.socket.ip.res_opts[1],
|
||||||
xfd->para.socket.ip.res_opts[0],
|
xfd->para.socket.ip.res_opts[0],
|
||||||
them, &themlen, us, &uslen,
|
them, &themlen, us, &uslen,
|
||||||
&needbind, &lowport, &socktype);
|
&needbind, &lowport, socktype);
|
||||||
if (result != STAT_OK) return STAT_NORETRY;
|
if (result != STAT_OK) return STAT_NORETRY;
|
||||||
|
|
||||||
if (xioopts.logopt == 'm') {
|
if (xioopts.logopt == 'm') {
|
||||||
@ -431,7 +431,7 @@ static int
|
|||||||
if (_xioopen_ipapp_listen_prepare(opts, &opts0, portname, &pf, ipproto,
|
if (_xioopen_ipapp_listen_prepare(opts, &opts0, portname, &pf, ipproto,
|
||||||
xfd->para.socket.ip.res_opts[1],
|
xfd->para.socket.ip.res_opts[1],
|
||||||
xfd->para.socket.ip.res_opts[0],
|
xfd->para.socket.ip.res_opts[0],
|
||||||
us, &uslen, &socktype)
|
us, &uslen, socktype)
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,9 @@
|
|||||||
#include "xio-process.h"
|
#include "xio-process.h"
|
||||||
#include "xio-progcall.h"
|
#include "xio-progcall.h"
|
||||||
|
|
||||||
|
#include "xio-socket.h"
|
||||||
|
|
||||||
|
|
||||||
/* these options are used by address pty too */
|
/* these options are used by address pty too */
|
||||||
#if HAVE_OPENPTY
|
#if HAVE_OPENPTY
|
||||||
const struct optdesc opt_openpty = { "openpty", NULL, OPT_OPENPTY, GROUP_PTY, PH_BIGEN, TYPE_BOOL, OFUNC_SPEC };
|
const struct optdesc opt_openpty = { "openpty", NULL, OPT_OPENPTY, GROUP_PTY, PH_BIGEN, TYPE_BOOL, OFUNC_SPEC };
|
||||||
@ -49,7 +52,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
|||||||
) {
|
) {
|
||||||
struct opt *popts; /* parent process options */
|
struct opt *popts; /* parent process options */
|
||||||
int numleft;
|
int numleft;
|
||||||
int d, type, protocol, sv[2], rdpip[2], wrpip[2];
|
int d, sv[2], rdpip[2], wrpip[2];
|
||||||
int rw = (xioflags & XIO_ACCMODE);
|
int rw = (xioflags & XIO_ACCMODE);
|
||||||
bool usepipes = false;
|
bool usepipes = false;
|
||||||
#if HAVE_PTY
|
#if HAVE_PTY
|
||||||
@ -358,13 +361,10 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
|
|||||||
applyopts(fd->fd, popts, PH_LATE);
|
applyopts(fd->fd, popts, PH_LATE);
|
||||||
if (applyopts_single(fd, popts, PH_LATE) < 0) return -1;
|
if (applyopts_single(fd, popts, PH_LATE) < 0) return -1;
|
||||||
} else {
|
} else {
|
||||||
d = AF_UNIX; type = SOCK_STREAM;
|
d = AF_UNIX;
|
||||||
protocol = 0; /* PF_UNIX does not work on AIX */
|
retropt_int(popts, OPT_PROTOCOL_FAMILY, &d);
|
||||||
retropt_int(popts, OPT_SO_TYPE, &type);
|
result = xiosocketpair(popts, d, SOCK_STREAM, 0, sv);
|
||||||
result = Socketpair(d, type, protocol, sv);
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
Error5("socketpair(%d, %d, %d, %p): %s",
|
|
||||||
d, type, protocol, sv, strerror(errno));
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
/*0 Info5("socketpair(%d, %d, %d, {%d,%d})",
|
/*0 Info5("socketpair(%d, %d, %d, {%d,%d})",
|
||||||
|
@ -131,7 +131,7 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts,
|
|||||||
xfd->para.socket.ip.res_opts[1],
|
xfd->para.socket.ip.res_opts[1],
|
||||||
xfd->para.socket.ip.res_opts[0],
|
xfd->para.socket.ip.res_opts[0],
|
||||||
them, &themlen, us, &uslen,
|
them, &themlen, us, &uslen,
|
||||||
&needbind, &lowport, &socktype);
|
&needbind, &lowport, socktype);
|
||||||
if (result != STAT_OK) return result;
|
if (result != STAT_OK) return result;
|
||||||
|
|
||||||
Notice4("opening connection to %s:%u via proxy %s:%s",
|
Notice4("opening connection to %s:%u via proxy %s:%s",
|
||||||
|
32
xio-rawip.c
32
xio-rawip.c
@ -17,7 +17,6 @@
|
|||||||
#include "xio-rawip.h"
|
#include "xio-rawip.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int xioopen_rawip_sendto(int argc, const char *argv[], struct opt *opts,
|
int xioopen_rawip_sendto(int argc, const char *argv[], struct opt *opts,
|
||||||
int xioflags, xiofile_t *fd, unsigned groups, int pf,
|
int xioflags, xiofile_t *fd, unsigned groups, int pf,
|
||||||
@ -38,7 +37,7 @@ int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts,
|
|||||||
static
|
static
|
||||||
int _xioopen_rawip_sendto(const char *hostname, const char *protname,
|
int _xioopen_rawip_sendto(const char *hostname, const char *protname,
|
||||||
struct opt *opts, int xioflags,
|
struct opt *opts, int xioflags,
|
||||||
xiofile_t *xxfd, unsigned groups, int pf);
|
xiofile_t *xxfd, unsigned groups, int *pf);
|
||||||
|
|
||||||
const struct addrdesc addr_rawip_sendto = { "ip-sendto", 3, xioopen_rawip_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6, PF_UNSPEC, 0, 0 HELP(":<host>:<protocol>") };
|
const struct addrdesc addr_rawip_sendto = { "ip-sendto", 3, xioopen_rawip_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6, PF_UNSPEC, 0, 0 HELP(":<host>:<protocol>") };
|
||||||
const struct addrdesc addr_rawip_datagram= { "ip-datagram", 3, xioopen_rawip_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_RANGE, PF_UNSPEC, 0, 0 HELP(":<host>:<protocol>") };
|
const struct addrdesc addr_rawip_datagram= { "ip-datagram", 3, xioopen_rawip_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_RANGE, PF_UNSPEC, 0, 0 HELP(":<host>:<protocol>") };
|
||||||
@ -75,17 +74,24 @@ int xioopen_rawip_sendto(int argc, const char *argv[], struct opt *opts,
|
|||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
if ((result = _xioopen_rawip_sendto(argv[1], argv[2], opts, xioflags, xxfd,
|
if ((result = _xioopen_rawip_sendto(argv[1], argv[2], opts, xioflags, xxfd,
|
||||||
groups, pf)) != STAT_OK) {
|
groups, &pf)) != STAT_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
_xio_openlate(&xxfd->stream, opts);
|
_xio_openlate(&xxfd->stream, opts);
|
||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
applies and consumes the following options:
|
||||||
|
PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECTED, PH_LATE
|
||||||
|
OFUNC_OFFSET
|
||||||
|
OPT_PROTOCOL_FAMILY, OPT_BIND, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER,
|
||||||
|
OPT_GROUP, OPT_CLOEXEC
|
||||||
|
*/
|
||||||
static
|
static
|
||||||
int _xioopen_rawip_sendto(const char *hostname, const char *protname,
|
int _xioopen_rawip_sendto(const char *hostname, const char *protname,
|
||||||
struct opt *opts, int xioflags, xiofile_t *xxfd,
|
struct opt *opts, int xioflags, xiofile_t *xxfd,
|
||||||
unsigned groups, int pf) {
|
unsigned groups, int *pf) {
|
||||||
char *garbage;
|
char *garbage;
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
xiosingle_t *xfd = &xxfd->stream;
|
||||||
union sockaddr_union us;
|
union sockaddr_union us;
|
||||||
@ -107,7 +113,7 @@ int _xioopen_rawip_sendto(const char *hostname, const char *protname,
|
|||||||
}
|
}
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
xfd->howtoend = END_SHUTDOWN;
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_int(opts, OPT_PROTOCOL_FAMILY, pf);
|
||||||
|
|
||||||
/* ...res_opts[] */
|
/* ...res_opts[] */
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
||||||
@ -115,29 +121,29 @@ int _xioopen_rawip_sendto(const char *hostname, const char *protname,
|
|||||||
|
|
||||||
xfd->salen = sizeof(xfd->peersa);
|
xfd->salen = sizeof(xfd->peersa);
|
||||||
if ((result =
|
if ((result =
|
||||||
xiogetaddrinfo(hostname, NULL, pf, socktype, ipproto,
|
xiogetaddrinfo(hostname, NULL, *pf, socktype, ipproto,
|
||||||
&xfd->peersa, &xfd->salen,
|
&xfd->peersa, &xfd->salen,
|
||||||
xfd->para.socket.ip.res_opts[0],
|
xfd->para.socket.ip.res_opts[0],
|
||||||
xfd->para.socket.ip.res_opts[1]))
|
xfd->para.socket.ip.res_opts[1]))
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if (pf == PF_UNSPEC) {
|
if (*pf == PF_UNSPEC) {
|
||||||
pf = xfd->peersa.soa.sa_family;
|
*pf = xfd->peersa.soa.sa_family;
|
||||||
}
|
}
|
||||||
|
|
||||||
uslen = socket_init(pf, &us);
|
uslen = socket_init(*pf, &us);
|
||||||
|
|
||||||
xfd->dtype = XIODATA_RECVFROM_SKIPIP;
|
xfd->dtype = XIODATA_RECVFROM_SKIPIP;
|
||||||
|
|
||||||
if (retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, feats,
|
if (retropt_bind(opts, *pf, socktype, ipproto, &us.soa, &uslen, feats,
|
||||||
xfd->para.socket.ip.res_opts[0],
|
xfd->para.socket.ip.res_opts[0],
|
||||||
xfd->para.socket.ip.res_opts[1]) != STAT_NOACTION) {
|
xfd->para.socket.ip.res_opts[1]) != STAT_NOACTION) {
|
||||||
needbind = true;
|
needbind = true;
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
||||||
opts, xioflags, xfd, groups, pf, socktype, ipproto);
|
opts, xioflags, xfd, groups, *pf, socktype, ipproto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -157,7 +163,7 @@ int xioopen_rawip_datagram(int argc, const char *argv[], struct opt *opts,
|
|||||||
}
|
}
|
||||||
if ((result =
|
if ((result =
|
||||||
_xioopen_rawip_sendto(argv[1], argv[2], opts, xioflags, xxfd,
|
_xioopen_rawip_sendto(argv[1], argv[2], opts, xioflags, xxfd,
|
||||||
groups, pf)) != STAT_OK) {
|
groups, &pf)) != STAT_OK) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +222,6 @@ int xioopen_rawip_recvfrom(int argc, const char *argv[], struct opt *opts,
|
|||||||
/*return STAT_NORETRY;*/
|
/*return STAT_NORETRY;*/
|
||||||
}
|
}
|
||||||
xfd->stream.howtoend = END_NONE;
|
xfd->stream.howtoend = END_NONE;
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
|
||||||
|
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
if (pf == PF_UNSPEC) {
|
if (pf == PF_UNSPEC) {
|
||||||
@ -274,7 +279,6 @@ int xioopen_rawip_recv(int argc, const char *argv[], struct opt *opts,
|
|||||||
protname);
|
protname);
|
||||||
/*return STAT_NORETRY;*/
|
/*return STAT_NORETRY;*/
|
||||||
}
|
}
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
|
||||||
|
|
||||||
retropt_socket_pf(opts, &pf);
|
retropt_socket_pf(opts, &pf);
|
||||||
if (pf == PF_UNSPEC) {
|
if (pf == PF_UNSPEC) {
|
||||||
|
93
xio-socket.c
93
xio-socket.c
@ -50,7 +50,7 @@ const struct optdesc opt_so_sndbuf_late={ "so-sndbuf-late","sndbuf-late",OPT_SO_
|
|||||||
const struct optdesc opt_so_rcvbuf = { "so-rcvbuf", "rcvbuf", OPT_SO_RCVBUF, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_RCVBUF};
|
const struct optdesc opt_so_rcvbuf = { "so-rcvbuf", "rcvbuf", OPT_SO_RCVBUF, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_RCVBUF};
|
||||||
const struct optdesc opt_so_rcvbuf_late={"so-rcvbuf-late","rcvbuf-late",OPT_SO_RCVBUF_LATE,GROUP_SOCKET,PH_LATE,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_RCVBUF };
|
const struct optdesc opt_so_rcvbuf_late={"so-rcvbuf-late","rcvbuf-late",OPT_SO_RCVBUF_LATE,GROUP_SOCKET,PH_LATE,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_RCVBUF };
|
||||||
const struct optdesc opt_so_error = { "so-error", "error", OPT_SO_ERROR, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_ERROR};
|
const struct optdesc opt_so_error = { "so-error", "error", OPT_SO_ERROR, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_ERROR};
|
||||||
const struct optdesc opt_so_type = { "so-type", "type", OPT_SO_TYPE, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_TYPE };
|
const struct optdesc opt_so_type = { "so-type", "type", OPT_SO_TYPE, GROUP_SOCKET, PH_SOCKET, TYPE_INT, OFUNC_SPEC, SOL_SOCKET, SO_TYPE };
|
||||||
const struct optdesc opt_so_dontroute= { "so-dontroute", "dontroute", OPT_SO_DONTROUTE,GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_DONTROUTE };
|
const struct optdesc opt_so_dontroute= { "so-dontroute", "dontroute", OPT_SO_DONTROUTE,GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_DONTROUTE };
|
||||||
#ifdef SO_RCVLOWAT
|
#ifdef SO_RCVLOWAT
|
||||||
const struct optdesc opt_so_rcvlowat = { "so-rcvlowat", "rcvlowat", OPT_SO_RCVLOWAT, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_RCVLOWAT };
|
const struct optdesc opt_so_rcvlowat = { "so-rcvlowat", "rcvlowat", OPT_SO_RCVLOWAT, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SOCKET, SO_RCVLOWAT };
|
||||||
@ -129,9 +129,9 @@ const struct optdesc opt_so_dgram_errind={"so-dgram-errind","dgramerrind",OPT_SO
|
|||||||
#ifdef SO_DONTLINGER /* Solaris */
|
#ifdef SO_DONTLINGER /* Solaris */
|
||||||
const struct optdesc opt_so_dontlinger = {"so-dontlinger", "dontlinger", OPT_SO_DONTLINGER, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_DONTLINGER };
|
const struct optdesc opt_so_dontlinger = {"so-dontlinger", "dontlinger", OPT_SO_DONTLINGER, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_DONTLINGER };
|
||||||
#endif
|
#endif
|
||||||
#ifdef SO_PROTOTYPE /* Solaris, HP-UX */
|
/* the SO_PROTOTYPE is OS defined on Solaris, HP-UX; we lend this for a more
|
||||||
const struct optdesc opt_so_prototype = {"so-prototype", "prototype", OPT_SO_PROTOTYPE, GROUP_SOCKET,PH_PASTSOCKET,TYPE_INT,OFUNC_SOCKOPT,SOL_SOCKET,SO_PROTOTYPE };
|
general purpose */
|
||||||
#endif
|
const struct optdesc opt_so_prototype = {"so-prototype", "prototype", OPT_SO_PROTOTYPE, GROUP_SOCKET,PH_SOCKET, TYPE_INT,OFUNC_SPEC, SOL_SOCKET,SO_PROTOTYPE };
|
||||||
#ifdef FIOSETOWN
|
#ifdef FIOSETOWN
|
||||||
const struct optdesc opt_fiosetown = { "fiosetown", NULL, OPT_FIOSETOWN, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_IOCTL, FIOSETOWN };
|
const struct optdesc opt_fiosetown = { "fiosetown", NULL, OPT_FIOSETOWN, GROUP_SOCKET, PH_PASTSOCKET, TYPE_INT, OFUNC_IOCTL, FIOSETOWN };
|
||||||
#endif
|
#endif
|
||||||
@ -141,15 +141,21 @@ const struct optdesc opt_siocspgrp = { "siocspgrp", NULL, OPT_SIOCSPGRP, GRO
|
|||||||
const struct optdesc opt_bind = { "bind", NULL, OPT_BIND, GROUP_SOCKET, PH_BIND, TYPE_STRING,OFUNC_SPEC };
|
const struct optdesc opt_bind = { "bind", NULL, OPT_BIND, GROUP_SOCKET, PH_BIND, TYPE_STRING,OFUNC_SPEC };
|
||||||
const struct optdesc opt_connect_timeout = { "connect-timeout", NULL, OPT_CONNECT_TIMEOUT, GROUP_SOCKET, PH_PASTSOCKET, TYPE_TIMEVAL, OFUNC_OFFSET, (int)&((xiofile_t *)0)->stream.para.socket.connect_timeout };
|
const struct optdesc opt_connect_timeout = { "connect-timeout", NULL, OPT_CONNECT_TIMEOUT, GROUP_SOCKET, PH_PASTSOCKET, TYPE_TIMEVAL, OFUNC_OFFSET, (int)&((xiofile_t *)0)->stream.para.socket.connect_timeout };
|
||||||
const struct optdesc opt_protocol_family = { "protocol-family", "pf", OPT_PROTOCOL_FAMILY, GROUP_SOCKET, PH_PRESOCKET, TYPE_STRING, OFUNC_SPEC };
|
const struct optdesc opt_protocol_family = { "protocol-family", "pf", OPT_PROTOCOL_FAMILY, GROUP_SOCKET, PH_PRESOCKET, TYPE_STRING, OFUNC_SPEC };
|
||||||
|
const struct optdesc opt_protocol = { "protocol", NULL, OPT_PROTOCOL, GROUP_SOCKET, PH_PRESOCKET, TYPE_STRING, OFUNC_SPEC };
|
||||||
|
|
||||||
/* a subroutine that is common to all socket addresses that want to connect
|
/* a subroutine that is common to all socket addresses that want to connect
|
||||||
to a peer address.
|
to a peer address.
|
||||||
might fork.
|
might fork.
|
||||||
|
applies and consumes the following options:
|
||||||
|
PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECT,
|
||||||
|
PH_CONNECTED, PH_LATE,
|
||||||
|
OFUNC_OFFSET,
|
||||||
|
OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC
|
||||||
returns 0 on success.
|
returns 0 on success.
|
||||||
*/
|
*/
|
||||||
int _xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen,
|
int _xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen,
|
||||||
struct sockaddr *them, size_t themlen,
|
struct sockaddr *them, size_t themlen,
|
||||||
struct opt *opts, int pf, int stype, int proto,
|
struct opt *opts, int pf, int socktype, int protocol,
|
||||||
bool alt, int level) {
|
bool alt, int level) {
|
||||||
int fcntl_flags = 0;
|
int fcntl_flags = 0;
|
||||||
char infobuff[256];
|
char infobuff[256];
|
||||||
@ -158,9 +164,7 @@ int _xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen,
|
|||||||
int _errno;
|
int _errno;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if ((xfd->fd = Socket(pf, stype, proto)) < 0) {
|
if ((xfd->fd = xiosocket(opts, pf, socktype, protocol, level)) < 0) {
|
||||||
Msg4(level,
|
|
||||||
"socket(%d, %d, %d): %s", pf, stype, proto, strerror(errno));
|
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,7 +358,7 @@ int _xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts_fchown(xfd->fd, opts);
|
applyopts_fchown(xfd->fd, opts); /* OPT_USER, OPT_GROUP */
|
||||||
applyopts(xfd->fd, opts, PH_CONNECTED);
|
applyopts(xfd->fd, opts, PH_CONNECTED);
|
||||||
applyopts(xfd->fd, opts, PH_LATE);
|
applyopts(xfd->fd, opts, PH_LATE);
|
||||||
|
|
||||||
@ -368,11 +372,16 @@ int _xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen,
|
|||||||
/* a subroutine that is common to all socket addresses that want to connect
|
/* a subroutine that is common to all socket addresses that want to connect
|
||||||
to a peer address.
|
to a peer address.
|
||||||
might fork.
|
might fork.
|
||||||
|
applies and consumes the following option:
|
||||||
|
PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECT,
|
||||||
|
PH_CONNECTED, PH_LATE,
|
||||||
|
OFUNC_OFFSET,
|
||||||
|
OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC
|
||||||
returns 0 on success.
|
returns 0 on success.
|
||||||
*/
|
*/
|
||||||
int xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen,
|
int xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen,
|
||||||
struct sockaddr *them, size_t themlen,
|
struct sockaddr *them, size_t themlen,
|
||||||
struct opt *opts, int pf, int stype, int proto,
|
struct opt *opts, int pf, int socktype, int protocol,
|
||||||
bool alt) {
|
bool alt) {
|
||||||
bool dofork = false;
|
bool dofork = false;
|
||||||
struct opt *opts0;
|
struct opt *opts0;
|
||||||
@ -381,7 +390,6 @@ int xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen,
|
|||||||
int result;
|
int result;
|
||||||
|
|
||||||
retropt_bool(opts, OPT_FORK, &dofork);
|
retropt_bool(opts, OPT_FORK, &dofork);
|
||||||
retropt_int(opts, OPT_SO_TYPE, &stype);
|
|
||||||
|
|
||||||
opts0 = copyopts(opts, GROUP_ALL);
|
opts0 = copyopts(opts, GROUP_ALL);
|
||||||
|
|
||||||
@ -398,7 +406,7 @@ int xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen,
|
|||||||
level = E_ERROR;
|
level = E_ERROR;
|
||||||
result =
|
result =
|
||||||
_xioopen_connect(xfd, us, uslen, them, themlen, opts,
|
_xioopen_connect(xfd, us, uslen, them, themlen, opts,
|
||||||
pf, stype, proto, alt, level);
|
pf, socktype, protocol, alt, level);
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case STAT_OK: break;
|
case STAT_OK: break;
|
||||||
#if WITH_RETRY
|
#if WITH_RETRY
|
||||||
@ -464,7 +472,12 @@ int xioopen_connect(struct single *xfd, struct sockaddr *us, size_t uslen,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* common to xioopen_udp_sendto, ..unix_sendto, ..rawip */
|
/* common to xioopen_udp_sendto, ..unix_sendto, ..rawip
|
||||||
|
applies and consumes the following option:
|
||||||
|
PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECTED, PH_LATE
|
||||||
|
OFUNC_OFFSET
|
||||||
|
OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC
|
||||||
|
*/
|
||||||
int _xioopen_dgram_sendto(/* them is already in xfd->peersa */
|
int _xioopen_dgram_sendto(/* them is already in xfd->peersa */
|
||||||
union sockaddr_union *us, socklen_t uslen,
|
union sockaddr_union *us, socklen_t uslen,
|
||||||
struct opt *opts,
|
struct opt *opts,
|
||||||
@ -474,9 +487,7 @@ int _xioopen_dgram_sendto(/* them is already in xfd->peersa */
|
|||||||
union sockaddr_union la; socklen_t lalen = sizeof(la);
|
union sockaddr_union la; socklen_t lalen = sizeof(la);
|
||||||
char infobuff[256];
|
char infobuff[256];
|
||||||
|
|
||||||
if ((xfd->fd = Socket(pf, socktype, ipproto)) < 0) {
|
if ((xfd->fd = xiosocket(opts, pf, socktype, ipproto, level)) < 0) {
|
||||||
Msg4(level,
|
|
||||||
"socket(%d, %d, %d): %s", pf, socktype, ipproto, strerror(errno));
|
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,6 +611,10 @@ void xiosigaction_hasread(int signum, siginfo_t *siginfo, void *ucontext) {
|
|||||||
This function does not retry. If you need retries, handle this is a
|
This function does not retry. If you need retries, handle this is a
|
||||||
loop in the calling function.
|
loop in the calling function.
|
||||||
after fork, we set the forever/retry of the child process to 0
|
after fork, we set the forever/retry of the child process to 0
|
||||||
|
applies and consumes the following options:
|
||||||
|
PH_INIT, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_EARLY, PH_PREOPEN, PH_FD,
|
||||||
|
PH_CONNECTED, PH_LATE, PH_LATE2
|
||||||
|
OPT_FORK, OPT_SO_TYPE, OPT_SO_PROTOTYPE, cloexec, OPT_RANGE, tcpwrap
|
||||||
*/
|
*/
|
||||||
int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
||||||
struct sockaddr *us, socklen_t uslen,
|
struct sockaddr *us, socklen_t uslen,
|
||||||
@ -626,9 +641,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
|||||||
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
|
|
||||||
if ((xfd->fd = Socket(pf, socktype, proto)) < 0) {
|
if ((xfd->fd = xiosocket(opts, pf, socktype, proto, level)) < 0) {
|
||||||
Msg4(level,
|
|
||||||
"socket(%d, %d, %d): %s", pf, socktype, proto, strerror(errno));
|
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -881,9 +894,7 @@ int _xioopen_dgram_recv(struct single *xfd, int xioflags,
|
|||||||
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
|
||||||
|
|
||||||
if ((xfd->fd = Socket(pf, socktype, proto)) < 0) {
|
if ((xfd->fd = xiosocket(opts, pf, socktype, proto, level)) < 0) {
|
||||||
Msg4(level,
|
|
||||||
"socket(%d, %d, %d): %s", pf, socktype, proto, strerror(errno));
|
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1371,3 +1382,41 @@ int xiosetsockaddrenv(const char *lr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _WITH_SOCKET */
|
#endif /* _WITH_SOCKET */
|
||||||
|
|
||||||
|
/* these do sockets internally */
|
||||||
|
|
||||||
|
/* retrieves options so-type and so-prototype from opts, calls socketpair, and
|
||||||
|
ev. generates an appropriate error message.
|
||||||
|
returns 0 on success or -1 if an error occurred. */
|
||||||
|
int
|
||||||
|
xiosocket(struct opt *opts, int pf, int socktype, int proto, int msglevel) {
|
||||||
|
int result;
|
||||||
|
|
||||||
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
|
retropt_int(opts, OPT_SO_PROTOTYPE, &proto);
|
||||||
|
result = Socket(pf, socktype, proto);
|
||||||
|
if (result < 0) {
|
||||||
|
Msg4(msglevel, "socket(%d, %d, %d): %s",
|
||||||
|
pf, socktype, proto, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* retrieves options so-type and so-prototype from opts, calls socketpair, and
|
||||||
|
ev. generates an appropriate error message.
|
||||||
|
returns 0 on success or -1 if an error occurred. */
|
||||||
|
int
|
||||||
|
xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]) {
|
||||||
|
int result;
|
||||||
|
|
||||||
|
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
||||||
|
retropt_int(opts, OPT_SO_PROTOTYPE, &proto);
|
||||||
|
result = Socketpair(pf, socktype, proto, sv);
|
||||||
|
if (result < 0) {
|
||||||
|
Error5("socketpair(%d, %d, %d, %p): %s",
|
||||||
|
pf, socktype, proto, sv, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
16
xio-socket.h
16
xio-socket.h
@ -5,6 +5,12 @@
|
|||||||
#ifndef __xio_socket_h_included
|
#ifndef __xio_socket_h_included
|
||||||
#define __xio_socket_h_included 1
|
#define __xio_socket_h_included 1
|
||||||
|
|
||||||
|
/* SO_PROTOTYPE is OS defined on Solaris, HP-UX; we lend this for a more
|
||||||
|
general purpose */
|
||||||
|
#ifndef SO_PROTOTYPE
|
||||||
|
#define SO_PROTOTYPE 0x9999
|
||||||
|
#endif
|
||||||
|
|
||||||
extern const struct optdesc opt_connect_timeout;
|
extern const struct optdesc opt_connect_timeout;
|
||||||
extern const struct optdesc opt_so_debug;
|
extern const struct optdesc opt_so_debug;
|
||||||
extern const struct optdesc opt_so_acceptconn;
|
extern const struct optdesc opt_so_acceptconn;
|
||||||
@ -61,12 +67,14 @@ extern int retropt_socket_pf(struct opt *opts, int *pf);
|
|||||||
extern int xioopen_connect(struct single *fd,
|
extern int xioopen_connect(struct single *fd,
|
||||||
struct sockaddr *us, size_t uslen,
|
struct sockaddr *us, size_t uslen,
|
||||||
struct sockaddr *them, size_t themlen,
|
struct sockaddr *them, size_t themlen,
|
||||||
struct opt *opts, int pf, int stype, int proto,
|
struct opt *opts,
|
||||||
|
int pf, int socktype, int protocol,
|
||||||
bool alt);
|
bool alt);
|
||||||
extern int _xioopen_connect(struct single *fd,
|
extern int _xioopen_connect(struct single *fd,
|
||||||
struct sockaddr *us, size_t uslen,
|
struct sockaddr *us, size_t uslen,
|
||||||
struct sockaddr *them, size_t themlen,
|
struct sockaddr *them, size_t themlen,
|
||||||
struct opt *opts, int pf, int stype, int proto,
|
struct opt *opts,
|
||||||
|
int pf, int socktype, int protocol,
|
||||||
bool alt, int level);
|
bool alt, int level);
|
||||||
|
|
||||||
/* common to xioopen_udp_sendto, ..unix_sendto, ..rawip */
|
/* common to xioopen_udp_sendto, ..unix_sendto, ..rawip */
|
||||||
@ -93,6 +101,10 @@ int xiogetpacketsrc(int fd, struct msghdr *msgh);
|
|||||||
extern
|
extern
|
||||||
int xiocheckpeer(xiosingle_t *xfd,
|
int xiocheckpeer(xiosingle_t *xfd,
|
||||||
union sockaddr_union *pa, union sockaddr_union *la);
|
union sockaddr_union *pa, union sockaddr_union *la);
|
||||||
|
extern int
|
||||||
|
xiosocket(struct opt *opts, int pf, int socktype, int proto, int level);
|
||||||
|
extern int
|
||||||
|
xiosocketpair(struct opt *opts, int pf, int socktype, int proto, int sv[2]);
|
||||||
extern
|
extern
|
||||||
int xiosetsockaddrenv(const char *lr, union sockaddr_union *sau, socklen_t salen, int proto);
|
int xiosetsockaddrenv(const char *lr, union sockaddr_union *sau, socklen_t salen, int proto);
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ static int xioopen_socks4_connect(int argc, const char *argv[], struct opt *opts
|
|||||||
xfd->para.socket.ip.res_opts[1],
|
xfd->para.socket.ip.res_opts[1],
|
||||||
xfd->para.socket.ip.res_opts[0],
|
xfd->para.socket.ip.res_opts[0],
|
||||||
them, &themlen, us, &uslen,
|
them, &themlen, us, &uslen,
|
||||||
&needbind, &lowport, &socktype);
|
&needbind, &lowport, socktype);
|
||||||
|
|
||||||
Notice5("opening connection to %s:%u via socks4 server %s:%s as user \"%s\"",
|
Notice5("opening connection to %s:%u via socks4 server %s:%s as user \"%s\"",
|
||||||
targetname,
|
targetname,
|
||||||
|
16
xio-udp.c
16
xio-udp.c
@ -114,7 +114,6 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
|||||||
applyopts(-1, opts, PH_INIT);
|
applyopts(-1, opts, PH_INIT);
|
||||||
|
|
||||||
uslen = socket_init(pf, &us);
|
uslen = socket_init(pf, &us);
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
|
||||||
retropt_bind(opts, pf, socktype, IPPROTO_UDP,
|
retropt_bind(opts, pf, socktype, IPPROTO_UDP,
|
||||||
(struct sockaddr *)&us, &uslen, 1,
|
(struct sockaddr *)&us, &uslen, 1,
|
||||||
fd->stream.para.socket.ip.res_opts[1],
|
fd->stream.para.socket.ip.res_opts[1],
|
||||||
@ -176,8 +175,7 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
|||||||
union sockaddr_union _sockname;
|
union sockaddr_union _sockname;
|
||||||
union sockaddr_union *la = &_sockname; /* local address */
|
union sockaddr_union *la = &_sockname; /* local address */
|
||||||
|
|
||||||
if ((fd->stream.fd = Socket(pf, socktype, ipproto)) < 0) {
|
if ((fd->stream.fd = xiosocket(opts, pf, socktype, ipproto, E_ERROR)) < 0) {
|
||||||
Error4("socket(%d, %d, %d): %s", pf, socktype, ipproto, strerror(errno));
|
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
applyopts(fd->stream.fd, opts, PH_PASTSOCKET);
|
applyopts(fd->stream.fd, opts, PH_PASTSOCKET);
|
||||||
@ -230,7 +228,7 @@ int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts,
|
|||||||
if (xiocheckpeer(&fd->stream, them, la) < 0) {
|
if (xiocheckpeer(&fd->stream, them, la) < 0) {
|
||||||
/* drop packet */
|
/* drop packet */
|
||||||
char buff[512];
|
char buff[512];
|
||||||
Recv(fd->stream.fd, buff, sizeof(buff), 0);
|
Recv(fd->stream.fd, buff, sizeof(buff), 0); /* drop packet */
|
||||||
Close(fd->stream.fd);
|
Close(fd->stream.fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -299,6 +297,8 @@ int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts,
|
|||||||
argv[0], argc-1);
|
argv[0], argc-1);
|
||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retropt_socket_pf(opts, &pf);
|
||||||
if ((result = _xioopen_udp_sendto(argv[1], argv[2], opts, xioflags, xxfd,
|
if ((result = _xioopen_udp_sendto(argv[1], argv[2], opts, xioflags, xxfd,
|
||||||
groups, pf, socktype, ipproto))
|
groups, pf, socktype, ipproto))
|
||||||
!= STAT_OK) {
|
!= STAT_OK) {
|
||||||
@ -308,6 +308,12 @@ int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts,
|
|||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
applies and consumes the following option:
|
||||||
|
PH_INIT, PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND, PH_CONNECTED, PH_LATE
|
||||||
|
OFUNC_OFFSET
|
||||||
|
OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC
|
||||||
|
*/
|
||||||
static
|
static
|
||||||
int _xioopen_udp_sendto(const char *hostname, const char *servname,
|
int _xioopen_udp_sendto(const char *hostname, const char *servname,
|
||||||
struct opt *opts,
|
struct opt *opts,
|
||||||
@ -321,7 +327,6 @@ int _xioopen_udp_sendto(const char *hostname, const char *servname,
|
|||||||
int result;
|
int result;
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
xfd->howtoend = END_SHUTDOWN;
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
|
||||||
|
|
||||||
/* ...res_opts[] */
|
/* ...res_opts[] */
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
||||||
@ -408,6 +413,7 @@ int xioopen_udp_datagram(int argc, const char *argv[], struct opt *opts,
|
|||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retropt_socket_pf(opts, &pf);
|
||||||
result =
|
result =
|
||||||
_xioopen_udp_sendto(hostname, argv[2], opts, xioflags, xxfd, groups,
|
_xioopen_udp_sendto(hostname, argv[2], opts, xioflags, xxfd, groups,
|
||||||
pf, socktype, ipproto);
|
pf, socktype, ipproto);
|
||||||
|
697
xio-unix.c
697
xio-unix.c
@ -15,76 +15,69 @@
|
|||||||
|
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
|
|
||||||
static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
/* to avoid unneccessary "live" if () conditionals when no abstract support is
|
||||||
static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
compiled in (or at least to give optimizing compilers a good chance) we need
|
||||||
static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
a constant that can be used in C expressions */
|
||||||
static int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
#if WITH_ABSTRACT_UNIXSOCKET
|
||||||
|
# define ABSTRACT 1
|
||||||
|
#else
|
||||||
|
# define ABSTRACT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3);
|
||||||
|
static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3);
|
||||||
|
static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3);
|
||||||
|
static int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3);
|
||||||
static
|
static
|
||||||
int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
||||||
int xioflags, xiofile_t *xfd, unsigned groups,
|
int xioflags, xiofile_t *xxfd, unsigned groups,
|
||||||
int pf, int socktype, int ipproto);
|
int abstract, int dummy2, int dummy3);
|
||||||
static
|
static
|
||||||
int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3);
|
||||||
|
|
||||||
|
/* the first free parameter is 0 for "normal" unix domain sockets, or 1 for
|
||||||
|
abstract unix sockets (Linux); the second and third free parameter are
|
||||||
|
unsused */
|
||||||
|
const struct addrdesc xioaddr_unix_connect = { "unix-connect", 3, xioopen_unix_connect, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":<filename>") };
|
||||||
|
#if WITH_LISTEN
|
||||||
|
const struct addrdesc xioaddr_unix_listen = { "unix-listen", 3, xioopen_unix_listen, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":<filename>") };
|
||||||
|
#endif /* WITH_LISTEN */
|
||||||
|
const struct addrdesc xioaddr_unix_sendto = { "unix-sendto", 3, xioopen_unix_sendto, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":<filename>") };
|
||||||
|
const struct addrdesc xioaddr_unix_recvfrom= { "unix-recvfrom", 3, xioopen_unix_recvfrom, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY|GROUP_CHILD, 0, 0, 0 HELP(":<filename>") };
|
||||||
|
const struct addrdesc xioaddr_unix_recv = { "unix-recv", 1, xioopen_unix_recv, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":<filename>") };
|
||||||
|
const struct addrdesc xioaddr_unix_client = { "unix-client", 3, xioopen_unix_client, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":<filename>") };
|
||||||
#if WITH_ABSTRACT_UNIXSOCKET
|
#if WITH_ABSTRACT_UNIXSOCKET
|
||||||
static int xioopen_abstract_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
const struct addrdesc xioaddr_abstract_connect = { "abstract-connect", 3, xioopen_unix_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":<filename>") };
|
||||||
static int xioopen_abstract_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
#if WITH_LISTEN
|
||||||
static int xioopen_abstract_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
const struct addrdesc xioaddr_abstract_listen = { "abstract-listen", 3, xioopen_unix_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 1, 0, 0 HELP(":<filename>") };
|
||||||
static int xioopen_abstract_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
#endif /* WITH_LISTEN */
|
||||||
static
|
const struct addrdesc xioaddr_abstract_sendto = { "abstract-sendto", 3, xioopen_unix_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":<filename>") };
|
||||||
int xioopen_abstract_recv(int argc, const char *argv[], struct opt *opts,
|
const struct addrdesc xioaddr_abstract_recvfrom= { "abstract-recvfrom", 3, xioopen_unix_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY|GROUP_CHILD, 1, 0, 0 HELP(":<filename>") };
|
||||||
int xioflags, xiofile_t *xfd, unsigned groups,
|
const struct addrdesc xioaddr_abstract_recv = { "abstract-recv", 1, xioopen_unix_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":<filename>") };
|
||||||
int pf, int socktype, int ipproto);
|
const struct addrdesc xioaddr_abstract_client = { "abstract-client", 3, xioopen_unix_client, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":<filename>") };
|
||||||
static
|
|
||||||
int xioopen_abstract_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, unsigned groups, int dummy1, int dummy2, int dummy3);
|
|
||||||
#endif /* WITH_ABSTRACT_UNIXSOCKET */
|
#endif /* WITH_ABSTRACT_UNIXSOCKET */
|
||||||
|
|
||||||
const struct addrdesc addr_unix_connect = { "unix-connect", 3, xioopen_unix_connect, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, SOCK_STREAM, 0 HELP(":<filename>") };
|
const struct optdesc xioopt_unix_tightsocklen = { "unix-tightsocklen", "tightsocklen", OPT_UNIX_TIGHTSOCKLEN, GROUP_SOCK_UNIX, PH_INIT, TYPE_BOOL, OFUNC_SPEC, 0, 0 };
|
||||||
#if WITH_LISTEN
|
|
||||||
const struct addrdesc addr_unix_listen = { "unix-listen", 3, xioopen_unix_listen, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 0, SOCK_STREAM, 0 HELP(":<filename>") };
|
|
||||||
#endif /* WITH_LISTEN */
|
|
||||||
const struct addrdesc addr_unix_sendto = { "unix-sendto", 3, xioopen_unix_sendto, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, SOCK_DGRAM, 0 HELP(":<filename>") };
|
|
||||||
const struct addrdesc addr_unix_recvfrom= { "unix-recvfrom", 3, xioopen_unix_recvfrom, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY|GROUP_CHILD, PF_UNIX, SOCK_DGRAM, 0 HELP(":<filename>") };
|
|
||||||
const struct addrdesc addr_unix_recv = { "unix-recv", 1, xioopen_unix_recv, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, PF_UNIX, SOCK_DGRAM, 0 HELP(":<filename>") };
|
|
||||||
const struct addrdesc addr_unix_client = { "unix-client", 3, xioopen_unix_client, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, PF_UNIX, 0, 0 HELP(":<filename>") };
|
|
||||||
#if WITH_ABSTRACT_UNIXSOCKET
|
|
||||||
const struct addrdesc xioaddr_abstract_connect = { "abstract-connect", 3, xioopen_abstract_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, SOCK_STREAM, 0 HELP(":<filename>") };
|
|
||||||
#if WITH_LISTEN
|
|
||||||
const struct addrdesc xioaddr_abstract_listen = { "abstract-listen", 3, xioopen_abstract_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 0, SOCK_STREAM, 0 HELP(":<filename>") };
|
|
||||||
#endif /* WITH_LISTEN */
|
|
||||||
const struct addrdesc xioaddr_abstract_sendto = { "abstract-sendto", 3, xioopen_abstract_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, SOCK_DGRAM, 0 HELP(":<filename>") };
|
|
||||||
const struct addrdesc xioaddr_abstract_recvfrom= { "abstract-recvfrom", 3, xioopen_abstract_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY|GROUP_CHILD, PF_UNIX, SOCK_DGRAM, 0 HELP(":<filename>") };
|
|
||||||
const struct addrdesc xioaddr_abstract_recv = { "abstract-recv", 1, xioopen_abstract_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, PF_UNIX, SOCK_DGRAM, 0 HELP(":<filename>") };
|
|
||||||
const struct addrdesc xioaddr_abstract_client = { "abstract-client", 3, xioopen_abstract_client, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, PF_UNIX, 0, 0 HELP(":<filename>") };
|
|
||||||
#endif /* WITH_ABSTRACT_UNIXSOCKET */
|
|
||||||
|
|
||||||
const struct optdesc opt_unix_tightsocklen = { "unix-tightsocklen", "tightsocklen", OPT_UNIX_TIGHTSOCKLEN, GROUP_SOCK_UNIX, PH_INIT, TYPE_BOOL, OFUNC_SPEC, 0, 0 };
|
|
||||||
|
|
||||||
|
|
||||||
|
/* fills the socket address struct and returns its effective length.
|
||||||
|
abstract is usually 0; != 0 generates an abstract socket address on Linux.
|
||||||
|
tight!=0 calculates the resulting length from the path length, not from the
|
||||||
|
structures length; this is more common.
|
||||||
|
the struct need not be initialized when calling this function.
|
||||||
|
*/
|
||||||
socklen_t
|
socklen_t
|
||||||
xiosetunix(struct sockaddr_un *saun,
|
xiosetunix(int pf,
|
||||||
|
struct sockaddr_un *saun,
|
||||||
const char *path,
|
const char *path,
|
||||||
bool abstract,
|
bool abstract,
|
||||||
bool tight) {
|
bool tight) {
|
||||||
size_t pathlen;
|
size_t pathlen;
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
|
|
||||||
if (!abstract) {
|
socket_un_init(saun);
|
||||||
if ((pathlen = strlen(path)) > sizeof(saun->sun_path)) {
|
#ifdef WITH_ABSTRACT_UNIXSOCKET
|
||||||
Warn2("unix socket address "F_Zu" characters long, truncating to "F_Zu"",
|
if (abstract) {
|
||||||
pathlen, sizeof(saun->sun_path));
|
|
||||||
}
|
|
||||||
strncpy(saun->sun_path, path, sizeof(saun->sun_path));
|
|
||||||
if (tight) {
|
|
||||||
len = sizeof(struct sockaddr_un)-sizeof(saun->sun_path)+
|
|
||||||
MIN(pathlen, sizeof(saun->sun_path));
|
|
||||||
#if HAVE_STRUCT_SOCKADDR_SALEN
|
|
||||||
saun->sun_len = len;
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
len = sizeof(struct sockaddr_un);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((pathlen = strlen(path)) >= sizeof(saun->sun_path)) {
|
if ((pathlen = strlen(path)) >= sizeof(saun->sun_path)) {
|
||||||
Warn2("socket address "F_Zu" characters long, truncating to "F_Zu"",
|
Warn2("socket address "F_Zu" characters long, truncating to "F_Zu"",
|
||||||
pathlen+1, sizeof(saun->sun_path));
|
pathlen+1, sizeof(saun->sun_path));
|
||||||
@ -100,15 +93,32 @@ xiosetunix(struct sockaddr_un *saun,
|
|||||||
} else {
|
} else {
|
||||||
len = sizeof(struct sockaddr_un);
|
len = sizeof(struct sockaddr_un);
|
||||||
}
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
#endif /* WITH_ABSTRACT_UNIXSOCKET */
|
||||||
|
|
||||||
|
if ((pathlen = strlen(path)) > sizeof(saun->sun_path)) {
|
||||||
|
Warn2("unix socket address "F_Zu" characters long, truncating to "F_Zu"",
|
||||||
|
pathlen, sizeof(saun->sun_path));
|
||||||
|
}
|
||||||
|
strncpy(saun->sun_path, path, sizeof(saun->sun_path));
|
||||||
|
if (tight) {
|
||||||
|
len = sizeof(struct sockaddr_un)-sizeof(saun->sun_path)+
|
||||||
|
MIN(pathlen, sizeof(saun->sun_path));
|
||||||
|
} else {
|
||||||
|
len = sizeof(struct sockaddr_un);
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WITH_LISTEN
|
#if WITH_LISTEN
|
||||||
static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) {
|
static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3) {
|
||||||
/* we expect the form: filename */
|
/* we expect the form: filename */
|
||||||
const char *name;
|
const char *name;
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
xiosingle_t *xfd = &xxfd->stream;
|
||||||
|
int pf = PF_UNIX;
|
||||||
|
int socktype = SOCK_STREAM;
|
||||||
|
int protocol = 0;
|
||||||
struct sockaddr_un us;
|
struct sockaddr_un us;
|
||||||
socklen_t uslen;
|
socklen_t uslen;
|
||||||
bool tight = true;
|
bool tight = true;
|
||||||
@ -123,50 +133,50 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
|
|||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_un_init(&us);
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
uslen = xiosetunix(&us, name, false, tight);
|
retropt_socket_pf(opts, &pf);
|
||||||
|
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
||||||
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
uslen = xiosetunix(pf, &us, name, abstract, tight);
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
|
||||||
|
|
||||||
if (opt_unlink_close) {
|
|
||||||
if ((xfd->unlink_close = strdup(name)) == NULL) {
|
|
||||||
Error1("strdup(\"%s\"): out of memory", name);
|
|
||||||
}
|
|
||||||
xfd->opt_unlink_close = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
xfd->howtoend = END_SHUTDOWN;
|
||||||
|
|
||||||
applyopts(-1, opts, PH_INIT);
|
if (!(ABSTRACT && abstract)) {
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
/* only for non abstract because abstract do not work in file system */
|
||||||
applyopts(-1, opts, PH_EARLY);
|
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
||||||
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
if (opt_unlink_early) {
|
if (opt_unlink_close) {
|
||||||
if (Unlink(name) < 0) {
|
if ((xfd->unlink_close = strdup(name)) == NULL) {
|
||||||
if (errno == ENOENT) {
|
Error1("strdup(\"%s\"): out of memory", name);
|
||||||
Warn2("unlink(\"%s\"): %s", name, strerror(errno));
|
|
||||||
} else {
|
|
||||||
Error2("unlink(\"%s\"): %s", name, strerror(errno));
|
|
||||||
}
|
}
|
||||||
|
xfd->opt_unlink_close = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* trying to set user-early, perm-early etc. here is useless because
|
applyopts(-1, opts, PH_INIT);
|
||||||
file system entry is available only past bind() call. */
|
applyopts(-1, opts, PH_EARLY);
|
||||||
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
if (!(ABSTRACT && abstract)) {
|
||||||
|
if (opt_unlink_early) {
|
||||||
|
if (Unlink(name) < 0) {
|
||||||
|
if (errno == ENOENT) {
|
||||||
|
Warn2("unlink(\"%s\"): %s", name, strerror(errno));
|
||||||
|
} else {
|
||||||
|
Error2("unlink(\"%s\"): %s", name, strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* trying to set user-early, perm-early etc. here is useless because
|
||||||
|
file system entry is available only past bind() call. */
|
||||||
|
applyopts_named(name, opts, PH_EARLY); /* umask! */
|
||||||
|
}
|
||||||
|
|
||||||
opts0 = copyopts(opts, GROUP_ALL);
|
opts0 = copyopts(opts, GROUP_ALL);
|
||||||
|
|
||||||
if ((result =
|
if ((result =
|
||||||
xioopen_listen(xfd, xioflags,
|
xioopen_listen(xfd, xioflags,
|
||||||
(struct sockaddr *)&us, uslen,
|
(struct sockaddr *)&us, uslen,
|
||||||
opts, opts0, PF_UNIX, socktype, 0))
|
opts, opts0, pf, socktype, protocol))
|
||||||
!= 0)
|
!= 0)
|
||||||
return result;
|
return result;
|
||||||
return 0;
|
return 0;
|
||||||
@ -174,10 +184,13 @@ static int xioopen_unix_listen(int argc, const char *argv[], struct opt *opts, i
|
|||||||
#endif /* WITH_LISTEN */
|
#endif /* WITH_LISTEN */
|
||||||
|
|
||||||
|
|
||||||
static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) {
|
static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3) {
|
||||||
/* we expect the form: filename */
|
/* we expect the form: filename */
|
||||||
const char *name;
|
const char *name;
|
||||||
struct single *xfd = &xxfd->stream;
|
struct single *xfd = &xxfd->stream;
|
||||||
|
int pf = PF_UNIX;
|
||||||
|
int socktype = SOCK_STREAM;
|
||||||
|
int protocol = 0;
|
||||||
struct sockaddr_un them, us;
|
struct sockaddr_un them, us;
|
||||||
socklen_t themlen, uslen;
|
socklen_t themlen, uslen;
|
||||||
bool tight = true;
|
bool tight = true;
|
||||||
@ -191,15 +204,15 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
|
|||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_un_init(&us);
|
|
||||||
socket_un_init(&them);
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
themlen = xiosetunix(&them, name, false, tight);
|
retropt_socket_pf(opts, &pf);
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
||||||
|
themlen = xiosetunix(pf, &them, name, abstract, tight);
|
||||||
if (retropt_bind(opts, AF_UNIX, socktype, 0, (struct sockaddr *)&us, &uslen, 0, 0, 0)
|
if (!(ABSTRACT && abstract)) {
|
||||||
|
/* only for non abstract because abstract do not work in file system */
|
||||||
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
|
}
|
||||||
|
if (retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen, 0, 0, 0)
|
||||||
!= STAT_NOACTION) {
|
!= STAT_NOACTION) {
|
||||||
needbind = true;
|
needbind = true;
|
||||||
}
|
}
|
||||||
@ -219,7 +232,7 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
|
|||||||
xioopen_connect(xfd,
|
xioopen_connect(xfd,
|
||||||
needbind?(struct sockaddr *)&us:NULL, uslen,
|
needbind?(struct sockaddr *)&us:NULL, uslen,
|
||||||
(struct sockaddr *)&them, themlen,
|
(struct sockaddr *)&them, themlen,
|
||||||
opts, PF_UNIX, socktype, 0, false)) != 0) {
|
opts, pf, socktype, protocol, false)) != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
if ((result = _xio_openlate(xfd, opts)) < 0) {
|
if ((result = _xio_openlate(xfd, opts)) < 0) {
|
||||||
@ -229,13 +242,16 @@ static int xioopen_unix_connect(int argc, const char *argv[], struct opt *opts,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) {
|
static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy, int dummy3) {
|
||||||
|
/* we expect the form: filename */
|
||||||
const char *name;
|
const char *name;
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
xiosingle_t *xfd = &xxfd->stream;
|
||||||
|
int pf = PF_UNIX;
|
||||||
|
int socktype = SOCK_DGRAM;
|
||||||
|
int protocol = 0;
|
||||||
union sockaddr_union us;
|
union sockaddr_union us;
|
||||||
socklen_t uslen;
|
socklen_t uslen;
|
||||||
bool tight = true;
|
bool tight = true;
|
||||||
int pf = PF_UNIX;
|
|
||||||
bool needbind = false;
|
bool needbind = false;
|
||||||
bool opt_unlink_close = false;
|
bool opt_unlink_close = false;
|
||||||
|
|
||||||
@ -245,22 +261,21 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i
|
|||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
uslen = socket_init(pf, &us);
|
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
||||||
xfd->salen = socket_init(pf, &xfd->peersa);
|
name = argv[1];
|
||||||
|
retropt_socket_pf(opts, &pf);
|
||||||
|
xfd->salen = xiosetunix(pf, &xfd->peersa.un, name, abstract, tight);
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
xfd->howtoend = END_SHUTDOWN;
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
if (!(ABSTRACT && abstract)) {
|
||||||
|
/* only for non abstract because abstract do not work in file system */
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
name = argv[1];
|
}
|
||||||
xfd->salen = xiosetunix(&xfd->peersa.un, name, false, tight);
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
|
||||||
|
|
||||||
xfd->dtype = XIODATA_RECVFROM;
|
xfd->dtype = XIODATA_RECVFROM;
|
||||||
|
|
||||||
if (retropt_bind(opts, pf, socktype, 0, &us.soa, &uslen, 0, 0, 0)
|
if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, 0, 0, 0)
|
||||||
!= STAT_NOACTION) {
|
!= STAT_NOACTION) {
|
||||||
needbind = true;
|
needbind = true;
|
||||||
}
|
}
|
||||||
@ -277,15 +292,21 @@ static int xioopen_unix_sendto(int argc, const char *argv[], struct opt *opts, i
|
|||||||
|
|
||||||
return
|
return
|
||||||
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
||||||
opts, xioflags, xfd, groups, pf, socktype, 0);
|
opts, xioflags, xfd, groups,
|
||||||
|
pf, socktype, protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
|
int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
|
||||||
int xioflags, xiofile_t *xfd, unsigned groups,
|
int xioflags, xiofile_t *xxfd, unsigned groups,
|
||||||
int pf, int socktype, int dummy3) {
|
int abstract, int dummy2, int dummy3) {
|
||||||
|
/* we expect the form: filename */
|
||||||
const char *name;
|
const char *name;
|
||||||
|
xiosingle_t *xfd = &xxfd->stream;
|
||||||
|
int pf = PF_UNIX;
|
||||||
|
int socktype = SOCK_DGRAM;
|
||||||
|
int protocol = 0;
|
||||||
struct sockaddr_un us;
|
struct sockaddr_un us;
|
||||||
socklen_t uslen;
|
socklen_t uslen;
|
||||||
bool tight = true;
|
bool tight = true;
|
||||||
@ -299,49 +320,57 @@ int xioopen_unix_recvfrom(int argc, const char *argv[], struct opt *opts,
|
|||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_un_init(&us);
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
uslen = xiosetunix(&us, name, false, tight);
|
retropt_socket_pf(opts, &pf);
|
||||||
|
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
||||||
|
uslen = xiosetunix(pf, &us, name, abstract, tight);
|
||||||
|
|
||||||
xfd->stream.howtoend = END_NONE;
|
xfd->howtoend = END_NONE;
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
retropt_bind(opts, pf, socktype, protocol, (struct sockaddr *)&us, &uslen,
|
||||||
retropt_bind(opts, pf, socktype, 0, (struct sockaddr *)&us, &uslen, 1, 0, 0);
|
1, 0, 0);
|
||||||
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
|
||||||
|
|
||||||
if (opt_unlink_close) {
|
if (!(ABSTRACT && abstract)) {
|
||||||
if ((xfd->stream.unlink_close = strdup(name)) == NULL) {
|
/* only for non abstract because abstract do not work in file system */
|
||||||
Error1("strdup(\"%s\"): out of memory", name);
|
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
||||||
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
|
if (opt_unlink_close) {
|
||||||
|
if ((xfd->unlink_close = strdup(name)) == NULL) {
|
||||||
|
Error1("strdup(\"%s\"): out of memory", name);
|
||||||
|
}
|
||||||
|
xfd->opt_unlink_close = true;
|
||||||
}
|
}
|
||||||
xfd->stream.opt_unlink_close = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opt_unlink_early) {
|
if (opt_unlink_early) {
|
||||||
if (Unlink(name) < 0) {
|
if (Unlink(name) < 0) {
|
||||||
if (errno == ENOENT) {
|
if (errno == ENOENT) {
|
||||||
Warn2("unlink(\"%s\"): %s", name, strerror(errno));
|
Warn2("unlink(\"%s\"): %s", name, strerror(errno));
|
||||||
} else {
|
} else {
|
||||||
Error2("unlink(\"%s\"): %s", name, strerror(errno));
|
Error2("unlink(\"%s\"): %s", name, strerror(errno));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xfd->stream.para.socket.la.soa.sa_family = pf;
|
xfd->para.socket.la.soa.sa_family = pf;
|
||||||
|
|
||||||
xfd->stream.dtype = XIODATA_RECVFROM_ONE;
|
xfd->dtype = XIODATA_RECVFROM_ONE;
|
||||||
return _xioopen_dgram_recvfrom(&xfd->stream, xioflags,
|
return
|
||||||
needbind?(struct sockaddr *)&us:NULL, uslen,
|
_xioopen_dgram_recvfrom(xfd, xioflags,
|
||||||
opts, pf, socktype, 0, E_ERROR);
|
needbind?(struct sockaddr *)&us:NULL, uslen,
|
||||||
|
opts, pf, socktype, protocol, E_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
||||||
int xioflags, xiofile_t *xfd, unsigned groups,
|
int xioflags, xiofile_t *xxfd, unsigned groups,
|
||||||
int pf, int socktype, int ipproto) {
|
int abstract, int dummy2, int dummy3) {
|
||||||
|
/* we expect the form: filename */
|
||||||
const char *name;
|
const char *name;
|
||||||
|
xiosingle_t *xfd = &xxfd->stream;
|
||||||
|
int pf = PF_UNIX;
|
||||||
|
int socktype = SOCK_DGRAM;
|
||||||
|
int protocol = 0;
|
||||||
union sockaddr_union us;
|
union sockaddr_union us;
|
||||||
socklen_t uslen;
|
socklen_t uslen;
|
||||||
bool tight = true;
|
bool tight = true;
|
||||||
@ -355,76 +384,97 @@ int xioopen_unix_recv(int argc, const char *argv[], struct opt *opts,
|
|||||||
return STAT_NORETRY;
|
return STAT_NORETRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
|
||||||
|
|
||||||
socket_un_init(&us.un);
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
name = argv[1];
|
name = argv[1];
|
||||||
uslen = xiosetunix(&us.un, name, false, tight);
|
retropt_socket_pf(opts, &pf);
|
||||||
|
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
||||||
|
uslen = xiosetunix(pf, &us.un, name, abstract, tight);
|
||||||
|
|
||||||
#if 1 /*!!! why bind option? */
|
#if 1 /*!!! why bind option? */
|
||||||
retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, 1, 0, 0);
|
retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, 1, 0, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
if (!(ABSTRACT && abstract)) {
|
||||||
if (opt_unlink_early) {
|
/* only for non abstract because abstract do not work in file system */
|
||||||
if (Unlink(name) < 0) {
|
retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
|
||||||
if (errno == ENOENT) {
|
if (opt_unlink_early) {
|
||||||
Warn2("unlink(\"%s\"): %s", name, strerror(errno));
|
if (Unlink(name) < 0) {
|
||||||
} else {
|
if (errno == ENOENT) {
|
||||||
Error2("unlink(\"%s\"): %s", name, strerror(errno));
|
Warn2("unlink(\"%s\"): %s", name, strerror(errno));
|
||||||
|
} else {
|
||||||
|
Error2("unlink(\"%s\"): %s", name, strerror(errno));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
|
|
||||||
if (opt_unlink_close) {
|
if (opt_unlink_close) {
|
||||||
if ((xfd->stream.unlink_close = strdup(name)) == NULL) {
|
if ((xfd->unlink_close = strdup(name)) == NULL) {
|
||||||
Error1("strdup(\"%s\"): out of memory", name);
|
Error1("strdup(\"%s\"): out of memory", name);
|
||||||
|
}
|
||||||
|
xfd->opt_unlink_close = true;
|
||||||
}
|
}
|
||||||
xfd->stream.opt_unlink_close = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xfd->stream.para.socket.la.soa.sa_family = pf;
|
xfd->para.socket.la.soa.sa_family = pf;
|
||||||
|
|
||||||
xfd->stream.dtype = XIODATA_RECV;
|
xfd->dtype = XIODATA_RECV;
|
||||||
result = _xioopen_dgram_recv(&xfd->stream, xioflags, &us.soa, uslen,
|
result = _xioopen_dgram_recv(xfd, xioflags, &us.soa, uslen,
|
||||||
opts, pf, socktype, ipproto, E_ERROR);
|
opts, pf, socktype, protocol, E_ERROR);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) {
|
static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int abstract, int dummy2, int dummy3) {
|
||||||
const char *name;
|
/* we expect the form: filename */
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
|
||||||
bool tight = true;
|
|
||||||
int pf = PF_UNIX;
|
|
||||||
union sockaddr_union them, us;
|
|
||||||
socklen_t themlen;
|
|
||||||
socklen_t uslen;
|
|
||||||
bool needbind = false;
|
|
||||||
bool opt_unlink_close = false;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
|
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
return
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
_xioopen_unix_client(&xxfd->stream, xioflags, groups, abstract, opts,
|
||||||
|
argv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
uslen = socket_init(pf, &us);
|
/* establishes communication with an existing UNIX type socket. supports stream
|
||||||
themlen = socket_init(pf, &them);
|
and datagram socket types: first tries to connect(), but when this fails it
|
||||||
|
falls back to sendto().
|
||||||
|
applies and consumes the following option:
|
||||||
|
PH_INIT, PH_PASTSOCKET, PH_FD, PH_PREBIND, PH_BIND, PH_PASTBIND,
|
||||||
|
PH_CONNECTED, PH_LATE, ?PH_CONNECT
|
||||||
|
OFUNC_OFFSET,
|
||||||
|
OPT_PROTOCOL_FAMILY, OPT_UNIX_TIGHTSOCKLEN, OPT_UNLINK_CLOSE, OPT_BIND,
|
||||||
|
OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_CLOEXEC, OPT_USER, OPT_GROUP, ?OPT_FORK,
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
_xioopen_unix_client(xiosingle_t *xfd, int xioflags, unsigned groups,
|
||||||
|
int abstract, struct opt *opts, const char *name) {
|
||||||
|
int pf = PF_UNIX;
|
||||||
|
int socktype = 0; /* to be determined by server socket type */
|
||||||
|
int protocol = 0;
|
||||||
|
union sockaddr_union them, us;
|
||||||
|
socklen_t themlen, uslen;
|
||||||
|
bool tight = true;
|
||||||
|
bool needbind = false;
|
||||||
|
bool opt_unlink_close = false;
|
||||||
|
struct opt *opts0;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
applyopts(-1, opts, PH_INIT);
|
||||||
|
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
||||||
|
|
||||||
|
xfd->howtoend = END_SHUTDOWN;
|
||||||
|
retropt_socket_pf(opts, &pf);
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
||||||
name = argv[1];
|
themlen = xiosetunix(pf, &them.un, name, abstract, tight);
|
||||||
themlen = xiosetunix(&them.un, name, false, tight);
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
if (!(ABSTRACT && abstract)) {
|
||||||
|
/* only for non abstract because abstract do not work in file system */
|
||||||
|
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
|
||||||
|
}
|
||||||
|
|
||||||
if (retropt_bind(opts, pf, socktype, 0, &us.soa, &uslen, 0, 0, 0)
|
if (retropt_bind(opts, pf, socktype, protocol, &us.soa, &uslen, 0, 0, 0)
|
||||||
!= STAT_NOACTION) {
|
!= STAT_NOACTION) {
|
||||||
needbind = true;
|
needbind = true;
|
||||||
}
|
}
|
||||||
@ -436,26 +486,29 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i
|
|||||||
xfd->opt_unlink_close = true;
|
xfd->opt_unlink_close = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* save options, because we might have to start again */
|
||||||
|
opts0 = copyopts(opts, GROUP_ALL);
|
||||||
|
|
||||||
/* xfd->dtype = DATA_STREAM; // is default */
|
/* xfd->dtype = DATA_STREAM; // is default */
|
||||||
if ((result =
|
if ((result =
|
||||||
xioopen_connect(xfd,
|
xioopen_connect(xfd,
|
||||||
needbind?(struct sockaddr *)&us:NULL, uslen,
|
needbind?(struct sockaddr *)&us:NULL, uslen,
|
||||||
(struct sockaddr *)&them, themlen,
|
(struct sockaddr *)&them, themlen,
|
||||||
opts, PF_UNIX, socktype?socktype:SOCK_STREAM, 0, false)) != 0) {
|
opts, pf, socktype?socktype:SOCK_STREAM, protocol,
|
||||||
|
false)) != 0) {
|
||||||
if (errno == EPROTOTYPE) {
|
if (errno == EPROTOTYPE) {
|
||||||
if (needbind) {
|
if (needbind) {
|
||||||
Unlink(us.un.sun_path);
|
Unlink(us.un.sun_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyopts(-1, opts, PH_INIT);
|
dropopts2(opts, PH_INIT, PH_SPEC); opts = opts0;
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
|
||||||
|
|
||||||
xfd->peersa = them;
|
xfd->peersa = them;
|
||||||
xfd->salen = sizeof(struct sockaddr_un);
|
xfd->salen = sizeof(struct sockaddr_un);
|
||||||
if ((result =
|
if ((result =
|
||||||
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
||||||
opts, xioflags, xfd, groups, pf,
|
opts, xioflags, xfd, groups,
|
||||||
socktype?socktype:SOCK_DGRAM, 0))
|
pf, socktype?socktype:SOCK_DGRAM, protocol))
|
||||||
!= 0) {
|
!= 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -469,278 +522,6 @@ static int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if WITH_ABSTRACT_UNIXSOCKET
|
|
||||||
#if WITH_LISTEN
|
|
||||||
static int xioopen_abstract_listen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) {
|
|
||||||
/* we expect the form: filename */
|
|
||||||
const char *name;
|
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
|
||||||
bool tight = true;
|
|
||||||
struct sockaddr_un us;
|
|
||||||
socklen_t uslen;
|
|
||||||
struct opt *opts0 = NULL;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
|
||||||
}
|
|
||||||
|
|
||||||
socket_un_init(&us);
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
name = argv[1];
|
|
||||||
uslen = xiosetunix(&us, name, true, tight);
|
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
|
||||||
|
|
||||||
applyopts(-1, opts, PH_INIT);
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
|
||||||
applyopts(-1, opts, PH_EARLY);
|
|
||||||
|
|
||||||
/* trying to set user-early, perm-early etc. here is useless because
|
|
||||||
file system entry is available only past bind() call. */
|
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
|
||||||
|
|
||||||
opts0 = copyopts(opts, GROUP_ALL);
|
|
||||||
|
|
||||||
if ((result =
|
|
||||||
xioopen_listen(xfd, xioflags,
|
|
||||||
(struct sockaddr *)&us, uslen,
|
|
||||||
opts, opts0, PF_UNIX, socktype, 0))
|
|
||||||
!= 0)
|
|
||||||
return result;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif /* WITH_LISTEN */
|
|
||||||
|
|
||||||
static int xioopen_abstract_connect(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) {
|
|
||||||
/* we expect the form: filename */
|
|
||||||
const char *name;
|
|
||||||
struct single *xfd = &xxfd->stream;
|
|
||||||
bool tight = true;
|
|
||||||
struct sockaddr_un them, us;
|
|
||||||
socklen_t themlen, uslen;
|
|
||||||
bool needbind = false;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
|
||||||
}
|
|
||||||
|
|
||||||
socket_un_init(&us);
|
|
||||||
socket_un_init(&them);
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
name = argv[1];
|
|
||||||
themlen = xiosetunix(&them, name, true, tight);
|
|
||||||
|
|
||||||
if (retropt_bind(opts, AF_UNIX, socktype, 0, (struct sockaddr *)&us, &uslen, 0, 0, 0)
|
|
||||||
!= STAT_NOACTION) {
|
|
||||||
needbind = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
applyopts(-1, opts, PH_INIT);
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
|
||||||
applyopts(-1, opts, PH_EARLY);
|
|
||||||
|
|
||||||
if ((result =
|
|
||||||
xioopen_connect(xfd,
|
|
||||||
needbind?(struct sockaddr *)&us:NULL, uslen,
|
|
||||||
(struct sockaddr *)&them, themlen,
|
|
||||||
opts, PF_UNIX, socktype, 0, false)) != 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if ((result = _xio_openlate(xfd, opts)) < 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int xioopen_abstract_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) {
|
|
||||||
const char *name;
|
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
|
||||||
union sockaddr_union us;
|
|
||||||
socklen_t uslen;
|
|
||||||
bool tight = true;
|
|
||||||
int pf = PF_UNIX;
|
|
||||||
bool needbind = false;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
|
||||||
}
|
|
||||||
|
|
||||||
uslen = socket_init(pf, &us);
|
|
||||||
xfd->salen = socket_init(pf, &xfd->peersa);
|
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
name = argv[1];
|
|
||||||
xfd->salen = xiosetunix(&xfd->peersa.un, name, true, tight);
|
|
||||||
|
|
||||||
xfd->dtype = XIODATA_RECVFROM;
|
|
||||||
|
|
||||||
if (retropt_bind(opts, pf, socktype, 0, &us.soa, &uslen, 0, 0, 0)
|
|
||||||
!= STAT_NOACTION) {
|
|
||||||
needbind = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
applyopts(-1, opts, PH_INIT);
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
|
||||||
|
|
||||||
return
|
|
||||||
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
|
||||||
opts, xioflags, xfd, groups, pf, socktype, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static
|
|
||||||
int xioopen_abstract_recvfrom(int argc, const char *argv[], struct opt *opts,
|
|
||||||
int xioflags, xiofile_t *xfd, unsigned groups,
|
|
||||||
int pf, int socktype, int dummy3) {
|
|
||||||
const char *name;
|
|
||||||
struct sockaddr_un us;
|
|
||||||
socklen_t uslen;
|
|
||||||
bool tight = true;
|
|
||||||
bool needbind = true;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
|
||||||
}
|
|
||||||
|
|
||||||
socket_un_init(&us);
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
name = argv[1];
|
|
||||||
uslen = xiosetunix(&us, name, true, tight);
|
|
||||||
|
|
||||||
xfd->stream.howtoend = END_NONE;
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
|
||||||
retropt_bind(opts, pf, socktype, 0, (struct sockaddr *)&us, &uslen, 1, 0, 0);
|
|
||||||
|
|
||||||
xfd->stream.para.socket.la.soa.sa_family = pf;
|
|
||||||
|
|
||||||
xfd->stream.dtype = XIODATA_RECVFROM_ONE;
|
|
||||||
return _xioopen_dgram_recvfrom(&xfd->stream, xioflags,
|
|
||||||
needbind?(struct sockaddr *)&us:NULL, uslen,
|
|
||||||
opts, pf, socktype, 0, E_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static
|
|
||||||
int xioopen_abstract_recv(int argc, const char *argv[], struct opt *opts,
|
|
||||||
int xioflags, xiofile_t *xfd, unsigned groups,
|
|
||||||
int pf, int socktype, int ipproto) {
|
|
||||||
const char *name;
|
|
||||||
union sockaddr_union us;
|
|
||||||
socklen_t uslen;
|
|
||||||
bool tight = true;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)",
|
|
||||||
argv[0], argc-1);
|
|
||||||
return STAT_NORETRY;
|
|
||||||
}
|
|
||||||
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
|
||||||
|
|
||||||
socket_un_init(&us.un);
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
name = argv[1];
|
|
||||||
uslen = xiosetunix(&us.un, name, true, tight);
|
|
||||||
|
|
||||||
#if 1 /*!!! why bind option? */
|
|
||||||
retropt_bind(opts, pf, socktype, ipproto, &us.soa, &uslen, 1, 0, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
xfd->stream.para.socket.la.soa.sa_family = pf;
|
|
||||||
|
|
||||||
xfd->stream.dtype = XIODATA_RECV;
|
|
||||||
result = _xioopen_dgram_recv(&xfd->stream, xioflags, &us.soa, uslen,
|
|
||||||
opts, pf, socktype, ipproto, E_ERROR);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int xioopen_abstract_client(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xxfd, unsigned groups, int dummy1, int socktype, int dummy3) {
|
|
||||||
const char *name;
|
|
||||||
xiosingle_t *xfd = &xxfd->stream;
|
|
||||||
bool tight = true;
|
|
||||||
int pf = PF_UNIX;
|
|
||||||
union sockaddr_union them, us;
|
|
||||||
socklen_t themlen;
|
|
||||||
socklen_t uslen;
|
|
||||||
bool needbind = false;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (argc != 2) {
|
|
||||||
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
xfd->howtoend = END_SHUTDOWN;
|
|
||||||
retropt_int(opts, OPT_SO_TYPE, &socktype);
|
|
||||||
|
|
||||||
uslen = socket_init(pf, &us);
|
|
||||||
themlen = socket_init(pf, &them);
|
|
||||||
|
|
||||||
retropt_bool(opts, OPT_UNIX_TIGHTSOCKLEN, &tight);
|
|
||||||
name = argv[1];
|
|
||||||
themlen = xiosetunix(&them.un, name, true, tight);
|
|
||||||
|
|
||||||
if (retropt_bind(opts, pf, socktype, 0, &us.soa, &uslen, 0, 0, 0)
|
|
||||||
!= STAT_NOACTION) {
|
|
||||||
needbind = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* xfd->dtype = DATA_STREAM; // is default */
|
|
||||||
if ((result =
|
|
||||||
xioopen_connect(xfd,
|
|
||||||
needbind?(struct sockaddr *)&us:NULL, uslen,
|
|
||||||
(struct sockaddr *)&them, themlen,
|
|
||||||
opts, PF_UNIX, socktype?socktype:SOCK_STREAM, 0, false)) != 0) {
|
|
||||||
if (errno == EPROTOTYPE) {
|
|
||||||
if (needbind) {
|
|
||||||
Unlink(us.un.sun_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ...res_opts[] */
|
|
||||||
applyopts(-1, opts, PH_INIT);
|
|
||||||
if (applyopts_single(xfd, opts, PH_INIT) < 0) return -1;
|
|
||||||
|
|
||||||
xfd->peersa = them;
|
|
||||||
xfd->salen = themlen;
|
|
||||||
if ((result =
|
|
||||||
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
|
|
||||||
opts, xioflags, xfd, groups, pf,
|
|
||||||
socktype?socktype:SOCK_DGRAM, 0))
|
|
||||||
!= 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
xfd->dtype = XIODATA_RECVFROM;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((result = _xio_openlate(xfd, opts)) < 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* WITH_ABSTRACT_UNIXSOCKET */
|
|
||||||
|
|
||||||
/* returns information that can be used for constructing an environment
|
/* returns information that can be used for constructing an environment
|
||||||
variable describing the socket address.
|
variable describing the socket address.
|
||||||
if idx is 0, this function writes "ADDR" into namebuff and the path into
|
if idx is 0, this function writes "ADDR" into namebuff and the path into
|
||||||
|
21
xio-unix.h
21
xio-unix.h
@ -5,12 +5,12 @@
|
|||||||
#ifndef __xio_unix_h_included
|
#ifndef __xio_unix_h_included
|
||||||
#define __xio_unix_h_included 1
|
#define __xio_unix_h_included 1
|
||||||
|
|
||||||
extern const struct addrdesc addr_unix_connect;
|
extern const struct addrdesc xioaddr_unix_connect;
|
||||||
extern const struct addrdesc addr_unix_listen;
|
extern const struct addrdesc xioaddr_unix_listen;
|
||||||
extern const struct addrdesc addr_unix_sendto;
|
extern const struct addrdesc xioaddr_unix_sendto;
|
||||||
extern const struct addrdesc addr_unix_recvfrom;
|
extern const struct addrdesc xioaddr_unix_recvfrom;
|
||||||
extern const struct addrdesc addr_unix_recv;
|
extern const struct addrdesc xioaddr_unix_recv;
|
||||||
extern const struct addrdesc addr_unix_client;
|
extern const struct addrdesc xioaddr_unix_client;
|
||||||
extern const struct addrdesc xioaddr_abstract_connect;
|
extern const struct addrdesc xioaddr_abstract_connect;
|
||||||
extern const struct addrdesc xioaddr_abstract_listen;
|
extern const struct addrdesc xioaddr_abstract_listen;
|
||||||
extern const struct addrdesc xioaddr_abstract_sendto;
|
extern const struct addrdesc xioaddr_abstract_sendto;
|
||||||
@ -18,10 +18,11 @@ extern const struct addrdesc xioaddr_abstract_recvfrom;
|
|||||||
extern const struct addrdesc xioaddr_abstract_recv;
|
extern const struct addrdesc xioaddr_abstract_recv;
|
||||||
extern const struct addrdesc xioaddr_abstract_client;
|
extern const struct addrdesc xioaddr_abstract_client;
|
||||||
|
|
||||||
extern const struct optdesc opt_unix_tightsocklen;
|
extern const struct optdesc xioopt_unix_tightsocklen;
|
||||||
|
|
||||||
extern socklen_t
|
extern socklen_t
|
||||||
xiosetunix(struct sockaddr_un *saun,
|
xiosetunix(int pf,
|
||||||
|
struct sockaddr_un *saun,
|
||||||
const char *path,
|
const char *path,
|
||||||
bool abstract,
|
bool abstract,
|
||||||
bool tight);
|
bool tight);
|
||||||
@ -30,4 +31,8 @@ xiosetsockaddrenv_unix(int idx, char *namebuff, size_t namelen,
|
|||||||
char *valuebuff, size_t valuelen,
|
char *valuebuff, size_t valuelen,
|
||||||
struct sockaddr_un *sa, socklen_t salen, int ipproto);
|
struct sockaddr_un *sa, socklen_t salen, int ipproto);
|
||||||
|
|
||||||
|
extern int
|
||||||
|
_xioopen_unix_client(xiosingle_t *xfd, int xioflags, unsigned groups,
|
||||||
|
int abstract, struct opt *opts, const char *name);
|
||||||
|
|
||||||
#endif /* !defined(__xio_unix_h_included) */
|
#endif /* !defined(__xio_unix_h_included) */
|
||||||
|
20
xioopen.c
20
xioopen.c
@ -106,7 +106,7 @@ const struct addrname addressnames[] = {
|
|||||||
#endif
|
#endif
|
||||||
#endif /* WITH_RAWIP */
|
#endif /* WITH_RAWIP */
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
{ "local", &addr_unix_connect },
|
{ "local", &xioaddr_unix_connect },
|
||||||
#endif
|
#endif
|
||||||
#if WITH_FILE
|
#if WITH_FILE
|
||||||
{ "open", &addr_open },
|
{ "open", &addr_open },
|
||||||
@ -231,19 +231,19 @@ const struct addrname addressnames[] = {
|
|||||||
{ "udp6-sendto", &addr_udp6_sendto },
|
{ "udp6-sendto", &addr_udp6_sendto },
|
||||||
#endif
|
#endif
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
{ "unix", &addr_unix_client },
|
{ "unix", &xioaddr_unix_client },
|
||||||
{ "unix-client", &addr_unix_client },
|
{ "unix-client", &xioaddr_unix_client },
|
||||||
{ "unix-connect", &addr_unix_connect },
|
{ "unix-connect", &xioaddr_unix_connect },
|
||||||
#endif
|
#endif
|
||||||
#if WITH_UNIX && WITH_LISTEN
|
#if WITH_UNIX && WITH_LISTEN
|
||||||
{ "unix-l", &addr_unix_listen },
|
{ "unix-l", &xioaddr_unix_listen },
|
||||||
{ "unix-listen", &addr_unix_listen },
|
{ "unix-listen", &xioaddr_unix_listen },
|
||||||
#endif
|
#endif
|
||||||
#if WITH_UNIX
|
#if WITH_UNIX
|
||||||
{ "unix-recv", &addr_unix_recv },
|
{ "unix-recv", &xioaddr_unix_recv },
|
||||||
{ "unix-recvfrom", &addr_unix_recvfrom },
|
{ "unix-recvfrom", &xioaddr_unix_recvfrom },
|
||||||
{ "unix-send", &addr_unix_sendto },
|
{ "unix-send", &xioaddr_unix_sendto },
|
||||||
{ "unix-sendto", &addr_unix_sendto },
|
{ "unix-sendto", &xioaddr_unix_sendto },
|
||||||
#endif
|
#endif
|
||||||
#else /* !0 */
|
#else /* !0 */
|
||||||
# if WITH_INTEGRATE
|
# if WITH_INTEGRATE
|
||||||
|
16
xioopts.c
16
xioopts.c
@ -1502,7 +1502,7 @@ const struct optname optionnames[] = {
|
|||||||
#ifdef O_TEXT
|
#ifdef O_TEXT
|
||||||
IF_ANY ("text", &opt_o_text)
|
IF_ANY ("text", &opt_o_text)
|
||||||
#endif
|
#endif
|
||||||
IF_UNIX ("tightsocklen", &opt_unix_tightsocklen)
|
IF_UNIX ("tightsocklen", &xioopt_unix_tightsocklen)
|
||||||
IF_TERMIOS("time", &opt_vtime)
|
IF_TERMIOS("time", &opt_vtime)
|
||||||
#ifdef SO_TIMESTAMP
|
#ifdef SO_TIMESTAMP
|
||||||
IF_SOCKET ("timestamp", &opt_so_timestamp)
|
IF_SOCKET ("timestamp", &opt_so_timestamp)
|
||||||
@ -1533,7 +1533,7 @@ const struct optname optionnames[] = {
|
|||||||
IF_ANY ("uid-l", &opt_user_late)
|
IF_ANY ("uid-l", &opt_user_late)
|
||||||
IF_NAMED ("umask", &opt_umask)
|
IF_NAMED ("umask", &opt_umask)
|
||||||
IF_IP6 ("unicast-hops", &opt_ipv6_unicast_hops)
|
IF_IP6 ("unicast-hops", &opt_ipv6_unicast_hops)
|
||||||
IF_UNIX ("unix-tightsocklen", &opt_unix_tightsocklen)
|
IF_UNIX ("unix-tightsocklen", &xioopt_unix_tightsocklen)
|
||||||
IF_NAMED ("unlink", &opt_unlink)
|
IF_NAMED ("unlink", &opt_unlink)
|
||||||
IF_NAMED ("unlink-close", &opt_unlink_close)
|
IF_NAMED ("unlink-close", &opt_unlink_close)
|
||||||
IF_NAMED ("unlink-early", &opt_unlink_early)
|
IF_NAMED ("unlink-early", &opt_unlink_early)
|
||||||
@ -2398,7 +2398,15 @@ int retropt_int(struct opt *opts, int optcode, int *result) {
|
|||||||
|
|
||||||
while (opt->desc != ODESC_END) {
|
while (opt->desc != ODESC_END) {
|
||||||
if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) {
|
if (opt->desc != ODESC_DONE && opt->desc->optcode == optcode) {
|
||||||
*result = opt->value.u_int;
|
switch (opt->desc->type) {
|
||||||
|
case TYPE_INT: *result = opt->value.u_int; break;
|
||||||
|
case TYPE_STRING: *result = strtol(opt->value.u_string, NULL, 0);
|
||||||
|
break;
|
||||||
|
default: Error2("cannot convert type %d of option %s to int",
|
||||||
|
opt->desc->type, opt->desc->defname);
|
||||||
|
opt->desc = ODESC_ERROR;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
opt->desc = ODESC_DONE;
|
opt->desc = ODESC_DONE;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2580,7 +2588,7 @@ int retropt_bind(struct opt *opts,
|
|||||||
{
|
{
|
||||||
bool tight = false;
|
bool tight = false;
|
||||||
struct sockaddr_un *s_un = (struct sockaddr_un *)sa;
|
struct sockaddr_un *s_un = (struct sockaddr_un *)sa;
|
||||||
*salen = xiosetunix(s_un, bindname, false, tight);
|
*salen = xiosetunix(af, s_un, bindname, false, tight);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* WITH_UNIX */
|
#endif /* WITH_UNIX */
|
||||||
|
@ -521,7 +521,8 @@ enum e_optcode {
|
|||||||
OPT_PIPES,
|
OPT_PIPES,
|
||||||
/*OPT_PORT,*/
|
/*OPT_PORT,*/
|
||||||
OPT_PROMPT, /* readline */
|
OPT_PROMPT, /* readline */
|
||||||
OPT_PROTOCOL_FAMILY,
|
OPT_PROTOCOL, /* 6=TCP, 17=UDP */
|
||||||
|
OPT_PROTOCOL_FAMILY, /* 1=PF_UNIX, 2=PF_INET, 10=PF_INET6 */
|
||||||
OPT_PROXYPORT,
|
OPT_PROXYPORT,
|
||||||
OPT_PROXY_AUTHORIZATION,
|
OPT_PROXY_AUTHORIZATION,
|
||||||
OPT_PROXY_RESOLVE,
|
OPT_PROXY_RESOLVE,
|
||||||
@ -615,9 +616,7 @@ enum e_optcode {
|
|||||||
#ifdef SO_PRIORITY
|
#ifdef SO_PRIORITY
|
||||||
OPT_SO_PRIORITY,
|
OPT_SO_PRIORITY,
|
||||||
#endif
|
#endif
|
||||||
#ifdef SO_PROTOTYPE
|
|
||||||
OPT_SO_PROTOTYPE,
|
OPT_SO_PROTOTYPE,
|
||||||
#endif
|
|
||||||
OPT_SO_RCVBUF,
|
OPT_SO_RCVBUF,
|
||||||
OPT_SO_RCVBUF_LATE,
|
OPT_SO_RCVBUF_LATE,
|
||||||
#ifdef SO_RCVLOWAT
|
#ifdef SO_RCVLOWAT
|
||||||
@ -794,7 +793,8 @@ enum e_optcode {
|
|||||||
|
|
||||||
/* keep consistent with xiohelp.c:optionphasenames ! */
|
/* keep consistent with xiohelp.c:optionphasenames ! */
|
||||||
enum e_phase {
|
enum e_phase {
|
||||||
PH_ALL, /* not for options; use in apply funcs to say "all phases" */
|
PH_ALL, /* not for option definitions; use in apply funcs to
|
||||||
|
say "all phases" */
|
||||||
PH_INIT, /* retrieving info from original state */
|
PH_INIT, /* retrieving info from original state */
|
||||||
PH_EARLY, /* before any other processing */
|
PH_EARLY, /* before any other processing */
|
||||||
PH_PREOPEN, /* before file descriptor is created/opened */
|
PH_PREOPEN, /* before file descriptor is created/opened */
|
||||||
|
Loading…
Reference in New Issue
Block a user