mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +00:00
merged feature sctp streams
This commit is contained in:
parent
d78b080ef0
commit
91057b0b68
17 changed files with 388 additions and 17 deletions
4
CHANGES
4
CHANGES
|
@ -1,5 +1,9 @@
|
|||
|
||||
new features:
|
||||
new address types SCTP-CONNECT and SCTP-LISTEN implement SCTP stream
|
||||
mode for IPv4 and IPv6; new address options sctp-maxseg and
|
||||
sctp-nodelay
|
||||
|
||||
added generic socket addresses: SOCKET-CONNECT, SOCKET-LISTEN,
|
||||
SOCKET-SENDTO, SOCKET-RECVFROM, SOCKET-RECV, SOCKET-DATAGRAM allow
|
||||
protocol independent socket handling; all parameters are explicitely
|
||||
|
|
|
@ -46,7 +46,7 @@ XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \
|
|||
xio-process.c xio-fd.c xio-fdnum.c xio-stdio.c xio-pipe.c \
|
||||
xio-gopen.c xio-creat.c xio-file.c xio-named.c \
|
||||
xio-socket.c xio-listen.c xio-unix.c xio-ip.c xio-ip4.c xio-ip6.c xio-ipapp.c xio-tcp.c xio-socks.c xio-proxy.c xio-udp.c \
|
||||
xio-rawip.c \
|
||||
xio-sctp.c xio-rawip.c \
|
||||
xio-progcall.c xio-exec.c xio-system.c xio-termios.c xio-readline.c \
|
||||
xio-pty.c xio-openssl.c \
|
||||
xio-ascii.c xiolockfile.c xio-tcpwrap.c xio-ext2.c xio-tun.c
|
||||
|
@ -63,6 +63,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-socket.h \
|
||||
xio-listen.h xio-unix.h xio-rawip.h xio-ip.h xio-ip4.h xio-ip6.h \
|
||||
xio-ipapp.h xio-tcp.h xio-udp.h xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \
|
||||
xio-sctp.h \
|
||||
xio-system.h xio-termios.h xio-readline.h \
|
||||
xio-pty.h xio-openssl.h \
|
||||
xio-ascii.h xiolockfile.h xio-tcpwrap.h xio-ext2.h xio-tun.h
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock+escape+timestamp+ancillary+envvar+protocol+ioctl+setsockopt+genericsocket"
|
||||
"1.6.0.1+ip4bind+recvfromfork+x64+execstderr+execspaces+cosmetics+poll+udplistencont+ignoreeofunblock+escape+timestamp+ancillary+envvar+protocol+ioctl+setsockopt+genericsocket+sctp"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* source: config.h.in */
|
||||
/* Copyright Gerhard Rieger 2001-2007 */
|
||||
/* Copyright Gerhard Rieger 2001-2008 */
|
||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||
|
||||
#ifndef __config_h_included
|
||||
|
@ -471,6 +471,7 @@
|
|||
#undef WITH_GENERICSOCKET
|
||||
#undef WITH_TCP
|
||||
#undef WITH_UDP
|
||||
#undef WITH_SCTP
|
||||
#undef WITH_LISTEN
|
||||
#undef WITH_SOCKS4
|
||||
#undef WITH_SOCKS4A
|
||||
|
|
|
@ -237,6 +237,14 @@ AC_ARG_ENABLE(udp, [ --disable-udp disable UDP support],
|
|||
esac],
|
||||
[AC_DEFINE(WITH_UDP) AC_MSG_RESULT(yes)])
|
||||
|
||||
AC_MSG_CHECKING(whether to include SCTP support)
|
||||
AC_ARG_ENABLE(tcp, [ --disable-sctp disable SCTP support],
|
||||
[case "$enableval" in
|
||||
no) AC_MSG_RESULT(no);;
|
||||
*) AC_DEFINE(WITH_SCTP) AC_MSG_RESULT(yes);;
|
||||
esac],
|
||||
[AC_DEFINE(WITH_SCTP) AC_MSG_RESULT(yes)])
|
||||
|
||||
AC_MSG_CHECKING(whether to include listen support)
|
||||
AC_ARG_ENABLE(listen, [ --disable-listen disable listen support],
|
||||
[case "$enableval" in
|
||||
|
|
101
doc/socat.yo
101
doc/socat.yo
|
@ -600,6 +600,69 @@ label(ADDRESS_READLINE)dit(bf(tt(READLINE)))
|
|||
link(noecho)(OPTION_NOECHO)nl()
|
||||
See also:
|
||||
link(STDIO)(ADDRESS_STDIO)
|
||||
label(ADDRESS_SCTP_CONNECT)dit(bf(tt(SCTP-CONNECT:<host>:<port>)))
|
||||
Establishes an SCTP stream connection to the specified <host> [link(IP
|
||||
address)(TYPE_IP_ADDRESS)] and <port> [link(TCP service)(TYPE_TCP_SERVICE)]
|
||||
using TCP/IP version 4 or 6 depending on address specification, name
|
||||
resolution, or option link(pf)(OPTION_PROTOCOL_FAMILY).nl()
|
||||
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(SCTP)(GROUP_SCTP),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY) nl()
|
||||
Useful options:
|
||||
link(bind)(OPTION_BIND),
|
||||
link(pf)(OPTION_PROTOCOL_FAMILY),
|
||||
link(connect-timeout)(OPTION_CONNECT_TIMEOUT),
|
||||
link(tos)(OPTION_TOS),
|
||||
link(mtudiscover)(OPTION_MTUDISCOVER),
|
||||
link(mss)(OPTION_MSS),
|
||||
link(nodelay)(OPTION_NODELAY),
|
||||
link(nonblock)(OPTION_NONBLOCK),
|
||||
link(sourceport)(OPTION_SOURCEPORT),
|
||||
link(retry)(OPTION_RETRY),
|
||||
link(readbytes)(OPTION_READBYTES)nl()
|
||||
See also:
|
||||
link(SCTP4-CONNECT)(ADDRESS_SCTP4_CONNECT),
|
||||
link(SCTP6-CONNECT)(ADDRESS_SCTP6_CONNECT),
|
||||
link(SCTP-LISTEN)(ADDRESS_SCTP_LISTEN),
|
||||
link(TCP-CONNECT)(ADDRESS_TCP_CONNECT)
|
||||
label(ADDRESS_SCTP4_CONNECT)dit(bf(tt(SCTP4-CONNECT:<host>:<port>)))
|
||||
Like link(SCTP-CONNECT)(ADDRESS_SCTP_CONNECT), but only supports IPv4 protocol.nl()
|
||||
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(SCTP)(GROUP_SCTP),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY) nl()
|
||||
label(ADDRESS_SCTP6_CONNECT)dit(bf(tt(SCTP6-CONNECT:<host>:<port>)))
|
||||
Like link(SCTP-CONNECT)(ADDRESS_SCTP_CONNECT), but only supports IPv6 protocol.nl()
|
||||
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP6)(GROUP_IP6),link(SCTP)(GROUP_SCTP),link(CHILD)(GROUP_CHILD),link(RETRY)(GROUP_RETRY) nl()
|
||||
label(ADDRESS_SCTP_LISTEN)dit(bf(tt(SCTP-LISTEN:<port>)))
|
||||
Listens on <port> [link(TCP service)(TYPE_TCP_SERVICE)] and accepts a
|
||||
TCP/IP connection. The IP version is 4 or the one specified with
|
||||
address option link(pf)(OPTION_PROTOCOL_FAMILY), socat option
|
||||
(link(-4)(option_4), link(-6)(option_6)), or environment variable link(SOCAT_DEFAULT_LISTEN_IP)(ENV_SOCAT_DEFAULT_LISTEN_IP).
|
||||
Note that opening
|
||||
this address usually blocks until a client connects.nl()
|
||||
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(SCTP)(GROUP_SCTP),link(RETRY)(GROUP_RETRY) nl()
|
||||
Useful options:
|
||||
link(crnl)(OPTION_CRNL),
|
||||
link(fork)(OPTION_FORK),
|
||||
link(bind)(OPTION_BIND),
|
||||
link(range)(OPTION_RANGE),
|
||||
link(tcpwrap)(OPTION_TCPWRAPPERS),
|
||||
link(pf)(OPTION_PROTOCOL_FAMILY),
|
||||
link(backlog)(OPTION_BACKLOG),
|
||||
link(mss)(OPTION_MSS),
|
||||
link(su)(OPTION_SUBSTUSER),
|
||||
link(reuseaddr)(OPTION_REUSEADDR),
|
||||
link(retry)(OPTION_RETRY),
|
||||
link(cool-write)(OPTION_COOL_WRITE)nl()
|
||||
See also:
|
||||
link(SCTP4-LISTEN)(ADDRESS_SCTP4_LISTEN),
|
||||
link(SCTP6-LISTEN)(ADDRESS_SCTP6_LISTEN),
|
||||
link(TCP-LISTEN)(ADDRESS_TCP_LISTEN),
|
||||
link(SCTP-CONNECT)(ADDRESS_SCTP_CONNECT)
|
||||
label(ADDRESS_SCTP4_LISTEN)dit(bf(tt(SCTP4-LISTEN:<port>)))
|
||||
Like link(SCTP-LISTEN)(ADDRESS_SCTP_LISTEN), but only supports IPv4
|
||||
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(IP4)(GROUP_IP4),link(SCTP)(GROUP_SCTP),link(RETRY)(GROUP_RETRY) nl()
|
||||
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 socket(2)) and connects to the remote-address.
|
||||
|
@ -829,6 +892,7 @@ label(ADDRESS_TCP_CONNECT)dit(bf(tt(TCP:<host>:<port>)))
|
|||
link(TCP6)(ADDRESS_TCP6_CONNECT),
|
||||
link(TCP-LISTEN)(ADDRESS_TCP_LISTEN),
|
||||
link(UDP)(ADDRESS_UDP_CONNECT),
|
||||
link(SCTP-CONNECT)(ADDRESS_SCTP_CONNECT),
|
||||
link(UNIX-CONNECT)(ADDRESS_UNIX_CONNECT)
|
||||
label(ADDRESS_TCP4_CONNECT)dit(bf(tt(TCP4:<host>:<port>)))
|
||||
Like link(TCP)(ADDRESS_TCP_CONNECT), but only supports IPv4 protocol (link(example)(EXAMPLE_ADDRESS_TCP4_CONNECT)).nl()
|
||||
|
@ -839,7 +903,8 @@ label(ADDRESS_TCP6_CONNECT)dit(bf(tt(TCP6:<host>:<port>)))
|
|||
label(ADDRESS_TCP_LISTEN)dit(bf(tt(TCP-LISTEN:<port>)))
|
||||
Listens on <port> [link(TCP service)(TYPE_TCP_SERVICE)] and accepts a
|
||||
TCP/IP connection. The IP version is 4 or the one specified with
|
||||
link(pf)(OPTION_PROTOCOL_FAMILY).
|
||||
address option link(pf)(OPTION_PROTOCOL_FAMILY), socat option
|
||||
(link(-4)(option_4), link(-6)(option_6)), or environment variable link(SOCAT_DEFAULT_LISTEN_IP)(ENV_SOCAT_DEFAULT_LISTEN_IP).
|
||||
Note that opening
|
||||
this address usually blocks until a client connects.nl()
|
||||
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(LISTEN)(GROUP_LISTEN),link(CHILD)(GROUP_CHILD),link(RANGE)(GROUP_RANGE),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(TCP)(GROUP_TCP),link(RETRY)(GROUP_RETRY) nl()
|
||||
|
@ -855,13 +920,15 @@ label(ADDRESS_TCP_LISTEN)dit(bf(tt(TCP-LISTEN:<port>)))
|
|||
link(su)(OPTION_SUBSTUSER),
|
||||
link(reuseaddr)(OPTION_REUSEADDR),
|
||||
link(retry)(OPTION_RETRY),
|
||||
link(retry)(OPTION_COOL_WRITE)nl()
|
||||
link(cool-write)(OPTION_COOL_WRITE)nl()
|
||||
See also:
|
||||
link(TCP4-LISTEN)(ADDRESS_TCP4_CONNECT),
|
||||
link(TCP4-LISTEN)(ADDRESS_TCP4_LISTEN),
|
||||
link(TCP6-LISTEN)(ADDRESS_TCP6_LISTEN),
|
||||
link(UDP-LISTEN)(ADDRESS_UDP_LISTEN),
|
||||
link(SCTP-LISTEN)(ADDRESS_SCTP_LISTEN),
|
||||
link(UNIX-LISTEN)(ADDRESS_UNIX_LISTEN),
|
||||
link(OPENSSL-LISTEN)(ADDRESS_OPENSSL_LISTEN)
|
||||
link(OPENSSL-LISTEN)(ADDRESS_OPENSSL_LISTEN),
|
||||
link(TCP-CONNECT)(ADDRESS_TCP_CONNECT)
|
||||
label(ADDRESS_TCP4_LISTEN)dit(bf(tt(TCP4-LISTEN:<port>)))
|
||||
Like link(TCP-LISTEN)(ADDRESS_TCP_LISTEN), but only supports IPv4
|
||||
protocol (link(example)(EXAMPLE_ADDRESS_TCP4_LISTEN)).nl()
|
||||
|
@ -2058,10 +2125,24 @@ enddit()
|
|||
startdit()enddit()nl()
|
||||
|
||||
|
||||
em(bf(UDP and TCP option groups))
|
||||
label(GROUP_SCTP)em(bf(SCTP option group))
|
||||
|
||||
These options may be applied to SCTP stream sockets.
|
||||
startdit()
|
||||
label(OPTION_SCTP_NODELAY)dit(bf(tt(sctp-nodelay)))
|
||||
Sets the SCTP_NODELAY socket option that disables the Nagle algorithm.
|
||||
label(OPTION_SCTP_MAXSEG)dit(bf(tt(sctp-maxseg=<bytes>)))
|
||||
Sets the SCTP_MAXSEG socket option to <bytes> [link(int)(TYPE_INT)]. This
|
||||
value is then proposed to the peer with the SYN or SYN/ACK packet.
|
||||
enddit()
|
||||
|
||||
startdit()enddit()nl()
|
||||
|
||||
|
||||
em(bf(UDP, TCP, and SCTP option groups))
|
||||
|
||||
Here we find options that are related to the network port mechanism and that
|
||||
thus can be used with UDP and TCP, client and server addresses.
|
||||
thus can be used with UDP, TCP, and SCTP client and server addresses.
|
||||
startdit()
|
||||
label(OPTION_SOURCEPORT)dit(bf(tt(sourceport=<port>)))
|
||||
For outgoing (client) TCP and UDP connections, it sets the source
|
||||
|
@ -3163,11 +3244,11 @@ by the upper case name of the executable or the value of option
|
|||
link(-lp)(option_lp).
|
||||
|
||||
startdit()
|
||||
label(ENV_SOCAT_DEFAULT_LISTEN_IP)
|
||||
dit(bf(SOCAT_DEFAULT_LISTEN_IP) (input)) (Values 4 or 6) Sets the IP version to
|
||||
be used
|
||||
for listen, recv, and recvfrom addresses if no link(pf)(OPTION_PROTOCOL_FAMILY)
|
||||
(protocol-family) option is given. Is overridden by socat options
|
||||
link(-4)(option_4) or link(-6)(option_6).
|
||||
be used for listen, recv, and recvfrom addresses if no
|
||||
link(pf)(OPTION_PROTOCOL_FAMILY) (protocol-family) option is given. Is
|
||||
overridden by socat options link(-4)(option_4) or link(-6)(option_6).
|
||||
|
||||
dit(bf(SOCAT_PREFERRED_RESOLVE_IP) (input)) (Values 0, 4, or 6) Sets the IP
|
||||
version to
|
||||
|
|
5
socat.c
5
socat.c
|
@ -438,6 +438,11 @@ void socat_version(FILE *fd) {
|
|||
#else
|
||||
fputs(" #undef WITH_UDP\n", fd);
|
||||
#endif
|
||||
#ifdef WITH_SCTP
|
||||
fprintf(fd, " #define WITH_SCTP %d\n", WITH_SCTP);
|
||||
#else
|
||||
fputs(" #undef WITH_SCTP\n", fd);
|
||||
#endif
|
||||
#ifdef WITH_LISTEN
|
||||
fprintf(fd, " #define WITH_LISTEN %d\n", WITH_LISTEN);
|
||||
#else
|
||||
|
|
|
@ -423,7 +423,9 @@ int xiopoll(struct pollfd fds[], nfds_t nfds, int timeout) {
|
|||
|
||||
|
||||
#if WITH_TCP || WITH_UDP
|
||||
/* returns port in network byte order */
|
||||
/* returns port in network byte order;
|
||||
ipproto==IPPROTO_UDP resolves as UDP service, every other value resolves as
|
||||
TCP */
|
||||
int parseport(const char *portname, int ipproto) {
|
||||
struct servent *se;
|
||||
char *extra;
|
||||
|
@ -438,7 +440,7 @@ int parseport(const char *portname, int ipproto) {
|
|||
return result;
|
||||
}
|
||||
|
||||
if ((se = getservbyname(portname, ipproto==IPPROTO_TCP?"tcp":"udp")) == NULL) {
|
||||
if ((se = getservbyname(portname, ipproto==IPPROTO_UDP?"udp":"tcp")) == NULL) {
|
||||
Error2("cannot resolve service \"%s/%d\"", portname, ipproto);
|
||||
return 0;
|
||||
}
|
||||
|
|
162
test.sh
162
test.sh
|
@ -1866,6 +1866,40 @@ waitudp4port () {
|
|||
return 1
|
||||
}
|
||||
|
||||
# wait until an SCTP4 listen port is ready
|
||||
waitsctp4port () {
|
||||
local port="$1"
|
||||
local logic="$2" # 0..wait until free; 1..wait until listening
|
||||
local timeout="$3"
|
||||
local l
|
||||
[ "$logic" ] || logic=1
|
||||
[ "$timeout" ] || timeout=5
|
||||
while [ $timeout -gt 0 ]; do
|
||||
case "$UNAME" in
|
||||
Linux) l=$(netstat -n -a |grep '^sctp .* .*[0-9*]:'$port' .* LISTEN') ;;
|
||||
# FreeBSD) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;;
|
||||
# NetBSD) l=$(netstat -an |grep '^tcp .* .*[0-9*]\.'$port' [ ]* \*\.\* [ ]* LISTEN.*') ;;
|
||||
# Darwin) case "$(uname -r)" in
|
||||
# [1-5]*) l=$(netstat -an |grep '^tcp.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;;
|
||||
# *) l=$(netstat -an |grep '^tcp4.* .*[0-9*]\.'$port' .* \*\.\* .* LISTEN') ;;
|
||||
# esac ;;
|
||||
# AIX) l=$(netstat -an |grep '^tcp[^6] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;;
|
||||
# SunOS) l=$(netstat -an -f inet -P tcp |grep '.*[1-9*]\.'$port' .*\* 0 .* LISTEN') ;;
|
||||
# HP-UX) l=$(netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' .* LISTEN$') ;;
|
||||
# OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') ;;
|
||||
# CYGWIN*) l=$(netstat -an -p TCP |grep '^ TCP [0-9.]*:'$port' .* LISTENING') ;;
|
||||
*) l=$(netstat -an |grep -i 'sctp .*[0-9*][:.]'$port' .* listen') ;;
|
||||
esac
|
||||
[ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
|
||||
\( \( $logic -eq 0 \) -a -z "$l" \) ] && return 0
|
||||
sleep 1
|
||||
timeout=$((timeout-1))
|
||||
done
|
||||
|
||||
$ECHO "!port $port timed out! \c" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
# wait until a tcp6 listen port is ready
|
||||
waittcp6port () {
|
||||
local port="$1"
|
||||
|
@ -1926,6 +1960,36 @@ waitudp6port () {
|
|||
return 1
|
||||
}
|
||||
|
||||
# wait until a sctp6 listen port is ready
|
||||
# not all (Linux) variants show this in netstat
|
||||
waitsctp6port () {
|
||||
local port="$1"
|
||||
local logic="$2" # 0..wait until free; 1..wait until listening
|
||||
local timeout="$3"
|
||||
local l
|
||||
[ "$logic" ] || logic=1
|
||||
[ "$timeout" ] || timeout=5
|
||||
while [ $timeout -gt 0 ]; do
|
||||
case "$UNAME" in
|
||||
Linux) l=$(netstat -an |grep '^sctp[6 ] .* [0-9a-f:]*:'$port' .* LISTEN') ;;
|
||||
# FreeBSD) l=$(netstat -an |grep -i 'tcp[46][6 ] .*[0-9*][:.]'$port' .* listen') ;;
|
||||
# NetBSD) l=$(netstat -an |grep '^tcp6 .*[0-9*]\.'$port' [ ]* \*\.\*') ;;
|
||||
# OpenBSD) l=$(netstat -an |grep -i 'tcp6 .*[0-9*][:.]'$port' .* listen') ;;
|
||||
# AIX) l=$(netstat -an |grep '^tcp[6 ] 0 0 .*[*0-9]\.'$port' .* LISTEN$') ;;
|
||||
# SunOS) l=$(netstat -an -f inet6 -P tcp |grep '.*[1-9*]\.'$port' .*\* [ ]* 0 .* LISTEN') ;;
|
||||
# #OSF1) l=$(/usr/sbin/netstat -an |grep '^tcp6 0 0 .*[0-9*]\.'$port' [ ]*\*\.\* [ ]*LISTEN') /*?*/;;
|
||||
*) l=$(netstat -an |grep -i 'stcp6 .*:'$port' .* listen') ;;
|
||||
esac
|
||||
[ \( \( $logic -ne 0 \) -a -n "$l" \) -o \
|
||||
\( \( $logic -eq 0 \) -a -z "$l" \) ] && return 0
|
||||
sleep 1
|
||||
timeout=$((timeout-1))
|
||||
done
|
||||
|
||||
$ECHO "!port $port timed out! \c" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
# we need this misleading function name for canonical reasons
|
||||
waitunixport () {
|
||||
waitfile "$1" "$2" "$3"
|
||||
|
@ -9174,6 +9238,7 @@ esac
|
|||
PORT=$((PORT+1))
|
||||
N=$((N+1))
|
||||
|
||||
|
||||
# test the SOCKET-RECV address (with UDP4-SENDTO)
|
||||
NAME=SOCKET_RECV
|
||||
case "$TESTS" in
|
||||
|
@ -9427,6 +9492,103 @@ PORT=$((PORT+1))
|
|||
N=$((N+1))
|
||||
|
||||
|
||||
NAME=SCTP4STREAM
|
||||
case "$TESTS" in
|
||||
*%functions%*|*%ip4%*|*%ipapp%*|*%sctp%*|*%$NAME%*)
|
||||
TEST="$NAME: echo via connection to SCTP V4 socket"
|
||||
if ! testaddrs sctp ip4 >/dev/null || ! runsip4 >/dev/null; then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}SCTP4 not available${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then
|
||||
# RHEL5 based systems became unusable when an sctp socket was created but
|
||||
# module sctp not loaded
|
||||
$PRINTF "test $F_n $TEST...${YELLOW}load sctp module!${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
else
|
||||
tf="$td/test$N.stdout"
|
||||
te="$td/test$N.stderr"
|
||||
tdiff="$td/test$N.diff"
|
||||
tsl=$PORT
|
||||
ts="127.0.0.1:$tsl"
|
||||
da=$(date)
|
||||
CMD1="$SOCAT $opts SCTP4-LISTEN:$tsl,reuseaddr PIPE"
|
||||
CMD2="$SOCAT $opts stdin!!stdout SCTP4:$ts"
|
||||
printf "test $F_n $TEST... " $N
|
||||
$CMD1 >"$tf" 2>"${te}1" &
|
||||
pid1=$!
|
||||
waitsctp4port $tsl 1
|
||||
# SCTP does not seem to support half close, so we let it 1s to finish
|
||||
(echo "$da"; sleep 1) |$CMD2 >>"$tf" 2>>"${te}2"
|
||||
if [ $? -ne 0 ]; then
|
||||
$PRINTF "$FAILED: $SOCAT:\n"
|
||||
echo "$CMD1 &"
|
||||
cat "${te}1"
|
||||
echo "$CMD2"
|
||||
cat "${te}2"
|
||||
numFAIL=$((numFAIL+1))
|
||||
elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
|
||||
$PRINTF "$FAILED\n"
|
||||
cat "$tdiff"
|
||||
numFAIL=$((numFAIL+1))
|
||||
else
|
||||
$PRINTF "$OK\n"
|
||||
if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
|
||||
numOK=$((numOK+1))
|
||||
fi
|
||||
kill $pid1 2>/dev/null
|
||||
wait
|
||||
fi ;; # sctp
|
||||
esac
|
||||
PORT=$((PORT+1))
|
||||
N=$((N+1))
|
||||
|
||||
NAME=SCTP6STREAM
|
||||
case "$TESTS" in
|
||||
*%functions%*|*%ip6%*|*%ipapp%*|*%sctp%*|*%$NAME%*)
|
||||
TEST="$NAME: echo via connection to SCTP V6 socket"
|
||||
if ! testaddrs sctp ip6 >/dev/null || ! runsip6 >/dev/null; then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}SCTP6 not available${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
elif [ "$UNAME" = Linux ] && ! grep ^sctp /proc/modules >/dev/null; then
|
||||
$PRINTF "test $F_n $TEST...${YELLOW}load sctp module!${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
else
|
||||
tf="$td/test$N.stdout"
|
||||
te="$td/test$N.stderr"
|
||||
tdiff="$td/test$N.diff"
|
||||
tsl=$PORT
|
||||
ts="[::1]:$tsl"
|
||||
da=$(date)
|
||||
CMD1="$SOCAT $opts SCTP6-listen:$tsl,reuseaddr PIPE"
|
||||
CMD2="$SOCAT $opts stdin!!stdout SCTP6:$ts"
|
||||
printf "test $F_n $TEST... " $N
|
||||
$CMD1 >"$tf" 2>"${te}1" &
|
||||
pid=$! # background process id
|
||||
waitsctp6port $tsl 1
|
||||
# SCTP does not seem to support half close, so we let it 1s to finish
|
||||
(echo "$da"; sleep 1) |$CMD2 >>"$tf" 2>>"${te}2"
|
||||
if [ $? -ne 0 ]; then
|
||||
$PRINTF "$FAILED: $SOCAT:\n"
|
||||
echo "$CMD1 &"
|
||||
echo "$CMD2"
|
||||
cat "$te"
|
||||
numFAIL=$((numFAIL+1))
|
||||
elif ! echo "$da" |diff - "$tf" >"$tdiff"; then
|
||||
$PRINTF "$FAILED: diff:\n"
|
||||
cat "$tdiff"
|
||||
numFAIL=$((numFAIL+1))
|
||||
else
|
||||
$PRINTF "$OK\n"
|
||||
if [ -n "$debug" ]; then cat "${te}1" "${te}2"; fi
|
||||
numOK=$((numOK+1))
|
||||
fi
|
||||
kill $pid 2>/dev/null
|
||||
fi ;; # sctp
|
||||
esac
|
||||
PORT=$((PORT+1))
|
||||
N=$((N+1))
|
||||
|
||||
|
||||
echo "summary: $((N-1)) tests; $numOK ok, $numFAIL failed, $numCANT could not be performed"
|
||||
|
||||
if [ "$numFAIL" -gt 0 ]; then
|
||||
|
|
50
xio-sctp.c
Normal file
50
xio-sctp.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* source: xio-sctp.c */
|
||||
/* Copyright Gerhard Rieger 2008 */
|
||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||
|
||||
/* this file contains the source for SCTP related functions and options */
|
||||
|
||||
#include "xiosysincludes.h"
|
||||
|
||||
#if WITH_SCTP
|
||||
|
||||
#include "xioopen.h"
|
||||
#include "xio-listen.h"
|
||||
#include "xio-ip4.h"
|
||||
#include "xio-ipapp.h"
|
||||
#include "xio-sctp.h"
|
||||
|
||||
/****** SCTP addresses ******/
|
||||
|
||||
#if WITH_IP4 || WITH_IP6
|
||||
const struct addrdesc addr_sctp_connect = { "sctp-connect", 1+XIO_RDWR, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_SCTP|GROUP_CHILD|GROUP_RETRY, SOCK_STREAM, IPPROTO_SCTP, PF_UNSPEC HELP(":<host>:<port>") };
|
||||
#if WITH_LISTEN
|
||||
const struct addrdesc addr_sctp_listen = { "sctp-listen", 1+XIO_RDWR, xioopen_ipapp_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_SCTP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE|GROUP_RETRY, SOCK_STREAM, IPPROTO_SCTP, PF_UNSPEC HELP(":<port>") };
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if WITH_IP4
|
||||
const struct addrdesc addr_sctp4_connect = { "sctp4-connect", 1+XIO_RDWR, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_SCTP|GROUP_CHILD|GROUP_RETRY, SOCK_STREAM, IPPROTO_SCTP, PF_INET HELP(":<host>:<port>") };
|
||||
#if WITH_LISTEN
|
||||
const struct addrdesc addr_sctp4_listen = { "sctp4-listen", 1+XIO_RDWR, xioopen_ipapp_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_SCTP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE|GROUP_RETRY, SOCK_STREAM, IPPROTO_SCTP, PF_INET HELP(":<port>") };
|
||||
#endif
|
||||
#endif /* WITH_IP4 */
|
||||
|
||||
#if WITH_IP6
|
||||
const struct addrdesc addr_sctp6_connect = { "sctp6-connect", 1+XIO_RDWR, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_SCTP|GROUP_CHILD|GROUP_RETRY, SOCK_STREAM, IPPROTO_SCTP, PF_INET6 HELP(":<host>:<port>") };
|
||||
#if WITH_LISTEN
|
||||
const struct addrdesc addr_sctp6_listen = { "sctp6-listen", 1+XIO_RDWR, xioopen_ipapp_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_SCTP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE|GROUP_RETRY, SOCK_STREAM, IPPROTO_SCTP, PF_INET6 HELP(":<port>") };
|
||||
#endif
|
||||
#endif /* WITH_IP6 */
|
||||
|
||||
/****** SCTP address options ******/
|
||||
|
||||
#ifdef SCTP_NODELAY
|
||||
const struct optdesc opt_sctp_nodelay = { "sctp-nodelay", "nodelay", OPT_SCTP_NODELAY, GROUP_IP_SCTP, PH_PASTSOCKET, TYPE_INT, OFUNC_SOCKOPT, SOL_SCTP, SCTP_NODELAY };
|
||||
#endif
|
||||
#ifdef SCTP_MAXSEG
|
||||
const struct optdesc opt_sctp_maxseg = { "sctp-maxseg", "mss", OPT_SCTP_MAXSEG, GROUP_IP_SCTP, PH_PASTSOCKET,TYPE_INT, OFUNC_SOCKOPT, SOL_SCTP, SCTP_MAXSEG };
|
||||
const struct optdesc opt_sctp_maxseg_late={"sctp-maxseg-late","mss-late",OPT_SCTP_MAXSEG_LATE,GROUP_IP_SCTP,PH_CONNECTED,TYPE_INT,OFUNC_SOCKOPT, SOL_SCTP, SCTP_MAXSEG};
|
||||
#endif
|
||||
|
||||
#endif /* WITH_SCTP */
|
19
xio-sctp.h
Normal file
19
xio-sctp.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* source: xio-sctp.h */
|
||||
/* Copyright Gerhard Rieger 2008 */
|
||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||
|
||||
#ifndef __xio_sctp_h_included
|
||||
#define __xio_sctp_h_included 1
|
||||
|
||||
extern const struct addrdesc addr_sctp_connect;
|
||||
extern const struct addrdesc addr_sctp_listen;
|
||||
extern const struct addrdesc addr_sctp4_connect;
|
||||
extern const struct addrdesc addr_sctp4_listen;
|
||||
extern const struct addrdesc addr_sctp6_connect;
|
||||
extern const struct addrdesc addr_sctp6_listen;
|
||||
|
||||
extern const struct optdesc opt_sctp_nodelay;
|
||||
extern const struct optdesc opt_sctp_maxseg;
|
||||
extern const struct optdesc opt_sctp_maxseg_late;
|
||||
|
||||
#endif /* !defined(__xio_sctp_h_included) */
|
|
@ -43,7 +43,7 @@ static const char *addressgroupnames[] = {
|
|||
"TERMIOS", "RANGE", "PTY", "PARENT",
|
||||
"UNIX", "IP4", "IP6", "INTERFACE",
|
||||
"UDP", "TCP", "SOCKS4", "OPENSSL",
|
||||
"PROCESS", "APPL", "HTTP", "undef"
|
||||
"PROCESS", "APPL", "HTTP", "SCTP"
|
||||
} ;
|
||||
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "xio-ipapp.h"
|
||||
#include "xio-tcp.h"
|
||||
#include "xio-udp.h"
|
||||
#include "xio-sctp.h"
|
||||
#include "xio-socks.h"
|
||||
#include "xio-proxy.h"
|
||||
#endif /* _WITH_SOCKET */
|
||||
|
|
20
xioopen.c
20
xioopen.c
|
@ -135,6 +135,26 @@ const struct addrname addressnames[] = {
|
|||
#if WITH_READLINE
|
||||
{ "readline", &addr_readline },
|
||||
#endif
|
||||
#if (WITH_IP4 || WITH_IP6) && WITH_SCTP
|
||||
{ "sctp", &addr_sctp_connect },
|
||||
{ "sctp-connect", &addr_sctp_connect },
|
||||
#if WITH_LISTEN
|
||||
{ "sctp-l", &addr_sctp_listen },
|
||||
{ "sctp-listen", &addr_sctp_listen },
|
||||
#endif
|
||||
{ "sctp4", &addr_sctp4_connect },
|
||||
{ "sctp4-connect", &addr_sctp4_connect },
|
||||
#if WITH_LISTEN
|
||||
{ "sctp4-l", &addr_sctp4_listen },
|
||||
{ "sctp4-listen", &addr_sctp4_listen },
|
||||
#endif
|
||||
{ "sctp6", &addr_sctp6_connect },
|
||||
{ "sctp6-connect", &addr_sctp6_connect },
|
||||
#if WITH_LISTEN
|
||||
{ "sctp6-l", &addr_sctp6_listen },
|
||||
{ "sctp6-listen", &addr_sctp6_listen },
|
||||
#endif
|
||||
#endif /* (WITH_IP4 || WITH_IP6) && WITH_SCTP */
|
||||
#if WITH_GENERICSOCKET
|
||||
{ "sendto", &xioaddr_socket_sendto },
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* source: xioopen.h */
|
||||
/* Copyright Gerhard Rieger 2001-2006 */
|
||||
/* Copyright Gerhard Rieger 2001-2008 */
|
||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||
|
||||
#ifndef __xioopen_h_included
|
||||
|
|
13
xioopts.c
13
xioopts.c
|
@ -82,6 +82,12 @@ bool xioopts_ignoregroups;
|
|||
# define IF_TCP(a,b)
|
||||
#endif
|
||||
|
||||
#if WITH_SCTP
|
||||
# define IF_SCTP(a,b) {a,b},
|
||||
#else
|
||||
# define IF_SCTP(a,b)
|
||||
#endif
|
||||
|
||||
#if WITH_SOCKS4
|
||||
# define IF_SOCKS4(a,b) {a,b},
|
||||
#else
|
||||
|
@ -1208,6 +1214,13 @@ const struct optname optionnames[] = {
|
|||
IF_TCP ("sackena", &opt_tcp_sackena)
|
||||
#endif
|
||||
IF_TERMIOS("sane", &opt_sane)
|
||||
#ifdef SCTP_MAXSEG
|
||||
IF_SCTP ("sctp-maxseg", &opt_sctp_maxseg)
|
||||
IF_SCTP ("sctp-maxseg-late", &opt_sctp_maxseg_late)
|
||||
#endif
|
||||
#ifdef SCTP_NODELAY
|
||||
IF_SCTP ("sctp-nodelay", &opt_sctp_nodelay)
|
||||
#endif
|
||||
#if WITH_EXT2 && defined(EXT2_SECRM_FL)
|
||||
IF_ANY ("secrm", &opt_ext2_secrm)
|
||||
#endif
|
||||
|
|
|
@ -166,6 +166,7 @@ enum e_func {
|
|||
#define GROUP_PROCESS 0x10000000 /* a process related option */
|
||||
#define GROUP_APPL 0x20000000 /* option handled by data loop */
|
||||
#define GROUP_HTTP 0x40000000 /* any HTTP client */
|
||||
#define GROUP_IP_SCTP 0x80000000
|
||||
|
||||
#define GROUP_ANY (GROUP_PROCESS|GROUP_APPL)
|
||||
#define GROUP_ALL 0xffffffff
|
||||
|
@ -568,6 +569,9 @@ enum e_optcode {
|
|||
OPT_RES_USEVC, /* resolver(3) */
|
||||
OPT_RETRY,
|
||||
OPT_SANE, /* termios */
|
||||
OPT_SCTP_MAXSEG,
|
||||
OPT_SCTP_MAXSEG_LATE,
|
||||
OPT_SCTP_NODELAY,
|
||||
OPT_SEEK32_CUR,
|
||||
OPT_SEEK32_END,
|
||||
OPT_SEEK32_SET,
|
||||
|
|
Loading…
Reference in a new issue