Lots of minor corrections

This commit is contained in:
Gerhard Rieger 2023-10-01 19:53:55 +02:00
parent 7d6295114b
commit 1c1a91027a
19 changed files with 197 additions and 78 deletions

View file

@ -166,6 +166,10 @@ Corrections:
by Socat. Now an error is printed when, e.g,, a read-only type address by Socat. Now an error is printed when, e.g,, a read-only type address
is opened for writing. is opened for writing.
A lot of minor corrections, e.g., catch readline() errors in filan,
detect byte order in procan
Test: EXEC_SIGINT
Coding: Coding:
Introduced groups_t instead of uint32_t, for more flexibility. Introduced groups_t instead of uint32_t, for more flexibility.

View file

@ -328,26 +328,6 @@ AC_ARG_ENABLE(interface, [ --disable-interface disable network interface suppo
*) AC_MSG_RESULT(yes); WITH_INTERFACE=1 ;; *) AC_MSG_RESULT(yes); WITH_INTERFACE=1 ;;
esac], esac],
[AC_MSG_RESULT(yes); WITH_INTERFACE=1 ]) [AC_MSG_RESULT(yes); WITH_INTERFACE=1 ])
if test "$WITH_INTERFACE"; then
AC_CHECK_HEADER(linux/if_packet.h,
AC_DEFINE(HAVE_LINUX_IF_PACKET_H),
[WITH_INTERFACE=;
AC_MSG_WARN([include file linux/if_packet.h not found, disabling interface])])
fi
if test "$WITH_INTERFACE"; then
AC_CHECK_HEADER(netinet/if_ether.h,
AC_DEFINE(HAVE_NETINET_IF_ETHER_H),
[WITH_INTERFACE=;
AC_MSG_WARN([include file netinet/if_ether.h not found, disabling interface])],
[AC_INCLUDES_DEFAULT
#if HAVE_NET_IF_H && HAVE_NETINET_IN_H
#include <net/if.h>
#include <netinet/in.h>
#endif])
fi
if test "$WITH_INTERFACE"; then
AC_DEFINE(WITH_INTERFACE)
fi
AC_MSG_CHECKING(whether to include TCP support) AC_MSG_CHECKING(whether to include TCP support)
AC_ARG_ENABLE(tcp, [ --disable-tcp disable TCP support], AC_ARG_ENABLE(tcp, [ --disable-tcp disable TCP support],
@ -835,6 +815,28 @@ if test -n "$WITH_TUN"; then
AC_DEFINE(WITH_TUN) AC_DEFINE(WITH_TUN)
fi fi
if test "$WITH_INTERFACE"; then
AC_CHECK_HEADER(netinet/if_ether.h,
AC_DEFINE(HAVE_NETINET_IF_ETHER_H),
[WITH_INTERFACE=;
AC_MSG_WARN([include file netinet/if_ether.h not found, disabling interface])],
[AC_INCLUDES_DEFAULT
#if HAVE_NET_IF_H && HAVE_NETINET_IN_H
#include <net/if.h>
#include <netinet/in.h>
#endif])
fi
if test "$WITH_INTERFACE" || test "$WITH_TUN"; then
AC_CHECK_HEADER(linux/if_packet.h,
AC_DEFINE(HAVE_LINUX_IF_PACKET_H),
[WITH_INTERFACE=;
AC_MSG_WARN([include file linux/if_packet.h not found, disabling interface])])
fi
if test "$WITH_INTERFACE"; then
AC_DEFINE(WITH_INTERFACE)
fi
AC_MSG_CHECKING(whether to include system call tracing) AC_MSG_CHECKING(whether to include system call tracing)
AC_ARG_ENABLE(sycls, [ --disable-sycls disable system call tracing], AC_ARG_ENABLE(sycls, [ --disable-sycls disable system call tracing],
[case "$enableval" in [case "$enableval" in

View file

@ -412,9 +412,13 @@ int filan_stat(
{ {
char linktarget[PATH_MAX+1]; char linktarget[PATH_MAX+1];
memset(linktarget, 0, PATH_MAX+1); memset(linktarget, 0, PATH_MAX+1);
Readlink(filename, linktarget, PATH_MAX); if (Readlink(filename, linktarget, PATH_MAX) < 0) {
Warn3("readlink(\"%s\", linktarget, %d): %s",
filename, PATH_MAX, strerror(errno));
} else {
fprintf(outfile, "LINKTARGET=%s", linktarget); fprintf(outfile, "LINKTARGET=%s", linktarget);
} }
}
break; break;
#endif /* S_IFLNK */ #endif /* S_IFLNK */
} }

View file

@ -32,6 +32,23 @@ int hostan(FILE *outfile) {
fprintf(outfile, "sizeof(long long) = %u\n", (unsigned int)sizeof(long long)); fprintf(outfile, "sizeof(long long) = %u\n", (unsigned int)sizeof(long long));
#endif #endif
fprintf(outfile, "sizeof(size_t) = %u\n", (unsigned int)sizeof(size_t)); fprintf(outfile, "sizeof(size_t) = %u\n", (unsigned int)sizeof(size_t));
{
union {
uint16_t s;
uint8_t c[2];
} bo;
bo.c[0] = 0x05;
bo.c[1] = 0xa0;
if (bo.s == 0x05a0) {
fprintf(outfile, "host byte order: network (BE \"big endian\", most significast byte first)\n");
} else if (bo.s == 0xa005) {
fprintf(outfile, "host byte order: intel (LE \"little endian\", least significast byte first\n");
} else {
fprintf(outfile, "host byte order: unknown\n");
fprintf(stderr, "failed to determine host byte order");
}
}
#include <sys/time.h> /* select(); OpenBSD: struct timespec */ #include <sys/time.h> /* select(); OpenBSD: struct timespec */
fprintf(outfile, "sizeof(struct timespec) = %u\n", (unsigned int)sizeof(struct timespec)); fprintf(outfile, "sizeof(struct timespec) = %u\n", (unsigned int)sizeof(struct timespec));
fprintf(outfile, "sizeof(struct diag_dgram) = %u\n", (unsigned int)sizeof(struct diag_dgram)); fprintf(outfile, "sizeof(struct diag_dgram) = %u\n", (unsigned int)sizeof(struct diag_dgram));

View file

@ -399,12 +399,14 @@ int main(int argc, const char *argv[]) {
} }
} }
#if WITH_STATS
#if HAVE_SIGACTION #if HAVE_SIGACTION
act.sa_handler = socat_signal_logstats; act.sa_handler = socat_signal_logstats;
Sigaction(SIGUSR1, &act, NULL); Sigaction(SIGUSR1, &act, NULL);
#else #else
Signal(SIGUSR1, socat_signal_logstats); Signal(SIGUSR1, socat_signal_logstats);
#endif #endif
#endif /* WITH_STATS */
} }
Signal(SIGPIPE, SIG_IGN); Signal(SIGPIPE, SIG_IGN);
@ -419,9 +421,11 @@ int main(int argc, const char *argv[]) {
} }
Atexit(socat_unlock); Atexit(socat_unlock);
#if WITH_STATS
if (socat_opts.statistics) { if (socat_opts.statistics) {
Atexit(socat_print_stats); Atexit(socat_print_stats);
} }
#endif /* WITH_STATS */
result = socat(arg1[0], arg1[1]); result = socat(arg1[0], arg1[1]);
if (result == EXIT_SUCCESS && engine_result != EXIT_SUCCESS) { if (result == EXIT_SUCCESS && engine_result != EXIT_SUCCESS) {

View file

@ -49,6 +49,7 @@ rm -rf $RPM_BUILD_ROOT
%doc README CHANGES EXAMPLES SECURITY doc/socat.html FAQ BUGREPORTS %doc README CHANGES EXAMPLES SECURITY doc/socat.html FAQ BUGREPORTS
%doc COPYING COPYING.OpenSSL FILES PORTING DEVELOPMENT %doc COPYING COPYING.OpenSSL FILES PORTING DEVELOPMENT
%{_bindir}/socat1 %{_bindir}/socat1
%{_bindir}/socat
%{_bindir}/procan %{_bindir}/procan
%{_bindir}/filan %{_bindir}/filan
%{_mandir}/man1/socat1.1 %{_mandir}/man1/socat1.1

View file

@ -30,7 +30,7 @@ union sockaddr_union {
#if WITH_VSOCK #if WITH_VSOCK
struct sockaddr_vm vm; struct sockaddr_vm vm;
#endif /* WITH_IP6 */ #endif /* WITH_IP6 */
#if WITH_INTERFACE #if _WITH_INTERFACE
struct sockaddr_ll ll; struct sockaddr_ll ll;
#endif #endif
} ; } ;

130
test.sh
View file

@ -71,7 +71,7 @@ while [ "$1" ]; do
X-N?*) NUMCOND="test \$N -gt ${1#-N}" ;; X-N?*) NUMCOND="test \$N -gt ${1#-N}" ;;
X-N) shift; NUMCOND="test \$N -ge $1" ;; X-N) shift; NUMCOND="test \$N -ge $1" ;;
X-C) rm -f testcert*.conf testcert.dh testcli*.* testsrv*.* ;; X-C) rm -f testcert*.conf testcert.dh testcli*.* testsrv*.* ;;
X-foreign) FOREIGN=1 ;; # allow access to 3rd party Internet hosts X-foreign|X--foreign) FOREIGN=1 ;; # allow access to 3rd party Internet hosts
X-expect-fail|X--expect-fail) OPT_EXPECT_FAIL=1; shift; EXPECT_FAIL="$1" ;; X-expect-fail|X--expect-fail) OPT_EXPECT_FAIL=1; shift; EXPECT_FAIL="$1" ;;
X-*) echo "Unknown option \"$1\"" >&2 X-*) echo "Unknown option \"$1\"" >&2
usage >&2 usage >&2
@ -136,6 +136,22 @@ if [ -z "$SOCAT_VERSION" ]; then
echo "Warning: failed to retrieve Socat version" >&2 echo "Warning: failed to retrieve Socat version" >&2
fi fi
if type ip >/dev/null 2>&1; then
if ip -V |grep -q -i -e "^ip utility, iproute2-" -e BusyBox; then
IP=$(type -p ip)
else
unset IP
fi
fi
if type ss >/dev/null 2>&1; then
if ss -V |grep -q "^ss utility, iproute2-"; then
SS=$(type -p ss)
else
unset SS
fi
fi
# for some tests we need a network interface # for some tests we need a network interface
if type ip >/dev/null 2>&1; then if type ip >/dev/null 2>&1; then
INTERFACE=$(ip r get 8.8.8.8 |grep ' dev ' |head -n 1 |sed "s/.*dev[[:space:]][[:space:]]*\([^[:space:]][^[:space:]]*\).*/\1/") INTERFACE=$(ip r get 8.8.8.8 |grep ' dev ' |head -n 1 |sed "s/.*dev[[:space:]][[:space:]]*\([^[:space:]][^[:space:]]*\).*/\1/")
@ -354,22 +370,6 @@ else
SUBSTUSER="$(grep -v '^[^:]*:^[^:]*:0:' /etc/passwd |tail -n 1 |cut -d: -f1)" SUBSTUSER="$(grep -v '^[^:]*:^[^:]*:0:' /etc/passwd |tail -n 1 |cut -d: -f1)"
fi fi
if type ip >/dev/null 2>&1; then
if ip -V |grep -q "^ip utility, iproute2-"; then
IP=$(type -p ip)
else
unset IP
fi
fi
if type ss >/dev/null 2>&1; then
if ss -V |grep -q "^ss utility, iproute2-"; then
SS=$(type -p ss)
else
unset SS
fi
fi
if [ -z "$SS" ]; then if [ -z "$SS" ]; then
# non-root users might miss ifconfig in their path # non-root users might miss ifconfig in their path
case "$UNAME" in case "$UNAME" in
@ -4458,7 +4458,7 @@ N=$((N+1))
NAME=READLINE NAME=READLINE
#set -vx #set -vx
case "$TESTS" in case "$TESTS" in
*%$N%*|*%functions%*|*%pty%*|*%readline%*|*%$NAME%*) *%$N%*|*%functions%*|*%pty%*|*%readline%*|*%sigint%*|*%$NAME%*)
TEST="$NAME: readline with password and sigint" TEST="$NAME: readline with password and sigint"
if ! eval $NUMCOND; then :; if ! eval $NUMCOND; then :;
elif ! feat=$(testfeats readline pty); then elif ! feat=$(testfeats readline pty); then
@ -8462,23 +8462,27 @@ kill "$pid1" 2>/dev/null; wait;
if [ "$rc2" -ne 0 ]; then if [ "$rc2" -ne 0 ]; then
$PRINTF "$FAILED: $TRACE $SOCAT:\n" $PRINTF "$FAILED: $TRACE $SOCAT:\n"
echo "$CMD1 &" echo "$CMD1 &"
cat "${te}1" >&2
echo "$CMD2" echo "$CMD2"
cat "${te}1" cat "${te}2" >&2
cat "${te}2"
numFAIL=$((numFAIL+1)) numFAIL=$((numFAIL+1))
listFAIL="$listFAIL $N" listFAIL="$listFAIL $N"
elif ! echo "$da" |diff - "$tf" >"$tdiff"; then elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
$PRINTF "$FAILED\n" $PRINTF "$FAILED\n"
cat "$tdiff" echo "$CMD1 &"
cat "${te}1" >&2
echo "$CMD2"
cat "${te}2" >&2
echo diff: >&2
cat "$tdiff" >&2
numFAIL=$((numFAIL+1)) numFAIL=$((numFAIL+1))
listFAIL="$listFAIL $N" listFAIL="$listFAIL $N"
else else
$PRINTF "$OK\n" $PRINTF "$OK\n"
if [ -n "$VERBOSE" ]; then if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
echo "$CMD1 &" if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
echo "$CMD2" if [ "$VERBOSE" ]; then echo "$CMD2"; fi
fi if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
if [ -n "$debug" ]; then cat $te; fi
numOK=$((numOK+1)) numOK=$((numOK+1))
fi fi
fi ;; # NUMCOND fi ;; # NUMCOND
@ -14751,6 +14755,7 @@ TEST="$NAME: UDP4-SEND with lowport"
# succeeded. # succeeded.
# This test does not require root because it just checks log of bind() but does # This test does not require root because it just checks log of bind() but does
# not require success # not require success
# This test fails if WITH_SYCLS is turned off
if ! eval $NUMCOND; then :; else if ! eval $NUMCOND; then :; else
tf="$td/test$N.stdout" tf="$td/test$N.stdout"
te="$td/test$N.stderr" te="$td/test$N.stderr"
@ -14766,13 +14771,18 @@ LOWPORT=$(grep '[DE] bind(.*:' $te |sed 's/.*:\([0-9][0-9]*\)[}]*,.*/\1/' |head
#type socat >&2 #type socat >&2
if [[ $LOWPORT =~ [0-9][0-9]* ]] && [ "$LOWPORT" -ge 640 -a "$LOWPORT" -le 1023 ]; then if [[ $LOWPORT =~ [0-9][0-9]* ]] && [ "$LOWPORT" -ge 640 -a "$LOWPORT" -le 1023 ]; then
$PRINTF "$OK\n" $PRINTF "$OK\n"
if [ "$VERBOSE" ]; then if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
echo "$CMD" >&2 if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
fi
numOK=$((numOK+1)) numOK=$((numOK+1))
elif $SOCAT -V |grep -q "undef WITH_SYCLS"; then
$PRINTF "$CANT (no SYCLS)\n"
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
numCANT=$((numCANT+1))
listCANT="$listCANT $N"
else else
$PRINTF "$FAILED\n" $PRINTF "$FAILED\n"
echo "$CMD" >&2 echo "$CMD"
cat "${te}" >&2 cat "${te}" >&2
numFAIL=$((numFAIL+1)) numFAIL=$((numFAIL+1))
listFAIL="$listFAIL $N" listFAIL="$listFAIL $N"
@ -15785,8 +15795,8 @@ case "$TESTS" in
*%$N%*|*%functions%*|*%exec%*|*%fork%*|*%socket%*|*%unix%*|*%$NAME%*) *%$N%*|*%functions%*|*%exec%*|*%fork%*|*%socket%*|*%unix%*|*%$NAME%*)
TEST="$NAME: test the children-shutup option" TEST="$NAME: test the children-shutup option"
# Run a UNIX domain listening server with options fork and children-shutup, and # Run a UNIX domain listening server with options fork and children-shutup, and
# an TCP client to invalid port that will fail. # that connects to a closed TCP4 port.
# Connect to the server and check if it logs the connect failure as warning. # Connect to the server and check if it logs the TCP4-CONNECT failure as warning.
if ! eval $NUMCOND; then :; if ! eval $NUMCOND; then :;
elif ! F=$(testfeats UNIX LISTEN EXEC FILE); then elif ! F=$(testfeats UNIX LISTEN EXEC FILE); then
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N $PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available${NORMAL}\n" $N
@ -15813,7 +15823,7 @@ printf "test $F_n $TEST... " $N
$CMD0 >/dev/null 2>"${te}0" & $CMD0 >/dev/null 2>"${te}0" &
pid0=$! pid0=$!
waitunixport $ts 1 waitunixport $ts 1
$CMD1 2>"${te}1" { $CMD1 2>"${te}1"; sleep 1; }
rc1=$? rc1=$?
kill $pid0 2>/dev/null; wait kill $pid0 2>/dev/null; wait
relsleep 1 # child process might need more time relsleep 1 # child process might need more time
@ -17056,6 +17066,60 @@ esac
N=$((N+1)) N=$((N+1))
# Test the sigint option
NAME=EXEC_SIGINT
case "$TESTS" in
*%$N%*|*%functions%*|*%socket%*|*%exec%*|*%sigint%*|*%$NAME%*)
TEST="$NAME: sigint option with EXEC"
# Run Socat with an EXEC address invoking Socat, with option sigint
# Send the parent a SIGINT; when the child gets SIGINT too (vs.SIGTERM)
# the test succeeded
if ! eval $NUMCOND; then :;
# Remove unneeded checks, adapt lists of the remaining ones
elif ! F=$(testfeats STDIO EXEC PIPE); then
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not configured in $SOCAT${NORMAL}\n" $N
numCANT=$((numCANT+1))
listCANT="$listCANT $N"
elif ! A=$(testaddrs STDIO EXEC PIPE); then
$PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
numCANT=$((numCANT+1))
listCANT="$listCANT $N"
elif ! o=$(testoptions setsid sigint) >/dev/null; then
$PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${NORMAL}\n" $N
numCANT=$((numCANT+1))
listCANT="$listCANT $N"
else
tf="$td/test$N.stdout"
te="$td/test$N.stderr"
tdiff="$td/test$N.diff"
da="test$N $(date) $RANDOM"
CMD0="$TRACE $SOCAT $opts -T 1 PIPE EXEC:cat,setsid,sigint"
printf "test $F_n $TEST... " $N
$CMD0 >/dev/null 2>"${te}0" &
pid0=$!
relsleep 2
kill -INT $pid0
wait
if grep -q " W waitpid..: child .* exited with status 130" "${te}0" ||
grep -q " W waitpid..: child .* exited on signal 2" "${te}0"; then
$PRINTF "$OK\n"
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
numOK=$((numOK+1))
else
$PRINTF "$FAILED\n"
echo "$CMD0 &"
cat "${te}0" >&2
numFAIL=$((numFAIL+1))
listFAIL="$listFAIL $N"
namesFAIL="$namesFAIL $NAME"
fi
fi # NUMCOND
;;
esac
N=$((N+1))
# end of common tests # end of common tests
################################################################################## ##################################################################################

