mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 07:22:34 +00:00
UDP-Lite (UDPlite) support
This commit is contained in:
parent
a846b94e6c
commit
2cfc39e9e5
21 changed files with 833 additions and 71 deletions
10
CHANGES
10
CHANGES
|
@ -179,6 +179,16 @@ Features:
|
|||
DCCP6-LISTEN (DCCP6-L)
|
||||
New option: dccp-set-ccid (ccid)
|
||||
|
||||
Support for UDP-Lite protocol, new addresses:
|
||||
UDPLITE-CONNECT
|
||||
UDPLITE-LISTEN
|
||||
UDPLITE-DATAGRAM
|
||||
UDPLITE-RECV
|
||||
UDPLITE-RECVFROM
|
||||
UDPLITE-SENDTO
|
||||
All these are also available in UDPLITE4-* and UDPLITE6-* form;
|
||||
options udplite-recv-cscov and udplite-send-cscov.
|
||||
|
||||
Corrections:
|
||||
When a sub process (EXEC, SYSTEM) terminated with exit code other than
|
||||
0, its last sent data might have been lost depending on timing of read/
|
||||
|
|
|
@ -50,7 +50,7 @@ XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \
|
|||
xio-socket.c xio-interface.c xio-listen.c xio-unix.c xio-vsock.c \
|
||||
xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c \
|
||||
xio-sctp.c xio-dccp.c xio-rawip.c xio-posixmq.c \
|
||||
xio-socks.c xio-socks5.c xio-proxy.c xio-udp.c \
|
||||
xio-socks.c xio-socks5.c xio-proxy.c xio-udp.c xio-udplite.c \
|
||||
xio-progcall.c xio-exec.c xio-system.c xio-shell.c \
|
||||
xio-termios.c xio-readline.c \
|
||||
xio-pty.c xio-openssl.c xio-streams.c xio-namespaces.c \
|
||||
|
@ -68,7 +68,7 @@ HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.
|
|||
xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \
|
||||
xio-socketpair.h xio-socket.h xio-interface.h xio-listen.h xio-unix.h xio-vsock.h \
|
||||
xio-ip.h xio-ip4.h xio-ip6.h xio-rawip.h xio-posixmq.h \
|
||||
xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h xio-dccp.h \
|
||||
xio-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h xio-dccp.h xio-udplite.h \
|
||||
xio-socks.h xio-socks5.h xio-proxy.h xio-progcall.h xio-exec.h \
|
||||
xio-system.h xio-shell.h xio-termios.h xio-readline.h \
|
||||
xio-pty.h xio-openssl.h xio-streams.h xio-namespaces.h \
|
||||
|
|
|
@ -712,6 +712,7 @@
|
|||
#undef WITH_INTERFACE
|
||||
#undef WITH_TCP
|
||||
#undef WITH_UDP
|
||||
#undef WITH_UDPLITE
|
||||
#undef WITH_SCTP
|
||||
#undef WITH_DCCP
|
||||
#undef WITH_LISTEN
|
||||
|
|
19
configure.ac
19
configure.ac
|
@ -345,6 +345,25 @@ AC_ARG_ENABLE(udp, [ --disable-udp disable UDP support],
|
|||
esac],
|
||||
[AC_DEFINE(WITH_UDP) AC_MSG_RESULT(yes)])
|
||||
|
||||
AC_MSG_CHECKING(whether to include UDP-Lite support)
|
||||
AC_ARG_ENABLE(udplite, [ --disable-udplite disable UDP-Lite support],
|
||||
[case "$enableval" in
|
||||
no) AC_MSG_RESULT(no); WITH_UDPLITE= ;;
|
||||
*) AC_MSG_RESULT(yes); WITH_UDPLITE=1 ;;
|
||||
esac],
|
||||
[AC_MSG_RESULT(yes); WITH_UDPLITE=1 ])
|
||||
if test -n "$WITH_UDPLITE"; then
|
||||
AC_MSG_CHECKING(for IPPROTO_UDPLITE)
|
||||
AC_TRY_COMPILE([#include <sys/types.h>
|
||||
#include <netinet/in.h>],
|
||||
[IPPROTO_UDPLITE;],
|
||||
[ AC_MSG_RESULT(yes); WITH_UDPLITE=1],
|
||||
[ AC_MSG_RESULT(no); WITH_UDPLITE=])
|
||||
if test "$WITH_UDPLITE"; then
|
||||
AC_DEFINE(WITH_UDPLITE)
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(whether to include SCTP support)
|
||||
AC_ARG_ENABLE(sctp, [ --disable-sctp disable SCTP support],
|
||||
[case "$enableval" in
|
||||
|
|
49
doc/socat.yo
49
doc/socat.yo
|
@ -927,6 +927,7 @@ label(ADDRESS_SCTP6_LISTEN)dit(bf(tt(SCTP6-LISTEN:<port>)))
|
|||
Like link(SCTP-LISTEN)(ADDRESS_SCTP_LISTEN), but only supports IPv6
|
||||
protocol.nl()
|
||||
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP6)(GROUP_IP6),link(SCTP)(GROUP_SCTP),link(RETRY)(GROUP_RETRY) nl()
|
||||
|
||||
label(ADDRESS_SOCKET_CONNECT)dit(bf(tt(SOCKET-CONNECT:<domain>:<protocol>:<remote-address>)))
|
||||
Creates a stream socket using the first and second given socket parameters
|
||||
and tt(SOCK_STREAM) (see man NOEXPAND(socket(2))) and connects to the remote-address.
|
||||
|
@ -1301,6 +1302,8 @@ label(ADDRESS_TUN)dit(bf(tt(TUN[:<if-addr>/<bits>])))
|
|||
link(netns)(OPTION_NETNS)nl()
|
||||
See also:
|
||||
link(ip-recv)(ADDRESS_IP_RECV)
|
||||
|
||||
label(ADDRESSES_UDP)
|
||||
label(ADDRESS_UDP_CONNECT)dit(bf(tt(UDP:<host>:<port>)))
|
||||
Connects to <port> [link(UDP service)(TYPE_UDP_SERVICE)] on
|
||||
<host> [link(IP address)(TYPE_IP_ADDRESS)] using UDP/IP version 4 or 6
|
||||
|
@ -1504,6 +1507,28 @@ label(ADDRESS_UDP6_RECV)dit(bf(tt(UDP6-RECV:<port>)))
|
|||
Like link(UDP-RECV)(ADDRESS_UDP_RECV), but only supports IPv6 protocol.nl()
|
||||
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP6)(GROUP_IP6),link(RANGE)(GROUP_RANGE)
|
||||
|
||||
dit(bf(tt(UDPLITE-CONNECT:<host>:<port>)))
|
||||
dit(bf(tt(UDPLITE4-CONNECT:<host>:<port>)))
|
||||
dit(bf(tt(UDPLITE6-CONNECT:<host>:<port>)))
|
||||
dit(bf(tt(UDPLITE-DATAGRAM:<address>:<port>)))
|
||||
dit(bf(tt(UDPLITE4-DATAGRAM:<address>:<port>)))
|
||||
dit(bf(tt(UDPLITE6-DATAGRAM:<address>:<port>)))
|
||||
dit(bf(tt(UDPLITE-LISTEN:<port>)))
|
||||
dit(bf(tt(UDPLITE4-LISTEN:<port>)))
|
||||
dit(bf(tt(UDPLITE6-LISTEN:<port>)))
|
||||
dit(bf(tt(UDPLITE-SENDTO:<host>:<port>)))
|
||||
dit(bf(tt(UDPLITE4-SENDTO:<host>:<port>)))
|
||||
dit(bf(tt(UDPLITE6-SENDTO:<host>:<port>)))
|
||||
dit(bf(tt(UDPLITE-RECVFROM:<port>)))
|
||||
dit(bf(tt(UDPLITE4-RECVFROM:<port>)))
|
||||
dit(bf(tt(UDPLITE6-RECVFROM:<port>)))
|
||||
dit(bf(tt(UDPLITE-RECV:<port>)))
|
||||
dit(bf(tt(UDPLITE4-RECV:<port>)))
|
||||
dit(bf(tt(UDPLITE6-RECV:<port>)))
|
||||
The UDPLITE addresses are almost identical to the related link(UDP addresses)(ADDRESSES_UDP)
|
||||
but they use UDP-Lite protocol and have the additional link(UDPLITE option
|
||||
group)(GROUP_UDPLITE).nl()
|
||||
|
||||
label(ADDRESS_UNIX_CONNECT)dit(bf(tt(UNIX-CONNECT:<filename>)))
|
||||
Connects to link(<filename>)(TYPE_FILENAME) assuming it is a unixdomain()
|
||||
socket.
|
||||
|
@ -2700,6 +2725,21 @@ enddit()
|
|||
startdit()enddit()nl()
|
||||
|
||||
|
||||
label(GROUP_UDPLITE)em(bf(UDPLITE option group))
|
||||
|
||||
These options may be applied to UDPLITE addresses:
|
||||
startdit()
|
||||
label(OPTION_UDPLITE_SEND_CSCOV)dit(bf(tt(udplite-send-cscov)))
|
||||
Sets the number of bytes for which the checksum is calculated and sent
|
||||
("checksum coverage").
|
||||
label(OPTION_UDPLITE_RECV_CSCOV)dit(bf(tt(udplite-recv-cscov)))
|
||||
Sets the number of bytes for which the checksum is checked ("checksum
|
||||
coverage").
|
||||
enddit()
|
||||
|
||||
startdit()enddit()nl()
|
||||
|
||||
|
||||
label(GROUP_SCTP)em(bf(SCTP option group))
|
||||
|
||||
These options may be applied to SCTP stream sockets.
|
||||
|
@ -2726,13 +2766,14 @@ enddit()
|
|||
startdit()enddit()nl()
|
||||
|
||||
|
||||
em(bf(UDP, TCP, SCTP, and DCCP option group))
|
||||
label(GROUP_IPAPP)em(bf(UDP, TCP, SCTP, DCCP, and UDPLITE option group))
|
||||
|
||||
Here we find options that are related to the network port mechanism and thus
|
||||
can be used with UDP, TCP, SCTP, and DCCP client and server addresses.
|
||||
can be used with UDP, TCP, SCTP, DCCP, and UDP-Lite client and server addresses.
|
||||
|
||||
startdit()
|
||||
label(OPTION_SOURCEPORT)dit(bf(tt(sourceport=<port>)))
|
||||
For outgoing (client) TCP and UDP connections, it sets the source
|
||||
For outgoing (client) connections, it sets the source
|
||||
link(<port>)(TYPE_PORT) using an extra code(bind()) call.
|
||||
With TCP or UDP listen addresses, socat immediately shuts down the
|
||||
connection if the client does not use this sourceport. UDP-RECV,
|
||||
|
@ -2740,7 +2781,7 @@ label(OPTION_SOURCEPORT)dit(bf(tt(sourceport=<port>)))
|
|||
it does not match.
|
||||
(link(example)(EXAMPLE_OPTION_SOURCEPORT)).
|
||||
label(OPTION_LOWPORT)dit(bf(tt(lowport)))
|
||||
Outgoing (client) TCP and UDP connections with this option use
|
||||
Outgoing (client) connections with this option use
|
||||
an unused random source port between 640 and 1023 incl. On UNIX class operating
|
||||
systems, this requires root privilege, and thus indicates that the
|
||||
client process is authorized by local root.
|
||||
|
|
|
@ -126,11 +126,14 @@ int procan_cdefs(FILE *outfile) {
|
|||
#ifdef IPPROTO_UDP
|
||||
fprintf(outfile, "#define IPPROTO_UDP %d\n", IPPROTO_UDP);
|
||||
#endif
|
||||
#ifdef IPPROTO_DCCP
|
||||
fprintf(outfile, "#define IPPROTO_DCCP %d\n", IPPROTO_DCCP);
|
||||
#endif
|
||||
#ifdef IPPROTO_SCTP
|
||||
fprintf(outfile, "#define IPPROTO_SCTP %d\n", IPPROTO_SCTP);
|
||||
#endif
|
||||
#ifdef IPPROTO_DCCP
|
||||
fprintf(outfile, "#define IPPROTO_DCCP %d\n", IPPROTO_DCCP);
|
||||
#ifdef IPPROTO_UDPLITE
|
||||
fprintf(outfile, "#define IPPROTO_UDPLITE %d\n", IPPROTO_UDPLITE);
|
||||
#endif
|
||||
#ifdef SOL_SOCKET
|
||||
fprintf(outfile, "#define SOL_SOCKET 0x%x\n", SOL_SOCKET);
|
||||
|
|
5
socat.c
5
socat.c
|
@ -604,6 +604,11 @@ void socat_version(FILE *fd) {
|
|||
#else
|
||||
fputs(" #undef WITH_DCCP\n", fd);
|
||||
#endif
|
||||
#ifdef WITH_UDPLITE
|
||||
fprintf(fd, " #define WITH_UDPLITE %d\n", WITH_UDPLITE);
|
||||
#else
|
||||
fputs(" #undef WITH_UDPLITE\n", fd);
|
||||
#endif
|
||||
#ifdef WITH_LISTEN
|
||||
fprintf(fd, " #define WITH_LISTEN %d\n", WITH_LISTEN);
|
||||
#else
|
||||
|
|
570
test.sh
570
test.sh
|
@ -607,6 +607,10 @@ case "$TESTS" in
|
|||
$ECHO "testing if address array is sorted...\c"
|
||||
TF="$TD/socat-q"
|
||||
IFS="$($ECHO ' \n\t')"
|
||||
if ! $SOCAT -hhh >/dev/null; then
|
||||
echo "Failed: $SOCAT -hhh" >&2
|
||||
exit -1
|
||||
fi
|
||||
$SOCAT -hhh |sed -n '/^ address-head:/,/^ opts:/ p' |grep -v -e "^ address-head:" -e "^ opts:" |sed -e 's/^[[:space:]]*//' -e 's/[: ].*//' |grep -v '^<' >"$TF"
|
||||
$SOCAT -hhh |sed -n '/^ address-head:/,/^ opts:/ p' |grep -v -e "^ address-head:" -e "^ opts:" |sed -e 's/^[[:space:]]*//' -e 's/[: ].*//' |grep -v '^<' |LC_ALL=C sort |diff "$TF" - >"$TF-diff"
|
||||
if [ -s "$TF-diff" ]; then
|
||||
|
@ -994,6 +998,20 @@ runsdccp6 () {
|
|||
return 0;
|
||||
}
|
||||
|
||||
# check if UDPLITE on IPv4 is available on host
|
||||
runsudplite4 () {
|
||||
runsip4 >/dev/null || { echo UDPLITE4; return 1; }
|
||||
$SOCAT -u -T 0.001 /dev/null UDPLITE4-SENDTO:$LOCALHOST4:0 2>/dev/null || return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
# check if UDPLITE on IPv6 is available on host
|
||||
runsudplite6 () {
|
||||
runsip6 >/dev/null || { echo UDPLITE6; return 1; }
|
||||
$SOCAT -u -T 0.001 /dev/null UDPLITE6-SENDTO:$LOCALHOST6:0 2>/dev/null || return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
# check if UNIX domain sockets work
|
||||
runsunix () {
|
||||
# for now...
|
||||
|
@ -1415,6 +1433,51 @@ waitsctp4port () {
|
|||
return 1
|
||||
}
|
||||
|
||||
# wait until a UDPLITE4 port is ready
|
||||
waitudplite4port () {
|
||||
local port="$1"
|
||||
local logic="$2" # 0..wait until free; 1..wait until listening
|
||||
local timeout="$3"
|
||||
local l
|
||||
local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
|
||||
[ "$logic" ] || logic=1
|
||||
[ "$timeout" ] || timeout=5
|
||||
while [ $timeout -gt 0 ]; do
|
||||
case "$UNAME" in
|
||||
Linux) #if [ "$SS" ]; then
|
||||
#l=$($SS -4 -l -n -u |grep "^UNCONN .*:$port\>")
|
||||
#else
|
||||
l=$(netstat -a -n -U -l |grep '^udpl .* .*[0-9*]:'$port' [ ]*0\.0\.0\.0:\*')
|
||||
#fi
|
||||
;;
|
||||
FreeBSD) l=$(netstat -an |egrep '^udpl46? .*[0-9*]\.'$port' .* \*\.\*') ;;
|
||||
NetBSD) l=$(netstat -an |grep '^udpl .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
|
||||
OpenBSD) l=$(netstat -an |grep '^udpl .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
|
||||
#Darwin) case "$(uname -r)" in
|
||||
# [1-5]*) l=$(netstat -an |grep '^udp.* .*[0-9*]\.'$port' .* \*\.\*') ;;
|
||||
# *) l=$(netstat -an |grep '^udp4.* .*[0-9*]\.'$port' .* \*\.\* .*') ;;
|
||||
# esac ;;
|
||||
#AIX) l=$(netstat -an |grep '^udp[4 ] 0 0 .*[*0-9]\.'$port' .* \*\.\*[ ]*$') ;;
|
||||
#SunOS) l=$(netstat -an -f inet -P udp |grep '.*[1-9*]\.'$port' [ ]*Idle') ;;
|
||||
#HP-UX) l=$(netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' .* \*\.\* ') ;;
|
||||
#OSF1) l=$(/usr/sbin/netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\*') ;;
|
||||
#DragonFly) l=$(netstat -an |grep '^udp4 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
|
||||
*) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;;
|
||||
esac
|
||||
if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
|
||||
\( \( $logic -eq 0 \) -a -z "$l" \) ]; then
|
||||
set ${vx}vx
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
timeout=$((timeout-1))
|
||||
done
|
||||
|
||||
$ECHO "!port $port timed out! \c" >&2
|
||||
set ${vx}vx
|
||||
return 1
|
||||
}
|
||||
|
||||
# check if a TCP6 port is in use
|
||||
# exits with 0 when it is not used
|
||||
checktcp6port () {
|
||||
|
@ -1557,6 +1620,48 @@ waitsctp6port () {
|
|||
return 1
|
||||
}
|
||||
|
||||
# wait until a UDPLITE6 port is ready
|
||||
waitudplite6port () {
|
||||
local port="$1"
|
||||
local logic="$2" # 0..wait until free; 1..wait until listening
|
||||
local timeout="$3"
|
||||
local l
|
||||
local vx=+; case $- in *vx*) set +vx; vx=-; esac # no tracing here
|
||||
[ "$logic" ] || logic=1
|
||||
[ "$timeout" ] || timeout=5
|
||||
while [ $timeout -gt 0 ]; do
|
||||
case "$UNAME" in
|
||||
Linux) #if [ "$SS" ]; then
|
||||
#l=$($SS -6 -u -l -n |grep "^UNCONN .*:$port\>")
|
||||
#else
|
||||
l=$(netstat -an |grep -E '^udpl6? .* .*[0-9*:%]:'$port' [ ]*:::\*')
|
||||
#fi
|
||||
;;
|
||||
FreeBSD) l=$(netstat -an |egrep '^udpl(6|46) .*[0-9*]\.'$port' .* \*\.\*') ;;
|
||||
NetBSD) l=$(netstat -an |grep '^udpl6 .* \*\.'$port' [ ]* \*\.\*') ;;
|
||||
OpenBSD) l=$(netstat -an |grep '^udpl6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
|
||||
Darwin) l=$(netstat -an |egrep '^udpl4?6 +[0-9]+ +[0-9]+ +[0-9a-z:%*]+\.'$port' +[0-9a-z:%*.]+') ;;
|
||||
#AIX) l=$(netstat -an |grep '^udp[6 ] 0 0 .*[*0-9]\.'$port' .* \*\.\*[ ]*$') ;;
|
||||
#SunOS) l=$(netstat -an -f inet6 -P udp |grep '.*[1-9*]\.'$port' [ ]*Idle') ;;
|
||||
#HP-UX) l=$(netstat -an |grep '^udp 0 0 .*[0-9*]\.'$port' ') ;;
|
||||
#OSF1) l=$(/usr/sbin/netstat -an |grep '^udp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\*') ;;
|
||||
#DragonFly) l=$(netstat -ant |grep '^udp6 .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]*') ;;
|
||||
*) l=$(netstat -an |grep -i 'udp .*[0-9*][:.]'$port' ') ;;
|
||||
esac
|
||||
if [ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
|
||||
\( \( $logic -eq 0 \) -a -z "$l" \) ]; then
|
||||
set ${vx}vx
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
timeout=$((timeout-1))
|
||||
done
|
||||
|
||||
$ECHO "!port $port timed out! \c" >&2
|
||||
set ${vx}vx
|
||||
return 1
|
||||
}
|
||||
|
||||
# we need this misleading function name for canonical reasons
|
||||
waitunixport () {
|
||||
waitfile "$1" "$2" "$3"
|
||||
|
@ -9897,14 +10002,14 @@ IP6 IP6 [::1] PROTO ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS
|
|||
# test: setting of environment variables that describe a stream socket
|
||||
# connection: SOCAT_SOCKADDR, SOCAT_PEERADDR; and SOCAT_SOCKPORT,
|
||||
# SOCAT_PEERPORT when applicable
|
||||
while read KEYW FEAT TEST_SOCKADDR TEST_PEERADDR PORTMETHOD; do
|
||||
while read KEYW FEAT SEL TEST_SOCKADDR TEST_PEERADDR PORTMETHOD; do
|
||||
if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi
|
||||
#
|
||||
protov="$(echo "$KEYW" |tr A-Z a-z)"
|
||||
proto="${protov%%[0-9]}"
|
||||
NAME=${KEYW}LISTENENV
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%tcp%*|*%$proto%*|*%$protov%*|*%envvar%*|*%listen%*|*%$NAME%*)
|
||||
*%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%$SEL%*|*%$proto%*|*%$protov%*|*%envvar%*|*%listen%*|*%$NAME%*)
|
||||
TEST="$NAME: $KEYW-LISTEN sets environment variables with socket addresses"
|
||||
# have a server accepting a connection and invoking some shell code. The shell
|
||||
# code extracts and prints the SOCAT related environment vars.
|
||||
|
@ -9993,19 +10098,19 @@ N=$((N+1))
|
|||
#set +xv
|
||||
#
|
||||
done <<<"
|
||||
TCP4 TCP 127.0.0.1 $SECONDADDR PORT
|
||||
TCP6 IP6 [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] PORT
|
||||
UDP6 IP6 [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] PORT
|
||||
SCTP4 SCTP 127.0.0.1 $SECONDADDR PORT
|
||||
SCTP6 SCTP [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] PORT
|
||||
UNIX UNIX $td/test\$N.server $td/test\$N.client ,
|
||||
TCP4 TCP tcp 127.0.0.1 $SECONDADDR PORT
|
||||
TCP6 IP6 tcp [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] PORT
|
||||
UDP6 IP6 udp [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] PORT
|
||||
SCTP4 SCTP sctp 127.0.0.1 $SECONDADDR PORT
|
||||
SCTP6 SCTP sctp [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] PORT
|
||||
UNIX UNIX unix $td/test\$N.server $td/test\$N.client ,
|
||||
"
|
||||
# this one fails due to weakness in socats UDP4-LISTEN implementation:
|
||||
#UDP4 $LOCALHOST $SECONDADDR $((PORT+4)) $((PORT+5))
|
||||
|
||||
|
||||
# test: environment variables from ancillary message
|
||||
while read PF KEYW ADDR IPPORT SCM_ENABLE SCM_RECV SCM_ENVNAME ROOT SCM_VALUE
|
||||
while read PF KEYW SEL ADDR IPPORT SCM_ENABLE SCM_RECV SCM_ENVNAME ROOT SCM_VALUE
|
||||
do
|
||||
if [ -z "$PF" ] || [[ "$PF" == \#* ]]; then continue; fi
|
||||
#
|
||||
|
@ -10013,7 +10118,7 @@ pf="$(echo "$PF" |tr A-Z a-z)"
|
|||
proto="$(echo "$KEYW" |tr A-Z a-z)"
|
||||
NAME=${KEYW}ENV_$SCM_ENVNAME
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%socket%*|*%$pf%*|*%dgram%*|*%udp%*|*%$proto%*|*%recv%*|*%ancillary%*|*%envvar%*|*%$ROOT%*|*%$NAME%*)
|
||||
*%$N%*|*%functions%*|*%socket%*|*%$pf%*|*%dgram%*|*%$SEL%*|*%$proto%*|*%recv%*|*%ancillary%*|*%envvar%*|*%$ROOT%*|*%$NAME%*)
|
||||
#set -vx
|
||||
TEST="$NAME: $KEYW ancillary message sets env SOCAT_$SCM_ENVNAME"
|
||||
# idea: start a socat process with *-RECVFROM:..,... , ev. with ancillary
|
||||
|
@ -10110,30 +10215,30 @@ esac
|
|||
N=$((N+1))
|
||||
#
|
||||
done <<<"
|
||||
IP4 UDP4 127.0.0.1 PORT ip-options=x01000000 ip-recvopts IP_OPTIONS user x01000000
|
||||
IP4 UDP4 127.0.0.1 PORT , so-timestamp TIMESTAMP user timestamp
|
||||
IP4 UDP4 127.0.0.1 PORT ip-ttl=53 ip-recvttl IP_TTL user 53
|
||||
IP4 UDP4 127.0.0.1 PORT ip-tos=7 ip-recvtos IP_TOS user 7
|
||||
IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_LOCADDR user 127.0.0.1
|
||||
IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_DSTADDR user 127.0.0.1
|
||||
IP4 UDP4 127.0.0.1 PORT , ip-pktinfo IP_IF user lo
|
||||
IP4 UDP4 127.0.0.1 PORT , ip-recvif IP_IF user lo0
|
||||
IP4 UDP4 127.0.0.1 PORT , ip-recvdstaddr IP_DSTADDR user 127.0.0.1
|
||||
IP4 IP4 127.0.0.1 PROTO ip-options=x01000000 ip-recvopts IP_OPTIONS root x01000000
|
||||
IP4 IP4 127.0.0.1 PROTO , so-timestamp TIMESTAMP root timestamp
|
||||
IP4 IP4 127.0.0.1 PROTO ip-ttl=53 ip-recvttl IP_TTL root 53
|
||||
IP4 IP4 127.0.0.1 PROTO ip-tos=7 ip-recvtos IP_TOS root 7
|
||||
IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_LOCADDR root 127.0.0.1
|
||||
IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_DSTADDR root 127.0.0.1
|
||||
IP4 IP4 127.0.0.1 PROTO , ip-pktinfo IP_IF root lo
|
||||
IP4 IP4 127.0.0.1 PROTO , ip-recvif IP_IF root lo0
|
||||
IP4 IP4 127.0.0.1 PROTO , ip-recvdstaddr IP_DSTADDR root 127.0.0.1
|
||||
IP6 UDP6 [::1] PORT , ipv6-recvpktinfo IPV6_DSTADDR user [[]0000:0000:0000:0000:0000:0000:0000:0001[]]
|
||||
IP6 UDP6 [::1] PORT ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT user 35
|
||||
IP6 UDP6 [::1] PORT ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS user x000000aa
|
||||
IP6 IP6 [::1] PROTO , ipv6-recvpktinfo IPV6_DSTADDR root [[]0000:0000:0000:0000:0000:0000:0000:0001[]]
|
||||
IP6 IP6 [::1] PROTO ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT root 35
|
||||
IP6 IP6 [::1] PROTO ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS root x000000aa
|
||||
IP4 UDP4 udp 127.0.0.1 PORT ip-options=x01000000 ip-recvopts IP_OPTIONS user x01000000
|
||||
IP4 UDP4 udp 127.0.0.1 PORT , so-timestamp TIMESTAMP user timestamp
|
||||
IP4 UDP4 udp 127.0.0.1 PORT ip-ttl=53 ip-recvttl IP_TTL user 53
|
||||
IP4 UDP4 udp 127.0.0.1 PORT ip-tos=7 ip-recvtos IP_TOS user 7
|
||||
IP4 UDP4 udp 127.0.0.1 PORT , ip-pktinfo IP_LOCADDR user 127.0.0.1
|
||||
IP4 UDP4 udp 127.0.0.1 PORT , ip-pktinfo IP_DSTADDR user 127.0.0.1
|
||||
IP4 UDP4 udp 127.0.0.1 PORT , ip-pktinfo IP_IF user lo
|
||||
IP4 UDP4 udp 127.0.0.1 PORT , ip-recvif IP_IF user lo0
|
||||
IP4 UDP4 udp 127.0.0.1 PORT , ip-recvdstaddr IP_DSTADDR user 127.0.0.1
|
||||
IP4 IP4 rawip 127.0.0.1 PROTO ip-options=x01000000 ip-recvopts IP_OPTIONS root x01000000
|
||||
IP4 IP4 rawip 127.0.0.1 PROTO , so-timestamp TIMESTAMP root timestamp
|
||||
IP4 IP4 rawip 127.0.0.1 PROTO ip-ttl=53 ip-recvttl IP_TTL root 53
|
||||
IP4 IP4 rawip 127.0.0.1 PROTO ip-tos=7 ip-recvtos IP_TOS root 7
|
||||
IP4 IP4 rawip 127.0.0.1 PROTO , ip-pktinfo IP_LOCADDR root 127.0.0.1
|
||||
IP4 IP4 rawip 127.0.0.1 PROTO , ip-pktinfo IP_DSTADDR root 127.0.0.1
|
||||
IP4 IP4 rawip 127.0.0.1 PROTO , ip-pktinfo IP_IF root lo
|
||||
IP4 IP4 rawip 127.0.0.1 PROTO , ip-recvif IP_IF root lo0
|
||||
IP4 IP4 rawip 127.0.0.1 PROTO , ip-recvdstaddr IP_DSTADDR root 127.0.0.1
|
||||
IP6 UDP6 udp [::1] PORT , ipv6-recvpktinfo IPV6_DSTADDR user [[]0000:0000:0000:0000:0000:0000:0000:0001[]]
|
||||
IP6 UDP6 udp [::1] PORT ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT user 35
|
||||
IP6 UDP6 udp [::1] PORT ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS user x000000aa
|
||||
IP6 IP6 rawip [::1] PROTO , ipv6-recvpktinfo IPV6_DSTADDR root [[]0000:0000:0000:0000:0000:0000:0000:0001[]]
|
||||
IP6 IP6 rawip [::1] PROTO ipv6-unicast-hops=35 ipv6-recvhoplimit IPV6_HOPLIMIT root 35
|
||||
IP6 IP6 rawip [::1] PROTO ipv6-tclass=0xaa ipv6-recvtclass IPV6_TCLASS root x000000aa
|
||||
#UNIX UNIX $td/test\$N.server - , so-timestamp TIMESTAMP user timestamp
|
||||
"
|
||||
|
||||
|
@ -11471,7 +11576,8 @@ UNIX unix $td/test\$N.server -
|
|||
# care for timing, understand what you want :-)
|
||||
|
||||
|
||||
while read KEYW FEAT ADDR IPPORT SHUT; do
|
||||
# test the max-children option on pseudo connected sockets
|
||||
while read KEYW FEAT SEL ADDR IPPORT SHUT; do
|
||||
if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi
|
||||
RUNS=$(tolower $KEYW)
|
||||
PROTO=$KEYW
|
||||
|
@ -11479,7 +11585,7 @@ proto="$(echo "$PROTO" |tr A-Z a-z)"
|
|||
# test the max-children option on pseudo connected sockets
|
||||
NAME=${KEYW}MAXCHILDREN
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%socket%*|*%listen%*|*%$NAME%*)
|
||||
*%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%$SEL%*|*%socket%*|*%listen%*|*%$NAME%*)
|
||||
TEST="$NAME: max-children option"
|
||||
# start a listen process with max-children=1; connect with a client, let it
|
||||
# send data and then sleep; connect with second client that wants to send
|
||||
|
@ -11546,8 +11652,8 @@ fi # NUMCOND
|
|||
esac
|
||||
N=$((N+1))
|
||||
done <<<"
|
||||
UDP4 UDP 127.0.0.1 PORT shut-null
|
||||
UDP6 UDP [::1] PORT shut-null
|
||||
UDP4 UDP udp 127.0.0.1 PORT shut-null
|
||||
UDP6 UDP udp [::1] PORT shut-null
|
||||
"
|
||||
# debugging this hanging test was difficult - following lessons learned:
|
||||
# kill <parent> had no effect when child process existed
|
||||
|
@ -18205,6 +18311,394 @@ esac
|
|||
N=$((N+1))
|
||||
|
||||
|
||||
NAME=UDPLITE4STREAM
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udplite%*|*%$NAME%*)
|
||||
TEST="$NAME: echo via connection to UDP-Lite V4 socket"
|
||||
if ! eval $NUMCOND; then :;
|
||||
# Remove unneeded checks, adapt lists of the remaining ones
|
||||
elif ! cond=$(checkconds \
|
||||
"" \
|
||||
"" \
|
||||
"" \
|
||||
"IP4 UDPLITE LISTEN STDIO PIPE" \
|
||||
"UDPLITE4-LISTEN PIPE STDIO UDPLITE4" \
|
||||
"so-reuseaddr" \
|
||||
"udplite4" ); 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"
|
||||
tsl=$PORT
|
||||
ts="$LOCALHOST:$tsl"
|
||||
da="test$N $(date) $RANDOM"
|
||||
CMD1="$TRACE $SOCAT $opts UDPLITE4-LISTEN:$tsl,$REUSEADDR PIPE"
|
||||
CMD2="$TRACE $SOCAT $opts - UDPLITE4:$ts"
|
||||
printf "test $F_n $TEST... " $N
|
||||
$CMD1 >"$tf" 2>"${te}1" &
|
||||
pid1=$!
|
||||
waitudplite4port $tsl 1
|
||||
echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
|
||||
rc2=$?
|
||||
kill $pid1 2>/dev/null; wait
|
||||
if [ $rc2 -ne 0 ]; then
|
||||
$PRINTF "$FAILED: $TRACE $SOCAT:\n"
|
||||
echo "$CMD1 &"
|
||||
cat "${te}1" >&2
|
||||
echo "$CMD2"
|
||||
cat "${te}2" >&2
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
|
||||
$PRINTF "$FAILED (diff)\n"
|
||||
echo "$CMD1 &" >&2
|
||||
cat "${te}1"
|
||||
echo "$CMD2" >&2
|
||||
cat "${te}2" >&2
|
||||
echo "// diff:" >&2
|
||||
cat "$tdiff" >&2
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
namesFAIL="$namesFAIL $NAME"
|
||||
else
|
||||
$PRINTF "$OK\n"
|
||||
if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
|
||||
if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
|
||||
if [ "$VERBOSE" ]; then echo "$CMD2"; fi
|
||||
if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
|
||||
numOK=$((numOK+1))
|
||||
fi
|
||||
fi ;; # NUMCOND
|
||||
esac
|
||||
PORT=$((PORT+1))
|
||||
N=$((N+1))
|
||||
|
||||
|
||||
NAME=UDPLITE4STREAM
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udplite%*|*%$NAME%*)
|
||||
TEST="$NAME: echo via connection to UDP-Lite V4 socket"
|
||||
if ! eval $NUMCOND; then :;
|
||||
# Remove unneeded checks, adapt lists of the remaining ones
|
||||
elif ! cond=$(checkconds \
|
||||
"" \
|
||||
"" \
|
||||
"" \
|
||||
"IP4 UDPLITE LISTEN STDIO PIPE" \
|
||||
"UDPLITE4-LISTEN PIPE STDIO UDPLITE4" \
|
||||
"so-reuseaddr" \
|
||||
"udplite4" ); 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"
|
||||
tsl=$PORT
|
||||
ts="$LOCALHOST:$tsl"
|
||||
da="test$N $(date) $RANDOM"
|
||||
CMD1="$TRACE $SOCAT $opts UDPLITE4-LISTEN:$tsl,$REUSEADDR PIPE"
|
||||
CMD2="$TRACE $SOCAT $opts - UDPLITE4:$ts"
|
||||
printf "test $F_n $TEST... " $N
|
||||
$CMD1 >"$tf" 2>"${te}1" &
|
||||
pid1=$!
|
||||
waitudplite4port $tsl 1
|
||||
echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
|
||||
rc2=$?
|
||||
kill $pid1 2>/dev/null; wait
|
||||
if [ $rc2 -ne 0 ]; then
|
||||
$PRINTF "$FAILED: $TRACE $SOCAT:\n"
|
||||
echo "$CMD1 &"
|
||||
cat "${te}1" >&2
|
||||
echo "$CMD2"
|
||||
cat "${te}2" >&2
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
|
||||
$PRINTF "$FAILED (diff)\n"
|
||||
echo "$CMD1 &" >&2
|
||||
cat "${te}1"
|
||||
echo "$CMD2" >&2
|
||||
cat "${te}2" >&2
|
||||
echo "// diff:" >&2
|
||||
cat "$tdiff" >&2
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
namesFAIL="$namesFAIL $NAME"
|
||||
else
|
||||
$PRINTF "$OK\n"
|
||||
if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
|
||||
if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
|
||||
if [ "$VERBOSE" ]; then echo "$CMD2"; fi
|
||||
if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
|
||||
numOK=$((numOK+1))
|
||||
fi
|
||||
fi ;; # NUMCOND
|
||||
esac
|
||||
PORT=$((PORT+1))
|
||||
N=$((N+1))
|
||||
|
||||
|
||||
NAME=UDPLITE4STREAM
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%udplite%*|*%$NAME%*)
|
||||
TEST="$NAME: echo via connection to UDP-Lite V4 socket"
|
||||
if ! eval $NUMCOND; then :;
|
||||
# Remove unneeded checks, adapt lists of the remaining ones
|
||||
elif ! cond=$(checkconds \
|
||||
"" \
|
||||
"" \
|
||||
"" \
|
||||
"IP4 UDPLITE LISTEN STDIO PIPE" \
|
||||
"UDPLITE4-LISTEN PIPE STDIO UDPLITE4" \
|
||||
"so-reuseaddr" \
|
||||
"udplite4" ); 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"
|
||||
tsl=$PORT
|
||||
ts="$LOCALHOST:$tsl"
|
||||
da="test$N $(date) $RANDOM"
|
||||
CMD1="$TRACE $SOCAT $opts UDPLITE4-LISTEN:$tsl,$REUSEADDR PIPE"
|
||||
CMD2="$TRACE $SOCAT $opts - UDPLITE4:$ts"
|
||||
printf "test $F_n $TEST... " $N
|
||||
$CMD1 >"$tf" 2>"${te}1" &
|
||||
pid1=$!
|
||||
waitudplite4port $tsl 1
|
||||
echo "$da" |$CMD2 >>"$tf" 2>>"${te}2"
|
||||
rc2=$?
|
||||
kill $pid1 2>/dev/null; wait
|
||||
if [ $rc2 -ne 0 ]; then
|
||||
$PRINTF "$FAILED: $TRACE $SOCAT:\n"
|
||||
echo "$CMD1 &"
|
||||
cat "${te}1" >&2
|
||||
echo "$CMD2"
|
||||
cat "${te}2" >&2
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
|
||||
$PRINTF "$FAILED (diff)\n"
|
||||
echo "$CMD1 &" >&2
|
||||
cat "${te}1"
|
||||
echo "$CMD2" >&2
|
||||
cat "${te}2" >&2
|
||||
echo "// diff:" >&2
|
||||
cat "$tdiff" >&2
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
namesFAIL="$namesFAIL $NAME"
|
||||
else
|
||||
$PRINTF "$OK\n"
|
||||
if [ "$VERBOSE" ]; then echo "$CMD1 &"; fi
|
||||
if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
|
||||
if [ "$VERBOSE" ]; then echo "$CMD2"; fi
|
||||
if [ "$DEBUG" ]; then cat "${te}2" >&2; fi
|
||||
numOK=$((numOK+1))
|
||||
fi
|
||||
fi ;; # NUMCOND
|
||||
esac
|
||||
PORT=$((PORT+1))
|
||||
N=$((N+1))
|
||||
|
||||
|
||||
# test: setting of environment variables that describe a stream socket
|
||||
# connection: SOCAT_SOCKADDR, SOCAT_PEERADDR; and SOCAT_SOCKPORT,
|
||||
# SOCAT_PEERPORT when applicable
|
||||
while read KEYW FEAT SEL TEST_SOCKADDR TEST_PEERADDR PORTMETHOD; do
|
||||
if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi
|
||||
#
|
||||
protov="$(echo "$KEYW" |tr A-Z a-z)"
|
||||
proto="${protov%%[0-9]}"
|
||||
NAME=${KEYW}LISTENENV
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%ip4%*|*%ipapp%*|*%$SEL%*|*%$proto%*|*%$protov%*|*%envvar%*|*%listen%*|*%$NAME%*)
|
||||
TEST="$NAME: $KEYW-LISTEN sets environment variables with socket addresses"
|
||||
# have a server accepting a connection and invoking some shell code. The shell
|
||||
# code extracts and prints the SOCAT related environment vars.
|
||||
# outside code then checks if the environment contains the variables correctly
|
||||
# describing the peer and local sockets.
|
||||
if ! eval $NUMCOND; then :;
|
||||
elif ! cond=$(checkconds \
|
||||
"" \
|
||||
"" \
|
||||
"" \
|
||||
"$FEAT $(echo $SEL |tr a-z A-Z) STDIO SYSTEM" \
|
||||
"$KEYW-LISTEN SYSTEM STDIO $KEYW-CONNECT" \
|
||||
"$REUSEADDR bind" \
|
||||
"$protov" ); 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"
|
||||
TEST_SOCKADDR="$(echo "$TEST_SOCKADDR" |sed "s/\$N/$N/g")" # actual vars
|
||||
tsa="$TEST_SOCKADDR" # test server address
|
||||
if [ "$PORTMETHOD" = PORT ]; then
|
||||
newport $proto; tsp="$PORT"; # test server port
|
||||
tsa1="$tsp"; tsa2="$tsa"; tsa="$tsa:$tsp" # tsa2 used for server bind=
|
||||
else
|
||||
tsa1="$tsa"; tsa2= # tsa1 used for addr parameter
|
||||
fi
|
||||
TEST_PEERADDR="$(echo "$TEST_PEERADDR" |sed "s/\$N/$N/g")" # actual vars
|
||||
tca="$TEST_PEERADDR" # test client address
|
||||
if [ "$PORTMETHOD" = PORT ]; then
|
||||
newport $proto; tcp="$PORT"; # test client port
|
||||
tca="$tca:$tcp"
|
||||
fi
|
||||
#CMD0="$TRACE $SOCAT $opts -u $KEYW-LISTEN:$tsa1 SYSTEM:\"export -p\""
|
||||
CMD0="$TRACE $SOCAT $opts -u -lpsocat $KEYW-LISTEN:$tsa1,$REUSEADDR SYSTEM:\"echo SOCAT_SOCKADDR=\\\$SOCAT_SOCKADDR; echo SOCAT_PEERADDR=\\\$SOCAT_PEERADDR; echo SOCAT_SOCKPORT=\\\$SOCAT_SOCKPORT; echo SOCAT_PEERPORT=\\\$SOCAT_PEERPORT; sleep 1\""
|
||||
CMD1="$TRACE $SOCAT $opts -u - $KEYW-CONNECT:$tsa,bind=$tca"
|
||||
printf "test $F_n $TEST... " $N
|
||||
eval "$CMD0 2>\"${te}0\" >\"$tf\" &"
|
||||
pid0=$!
|
||||
wait${protov}port $tsa1 1
|
||||
{ echo; sleep 0.1; } |$CMD1 2>"${te}1"
|
||||
rc1=$?
|
||||
waitfile "$tf" 2
|
||||
kill $pid0 2>/dev/null; wait
|
||||
#set -vx
|
||||
if [ $rc1 != 0 ]; then
|
||||
$PRINTF "$NO_RESULT (client failed):\n"
|
||||
echo "$CMD0 &"
|
||||
cat "${te}0"
|
||||
echo "$CMD1"
|
||||
cat "${te}1"
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif [ "$(grep SOCAT_SOCKADDR "${tf}" |sed -e 's/^[^=]*=//' |sed -e "s/[\"']//g")" = "$TEST_SOCKADDR" -a \
|
||||
"$(grep SOCAT_PEERADDR "${tf}" |sed -e 's/^[^=]*=//' -e "s/[\"']//g")" = "$TEST_PEERADDR" -a \
|
||||
\( "$PORTMETHOD" = ',' -o "$(grep SOCAT_SOCKPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$tsp" \) -a \
|
||||
\( "$PORTMETHOD" = ',' -o "$(grep SOCAT_PEERPORT "${tf}" |sed -e 's/^[^=]*=//' |sed -e 's/"//g')" = "$tcp" \) \
|
||||
]; then
|
||||
$PRINTF "$OK\n"
|
||||
if [ "$debug" ]; then
|
||||
echo "$CMD0 &"
|
||||
cat "${te}0"
|
||||
echo "$CMD1"
|
||||
cat "${te}1"
|
||||
fi
|
||||
numOK=$((numOK+1))
|
||||
else
|
||||
$PRINTF "$FAILED\n"
|
||||
echo "$CMD0 &"
|
||||
cat "${te}0"
|
||||
echo "$CMD1"
|
||||
cat "${te}1"
|
||||
echo -e "SOCAT_SOCKADDR=$TEST_SOCKADDR\nSOCAT_PEERADDR=$TEST_PEERADDR\nSOCAT_SOCKPORT=$TEST_SOCKPORT\nSOCAT_PEERPORT=$TEST_PEERPORT" |
|
||||
diff - "${tf}"
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
fi
|
||||
fi # NUMCOND, feats
|
||||
;;
|
||||
esac
|
||||
N=$((N+1))
|
||||
#set +xv
|
||||
#
|
||||
done <<<"
|
||||
UDPLITE4 IP4 udplite 127.0.0.1 $SECONDADDR PORT
|
||||
UDPLITE6 IP6 udplite [0000:0000:0000:0000:0000:0000:0000:0001] [0000:0000:0000:0000:0000:0000:0000:0001] PORT
|
||||
"
|
||||
|
||||
|
||||
# test the max-children option on pseudo connected sockets
|
||||
while read KEYW FEAT SEL ADDR IPPORT SHUT; do
|
||||
if [ -z "$KEYW" ] || [[ "$KEYW" == \#* ]]; then continue; fi
|
||||
RUNS=$(tolower $KEYW)
|
||||
PROTO=$KEYW
|
||||
proto="$(echo "$PROTO" |tr A-Z a-z)"
|
||||
# test the max-children option on pseudo connected sockets
|
||||
NAME=${KEYW}MAXCHILDREN
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%fork%*|*%maxchildren%*|*%$SEL%*|*%socket%*|*%listen%*|*%$NAME%*)
|
||||
TEST="$NAME: max-children option"
|
||||
# start a listen process with max-children=1; connect with a client, let it
|
||||
# send data and then sleep; connect with second client that wants to send
|
||||
# data immediately, but keep first client active until server terminates.
|
||||
#If max-children is working correctly only the first data should
|
||||
# arrive.
|
||||
if ! eval $NUMCOND; then :;
|
||||
elif ! cond=$(checkconds \
|
||||
"" \
|
||||
"" \
|
||||
"" \
|
||||
"$FEAT IP${KEYW##*[A-Z]} FILE STDIO" \
|
||||
"FILE $PROTO-LISTEN STDIO $PROTO-CONNECT" \
|
||||
"$REUSEADDR o-trunc o-creat o-append fork max-children $SHUT" \
|
||||
"$RUNS" ); then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
namesCANT="$namesCANT $NAME"
|
||||
else
|
||||
case "X$IPPORT" in
|
||||
"XPORT")
|
||||
newport $proto
|
||||
tsl=$PORT # test socket listen address
|
||||
tsc="$ADDR:$PORT" # test socket connect address
|
||||
;;
|
||||
*)
|
||||
tsl="$(eval echo "$ADDR")" # resolve $N
|
||||
tsc=$tsl
|
||||
esac
|
||||
#ts="$td/test$N.sock"
|
||||
tf="$td/test$N.stdout"
|
||||
te="$td/test$N.stderr"
|
||||
tdiff="$td/test$N.diff"
|
||||
da="test$N $(date) $RANDOM"
|
||||
# on some Linux distributions it hangs, thus -T option here
|
||||
CMD0="$TRACE $SOCAT $opts -U -T 4 FILE:$tf,o-trunc,o-creat,o-append $PROTO-LISTEN:$tsl,$REUSEADDR,fork,max-children=1"
|
||||
CMD1="$TRACE $SOCAT $opts -u - $PROTO-CONNECT:$tsc,$SHUT"
|
||||
printf "test $F_n $TEST... " $N
|
||||
$CMD0 >/dev/null 2>"${te}0" &
|
||||
pid0=$!
|
||||
wait${proto}port $tsl 1
|
||||
(echo "$da 1"; sleep 3) |$CMD1 >"${tf}1" 2>"${te}1" &
|
||||
pid1=$!
|
||||
sleep 1
|
||||
echo "$da 2" |$CMD1 >"${tf}2" 2>"${te}2" &
|
||||
pid2=$!
|
||||
sleep 1
|
||||
cpids="$(childpids $pid0)"
|
||||
kill $pid1 $pid2 $cpids $pid0 2>/dev/null; wait
|
||||
if echo -e "$da 1" |diff - $tf >$tdiff; then
|
||||
$PRINTF "$OK\n"
|
||||
numOK=$((numOK+1))
|
||||
else
|
||||
$PRINTF "$FAILED\n"
|
||||
echo "$CMD0 &"
|
||||
echo "(echo \"$da 1\"; sleep 2) |$CMD1"
|
||||
echo "echo \"$da 2\" |$CMD1"
|
||||
cat "${te}0"
|
||||
cat "${te}1"
|
||||
cat "${te}2"
|
||||
cat "$tdiff"
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
fi
|
||||
fi # NUMCOND
|
||||
;;
|
||||
esac
|
||||
N=$((N+1))
|
||||
done <<<"
|
||||
UDPLITE4 UDPLITE udplite 127.0.0.1 PORT shut-null
|
||||
UDPLITE6 UDPLITE udplite [::1] PORT shut-null
|
||||
"
|
||||
|
||||
|
||||
# end of common tests
|
||||
|
||||
##################################################################################
|
||||
|
|
1
xio-ip.c
1
xio-ip.c
|
@ -255,6 +255,7 @@ int xiogetaddrinfo(const char *node, const char *service,
|
|||
free(numnode);
|
||||
return STAT_NORETRY;
|
||||
}
|
||||
/* Probably unsupported protocol (e.g. UDP-Lite), fallback to 0 */
|
||||
hints.ai_protocol = 0;
|
||||
continue;
|
||||
}
|
||||
|
|
38
xio-socket.c
38
xio-socket.c
|
@ -1165,6 +1165,7 @@ int _xioopen_dgram_recvfrom(struct single *sfd, int xioflags,
|
|||
}
|
||||
|
||||
applyopts(sfd, -1, opts, PH_PASTSOCKET);
|
||||
applyopts(sfd, -1, opts, PH_FD);
|
||||
|
||||
applyopts_cloexec(sfd->fd, opts);
|
||||
|
||||
|
@ -1183,6 +1184,24 @@ int _xioopen_dgram_recvfrom(struct single *sfd, int xioflags,
|
|||
}
|
||||
#endif /* WITH_UNIX */
|
||||
|
||||
#if WITH_IP4 /*|| WITH_IP6*/
|
||||
switch (proto) {
|
||||
case IPPROTO_UDP:
|
||||
#ifdef IPPROTO_UDPLITE
|
||||
case IPPROTO_UDPLITE:
|
||||
#endif
|
||||
if (pf == PF_INET && ((struct sockaddr_in *)us)->sin_port == 0 ||
|
||||
pf == PF_INET6 && ((struct sockaddr_in6 *)us)->sin6_port == 0) {
|
||||
struct sockaddr_storage bound;
|
||||
socklen_t bndlen = sizeof(bound);
|
||||
char sockbuff[256];
|
||||
Getsockname(sfd->fd, (struct sockaddr *)&bound, &bndlen);
|
||||
sockaddr_info((struct sockaddr *)&bound, sizeof(struct sockaddr_storage), sockbuff, sizeof(sockbuff));
|
||||
Notice1("_xioopen_dgram_recvfrom(): bound to %s", sockbuff);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* for generic sockets, this has already been retrieved */
|
||||
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
||||
if (xioparserange(rangename, pf, &sfd->para.socket.range,
|
||||
|
@ -1370,6 +1389,7 @@ int _xioopen_dgram_recv(struct single *sfd, int xioflags,
|
|||
}
|
||||
|
||||
applyopts(sfd, -1, opts, PH_PASTSOCKET);
|
||||
applyopts(sfd, -1, opts, PH_FD);
|
||||
|
||||
applyopts_cloexec(sfd->fd, opts);
|
||||
|
||||
|
@ -1386,6 +1406,23 @@ int _xioopen_dgram_recv(struct single *sfd, int xioflags,
|
|||
#endif /* WITH_UNIX */
|
||||
|
||||
#if WITH_IP4 /*|| WITH_IP6*/
|
||||
switch (proto) {
|
||||
case IPPROTO_UDP:
|
||||
#ifdef IPPROTO_UDPLITE
|
||||
case IPPROTO_UDPLITE:
|
||||
#endif
|
||||
if (pf == PF_INET && ((struct sockaddr_in *)us)->sin_port == 0 ||
|
||||
pf == PF_INET6 && ((struct sockaddr_in6 *)us)->sin6_port == 0) {
|
||||
struct sockaddr_storage bound;
|
||||
socklen_t bndlen = sizeof(bound);
|
||||
char sockbuff[256];
|
||||
Getsockname(sfd->fd, (struct sockaddr *)&bound, &bndlen);
|
||||
sockaddr_info((struct sockaddr *)&bound, sizeof(struct sockaddr_storage), sockbuff, sizeof(sockbuff));
|
||||
Notice1("_xioopen_dgram_recv(): bound to %s", sockbuff);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (retropt_string(opts, OPT_RANGE, &rangename) >= 0) {
|
||||
if (xioparserange(rangename, pf, &sfd->para.socket.range,
|
||||
sfd->para.socket.ip.ai_flags)
|
||||
|
@ -1396,7 +1433,6 @@ int _xioopen_dgram_recv(struct single *sfd, int xioflags,
|
|||
free(rangename);
|
||||
sfd->para.socket.dorange = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
|
||||
xio_retropt_tcpwrap(sfd, opts);
|
||||
|
|
20
xio-udp.c
20
xio-udp.c
|
@ -19,17 +19,6 @@
|
|||
#include "xio-udp.h"
|
||||
|
||||
|
||||
static int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||
static int xioopen_udp_datagram(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||
static int xioopen_udp_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||
static int xioopen_udp_recv(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||
|
||||
static
|
||||
int _xioopen_udp_sendto(const char *hostname, const char *servname,
|
||||
struct opt *opts,
|
||||
int xioflags, xiofile_t *xxfd, groups_t groups,
|
||||
int pf, int socktype, int ipproto);
|
||||
|
||||
const struct addrdesc xioaddr_udp_connect = { "UDP-CONNECT", 1+XIO_RDWR, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP, SOCK_DGRAM, IPPROTO_UDP, PF_UNSPEC HELP(":<host>:<port>") };
|
||||
#if WITH_LISTEN
|
||||
const struct addrdesc xioaddr_udp_listen = { "UDP-LISTEN", 1+XIO_RDWR, xioopen_ipdgram_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE, PF_UNSPEC, IPPROTO_UDP, PF_UNSPEC HELP(":<port>") };
|
||||
|
@ -338,7 +327,7 @@ int xioopen_ipdgram_listen(
|
|||
opts, pf, socktype, ipproto);
|
||||
}
|
||||
|
||||
static int xioopen_udp_sendto(
|
||||
int xioopen_udp_sendto(
|
||||
int argc,
|
||||
const char *argv[],
|
||||
struct opt *opts,
|
||||
|
@ -372,7 +361,6 @@ static int xioopen_udp_sendto(
|
|||
OFUNC_OFFSET
|
||||
OPT_BIND, OPT_SOURCEPORT, OPT_LOWPORT, OPT_SO_TYPE, OPT_SO_PROTOTYPE, OPT_USER, OPT_GROUP, OPT_CLOEXEC
|
||||
*/
|
||||
static
|
||||
int _xioopen_udp_sendto(const char *hostname, const char *servname,
|
||||
struct opt *opts,
|
||||
int xioflags, xiofile_t *xxfd, groups_t groups,
|
||||
|
@ -437,7 +425,7 @@ int _xioopen_udp_sendto(const char *hostname, const char *servname,
|
|||
}
|
||||
|
||||
|
||||
static int xioopen_udp_datagram(
|
||||
int xioopen_udp_datagram(
|
||||
int argc,
|
||||
const char *argv[],
|
||||
struct opt *opts,
|
||||
|
@ -517,7 +505,7 @@ static int xioopen_udp_datagram(
|
|||
}
|
||||
|
||||
|
||||
static int xioopen_udp_recvfrom(
|
||||
int xioopen_udp_recvfrom(
|
||||
int argc,
|
||||
const char *argv[],
|
||||
struct opt *opts,
|
||||
|
@ -609,7 +597,7 @@ static int xioopen_udp_recvfrom(
|
|||
}
|
||||
|
||||
|
||||
static int xioopen_udp_recv(
|
||||
int xioopen_udp_recv(
|
||||
int argc,
|
||||
const char *argv[],
|
||||
struct opt *opts,
|
||||
|
|
|
@ -28,6 +28,13 @@ extern int _xioopen_ipdgram_listen(struct single *sfd,
|
|||
int xioflags, union sockaddr_union *us, socklen_t uslen,
|
||||
struct opt *opts, int pf, int socktype, int ipproto);
|
||||
|
||||
extern int xioopen_udp_sendto(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||
extern int xioopen_udp_datagram(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||
extern int xioopen_udp_recvfrom(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||
extern int xioopen_udp_recv(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||
|
||||
extern int _xioopen_udp_sendto(const char *hostname, const char *servname, struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int pf, int socktype, int ipproto);
|
||||
|
||||
extern int xioopen_ipdgram_listen(int argc, const char *argv[], struct opt *opts, int rw, xiofile_t *xfd, const struct addrdesc *addrdesc);
|
||||
|
||||
#endif /* !defined(__xio_udp_h_included) */
|
||||
|
|
66
xio-udplite.c
Normal file
66
xio-udplite.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
/* source: xio-udplite.c */
|
||||
/* Copyright Gerhard Rieger and contributors (see file CHANGES) */
|
||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||
|
||||
/* this file contains the source for handling UDPLITE addresses */
|
||||
|
||||
#include "xiosysincludes.h"
|
||||
|
||||
#if WITH_UDPLITE && (WITH_IP4 || WITH_IP6)
|
||||
|
||||
#include "xioopen.h"
|
||||
#include "xio-socket.h"
|
||||
#include "xio-ip4.h"
|
||||
#include "xio-ip6.h"
|
||||
#include "xio-ip.h"
|
||||
#include "xio-ipapp.h"
|
||||
#include "xio-tcpwrap.h"
|
||||
|
||||
#include "xio-udp.h"
|
||||
#include "xio-udplite.h"
|
||||
|
||||
|
||||
/* due to bug in Ubuntu-18.04 */
|
||||
#ifndef UDPLITE_SEND_CSCOV
|
||||
# define UDPLITE_SEND_CSCOV 10
|
||||
#endif
|
||||
#ifndef UDPLITE_RECV_CSCOV
|
||||
# define UDPLITE_RECV_CSCOV 11
|
||||
#endif
|
||||
|
||||
|
||||
const struct addrdesc xioaddr_udplite_connect = { "UDPLITE-CONNECT", 1+XIO_RDWR, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_IP_UDPLITE, SOCK_DGRAM, IPPROTO_UDPLITE, PF_UNSPEC HELP(":<host>:<port>") };
|
||||
#if WITH_LISTEN
|
||||
const struct addrdesc xioaddr_udplite_listen = { "UDPLITE-LISTEN", 1+XIO_RDWR, xioopen_ipdgram_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_IP_UDPLITE|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE, PF_UNSPEC, IPPROTO_UDPLITE, PF_UNSPEC HELP(":<port>") };
|
||||
#endif /* WITH_LISTEN */
|
||||
const struct addrdesc xioaddr_udplite_sendto = { "UDPLITE-SENDTO", 1+XIO_RDWR, xioopen_udp_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_IP_UDPLITE, PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDPLITE HELP(":<host>:<port>") };
|
||||
const struct addrdesc xioaddr_udplite_recvfrom = { "UDPLITE-RECVFROM", 1+XIO_RDWR, xioopen_udp_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_IP_UDPLITE|GROUP_CHILD|GROUP_RANGE, PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDPLITE HELP(":<port>") };
|
||||
const struct addrdesc xioaddr_udplite_recv = { "UDPLITE-RECV", 1+XIO_RDONLY, xioopen_udp_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_IP_UDPLITE|GROUP_RANGE, PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDPLITE HELP(":<port>") };
|
||||
const struct addrdesc xioaddr_udplite_datagram = { "UDPLITE-DATAGRAM", 1+XIO_RDWR, xioopen_udp_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_IP_UDPLITE|GROUP_RANGE, PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDPLITE HELP(":<host>:<port>") };
|
||||
|
||||
#if WITH_IP4
|
||||
const struct addrdesc xioaddr_udplite4_connect = { "UDPLITE4-CONNECT", 1+XIO_RDWR, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP|GROUP_IP_UDPLITE, SOCK_DGRAM, IPPROTO_UDPLITE, PF_INET HELP(":<host>:<port>") };
|
||||
#if WITH_LISTEN
|
||||
const struct addrdesc xioaddr_udplite4_listen = { "UDPLITE4-LISTEN", 1+XIO_RDWR, xioopen_ipdgram_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP|GROUP_IP_UDPLITE|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE, PF_INET, IPPROTO_UDPLITE, PF_INET HELP(":<port>") };
|
||||
#endif /* WITH_LISTEN */
|
||||
const struct addrdesc xioaddr_udplite4_sendto = { "UDPLITE4-SENDTO", 1+XIO_RDWR, xioopen_udp_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP|GROUP_IP_UDPLITE, PF_INET, SOCK_DGRAM, IPPROTO_UDPLITE HELP(":<host>:<port>") };
|
||||
const struct addrdesc xioaddr_udplite4_datagram = { "UDPLITE4-DATAGRAM", 1+XIO_RDWR, xioopen_udp_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP|GROUP_IP_UDPLITE|GROUP_RANGE, PF_INET, SOCK_DGRAM, IPPROTO_UDPLITE HELP(":<remote-address>:<port>") };
|
||||
const struct addrdesc xioaddr_udplite4_recvfrom = { "UDPLITE4-RECVFROM", 1+XIO_RDWR, xioopen_udp_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP|GROUP_IP_UDPLITE|GROUP_CHILD|GROUP_RANGE, PF_INET, SOCK_DGRAM, IPPROTO_UDPLITE HELP(":<host>:<port>") };
|
||||
const struct addrdesc xioaddr_udplite4_recv = { "UDPLITE4-RECV", 1+XIO_RDONLY, xioopen_udp_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP|GROUP_IP_UDPLITE|GROUP_RANGE, PF_INET, SOCK_DGRAM, IPPROTO_UDPLITE HELP(":<port>") };
|
||||
#endif /* WITH_IP4 */
|
||||
|
||||
#if WITH_IP6
|
||||
const struct addrdesc xioaddr_udplite6_connect = { "UDPLITE6-CONNECT", 1+XIO_RDWR, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_IP_UDPLITE, SOCK_DGRAM, IPPROTO_UDPLITE, PF_INET6 HELP(":<host>:<port>") };
|
||||
#if WITH_LISTEN
|
||||
const struct addrdesc xioaddr_udplite6_listen = { "UDPLITE6-LISTEN", 1+XIO_RDWR, xioopen_ipdgram_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_IP_UDPLITE|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE, PF_INET6, IPPROTO_UDPLITE, 0 HELP(":<port>") };
|
||||
#endif /* WITH_LISTEN */
|
||||
const struct addrdesc xioaddr_udplite6_sendto = { "UDPLITE6-SENDTO", 1+XIO_RDWR, xioopen_udp_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_IP_UDPLITE, PF_INET6, SOCK_DGRAM, IPPROTO_UDPLITE HELP(":<host>:<port>") };
|
||||
const struct addrdesc xioaddr_udplite6_datagram = { "UDPLITE6-DATAGRAM", 1+XIO_RDWR, xioopen_udp_datagram,GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_IP_UDPLITE|GROUP_RANGE, PF_INET6, SOCK_DGRAM, IPPROTO_UDPLITE HELP(":<host>:<port>") };
|
||||
const struct addrdesc xioaddr_udplite6_recvfrom = { "UDPLITE6-RECVFROM", 1+XIO_RDWR, xioopen_udp_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_IP_UDPLITE|GROUP_CHILD|GROUP_RANGE, PF_INET6, SOCK_DGRAM, IPPROTO_UDPLITE HELP(":<port>") };
|
||||
const struct addrdesc xioaddr_udplite6_recv = { "UDPLITE6-RECV", 1+XIO_RDONLY, xioopen_udp_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_IP_UDPLITE|GROUP_RANGE, PF_INET6, SOCK_DGRAM, IPPROTO_UDPLITE HELP(":<port>") };
|
||||
#endif /* WITH_IP6 */
|
||||
|
||||
const struct optdesc xioopt_udplite_send_cscov = { "udplite-send-cscov", NULL, OPT_UDPLITE_SEND_CSCOV, GROUP_IP_UDPLITE, PH_FD, TYPE_INT, OFUNC_SOCKOPT, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV};
|
||||
const struct optdesc xioopt_udplite_recv_cscov = { "udplite-recv-cscov", NULL, OPT_UDPLITE_RECV_CSCOV, GROUP_IP_UDPLITE, PH_FD, TYPE_INT, OFUNC_SOCKOPT, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV};
|
||||
|
||||
#endif /* WITH_UDPLITE && (WITH_IP4 || WITH_IP6) */
|
30
xio-udplite.h
Normal file
30
xio-udplite.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* source: xio-udplite.h */
|
||||
/* Copyright Gerhard Rieger and contributors (see file CHANGES) */
|
||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||
|
||||
#ifndef __xio_udplite_h_included
|
||||
#define __xio_udplite_h_included 1
|
||||
|
||||
extern const struct addrdesc xioaddr_udplite_connect;
|
||||
extern const struct addrdesc xioaddr_udplite_listen;
|
||||
extern const struct addrdesc xioaddr_udplite_sendto;
|
||||
extern const struct addrdesc xioaddr_udplite_datagram;
|
||||
extern const struct addrdesc xioaddr_udplite_recvfrom;
|
||||
extern const struct addrdesc xioaddr_udplite_recv;
|
||||
extern const struct addrdesc xioaddr_udplite4_connect;
|
||||
extern const struct addrdesc xioaddr_udplite4_listen;
|
||||
extern const struct addrdesc xioaddr_udplite4_sendto;
|
||||
extern const struct addrdesc xioaddr_udplite4_datagram;
|
||||
extern const struct addrdesc xioaddr_udplite4_recvfrom;
|
||||
extern const struct addrdesc xioaddr_udplite4_recv;
|
||||
extern const struct addrdesc xioaddr_udplite6_connect;
|
||||
extern const struct addrdesc xioaddr_udplite6_listen;
|
||||
extern const struct addrdesc xioaddr_udplite6_sendto;
|
||||
extern const struct addrdesc xioaddr_udplite6_datagram;
|
||||
extern const struct addrdesc xioaddr_udplite6_recvfrom;
|
||||
extern const struct addrdesc xioaddr_udplite6_recv;
|
||||
|
||||
extern const struct optdesc xioopt_udplite_send_cscov;
|
||||
extern const struct optdesc xioopt_udplite_recv_cscov;
|
||||
|
||||
#endif /* !defined(__xio_udplite_h_included) */
|
2
xio.h
2
xio.h
|
@ -95,7 +95,7 @@ enum xiotag {
|
|||
} ;
|
||||
|
||||
/* Keep condition consistent with xioopts.h:GROUP_*! */
|
||||
#if WITH_POSIXMQ || WITH_SCTP || WITH_DCCP
|
||||
#if WITH_POSIXMQ || WITH_SCTP || WITH_DCCP || WITH_UDPLITE
|
||||
typedef uint64_t groups_t;
|
||||
#define F_groups_t F_uint64_x
|
||||
#else
|
||||
|
|
|
@ -48,7 +48,7 @@ static const char *addressgroupnames[] = {
|
|||
"UNIX", "IP4", "IP6", "INTERFACE",
|
||||
"UDP", "TCP", "SOCKS4", "OPENSSL",
|
||||
"PROCESS", "APPL", "HTTP", "undef",
|
||||
"POSIXMQ", "SCTP", "DCCP"
|
||||
"POSIXMQ", "SCTP", "DCCP", "UDPLITE"
|
||||
} ;
|
||||
|
||||
/* keep consistent with xioopts.h:enum ephase ! */
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "xio-udp.h"
|
||||
#include "xio-sctp.h"
|
||||
#include "xio-dccp.h"
|
||||
#include "xio-udplite.h"
|
||||
#include "xio-socks.h"
|
||||
#include "xio-socks5.h"
|
||||
#include "xio-proxy.h"
|
||||
|
|
48
xioopen.c
48
xioopen.c
|
@ -341,6 +341,54 @@ const struct addrname addressnames[] = {
|
|||
{ "UDP6-SEND", &xioaddr_udp6_sendto },
|
||||
{ "UDP6-SENDTO", &xioaddr_udp6_sendto },
|
||||
#endif
|
||||
#if (WITH_IP4 || WITH_IP6) && WITH_UDPLITE
|
||||
{ "UDPLITE", &xioaddr_udplite_connect },
|
||||
{ "UDPLITE-CONNECT", &xioaddr_udplite_connect },
|
||||
{ "UDPLITE-DATAGRAM", &xioaddr_udplite_datagram },
|
||||
{ "UDPLITE-DGRAM", &xioaddr_udplite_datagram },
|
||||
#endif
|
||||
#if (WITH_IP4 || WITH_IP6) && WITH_UDPLITE && WITH_LISTEN
|
||||
{ "UDPLITE-L", &xioaddr_udplite_listen },
|
||||
{ "UDPLITE-LISTEN", &xioaddr_udplite_listen },
|
||||
#endif
|
||||
#if (WITH_IP4 || WITH_IP6) && WITH_UDPLITE
|
||||
{ "UDPLITE-RECV", &xioaddr_udplite_recv },
|
||||
{ "UDPLITE-RECVFROM", &xioaddr_udplite_recvfrom },
|
||||
{ "UDPLITE-SEND", &xioaddr_udplite_sendto },
|
||||
{ "UDPLITE-SENDTO", &xioaddr_udplite_sendto },
|
||||
#endif
|
||||
#if WITH_IP4 && WITH_UDPLITE
|
||||
{ "UDPLITE4", &xioaddr_udplite4_connect },
|
||||
{ "UDPLITE4-CONNECT", &xioaddr_udplite4_connect },
|
||||
{ "UDPLITE4-DATAGRAM", &xioaddr_udplite4_datagram },
|
||||
{ "UDPLITE4-DGRAM", &xioaddr_udplite4_datagram },
|
||||
#endif
|
||||
#if WITH_IP4 && WITH_UDPLITE && WITH_LISTEN
|
||||
{ "UDPLITE4-L", &xioaddr_udplite4_listen },
|
||||
{ "UDPLITE4-LISTEN", &xioaddr_udplite4_listen },
|
||||
#endif
|
||||
#if WITH_IP4 && WITH_UDPLITE
|
||||
{ "UDPLITE4-RECV", &xioaddr_udplite4_recv },
|
||||
{ "UDPLITE4-RECVFROM", &xioaddr_udplite4_recvfrom },
|
||||
{ "UDPLITE4-SEND", &xioaddr_udplite4_sendto },
|
||||
{ "UDPLITE4-SENDTO", &xioaddr_udplite4_sendto },
|
||||
#endif
|
||||
#if WITH_IP6 && WITH_UDPLITE
|
||||
{ "UDPLITE6", &xioaddr_udplite6_connect },
|
||||
{ "UDPLITE6-CONNECT", &xioaddr_udplite6_connect },
|
||||
{ "UDPLITE6-DATAGRAM", &xioaddr_udplite6_datagram },
|
||||
{ "UDPLITE6-DGRAM", &xioaddr_udplite6_datagram },
|
||||
#endif
|
||||
#if WITH_IP6 && WITH_UDPLITE && WITH_LISTEN
|
||||
{ "UDPLITE6-L", &xioaddr_udplite6_listen },
|
||||
{ "UDPLITE6-LISTEN", &xioaddr_udplite6_listen },
|
||||
#endif
|
||||
#if WITH_IP6 && WITH_UDPLITE
|
||||
{ "UDPLITE6-RECV", &xioaddr_udplite6_recv },
|
||||
{ "UDPLITE6-RECVFROM", &xioaddr_udplite6_recvfrom },
|
||||
{ "UDPLITE6-SEND", &xioaddr_udplite6_sendto },
|
||||
{ "UDPLITE6-SENDTO", &xioaddr_udplite6_sendto },
|
||||
#endif
|
||||
#if WITH_UNIX
|
||||
{ "UNIX", &xioaddr_unix_client },
|
||||
{ "UNIX-CLIENT", &xioaddr_unix_client },
|
||||
|
|
|
@ -102,6 +102,12 @@ bool xioopts_ignoregroups;
|
|||
# define IF_DCCP(a,b)
|
||||
#endif
|
||||
|
||||
#if WITH_UDPLITE
|
||||
# define IF_UDPLITE(a,b) {a,b},
|
||||
#else
|
||||
# define IF_UDPLITE(a,b)
|
||||
#endif
|
||||
|
||||
#if WITH_SOCKS4
|
||||
# define IF_SOCKS4(a,b) {a,b},
|
||||
#else
|
||||
|
@ -1894,6 +1900,8 @@ const struct optname optionnames[] = {
|
|||
IF_TUN ("tun-no-pi", &opt_iff_no_pi)
|
||||
IF_TUN ("tun-type", &opt_tun_type)
|
||||
IF_SOCKET ("type", &opt_so_type)
|
||||
IF_UDPLITE("udplite-recv-cscov", &xioopt_udplite_recv_cscov)
|
||||
IF_UDPLITE("udplite-send-cscov", &xioopt_udplite_send_cscov)
|
||||
IF_ANY ("uid", &opt_user)
|
||||
IF_NAMED ("uid-e", &opt_user_early)
|
||||
IF_ANY ("uid-l", &opt_user_late)
|
||||
|
|
14
xioopts.h
14
xioopts.h
|
@ -190,20 +190,22 @@ enum e_func {
|
|||
#define GROUP_HTTP 0x40000000 /* any HTTP client */
|
||||
|
||||
/* Keep condition consistent with xio.h:groups_t! */
|
||||
#if WITH_POSIXMQ || WITH_SCTP || WITH_DCCP
|
||||
#if WITH_POSIXMQ || WITH_SCTP || WITH_DCCP || WITH_UDPLITE
|
||||
/* The following groups are not expected on systems without uint64_t */
|
||||
#define GROUP_POSIXMQ 0x0100000000U
|
||||
#define GROUP_IP_SCTP 0x0200000000U
|
||||
#define GROUP_IP_DCCP 0x0400000000U
|
||||
#define GROUP_ALL 0x07ffffffffU
|
||||
#else /* !(WITH_POSIXMQ || WITH_SCTP || WITH_DCCP) */
|
||||
#define GROUP_IP_UDPLITE 0x0800000000U
|
||||
#define GROUP_ALL 0x0fffffffffU
|
||||
#else /* !(WITH_POSIXMQ || WITH_SCTP || WITH_DCCP || WITH_UDPLITE) */
|
||||
#define GROUP_POSIXMQ 0
|
||||
#define GROUP_IP_SCTP 0
|
||||
#define GROUP_IP_DCCP 0
|
||||
#define GROUP_IP_UDPLITE 0
|
||||
#define GROUP_ALL 0xffffffffU
|
||||
#endif /* !(WITH_POSIXMQ || WITH_SCTP || WITH_DCCP) */
|
||||
#endif /* !(WITH_POSIXMQ || WITH_SCTP || WITH_DCCP || WITH_UDPLITE) */
|
||||
|
||||
#define GROUP_IPAPP (GROUP_IP_UDP|GROUP_IP_TCP|GROUP_IP_SCTP|GROUP_IP_DCCP) /* true: indicates one of UDP, TCP, SCTP, DCCP */
|
||||
#define GROUP_IPAPP (GROUP_IP_UDP|GROUP_IP_TCP|GROUP_IP_SCTP|GROUP_IP_DCCP|GROUP_IP_UDPLITE) /* true: indicates one of UDP, TCP, SCTP, DCCP, UDPlite */
|
||||
#define GROUP_ANY (GROUP_PROCESS|GROUP_APPL)
|
||||
|
||||
|
||||
|
@ -860,6 +862,8 @@ enum e_optcode {
|
|||
OPT_TUN_DEVICE, /* tun: /dev/net/tun ... */
|
||||
OPT_TUN_NAME, /* tun: tun0 */
|
||||
OPT_TUN_TYPE, /* tun: tun|tap */
|
||||
OPT_UDPLITE_RECV_CSCOV,
|
||||
OPT_UDPLITE_SEND_CSCOV,
|
||||
OPT_UMASK,
|
||||
OPT_UNIX_BIND_TEMPNAME, /* UNIX domain sockets */
|
||||
OPT_UNIX_TIGHTSOCKLEN,
|
||||
|
|
Loading…
Reference in a new issue