Fixed IP-SENDTO with option pf with protocol name

This commit is contained in:
Gerhard Rieger 2024-07-26 09:48:17 +02:00
parent 50b6301bda
commit 0cfe39a413
7 changed files with 75 additions and 15 deletions

View file

@ -19,6 +19,11 @@ Corrections:
did not work. did not work.
Thanks to Linus Luessing for reporting this bug. Thanks to Linus Luessing for reporting this bug.
Up to version 1.8.0.0 IP-SENDTO and option pf (protocol-family) with
protocol name (vs.numeric argument) failed with message:
E retropts_int(): trailing garbage in numerical arg of option "protocol-family"
Test: IP_SENDTO_PF
Features: Features:
Total inactivity timeout option -T 0 now means 0.0 seconds; up to Total inactivity timeout option -T 0 now means 0.0 seconds; up to
version 1.8.0.0 it meant no total inactivity timeout. version 1.8.0.0 it meant no total inactivity timeout.

53
test.sh
View file

@ -19862,6 +19862,59 @@ esac
N=$((N+1)) N=$((N+1))
# Test for a bug (up to 1.8.0.0) with IP-SENDTO and option pf (protocol-family)
# with protocol name (vs.numeric)
NAME=IP_SENDTO_PF
case "$TESTS" in
*%$N%*|*%functions%*|*%root%*|*%bugs%*|*%socket%*|*%ip4%*|*%rawip%*|*%gopen%*|*%$NAME%*)
TEST="$NAME: test IP-SENDTO with option pf with protocol name"
# Invoke Socat with address IP-SENDTO with option pf=ip4
# When this works the test succeeded; when an error (in particular:
# E retropts_int(): trailing garbage in numerical arg of option "protocol-family")
# occurs, the test fails
if ! eval $NUMCOND; then :
# Remove unneeded checks, adapt lists of the remaining ones
elif ! cond=$(checkconds \
"" \
"root" \
"" \
"IP4 RAWIP GOPEN" \
"GOPEN IP-SENDTO" \
"pf" \
"ip4" ); then
$PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
numCANT=$((numCANT+1))
listCANT="$listCANT $N"
namesCANT="$namesCANT $NAME"
else
tf="$td/test$N.stdout"
te="$td/test$N.stderr"
tdiff="$td/test$N.diff"
da="test$N $(date) $RANDOM"
CMD0="$TRACE $SOCAT $opts -u /dev/null IP-SENDTO:127.0.0.1:254,pf=ip4"
printf "test $F_n $TEST... " $N
$CMD0 >/dev/null 2>"${te}0"
rc0=$?
if [ "$rc0" -ne 0 ]; then
$PRINTF "$FAILED (rc0=$rc0)\n"
echo "$CMD0 &"
cat "${te}0" >&2
numFAIL=$((numFAIL+1))
listFAIL="$listFAIL $N"
namesFAIL="$namesFAIL $NAME"
else
$PRINTF "$OK\n"
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
numOK=$((numOK+1))
listOK="$listOK $N"
fi
fi # NUMCOND
;;
esac
N=$((N+1))
# end of common tests # end of common tests
################################################################################## ##################################################################################

View file

@ -132,15 +132,17 @@ int xioinit_ip(
char ipv) char ipv)
{ {
if (*pf == PF_UNSPEC) { if (*pf == PF_UNSPEC) {
#if WITH_IP4 && WITH_IP6
switch (ipv) { switch (ipv) {
case '0': *pf = PF_UNSPEC; break;
#if WITH_IP4
case '4': *pf = PF_INET; break; case '4': *pf = PF_INET; break;
#endif
#if WITH_IP6
case '6': *pf = PF_INET6; break; case '6': *pf = PF_INET6; break;
#endif default: break; /* includes \0 */
} }
#elif WITH_IP6
*pf = PF_INET6;
#else
*pf = PF_INET;
#endif
} }
return 0; return 0;
} }

