GOPEN handles UNIX seqpacket sockets

This commit is contained in:
Gerhard Rieger 2020-12-29 05:30:52 +01:00
parent d9d320cb47
commit 0dccf48d69
3 changed files with 98 additions and 15 deletions

View file

@ -95,6 +95,11 @@ Testing:
* do not use sort -V
* renamed testaddrs() to testfeats(), and introduced new testaddrs()
New features:
GOPEN and UNIX-CLIENT addresses now support sockets of type SEQPACKET.
Test: GOPENUNIXSEQPACKET
Feature suggested by vi0oss.
####################### V 1.7.3.4:
Corrections:

52
test.sh
View file

@ -3772,6 +3772,58 @@ fi # NUMCOND
esac
N=$((N+1))
NAME=GOPENUNIXSEQPACKET
case "$TESTS" in
*%$N%*|*%functions%*|*%gopen%*|*%unix%*|*%listen%*|*%seqpacket%*|*%$NAME%*)
TEST="$NAME: GOPEN on UNIX seqpacket socket"
if ! eval $NUMCOND; then :; else
case "$UNAME" in
SunOS) SOCK_SEQPACKET=6 ;;
*) SOCK_SEQPACKET=5 ;;
esac
ts="$td/test$N.socket"
tf="$td/test$N.stdout"
te="$td/test$N.stderr"
tdiff="$td/test$N.diff"
da1="test$N $(date) $RANDOM"
#establish a listening unix socket in background
SRV="$TRACE $SOCAT $opts -lpserver UNIX-LISTEN:\"$ts\",so-type=$SOCK_SEQPACKET PIPE"
#make a connection
CMD="$TRACE $SOCAT $opts - $ts"
$PRINTF "test $F_n $TEST... " $N
eval "$SRV 2>${te}s &"
pids=$!
waitfile "$ts"
echo "$da1" |eval "$CMD" >"${tf}1" 2>"${te}1"
if [ $? -ne 0 ]; then
kill "$pids" 2>/dev/null
$PRINTF "$FAILED:\n"
echo "$SRV &"
cat "${te}s"
echo "$CMD"
cat "${te}1"
numFAIL=$((numFAIL+1))
listFAIL="$listFAIL $N"
elif ! echo "$da1" |diff - "${tf}1" >"$tdiff"; then
kill "$pids" 2>/dev/null
$PRINTF "$FAILED:\n"
echo "$SRV &"
cat "${te}s"
echo "$CMD"
cat "${te}1"
cat "$tdiff"
numFAIL=$((numFAIL+1))
listFAIL="$listFAIL $N"
else
$PRINTF "$OK\n"
if [ -n "$debug" ]; then cat $te; fi
numOK=$((numOK+1))
fi # !(rc -ne 0)
wait
fi # NUMCOND
esac
N=$((N+1))
NAME=GOPENUNIXDGRAM
case "$TESTS" in

View file

@ -541,6 +541,8 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, unsigned groups,
if (applyopts_single(xfd, opts, PH_INIT) < 0) return STAT_NORETRY;
applyopts(-1, opts, PH_INIT);
applyopts_offset(xfd, opts);
retropt_int(opts, OPT_SO_TYPE, &socktype);
retropt_int(opts, OPT_SO_PROTOTYPE, &protocol);
applyopts(-1, opts, PH_EARLY);
themlen = xiosetunix(pf, &them.un, name, abstract, xfd->para.socket.un.tight);
@ -569,32 +571,56 @@ _xioopen_unix_client(xiosingle_t *xfd, int xioflags, unsigned groups,
/* save options, because we might have to start again */
opts0 = copyopts(opts, GROUP_ALL);
/* xfd->dtype = DATA_STREAM; // is default */
if ((result =
/* just a breakable block, helps to avoid goto */
do {
/* xfd->dtype = DATA_STREAM; // is default */
/* this function handles AF_UNIX with EPROTOTYPE specially for us */
if ((result =
xioopen_connect(xfd,
needbind?&us:NULL, uslen,
&them.soa, themlen,
opts, pf, socktype?socktype:SOCK_STREAM, protocol,
false)) != 0) {
if (errno == EPROTOTYPE) {
if (needbind) {
Unlink(us.un.sun_path);
}
false)) == 0)
break;
if (errno != EPROTOTYPE || socktype != 0)
break;
if (needbind)
Unlink(us.un.sun_path);
dropopts2(opts, PH_INIT, PH_SPEC); opts = opts0;
dropopts2(opts, PH_INIT, PH_SPEC); opts = opts0;
socktype = SOCK_SEQPACKET;
if ((result =
xioopen_connect(xfd,
needbind?&us:NULL, uslen,
(struct sockaddr *)&them, themlen,
opts, pf, SOCK_SEQPACKET, protocol,
false)) == 0)
break;
if (errno != EPROTOTYPE)
break;
if (needbind)
Unlink(us.un.sun_path);
dropopts2(opts, PH_INIT, PH_SPEC); opts = opts0;
xfd->peersa = them;
xfd->salen = sizeof(struct sockaddr_un);
if ((result =
xfd->peersa = them;
xfd->salen = sizeof(struct sockaddr_un);
if ((result =
_xioopen_dgram_sendto(needbind?&us:NULL, uslen,
opts, xioflags, xfd, groups,
pf, socktype?socktype:SOCK_DGRAM, protocol))
!= 0) {
return result;
}
pf, SOCK_DGRAM, protocol))
== 0) {
xfd->dtype = XIODATA_RECVFROM;
break;
}
} while (0);
if (result != 0) {
if (needbind) {
Unlink(us.un.sun_path);
}
return result;
}
if ((result = _xio_openlate(xfd, opts)) < 0) {
return result;
}