View file

@ -47,7 +47,7 @@ const struct optdesc opt_iff_automedia = { "iff-automedia", "automedia", O
#endif #endif
/*const struct optdesc opt_iff_dynamic = { "iff-dynamic", "dynamic", OPT_IFF_DYNAMIC, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(short), IFF_DYNAMIC };*/ /*const struct optdesc opt_iff_dynamic = { "iff-dynamic", "dynamic", OPT_IFF_DYNAMIC, GROUP_INTERFACE, PH_OFFSET, TYPE_BOOL, OFUNC_OFFSET_MASKS, XIO_OFFSETOF(para.interface.iff_opts), XIO_SIZEOF(short), IFF_DYNAMIC };*/
#ifdef PACKET_AUXDATA #ifdef PACKET_AUXDATA
const struct optdesc opt_retrieve_vlan = { "retrieve-vlan", NULL, OPT_RETRIEVE_VLAN, GROUP_INTERFACE, PH_LATE, TYPE_INT, OFUNC_SPEC }; const struct optdesc opt_retrieve_vlan = { "retrieve-vlan", NULL, OPT_RETRIEVE_VLAN, GROUP_INTERFACE, PH_LATE, TYPE_CONST, OFUNC_SPEC };
#endif #endif
#if LATER #if LATER
const struct optdesc opt_route = { "route", NULL, OPT_ROUTE, GROUP_INTERFACE, PH_INIT, TYPE_STRING, OFUNC_SPEC }; const struct optdesc opt_route = { "route", NULL, OPT_ROUTE, GROUP_INTERFACE, PH_INIT, TYPE_STRING, OFUNC_SPEC };

View file

@ -612,7 +612,7 @@ int xiotype_ip6_join_source_group(
opt->value3.u_string/*srcaddr*/); opt->value3.u_string/*srcaddr*/);
if (!xioparms.experimental) { if (!xioparms.experimental) {
Warn("option ipv6-join-source-group is experimental"); Warn1("option %s is experimental", opt->desc->defname);
} }
return 0; return 0;