View file

@ -56,7 +56,7 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
struct opt *popts = NULL; /* parent options */ struct opt *popts = NULL; /* parent options */
struct opt *copts; /* child options */ struct opt *copts; /* child options */
int numleft; int numleft;
int d, sv[2], rdpip[2], wrpip[2]; int 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
@ -355,10 +355,11 @@ int _xioopen_foxec(int xioflags, /* XIO_RDONLY etc. */
/* end withfork, use_pipes */ /* end withfork, use_pipes */
} else { } else {
/* withfork, socketpair */ /* withfork, socketpair */
int pf;
d = AF_UNIX; pf = AF_UNIX;
retropt_int(opts, OPT_PROTOCOL_FAMILY, &d); retropt_socket_pf(opts, &pf);
result = xiosocketpair(opts, d, SOCK_STREAM, 0, sv); result = xiosocketpair(opts, pf, SOCK_STREAM, 0, sv);
if (result < 0) { if (result < 0) {
return -1; return -1;
} }

View file

@ -108,7 +108,7 @@ int _xioopen_rawip_sendto(const char *hostname, const char *protname,
if (sfd->howtoend == END_UNSPEC) if (sfd->howtoend == END_UNSPEC)
sfd->howtoend = END_SHUTDOWN; sfd->howtoend = END_SHUTDOWN;
retropt_int(opts, OPT_PROTOCOL_FAMILY, pf); retropt_socket_pf(opts, pf);
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
applyopts(sfd, -1, opts, PH_INIT); applyopts(sfd, -1, opts, PH_INIT);

View file

@ -1460,15 +1460,13 @@ int retropt_socket_pf(struct opt *opts, int *pf) {
} else if (!strcasecmp("inet", pfname) || } else if (!strcasecmp("inet", pfname) ||
!strcasecmp("inet4", pfname) || !strcasecmp("inet4", pfname) ||
!strcasecmp("ip4", pfname) || !strcasecmp("ip4", pfname) ||
!strcasecmp("ipv4", pfname) || !strcasecmp("ipv4", pfname)) {
!strcasecmp("2", pfname)) {
*pf = PF_INET; *pf = PF_INET;
#endif /* WITH_IP4 */ #endif /* WITH_IP4 */
#if WITH_IP6 #if WITH_IP6
} else if (!strcasecmp("inet6", pfname) || } else if (!strcasecmp("inet6", pfname) ||
!strcasecmp("ip6", pfname) || !strcasecmp("ip6", pfname) ||
!strcasecmp("ipv6", pfname) || !strcasecmp("ipv6", pfname)) {
!strcasecmp("10", pfname)) {
*pf = PF_INET6; *pf = PF_INET6;
#endif /* WITH_IP6 */ #endif /* WITH_IP6 */
} else { } else {

View file

@ -7,6 +7,7 @@
#include "xiosysincludes.h" #include "xiosysincludes.h"
#include "xioopen.h" #include "xioopen.h"
#include "xio-socket.h"
#include "xio-named.h" #include "xio-named.h"
#include "xio-socketpair.h" #include "xio-socketpair.h"
@ -44,7 +45,7 @@ static int xioopen_socketpair(
sfd->para.bipipe.socktype = SOCK_DGRAM; sfd->para.bipipe.socktype = SOCK_DGRAM;
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1; if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
applyopts(sfd, -1, opts, PH_INIT); applyopts(sfd, -1, opts, PH_INIT);
retropt_int(opts, OPT_PROTOCOL_FAMILY, &pf); retropt_socket_pf(opts, &pf);
retropt_int(opts, OPT_SO_TYPE, &sfd->para.bipipe.socktype); retropt_int(opts, OPT_SO_TYPE, &sfd->para.bipipe.socktype);
retropt_int(opts, OPT_SO_PROTOTYPE, &protocol); retropt_int(opts, OPT_SO_PROTOTYPE, &protocol);