From e1aadc577dcffa69d05a561571d471aaa6f2a84f Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Wed, 21 Jun 2023 20:44:29 +0200 Subject: [PATCH] xioopen() checks r/w mode of addresses --- CHANGES | 4 ++++ doc/socat.yo | 24 +++++++++++++++++++----- test.sh | 11 ++++------- xio-creat.c | 2 +- xio-rawip.c | 24 ++++++++++++------------ xio-socket.c | 12 ++++++------ xio-udp.c | 36 ++++++++++++++++++------------------ xio-unix.c | 24 ++++++++++++------------ xioopen.c | 7 ++++++- 9 files changed, 82 insertions(+), 62 deletions(-) diff --git a/CHANGES b/CHANGES index 63a4362..df39858 100644 --- a/CHANGES +++ b/CHANGES @@ -156,6 +156,10 @@ Corrections: INTERFACE addresses did not accept options of INTERFACE group (for historical reasons they were only available with TUN addresses). + Opening addresses did not check if they support all directions expected + by Socat. Now an error is printed when, e.g,, a read-only type address + is opened for writing. + Coding: Introduced groups_t instead of uint32_t, for more flexibility. diff --git a/doc/socat.yo b/doc/socat.yo index 350ef4f..a8e6a6b 100644 --- a/doc/socat.yo +++ b/doc/socat.yo @@ -296,8 +296,9 @@ startdit() label(ADDRESS_CREAT)dit(bf(tt(CREATE:))) Opens link()(TYPE_FILENAME) with code(creat()) and uses the file descriptor for writing. - This address type requires write-only context, because a file opened with - code(creat) cannot be read from. nl() + This is a write-only address because a file opened with code(creat) cannot + be read from. See options link(-u)(option_u) and + link(-U)(option_U), and link(dual addresses)(ADDRESS_DUAL).nl() Flags like O_LARGEFILE cannot be applied. If you need them use link(OPEN)(ADDRESS_OPEN) with options link(create)(OPTION_O_CREAT),link(create)(OPTION_O_TRUNC). nl() @@ -480,7 +481,8 @@ label(ADDRESS_IP6_RECVFROM)dit(bf(tt(IP6-RECVFROM:))) label(ADDRESS_IP_RECV)dit(bf(tt(IP-RECV:))) Opens a raw IP socket of link()(TYPE_PROTOCOL). Depending on option link(pf)(OPTION_PROTOCOL_FAMILY), IP protocol version 4 or 6 is used. It receives packets from multiple unspecified peers and merges the data. - No replies are possible. + No replies are possible, this is a read-only address, see options link(-u)(option_u) and + link(-U)(option_U), and link(dual addresses)(ADDRESS_DUAL). It can be, e.g., addressed by socat IP-SENDTO address peers. Protocol 255 uses the raw socket with the IP header being part of the data.nl() @@ -1014,10 +1016,14 @@ label(ADDRESS_SOCKS5_LISTEN)dit(bf(tt(SOCKS5-LISTEN::: label(ADDRESS_STDERR)dit(bf(tt(STDERR))) Uses file descriptor 2.nl() + This is a write-only address, see options link(-u)(option_u) and + link(-U)(option_U), and link(dual addresses)(ADDRESS_DUAL).nl() Option groups: link(FD)(GROUP_FD) (link(TERMIOS)(GROUP_TERMIOS),link(REG)(GROUP_REG),link(SOCKET)(GROUP_SOCKET)) nl() See also: link(FD)(ADDRESS_FD) label(ADDRESS_STDIN)dit(bf(tt(STDIN))) Uses file descriptor 0.nl() + This is a read-only address, see options link(-u)(option_u) and + link(-U)(option_U), and link(dual addresses)(ADDRESS_DUAL).nl() Option groups: link(FD)(GROUP_FD) (link(TERMIOS)(GROUP_TERMIOS),link(REG)(GROUP_REG),link(SOCKET)(GROUP_SOCKET)) nl() Useful options: link(readbytes)(OPTION_READBYTES)nl() @@ -1030,6 +1036,8 @@ label(ADDRESS_STDIO)dit(bf(tt(STDIO))) See also: link(FD)(ADDRESS_FD) label(ADDRESS_STDOUT)dit(bf(tt(STDOUT))) Uses file descriptor 1.nl() + This is a write-only address, see options link(-u)(option_u) and + link(-U)(option_U), and link(dual addresses)(ADDRESS_DUAL).nl() Option groups: link(FD)(GROUP_FD) (link(TERMIOS)(GROUP_TERMIOS),link(REG)(GROUP_REG),link(SOCKET)(GROUP_SOCKET)) nl() See also: link(FD)(ADDRESS_FD) label(ADDRESS_SYSTEM)dit(bf(tt(SYSTEM:))) @@ -1326,7 +1334,11 @@ label(ADDRESS_UDP_RECV)dit(bf(tt(UDP-RECV:))) Creates a UDP socket on [link(UDP service)(TYPE_UDP_SERVICE)] using UDP/IP version 4 or 6 depending on option link(pf)(OPTION_PROTOCOL_FAMILY). It receives packets from multiple unspecified peers and merges the data. - No replies are possible. It works well with, e.g., socat link(UDP-SENDTO)(ADDRESS_UDP_SENDTO) address peers; it behaves similar to a syslog server.nl() + No replies are possible. It works well with, e.g., socat + link(UDP-SENDTO)(ADDRESS_UDP_SENDTO) address peers; it behaves similar to a + syslog server.nl() + This is a read-only address, see options link(-u)(option_u) and + link(-U)(option_U), and link(dual addresses)(ADDRESS_DUAL).nl() Note: if you need the link(fork)(OPTION_FORK) option, use link(UDP-RECVFROM)(ADDRESS_UDP_RECVFROM) in unidirectional mode (with link(option -u)(option_u)) instead.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(IP4)(GROUP_IP4),link(IP6)(GROUP_IP6),link(RANGE)(GROUP_RANGE) nl() Useful options: @@ -1426,7 +1438,9 @@ label(ADDRESS_UNIX_RECVFROM)dit(bf(tt(UNIX-RECVFROM:))) label(ADDRESS_UNIX_RECV)dit(bf(tt(UNIX-RECV:))) Creates a unixdomain() datagram socket [link()(TYPE_FILENAME)]. Receives packets from multiple unspecified peers and merges the data. - No replies are possible. It can be, e.g., addressed by socat UNIX-SENDTO address peers. + No replies are possible, this is a read-only address, see options link(-u)(option_u) and + link(-U)(option_U), and link(dual addresses)(ADDRESS_DUAL). + It can be, e.g., addressed by socat UNIX-SENDTO address peers. It behaves similar to a syslog server.nl() Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET),link(NAMED)(GROUP_NAMED),link(UNIX)(GROUP_SOCK_UNIX) nl() See also: diff --git a/test.sh b/test.sh index 944d6f1..bf2be0e 100755 --- a/test.sh +++ b/test.sh @@ -3526,6 +3526,7 @@ while read NAMEKEYW FEAT RUNS TESTTMPL PEERTMPL WAITTMPL; do if [ -z "$NAMEKEYW" ] || [[ "$NAMEKEYW" == \#* ]]; then continue; fi export ts="$td/test$N.socket" +case $RUNS in tcp4|tcp6) newport $RUNS;; esac WAITTMPL="$(echo "$WAITTMPL" |sed -e 's/\040/ /g')" TESTADDR=$(eval echo $TESTTMPL) PEERADDR=$(eval echo $PEERTMPL) @@ -3542,11 +3543,11 @@ TEST="$NAME: $TESTKEYW half close" # connecting socat brings the result of od if ! eval $NUMCOND; then :; elif [ "$FEAT" != ',' ] && ! testfeats "$FEAT" >/dev/null; then - $PRINTF "test $F_n $TEST... ${YELLOW}$FEAT not available${NORMAL}\n" $N + $PRINTF "test $F_n $TEST... ${YELLOW}Feature $FEAT not configured${NORMAL}\n" $N numCANT=$((numCANT+1)) listCANT="$listCANT $N" elif ! runs$RUNS >/dev/null; then - $PRINTF "test $F_n $TEST... ${YELLOW}$RUNS not available${NORMAL}\n" $N + $PRINTF "test $F_n $TEST... ${YELLOW}$RUNS not available$ on host${NORMAL}\n" $N numCANT=$((numCANT+1)) listCANT="$listCANT $N" else @@ -16882,11 +16883,7 @@ elif ! o=$(testoptions so-reuseaddr fork) >/dev/null; then numCANT=$((numCANT+1)) listCANT="$listCANT $N" elif ! runsip4 >/dev/null; then - $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N - numCANT=$((numCANT+1)) - listCANT="$listCANT $N" -elif ! runsip4 >/dev/null; then - $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available${NORMAL}\n" $N + $PRINTF "test $F_n $TEST... ${YELLOW}IPv4 not available on host${NORMAL}\n" $N numCANT=$((numCANT+1)) listCANT="$listCANT $N" elif [ -z "$FOREIGN" ]; then diff --git a/xio-creat.c b/xio-creat.c index de5faac..e5b197a 100644 --- a/xio-creat.c +++ b/xio-creat.c @@ -17,7 +17,7 @@ static int xioopen_creat(int arg, const char *argv[], struct opt *opts, int rw, /*! within stream model, this is a write-only address - use 2 instead of 3 */ -const struct addrdesc xioaddr_creat = { "CREATE", 3, xioopen_creat, GROUP_FD|GROUP_NAMED|GROUP_FILE, 0, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_creat = { "CREATE", 1+XIO_WRONLY, xioopen_creat, GROUP_FD|GROUP_NAMED|GROUP_FILE, 0, 0, 0 HELP(":") }; /* retrieve the mode option and perform the creat() call. diff --git a/xio-rawip.c b/xio-rawip.c index 9bad320..fe05e95 100644 --- a/xio-rawip.c +++ b/xio-rawip.c @@ -39,23 +39,23 @@ int _xioopen_rawip_sendto(const char *hostname, const char *protname, struct opt *opts, int xioflags, xiofile_t *xxfd, groups_t groups, int *pf); -const struct addrdesc xioaddr_rawip_sendto = { "IP-SENDTO", 3, xioopen_rawip_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6, PF_UNSPEC, 0, 0 HELP("::") }; -const struct addrdesc xioaddr_rawip_datagram= { "IP-DATAGRAM", 3, xioopen_rawip_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_RANGE, PF_UNSPEC, 0, 0 HELP("::") }; -const struct addrdesc xioaddr_rawip_recvfrom= { "IP-RECVFROM", 3, xioopen_rawip_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_CHILD|GROUP_RANGE, PF_UNSPEC, SOCK_RAW, 0 HELP(":") }; -const struct addrdesc xioaddr_rawip_recv = { "IP-RECV", 1, xioopen_rawip_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_RANGE, PF_UNSPEC, SOCK_RAW, 0 HELP(":") }; +const struct addrdesc xioaddr_rawip_sendto = { "IP-SENDTO", 1+XIO_RDWR, xioopen_rawip_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6, PF_UNSPEC, 0, 0 HELP("::") }; +const struct addrdesc xioaddr_rawip_datagram= { "IP-DATAGRAM", 1+XIO_RDWR, xioopen_rawip_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_RANGE, PF_UNSPEC, 0, 0 HELP("::") }; +const struct addrdesc xioaddr_rawip_recvfrom= { "IP-RECVFROM", 1+XIO_RDWR, xioopen_rawip_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_CHILD|GROUP_RANGE, PF_UNSPEC, SOCK_RAW, 0 HELP(":") }; +const struct addrdesc xioaddr_rawip_recv = { "IP-RECV", 1+XIO_RDONLY, xioopen_rawip_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_RANGE, PF_UNSPEC, SOCK_RAW, 0 HELP(":") }; #if WITH_IP4 -const struct addrdesc xioaddr_rawip4_sendto = { "IP4-SENDTO", 3, xioopen_rawip_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4, PF_INET, 0, 0 HELP("::") }; -const struct addrdesc xioaddr_rawip4_datagram= { "IP4-DATAGRAM", 3, xioopen_rawip_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_RANGE, PF_INET, 0, 0 HELP("::") }; -const struct addrdesc xioaddr_rawip4_recvfrom= { "IP4-RECVFROM", 3, xioopen_rawip_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_CHILD|GROUP_RANGE, PF_INET, SOCK_RAW, 0 HELP(":") }; -const struct addrdesc xioaddr_rawip4_recv = { "IP4-RECV", 1, xioopen_rawip_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_RANGE, PF_INET, SOCK_RAW, 0 HELP(":") }; +const struct addrdesc xioaddr_rawip4_sendto = { "IP4-SENDTO", 1+XIO_RDWR, xioopen_rawip_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4, PF_INET, 0, 0 HELP("::") }; +const struct addrdesc xioaddr_rawip4_datagram= { "IP4-DATAGRAM", 1+XIO_RDWR, xioopen_rawip_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_RANGE, PF_INET, 0, 0 HELP("::") }; +const struct addrdesc xioaddr_rawip4_recvfrom= { "IP4-RECVFROM", 1+XIO_RDWR, xioopen_rawip_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_CHILD|GROUP_RANGE, PF_INET, SOCK_RAW, 0 HELP(":") }; +const struct addrdesc xioaddr_rawip4_recv = { "IP4-RECV", 1+XIO_RDONLY, xioopen_rawip_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_RANGE, PF_INET, SOCK_RAW, 0 HELP(":") }; #endif #if WITH_IP6 -const struct addrdesc xioaddr_rawip6_sendto = { "IP6-SENDTO", 3, xioopen_rawip_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6, PF_INET6, 0, 0 HELP("::") }; -const struct addrdesc xioaddr_rawip6_datagram= { "IP6-DATAGRAM", 3, xioopen_rawip_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_RANGE, PF_INET6, 0, 0 HELP("::") }; -const struct addrdesc xioaddr_rawip6_recvfrom= { "IP6-RECVFROM", 3, xioopen_rawip_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_CHILD|GROUP_RANGE, PF_INET6, SOCK_RAW, 0 HELP(":") }; -const struct addrdesc xioaddr_rawip6_recv = { "IP6-RECV", 1, xioopen_rawip_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_RANGE, PF_INET6, SOCK_RAW, 0 HELP(":") }; +const struct addrdesc xioaddr_rawip6_sendto = { "IP6-SENDTO", 1+XIO_RDWR, xioopen_rawip_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6, PF_INET6, 0, 0 HELP("::") }; +const struct addrdesc xioaddr_rawip6_datagram= { "IP6-DATAGRAM", 1+XIO_RDWR, xioopen_rawip_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_RANGE, PF_INET6, 0, 0 HELP("::") }; +const struct addrdesc xioaddr_rawip6_recvfrom= { "IP6-RECVFROM", 1+XIO_RDWR, xioopen_rawip_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_CHILD|GROUP_RANGE, PF_INET6, SOCK_RAW, 0 HELP(":") }; +const struct addrdesc xioaddr_rawip6_recv = { "IP6-RECV", 1+XIO_RDONLY, xioopen_rawip_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_RANGE, PF_INET6, SOCK_RAW, 0 HELP(":") }; #endif diff --git a/xio-socket.c b/xio-socket.c index e2397b8..26eda94 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -79,14 +79,14 @@ static int xiobind( #if WITH_GENERICSOCKET /* generic socket addresses */ -const struct addrdesc xioaddr_socket_connect = { "SOCKET-CONNECT", 1, xioopen_socket_connect, GROUP_FD|GROUP_SOCKET|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":::") }; +const struct addrdesc xioaddr_socket_connect = { "SOCKET-CONNECT", 1+XIO_RDWR, xioopen_socket_connect, GROUP_FD|GROUP_SOCKET|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":::") }; #if WITH_LISTEN -const struct addrdesc xioaddr_socket_listen = { "SOCKET-LISTEN", 1, xioopen_socket_listen, GROUP_FD|GROUP_SOCKET|GROUP_LISTEN|GROUP_RANGE|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":::") }; +const struct addrdesc xioaddr_socket_listen = { "SOCKET-LISTEN", 1+XIO_RDWR, xioopen_socket_listen, GROUP_FD|GROUP_SOCKET|GROUP_LISTEN|GROUP_RANGE|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":::") }; #endif /* WITH_LISTEN */ -const struct addrdesc xioaddr_socket_sendto = { "SOCKET-SENDTO", 3, xioopen_socket_sendto, GROUP_FD|GROUP_SOCKET, 0, 0, 0 HELP("::::") }; -const struct addrdesc xioaddr_socket_datagram= { "SOCKET-DATAGRAM", 3, xioopen_socket_datagram, GROUP_FD|GROUP_SOCKET|GROUP_RANGE, 0, 0, 0 HELP("::::") }; -const struct addrdesc xioaddr_socket_recvfrom= { "SOCKET-RECVFROM", 3, xioopen_socket_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_RANGE|GROUP_CHILD, 0, 0, 0 HELP("::::") }; -const struct addrdesc xioaddr_socket_recv = { "SOCKET-RECV", 1, xioopen_socket_recv, GROUP_FD|GROUP_SOCKET|GROUP_RANGE, 0, 0, 0 HELP("::::") }; +const struct addrdesc xioaddr_socket_sendto = { "SOCKET-SENDTO", 1+XIO_RDWR, xioopen_socket_sendto, GROUP_FD|GROUP_SOCKET, 0, 0, 0 HELP("::::") }; +const struct addrdesc xioaddr_socket_datagram= { "SOCKET-DATAGRAM", 1+XIO_RDWR, xioopen_socket_datagram, GROUP_FD|GROUP_SOCKET|GROUP_RANGE, 0, 0, 0 HELP("::::") }; +const struct addrdesc xioaddr_socket_recvfrom= { "SOCKET-RECVFROM", 1+XIO_RDWR, xioopen_socket_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_RANGE|GROUP_CHILD, 0, 0, 0 HELP("::::") }; +const struct addrdesc xioaddr_socket_recv = { "SOCKET-RECV", 1+XIO_RDONLY, xioopen_socket_recv, GROUP_FD|GROUP_SOCKET|GROUP_RANGE, 0, 0, 0 HELP("::::") }; #endif /* WITH_GENERICSOCKET */ diff --git a/xio-udp.c b/xio-udp.c index 5992da2..6c4d4c6 100644 --- a/xio-udp.c +++ b/xio-udp.c @@ -42,35 +42,35 @@ int _xioopen_udp_sendto(const char *hostname, const char *servname, int xioflags, xiofile_t *xxfd, groups_t groups, int pf, int socktype, int ipproto); -const struct addrdesc xioaddr_udp_connect = { "UDP-CONNECT", 3, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP, SOCK_DGRAM, IPPROTO_UDP, PF_UNSPEC HELP("::") }; +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("::") }; #if WITH_LISTEN -const struct addrdesc xioaddr_udp_listen = { "UDP-LISTEN", 3, 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(":") }; +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(":") }; #endif /* WITH_LISTEN */ -const struct addrdesc xioaddr_udp_sendto = { "UDP-SENDTO", 3, xioopen_udp_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP, PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; -const struct addrdesc xioaddr_udp_recvfrom = { "UDP-RECVFROM", 3, xioopen_udp_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_CHILD|GROUP_RANGE, PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP HELP(":") }; -const struct addrdesc xioaddr_udp_recv = { "UDP-RECV", 1, xioopen_udp_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_RANGE, PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP HELP(":") }; -const struct addrdesc xioaddr_udp_datagram = { "UDP-DATAGRAM", 3, xioopen_udp_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_RANGE, PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; +const struct addrdesc xioaddr_udp_sendto = { "UDP-SENDTO", 1+XIO_RDWR, xioopen_udp_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP, PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; +const struct addrdesc xioaddr_udp_recvfrom = { "UDP-RECVFROM", 1+XIO_RDWR, xioopen_udp_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_CHILD|GROUP_RANGE, PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP HELP(":") }; +const struct addrdesc xioaddr_udp_recv = { "UDP-RECV", 1+XIO_RDONLY, xioopen_udp_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_RANGE, PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP HELP(":") }; +const struct addrdesc xioaddr_udp_datagram = { "UDP-DATAGRAM", 1+XIO_RDWR, xioopen_udp_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_RANGE, PF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; #if WITH_IP4 -const struct addrdesc xioaddr_udp4_connect = { "UDP4-CONNECT", 3, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP, SOCK_DGRAM, IPPROTO_UDP, PF_INET HELP("::") }; +const struct addrdesc xioaddr_udp4_connect = { "UDP4-CONNECT", 1+XIO_RDWR, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP, SOCK_DGRAM, IPPROTO_UDP, PF_INET HELP("::") }; #if WITH_LISTEN -const struct addrdesc xioaddr_udp4_listen = { "UDP4-LISTEN", 3, xioopen_ipdgram_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE, PF_INET, IPPROTO_UDP, PF_INET HELP(":") }; +const struct addrdesc xioaddr_udp4_listen = { "UDP4-LISTEN", 1+XIO_RDWR, xioopen_ipdgram_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE, PF_INET, IPPROTO_UDP, PF_INET HELP(":") }; #endif /* WITH_LISTEN */ -const struct addrdesc xioaddr_udp4_sendto = { "UDP4-SENDTO", 3, xioopen_udp_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP, PF_INET, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; -const struct addrdesc xioaddr_udp4_datagram = { "UDP4-DATAGRAM",3, xioopen_udp_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP|GROUP_RANGE, PF_INET, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; -const struct addrdesc xioaddr_udp4_recvfrom = { "UDP4-RECVFROM", 3, xioopen_udp_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP|GROUP_CHILD|GROUP_RANGE, PF_INET, SOCK_DGRAM, IPPROTO_UDP HELP(":") }; -const struct addrdesc xioaddr_udp4_recv = { "UDP4-RECV", 1, xioopen_udp_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP|GROUP_RANGE, PF_INET, SOCK_DGRAM, IPPROTO_UDP HELP(":") }; +const struct addrdesc xioaddr_udp4_sendto = { "UDP4-SENDTO", 1+XIO_RDWR, xioopen_udp_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP, PF_INET, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; +const struct addrdesc xioaddr_udp4_datagram = { "UDP4-DATAGRAM", 1+XIO_RDWR, xioopen_udp_datagram, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP|GROUP_RANGE, PF_INET, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; +const struct addrdesc xioaddr_udp4_recvfrom= { "UDP4-RECVFROM", 1+XIO_RDWR, xioopen_udp_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP|GROUP_CHILD|GROUP_RANGE, PF_INET, SOCK_DGRAM, IPPROTO_UDP HELP(":") }; +const struct addrdesc xioaddr_udp4_recv = { "UDP4-RECV", 1+XIO_RDONLY, xioopen_udp_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP4|GROUP_IP_UDP|GROUP_RANGE, PF_INET, SOCK_DGRAM, IPPROTO_UDP HELP(":") }; #endif /* WITH_IP4 */ #if WITH_IP6 -const struct addrdesc xioaddr_udp6_connect = { "UDP6-CONNECT", 3, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP, SOCK_DGRAM, IPPROTO_UDP, PF_INET6 HELP("::") }; +const struct addrdesc xioaddr_udp6_connect = { "UDP6-CONNECT", 1+XIO_RDWR, xioopen_ipapp_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP, SOCK_DGRAM, IPPROTO_UDP, PF_INET6 HELP("::") }; #if WITH_LISTEN -const struct addrdesc xioaddr_udp6_listen = { "UDP6-LISTEN", 3, xioopen_ipdgram_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE, PF_INET6, IPPROTO_UDP, 0 HELP(":") }; +const struct addrdesc xioaddr_udp6_listen = { "UDP6-LISTEN", 1+XIO_RDWR, xioopen_ipdgram_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_LISTEN|GROUP_CHILD|GROUP_RANGE, PF_INET6, IPPROTO_UDP, 0 HELP(":") }; #endif /* WITH_LISTEN */ -const struct addrdesc xioaddr_udp6_sendto = { "UDP6-SENDTO", 3, xioopen_udp_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP, PF_INET6, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; -const struct addrdesc xioaddr_udp6_datagram = { "UDP6-DATAGRAM", 3, xioopen_udp_datagram,GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_RANGE, PF_INET6, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; -const struct addrdesc xioaddr_udp6_recvfrom = { "UDP6-RECVFROM", 3, xioopen_udp_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_CHILD|GROUP_RANGE, PF_INET6, SOCK_DGRAM, IPPROTO_UDP HELP(":") }; -const struct addrdesc xioaddr_udp6_recv = { "UDP6-RECV", 1, xioopen_udp_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_RANGE, PF_INET6, SOCK_DGRAM, IPPROTO_UDP HELP(":") }; +const struct addrdesc xioaddr_udp6_sendto = { "UDP6-SENDTO", 1+XIO_RDWR, xioopen_udp_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP, PF_INET6, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; +const struct addrdesc xioaddr_udp6_datagram= { "UDP6-DATAGRAM", 1+XIO_RDWR, xioopen_udp_datagram,GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_RANGE, PF_INET6, SOCK_DGRAM, IPPROTO_UDP HELP("::") }; +const struct addrdesc xioaddr_udp6_recvfrom= { "UDP6-RECVFROM", 1+XIO_RDWR, xioopen_udp_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_CHILD|GROUP_RANGE, PF_INET6, SOCK_DGRAM, IPPROTO_UDP HELP(":") }; +const struct addrdesc xioaddr_udp6_recv = { "UDP6-RECV", 1+XIO_RDONLY, xioopen_udp_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_IP6|GROUP_IP_UDP|GROUP_RANGE, PF_INET6, SOCK_DGRAM, IPPROTO_UDP HELP(":") }; #endif /* WITH_IP6 */ diff --git a/xio-unix.c b/xio-unix.c index 1952c75..f5d6263 100644 --- a/xio-unix.c +++ b/xio-unix.c @@ -38,23 +38,23 @@ int xioopen_unix_client(int argc, const char *argv[], struct opt *opts, int xiof /* the first free parameter is 0 for "normal" unix domain sockets, or 1 for abstract unix sockets (Linux); the second and third free parameter are unsused */ -const struct addrdesc xioaddr_unix_connect = { "UNIX-CONNECT", 3, xioopen_unix_connect, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_unix_connect = { "UNIX-CONNECT", 1+XIO_RDWR, xioopen_unix_connect, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":") }; #if WITH_LISTEN -const struct addrdesc xioaddr_unix_listen = { "UNIX-LISTEN", 3, xioopen_unix_listen, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_unix_listen = { "UNIX-LISTEN", 1+XIO_RDWR, xioopen_unix_listen, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 0, 0, 0 HELP(":") }; #endif /* WITH_LISTEN */ -const struct addrdesc xioaddr_unix_sendto = { "UNIX-SENDTO", 3, xioopen_unix_sendto, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":") }; -const struct addrdesc xioaddr_unix_recvfrom= { "UNIX-RECVFROM", 3, xioopen_unix_recvfrom, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY|GROUP_CHILD, 0, 0, 0 HELP(":") }; -const struct addrdesc xioaddr_unix_recv = { "UNIX-RECV", 1, xioopen_unix_recv, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":") }; -const struct addrdesc xioaddr_unix_client = { "UNIX-CLIENT", 3, xioopen_unix_client, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_unix_sendto = { "UNIX-SENDTO", 1+XIO_RDWR, xioopen_unix_sendto, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_unix_recvfrom= { "UNIX-RECVFROM", 1+XIO_RDWR, xioopen_unix_recvfrom, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY|GROUP_CHILD, 0, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_unix_recv = { "UNIX-RECV", 1+XIO_RDONLY, xioopen_unix_recv, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_unix_client = { "UNIX-CLIENT", 1+XIO_RDWR, xioopen_unix_client, GROUP_FD|GROUP_NAMED|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 0, 0, 0 HELP(":") }; #if WITH_ABSTRACT_UNIXSOCKET -const struct addrdesc xioaddr_abstract_connect = { "ABSTRACT-CONNECT", 3, xioopen_unix_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_abstract_connect = { "ABSTRACT-CONNECT", 1+XIO_RDWR, xioopen_unix_connect, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":") }; #if WITH_LISTEN -const struct addrdesc xioaddr_abstract_listen = { "ABSTRACT-LISTEN", 3, xioopen_unix_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 1, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_abstract_listen = { "ABSTRACT-LISTEN", 1+XIO_RDWR, xioopen_unix_listen, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_LISTEN|GROUP_CHILD|GROUP_RETRY, 1, 0, 0 HELP(":") }; #endif /* WITH_LISTEN */ -const struct addrdesc xioaddr_abstract_sendto = { "ABSTRACT-SENDTO", 3, xioopen_unix_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":") }; -const struct addrdesc xioaddr_abstract_recvfrom= { "ABSTRACT-RECVFROM", 3, xioopen_unix_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY|GROUP_CHILD, 1, 0, 0 HELP(":") }; -const struct addrdesc xioaddr_abstract_recv = { "ABSTRACT-RECV", 1, xioopen_unix_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":") }; -const struct addrdesc xioaddr_abstract_client = { "ABSTRACT-CLIENT", 3, xioopen_unix_client, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_abstract_sendto = { "ABSTRACT-SENDTO", 1+XIO_RDWR, xioopen_unix_sendto, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_abstract_recvfrom= { "ABSTRACT-RECVFROM", 1+XIO_RDWR, xioopen_unix_recvfrom, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY|GROUP_CHILD, 1, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_abstract_recv = { "ABSTRACT-RECV", 1+XIO_RDONLY, xioopen_unix_recv, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":") }; +const struct addrdesc xioaddr_abstract_client = { "ABSTRACT-CLIENT", 1+XIO_RDWR, xioopen_unix_client, GROUP_FD|GROUP_SOCKET|GROUP_SOCK_UNIX|GROUP_RETRY, 1, 0, 0 HELP(":") }; #endif /* WITH_ABSTRACT_UNIXSOCKET */ const struct optdesc xioopt_unix_tightsocklen = { "unix-tightsocklen", "tightsocklen", OPT_UNIX_TIGHTSOCKLEN, GROUP_SOCK_UNIX, PH_PREBIND, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(para.socket.un.tight), XIO_SIZEOF(para.socket.un.tight) }; diff --git a/xioopen.c b/xioopen.c index ca93f88..7a49811 100644 --- a/xioopen.c +++ b/xioopen.c @@ -603,6 +603,7 @@ static xiosingle_t *xioparse_single(const char **addr) { int xioopen_single(xiofile_t *xfd, int xioflags) { struct single *sfd = &xfd->stream; const struct addrdesc *addrdesc; + const char *modetext[4] = { "none", "read-only", "write-only", "read-write" } ; int result; /* Values to be saved until xioopen() is finished */ #if HAVE_RESOLV_H @@ -642,6 +643,11 @@ int xioopen_single(xiofile_t *xfd, int xioflags) { return STAT_NORETRY; #endif /* HAVE_RESOLV_H */ + addrdesc = xfd->stream.addr; + /* Check if address supports required data directions */ + if (((xioflags+1)&XIO_ACCMODE) & ~(addrdesc->directions)) { + Warn2("address is opened in %s mode but only supports %s", modetext[(xioflags+1)&XIO_ACCMODE], modetext[addrdesc->directions]); + } if ((xioflags&XIO_ACCMODE) == XIO_RDONLY) { xfd->tag = XIO_TAG_RDONLY; } else if ((xioflags&XIO_ACCMODE) == XIO_WRONLY) { @@ -653,7 +659,6 @@ int xioopen_single(xiofile_t *xfd, int xioflags) { } xfd->stream.flags &= (~XIO_ACCMODE); xfd->stream.flags |= (xioflags & XIO_ACCMODE); - addrdesc = xfd->stream.addr; result = (*addrdesc->func)(xfd->stream.argc, xfd->stream.argv, xfd->stream.opts, xioflags, xfd, addrdesc->groups, addrdesc->arg1,