View file

@ -58,6 +58,7 @@ static int xioopen_posixmq(
if (!xioparms.experimental) { if (!xioparms.experimental) {
Error1("%s: use option --experimental to acknowledge unmature state", argv[0]); Error1("%s: use option --experimental to acknowledge unmature state", argv[0]);
return STAT_NORETRY;
} }
if (argc != 2) { if (argc != 2) {
Error2("%s: wrong number of parameters (%d instead of 1)", Error2("%s: wrong number of parameters (%d instead of 1)",
@ -210,9 +211,11 @@ static int xioopen_posixmq(
; ;
} }
#if WITH_RETRY
if (with_intv) { if (with_intv) {
Nanosleep(&sfd->intervall, NULL); Nanosleep(&sfd->intervall, NULL);
} }
#endif
/* now we are ready to handle signals */ /* now we are ready to handle signals */
Sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL); Sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL);

View file

@ -1524,7 +1524,7 @@ int xiodopacketinfo(
valbuff, sizeof(valbuff)-1); valbuff, sizeof(valbuff)-1);
break; break;
#endif /* WITH_IP6 */ #endif /* WITH_IP6 */
#if HAVE_STRUCT_CMSGHDR && HAVE_STRUCT_TPACKET_AUXDATA #if _WITH_INTERFACE && HAVE_STRUCT_CMSGHDR && HAVE_STRUCT_TPACKET_AUXDATA
case SOL_PACKET: case SOL_PACKET:
xiolog_ancillary_packet(sfd, cmsg, &num, typbuff, sizeof(typbuff)-1, xiolog_ancillary_packet(sfd, cmsg, &num, typbuff, sizeof(typbuff)-1,
nambuff, sizeof(nambuff)-1, nambuff, sizeof(nambuff)-1,

View file

@ -517,12 +517,18 @@ static int xioopen_socks5(
char infobuff[256]; char infobuff[256];
if (!xioparms.experimental) { if (!xioparms.experimental) {
Error1("%s: requires option --experimental", argv[0]); Error1("%s: use option --experimental to acknowledge unmature state", argv[0]);
return STAT_NORETRY; return STAT_NORETRY;
} }
if (argc != 5) { if (argc != 5) {
Error1("%s: 4 parameters required like :<socks-server>:<socks-port>:<target-server>:<target-port>", #if WITH_HELP
argv[0]); Error2("%s: 4 parameters required like %s", argv[0],
socks_command==SOCKS5_COMMAND_CONNECT ?
xioaddr_socks5_connect.syntax :
xioaddr_socks5_listen.syntax);
#else
Error1("%s: 4 parameters required", argv[0]);
#endif
return STAT_NORETRY; return STAT_NORETRY;
} }

4
xio.h
View file

@ -95,7 +95,7 @@ enum xiotag {
} ; } ;
/* Keep condition consistent with xioopts.h:GROUP_*! */ /* Keep condition consistent with xioopts.h:GROUP_*! */
#if WITH_SCTP #if WITH_SCTP || WITH_POSIXMQ
typedef uint64_t groups_t; typedef uint64_t groups_t;
#define F_groups_t F_uint64_x #define F_groups_t F_uint64_x
#else #else
@ -327,7 +327,7 @@ typedef union bipipe {
enum xiotag tag; enum xiotag tag;
const struct addrdesc *addr; const struct addrdesc *addr;
int flags; int flags;
} common; } common; /* "bipipe.common" */
struct single stream; struct single stream;
struct { struct {
enum xiotag tag; enum xiotag tag;

View file

@ -14,7 +14,7 @@
/* keep consistent with xioopts.h:enum e_types ! */ /* keep consistent with xioopts.h:enum e_types ! */
static const char *optiontypenames[] = { static const char *optiontypenames[] = {
"CONST", "BIN", "BOOL", "BYTE", "CONST", "BIN", "BOOL", "BYTE",
"INT", "LONG", "STRING", "PTRDIFF", "INT", "INT/NULL", "LONG", "STRING", "PTRDIFF",
"SHORT", "SIZE_T", "SOCKADDR", "UNSIGNED-INT", "SHORT", "SIZE_T", "SOCKADDR", "UNSIGNED-INT",
"UNSIGNED-LONG","UNSIGNED-SHORT","MODE_T", "GID_T", "UNSIGNED-LONG","UNSIGNED-SHORT","MODE_T", "GID_T",
"UID_T", "INT[3]", "STRUCT-TIMEVAL", "STRUCT-TIMESPEC", "UID_T", "INT[3]", "STRUCT-TIMEVAL", "STRUCT-TIMESPEC",
@ -23,7 +23,6 @@ static const char *optiontypenames[] = {
"INT:STRING", "INT:INT:INT", "INT:INT:BIN", "INT:INT:STRING", "INT:STRING", "INT:INT:INT", "INT:INT:BIN", "INT:INT:STRING",
"INT:INT:GENERIC", "INT:INT:GENERIC",
"IP4NAME", "IP4NAME",
#if HAVE_STRUCT_LINGER #if HAVE_STRUCT_LINGER
"STRUCT-LINGER", "STRUCT-LINGER",
#endif #endif
@ -49,7 +48,7 @@ static const char *addressgroupnames[] = {
"UNIX", "IP4", "IP6", "INTERFACE", "UNIX", "IP4", "IP6", "INTERFACE",
"UDP", "TCP", "SOCKS4", "OPENSSL", "UDP", "TCP", "SOCKS4", "OPENSSL",
"PROCESS", "APPL", "HTTP", "undef", "PROCESS", "APPL", "HTTP", "undef",
"SCTP" "SCTP", "POSIXMQ"
} ; } ;
/* keep consistent with xioopts.h:enum ephase ! */ /* keep consistent with xioopts.h:enum ephase ! */
@ -66,7 +65,8 @@ static char *optionphasenames[] = {
"CONNECTED", "CONNECTED",
"PREFORK", "FORK", "PASTFORK", "PREFORK", "FORK", "PASTFORK",
"LATE", "LATE2", "LATE", "LATE2",
"PREEXEC", "EXEC", "SPECIFIC", "PREEXEC", "EXEC", "PASTEXEC",
"SPECIFIC",
NULL NULL
} ; } ;

View file

@ -33,7 +33,7 @@ const struct addrname addressnames[] = {
{ "ABSTRACT-RECVFROM", &xioaddr_abstract_recvfrom }, { "ABSTRACT-RECVFROM", &xioaddr_abstract_recvfrom },
{ "ABSTRACT-SENDTO", &xioaddr_abstract_sendto }, { "ABSTRACT-SENDTO", &xioaddr_abstract_sendto },
#endif /* defined(WITH_UNIX) && defined(WITH_ABSTRACT_UNIXSOCKET) */ #endif /* defined(WITH_UNIX) && defined(WITH_ABSTRACT_UNIXSOCKET) */
#if WITH_LISTEN #if WITH_LISTEN && WITH_FDNUM
{ "ACCEPT", &xioaddr_accept_fd }, { "ACCEPT", &xioaddr_accept_fd },
{ "ACCEPT-FD", &xioaddr_accept_fd }, { "ACCEPT-FD", &xioaddr_accept_fd },
#endif #endif

View file

@ -309,7 +309,9 @@ const struct optname optionnames[] = {
IF_OPENSSL("cert", &opt_openssl_certificate) IF_OPENSSL("cert", &opt_openssl_certificate)
IF_OPENSSL("certificate", &opt_openssl_certificate) IF_OPENSSL("certificate", &opt_openssl_certificate)
IF_TERMIOS("cfmakeraw", &opt_termios_cfmakeraw) IF_TERMIOS("cfmakeraw", &opt_termios_cfmakeraw)
#if WITH_LISTEN
IF_ANY ("children-shutup", &opt_children_shutup) IF_ANY ("children-shutup", &opt_children_shutup)
#endif
IF_ANY ("chroot", &opt_chroot) IF_ANY ("chroot", &opt_chroot)
IF_ANY ("chroot-early", &opt_chroot_early) IF_ANY ("chroot-early", &opt_chroot_early)
/*IF_TERMIOS("cibaud", &opt_cibaud)*/ /*IF_TERMIOS("cibaud", &opt_cibaud)*/
@ -2593,7 +2595,7 @@ int parseopts_table(const char **a, groups_t groups, struct opt **opts,
break; break;
#endif #endif
#if HAVE_STRUCT_GROUP_SOURCE_REQ #if WITH_IP6 && HAVE_STRUCT_GROUP_SOURCE_REQ
case TYPE_GROUP_SOURCE_REQ: case TYPE_GROUP_SOURCE_REQ:
xiotype_ip6_join_source_group(token, ent, opt); xiotype_ip6_join_source_group(token, ent, opt);
break; break;
@ -3831,7 +3833,7 @@ int applyopt(
#if _WITH_INTERFACE #if _WITH_INTERFACE
case OPT_RETRIEVE_VLAN: case OPT_RETRIEVE_VLAN:
if (!xioparms.experimental) { if (!xioparms.experimental) {
Warn("option retrieve-vlan is experimental"); Warn1("option %s is experimental", opt->desc->defname);
} }
if (_interface_setsockopt_auxdata(fd, 1) < 0) { if (_interface_setsockopt_auxdata(fd, 1) < 0) {
return -1; return -1;
@ -3953,8 +3955,8 @@ int applyopts2(int fd, struct opt *opts, unsigned int from, unsigned int to) {
int applyopts_optgroup( int applyopts_optgroup(
int fd, int fd,
struct opt *opts, struct opt *opts,
unsigned int from, /* -1: from first phase, not in order */ int from, /* -1: from first phase, not in order */
unsigned int to, /* -1: to last phase, not in order */ int to, /* -1: to last phase, not in order */
groups_t groups) groups_t groups)
{ {
struct opt *opt = opts; struct opt *opt = opts;

View file

@ -24,11 +24,10 @@ enum e_types {
TYPE_CONST, /* keyword means a fix value - implies int type */ TYPE_CONST, /* keyword means a fix value - implies int type */
TYPE_BIN, /* raw binary data, length determined by data */ TYPE_BIN, /* raw binary data, length determined by data */
TYPE_BOOL, /* value is 0 or 1 (no-value is interpreted as 1) */ TYPE_BOOL, /* value is 0 or 1 (no-value is interpreted as 1) */
TYPE_BOOL_NULL, /* value is 0 or 1 (no-value is interpreted as 1), or just opt= */
TYPE_BYTE, /* unsigned char */ TYPE_BYTE, /* unsigned char */
TYPE_INT, /* int */ TYPE_INT, /* int */
TYPE_INT_NULL, /* int, or opt= for no action (instead of default) */ TYPE_INT_NULL, /* int, or just opt= for no action (instead of default) */
TYPE_LONG, /* long */ TYPE_LONG, /* long */
TYPE_STRING, /* char * */ TYPE_STRING, /* char * */
TYPE_NAME = TYPE_STRING, TYPE_NAME = TYPE_STRING,
@ -152,7 +151,6 @@ enum e_func {
#define GROUP_FILE GROUP_REG #define GROUP_FILE GROUP_REG
#define GROUP_SOCKET 0x00000020 #define GROUP_SOCKET 0x00000020
#define GROUP_READLINE 0x00000040 #define GROUP_READLINE 0x00000040
#define GROUP_POSIXMQ 0x00000080
#define GROUP_NAMED 0x00000100 /* file system entry */ #define GROUP_NAMED 0x00000100 /* file system entry */
#define GROUP_OPEN 0x00000200 /* flags for open() */ #define GROUP_OPEN 0x00000200 /* flags for open() */
@ -186,12 +184,15 @@ enum e_func {
#define GROUP_HTTP 0x40000000 /* any HTTP client */ #define GROUP_HTTP 0x40000000 /* any HTTP client */
/* Keep condition consistent with xio.h:groups_t! */ /* Keep condition consistent with xio.h:groups_t! */
#if WITH_SCTP #if WITH_SCTP || WITH_POSIXMQ
/* The following groups are not expected on systems without uint64_t */ /* The following groups are not expected on systems without uint64_t */
/* The following groups are not expected on systems withous uint64_t */
#define GROUP_IP_SCTP 0x0100000000U #define GROUP_IP_SCTP 0x0100000000U
#define GROUP_POSIXMQ 0x0200000000U
#define GROUP_ALL 0x03ffffffffU #define GROUP_ALL 0x03ffffffffU
#else #else
#define GROUP_IP_SCTP 0 #define GROUP_IP_SCTP 0
#define GROUP_POSIXMQ 0
#define GROUP_ALL 0xffffffffU #define GROUP_ALL 0xffffffffU
#endif #endif
@ -902,34 +903,44 @@ enum e_phase {
PH_OFFSET, /* automatically applied to xio-fd */ PH_OFFSET, /* automatically applied to xio-fd */
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 */
PH_OPEN, /* during filesystem entry creation/open */ PH_OPEN, /* during filesystem entry creation/open */
PH_PASTOPEN, /* past filesystem entry creation/open */ PH_PASTOPEN, /* past filesystem entry creation/open */
PH_PRESOCKET, /* before socket call */ PH_PRESOCKET, /* before socket call */
PH_SOCKET, /* for socket call */ PH_SOCKET, /* for socket call */
PH_PASTSOCKET, /* after socket call */ PH_PASTSOCKET, /* after socket call */
PH_PREBIGEN, /* before socketpair() pipe() openpty() */ PH_PREBIGEN, /* before socketpair() pipe() openpty() */
PH_BIGEN, /* during socketpair() pipe() openpty() */ PH_BIGEN, /* during socketpair() pipe() openpty() */
PH_PASTBIGEN, /* past socketpair() pipe() openpty() */ PH_PASTBIGEN, /* past socketpair() pipe() openpty() */
PH_FD, /* soon after FD creation or identification */ PH_FD, /* soon after FD creation or identification */
PH_PREBIND, /* before socket bind() */ PH_PREBIND, /* before socket bind() */
PH_BIND, /* during socket bind() ? */ PH_BIND, /* during socket bind() ? */
PH_PASTBIND, /* past socket bind() - for client and server sockets! */ PH_PASTBIND, /* past socket bind() - for client and server sockets! */
PH_PRELISTEN, /* before socket listen() */ PH_PRELISTEN, /* before socket listen() */
PH_LISTEN, /* during socket listen() ? */ PH_LISTEN, /* during socket listen() ? */
PH_PASTLISTEN, /* after socket listen() */ PH_PASTLISTEN, /* after socket listen() */
PH_PRECONNECT, /* before socket connect() */ PH_PRECONNECT, /* before socket connect() */
PH_CONNECT, /* during socket connect() ? */ PH_CONNECT, /* during socket connect() ? */
PH_PASTCONNECT, /* after socket connect() */ PH_PASTCONNECT, /* after socket connect() */
PH_PREACCEPT, /* before socket accept() */ PH_PREACCEPT, /* before socket accept() */
PH_ACCEPT, /* during socket accept() ? */ PH_ACCEPT, /* during socket accept() ? */
PH_PASTACCEPT, /* after socket accept() */ PH_PASTACCEPT, /* after socket accept() */
PH_CONNECTED, /* for sockets, after connect() or accept() */ PH_CONNECTED, /* for sockets, after connect() or accept() */
PH_PREFORK, /* before fork() (with both listen and exec!) */ PH_PREFORK, /* before fork() (with both listen and exec!) */
PH_FORK, /* during fork() (with both listen and exec!) */ PH_FORK, /* during fork() (with both listen and exec!) */
PH_PASTFORK, /* after fork() (with both listen and exec!) */ PH_PASTFORK, /* after fork() (with both listen and exec!) */
PH_LATE, /* FD is ready, before start of data loop */ PH_LATE, /* FD is ready, before start of data loop */
PH_LATE2, /* FD is ready, dropping privileges */ PH_LATE2, /* FD is ready, dropping privileges */
PH_PREEXEC, /* before exec() or system() */ PH_PREEXEC, /* before exec() or system() */
PH_EXEC, /* during exec() or system() */ PH_EXEC, /* during exec() or system() */
PH_PASTEXEC, /* only reached on addresses that do NOT exec() */ PH_PASTEXEC, /* only reached on addresses that do NOT exec() */
@ -971,7 +982,7 @@ extern int retropt_timespec(struct opt *opts, int optcode, struct timespec *resu
extern int retropt_bind(struct opt *opts, int af, int socktype, int ipproto, struct sockaddr *sa, socklen_t *salen, int feats, const int ai_flags[2]); extern int retropt_bind(struct opt *opts, int af, int socktype, int ipproto, struct sockaddr *sa, socklen_t *salen, int feats, const int ai_flags[2]);
extern int applyopts(int fd, struct opt *opts, enum e_phase phase); extern int applyopts(int fd, struct opt *opts, enum e_phase phase);
extern int applyopts2(int fd, struct opt *opts, unsigned int from, unsigned int to); extern int applyopts2(int fd, struct opt *opts, unsigned int from, unsigned int to);
extern int applyopts_optgroup(int fd, struct opt *opts, unsigned int from, unsigned int to, groups_t groups); extern int applyopts_optgroup(int fd, struct opt *opts, int from, int to, groups_t groups);
extern int applyopts_flags(struct opt *opts, groups_t group, flags_t *result); extern int applyopts_flags(struct opt *opts, groups_t group, flags_t *result);
extern int applyopts_cloexec(int fd, struct opt *opts); extern int applyopts_cloexec(int fd, struct opt *opts);
extern int applyopts_early(const char *path, struct opt *opts); extern int applyopts_early(const char *path, struct opt *opts);

View file

@ -72,6 +72,7 @@ int xioshutdown(xiofile_t *sock, int how) {
return 0; return 0;
#if _WITH_SOCKET #if _WITH_SOCKET
case XIOSHUT_NULL: case XIOSHUT_NULL:
writenull = '\0'; /* assign something to make gcc happy */
/* send an empty packet; only useful on datagram sockets? */ /* send an empty packet; only useful on datagram sockets? */
xiowrite(sock, &writenull, 0); xiowrite(sock, &writenull, 0);
return 0; return 0;