mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +00:00
New address SOCKETPAIR for echoing datagrams
This commit is contained in:
parent
f152c55584
commit
c311542e11
18 changed files with 285 additions and 13 deletions
6
CHANGES
6
CHANGES
|
@ -13,6 +13,12 @@ Features:
|
|||
The number of warnings has been reduced, e.g.removing a non existing
|
||||
file does in most cases no longer log a warning.
|
||||
|
||||
Added address type internal SOCKETPAIR. This is similar to the unnamed
|
||||
PIPE address (only for internal echoing) but it provides datagram mode
|
||||
(the default) and thus keeps packet boundaries.
|
||||
Tests: SOCKETPAIR_STREAM SOCKETPAIR_DATAGRAM SOCKETPAIR_SEQPACKET
|
||||
SOCKETPAIR_BOUNDARIES
|
||||
|
||||
New option -S <mask> controls catching and logging of signals that are
|
||||
not internally used by Socat.
|
||||
Tests: SIGTERM_NOLOG SIG31_LOG
|
||||
|
|
|
@ -45,7 +45,7 @@ XIOSRCS = xioinitialize.c xiohelp.c xioparam.c xiodiag.c xioopen.c xioopts.c \
|
|||
xiosignal.c xiosigchld.c xioread.c xiowrite.c \
|
||||
xiolayer.c xioshutdown.c xioclose.c xioexit.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-socketpair.c xio-gopen.c xio-creat.c xio-file.c xio-named.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-rawip.c \
|
||||
|
@ -64,7 +64,7 @@ HFILES = sycls.h sslcls.h error.h dalan.h procan.h filan.h hostan.h sysincludes.
|
|||
xioconfig.h mytypes.h xioopts.h xiodiag.h xiohelp.h xiosysincludes.h \
|
||||
xiomodes.h xiolayer.h xio-process.h xio-fd.h xio-fdnum.h xio-stdio.h \
|
||||
xio-named.h xio-file.h xio-creat.h xio-gopen.h xio-pipe.h \
|
||||
xio-socket.h xio-interface.h xio-listen.h xio-unix.h xio-vsock.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-ipapp.h xio-tcp.h xio-udp.h xio-sctp.h \
|
||||
xio-socks.h xio-proxy.h xio-progcall.h xio-exec.h \
|
||||
|
|
|
@ -692,6 +692,7 @@
|
|||
#undef WITH_GOPEN
|
||||
#undef WITH_TERMIOS
|
||||
#undef WITH_PIPE
|
||||
#undef WITH_SOCKETPAIR
|
||||
#undef WITH_UNIX
|
||||
#undef WITH_ABSTRACT_UNIXSOCKET
|
||||
#undef WITH_IP4
|
||||
|
|
|
@ -219,6 +219,14 @@ AC_ARG_ENABLE(pipe, [ --disable-pipe disable pipe support],
|
|||
esac],
|
||||
[AC_DEFINE(WITH_PIPE) AC_MSG_RESULT(yes)])
|
||||
|
||||
AC_MSG_CHECKING(whether to include explicit socketpair support)
|
||||
AC_ARG_ENABLE(socketpair, [ --disable-socketpair disable socketpair support],
|
||||
[case "$enableval" in
|
||||
no) AC_MSG_RESULT(no);;
|
||||
*) AC_DEFINE(WITH_SOCKETPAIR) AC_MSG_RESULT(yes);;
|
||||
esac],
|
||||
[AC_DEFINE(WITH_SOCKETPAIR) AC_MSG_RESULT(yes)])
|
||||
|
||||
AC_MSG_CHECKING(whether to include explicit termios support)
|
||||
AC_ARG_ENABLE(termios, [ --disable-termios disable termios support],
|
||||
[case "$enableval" in
|
||||
|
|
15
doc/socat.yo
15
doc/socat.yo
|
@ -682,13 +682,22 @@ label(ADDRESS_NAMED_PIPE)dit(bf(tt(PIPE:<filename>)))
|
|||
See also: link(unnamed pipe)(ADDRESS_UNNAMED_PIPE)
|
||||
label(ADDRESS_UNNAMED_PIPE)dit(bf(tt(PIPE)))
|
||||
Creates an unnamed pipe and uses it for reading and writing. It works as an
|
||||
echo, because everything written
|
||||
to it appeares immediately as read data.nl()
|
||||
echo, because everything written to it appeares immediately as read
|
||||
data.nl()
|
||||
Note: When socat tries to write more bytes than the pipe can queue (Linux
|
||||
2.4: 2048 bytes), socat might block. Consider, e.g., using
|
||||
option code(-b 2048) nl()
|
||||
Option groups: link(FD)(GROUP_FD) nl()
|
||||
See also: link(named pipe)(ADDRESS_NAMED_PIPE)
|
||||
See also: link(named pipe)(ADDRESS_NAMED_PIPE), link(SOCKETPAIR)(ADDRESS_SOCKETPAIR)
|
||||
label(ADDRESS_SOCKETPAIR)dit(bf(tt(SOCKETPAIR)))
|
||||
Creates a socketpair and uses it for reading and writing. It works as an
|
||||
echo, because everything written to it appeares immediately as read
|
||||
data. The default socket type is datagram, so it keeps packet boundaries.
|
||||
nl()
|
||||
Option groups: link(FD)(GROUP_FD) nl()
|
||||
Useful options:
|
||||
link(socktype)(OPTION_SO_TYPE)nl()
|
||||
See also: link(unnamed pipe)(ADDRESS_UNNAMED_PIPE)
|
||||
label(ADDRESS_PROXY_CONNECT)dit(bf(tt(PROXY:<proxy>:<hostname>:<port>)))
|
||||
Connects to an HTTP proxy server on port 8080 using TCP/IP version 4 or 6
|
||||
depending on address specification, name resolution, or option
|
||||
|
|
5
socat.c
5
socat.c
|
@ -540,6 +540,11 @@ void socat_version(FILE *fd) {
|
|||
#else
|
||||
fputs(" #undef WITH_PIPE\n", fd);
|
||||
#endif
|
||||
#ifdef WITH_SOCKETPAIR
|
||||
fprintf(fd, " #define WITH_SOCKETPAIR %d\n", WITH_SOCKETPAIR);
|
||||
#else
|
||||
fputs(" #undef WITH_SOCKETPAIR\n", fd);
|
||||
#endif
|
||||
#ifdef WITH_UNIX
|
||||
fprintf(fd, " #define WITH_UNIX %d\n", WITH_UNIX);
|
||||
#else
|
||||
|
|
102
test.sh
102
test.sh
|
@ -16546,6 +16546,108 @@ esac
|
|||
N=$((N+1))
|
||||
|
||||
|
||||
NAME=SOCKETPAIR_STREAM
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%stdio%*|*%socketpair%*|*%$NAME%*)
|
||||
TEST="$NAME: stdio and internal socketpair with stream"
|
||||
testecho "$N" "$TEST" "STDIO" "SOCKETPAIR" "$opts"
|
||||
esac
|
||||
N=$((N+1))
|
||||
|
||||
NAME=SOCKETPAIR_DATAGRAM
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%stdio%*|*%socketpair%*|*%$NAME%*)
|
||||
TEST="$NAME: stdio and internal socketpair with datagram"
|
||||
testecho "$N" "$TEST" "STDIO" "SOCKETPAIR,socktype=2" "$opts"
|
||||
esac
|
||||
N=$((N+1))
|
||||
|
||||
NAME=SOCKETPAIR_SEQPACKET
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%stdio%*|*%socketpair%*|*%$NAME%*)
|
||||
TEST="$NAME: stdio and internal socketpair with seqpacket"
|
||||
testecho "$N" "$TEST" "STDIO" "SOCKETPAIR,socktype=$SOCK_SEQPACKET" "$opts"
|
||||
esac
|
||||
N=$((N+1))
|
||||
|
||||
# Test if SOCKETPAIR address with SOCK_DGRAM keeps packet boundaries
|
||||
NAME=SOCKETPAIR_BOUNDARIES
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%socketpair%*|*%udp%*|*%udp4%*|*%ip4%*|*%dgram%*|*%$NAME%*)
|
||||
TEST="$NAME: Internal socketpair keeps packet boundaries"
|
||||
# Start a UDP4-DATAGRAM process that echoes data with datagram SOCKETPAIR;
|
||||
# a client sends two packets with 24 and ~18 bytes using a UDP4-DATAGRAM. The
|
||||
# client truncates packets to size 24, so when a large merged packet comes from
|
||||
# server some data will be lost. If the original data is received, the test
|
||||
# succeeded.
|
||||
if ! eval $NUMCOND; then :;
|
||||
elif ! F=$(testfeats STDIO IP4 UDP SOCKETPAIR); then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Feature $F not available in $SOCAT${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif ! A=$(testaddrs - STDIO UDP4-DATAGRAM SOCKETPAIR); then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Address $A not available in $SOCAT${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif ! o=$(testoptions bind socktype ) >/dev/null; then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}Option $o not available in $SOCAT${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
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
else
|
||||
tf="$td/test$N.stdout"
|
||||
te="$td/test$N.stderr"
|
||||
tdiff="$td/test$N.diff"
|
||||
ts1p=$PORT; PORT=$((PORT+1))
|
||||
ts2p=$PORT; PORT=$((PORT+1))
|
||||
da="test$N $(date) $RANDOM"
|
||||
CMD1="$TRACE $SOCAT $opts -T 0.2 UDP4-DATAGRAM:$LOCALHOST:$ts2p,bind=$LOCALHOST:$ts1p SOCKETPAIR,socktype=$SOCK_DGRAM"
|
||||
CMD2="$TRACE $SOCAT $opts -b 24 -t 0.2 -T 0.3 - UDP4-DATAGRAM:$LOCALHOST:$ts1p,bind=$LOCALHOST:$ts2p"
|
||||
printf "test $F_n $TEST... " $N
|
||||
export SOCAT_TRANSFER_WAIT=0.2
|
||||
$CMD1 2>"${te}1" &
|
||||
pid1="$!"
|
||||
unset SOCAT_TRANSFER_WAIT
|
||||
waitudp4port $ts1p 1
|
||||
{ echo -n "${da:0:20}"; usleep 100000; echo "${da:20}"; } |$CMD2 >>"$tf" 2>>"${te}2"
|
||||
rc2="$?"
|
||||
kill "$pid1" 2>/dev/null; wait;
|
||||
if [ "$rc2" -ne 0 ]; then
|
||||
$PRINTF "$FAILED (rc2=$rc2): $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\n"
|
||||
echo "$CMD1 &"
|
||||
cat "${te}1" >&2
|
||||
echo "$CMD2"
|
||||
cat "${te}2" >&2
|
||||
echo diff:
|
||||
cat "$tdiff"
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
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))
|
||||
|
||||
|
||||
# end of common tests
|
||||
|
||||
##################################################################################
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include "xio-named.h"
|
||||
|
||||
#include "xio-pipe.h"
|
||||
|
||||
|
||||
#if WITH_PIPE
|
||||
|
||||
|
@ -40,6 +42,7 @@ static int xioopen_fifo_unnamed(xiofile_t *sock, struct opt *opts) {
|
|||
sock->stream.dtype = XIODATA_PIPE;
|
||||
sock->stream.fd = filedes[0];
|
||||
sock->stream.para.bipipe.fdout = filedes[1];
|
||||
sock->stream.para.bipipe.socktype = SOCK_STREAM; /* due to socketpair reuse */
|
||||
applyopts_cloexec(sock->stream.fd, opts);
|
||||
applyopts_cloexec(sock->stream.para.bipipe.fdout, opts);
|
||||
|
||||
|
|
|
@ -7,6 +7,4 @@
|
|||
|
||||
extern const struct addrdesc xioaddr_pipe;
|
||||
|
||||
extern int xioopen_fifo_unnamed(char *arg, xiofile_t *sock);
|
||||
|
||||
#endif /* !defined(__xio_pipe_h_included) */
|
||||
|
|
|
@ -202,7 +202,6 @@ const struct optdesc opt_siocspgrp = { "siocspgrp", NULL, OPT_SIOCSPGRP, GRO
|
|||
const struct optdesc opt_bind = { "bind", NULL, OPT_BIND, GROUP_SOCKET, PH_BIND, TYPE_STRING,OFUNC_SPEC };
|
||||
const struct optdesc opt_connect_timeout = { "connect-timeout", NULL, OPT_CONNECT_TIMEOUT, GROUP_SOCKET, PH_PASTSOCKET, TYPE_TIMEVAL, OFUNC_OFFSET, XIO_OFFSETOF(para.socket.connect_timeout) };
|
||||
const struct optdesc opt_protocol_family = { "protocol-family", "pf", OPT_PROTOCOL_FAMILY, GROUP_SOCKET, PH_PRESOCKET, TYPE_STRING, OFUNC_SPEC };
|
||||
const struct optdesc opt_protocol = { "protocol", NULL, OPT_PROTOCOL, GROUP_SOCKET, PH_PRESOCKET, TYPE_STRING, OFUNC_SPEC };
|
||||
|
||||
/* generic setsockopt() options */
|
||||
const struct optdesc opt_setsockopt = { "setsockopt", "sockopt", OPT_SETSOCKOPT_BIN, GROUP_SOCKET,PH_CONNECTED, TYPE_INT_INT_BIN, OFUNC_SOCKOPT_GENERIC, 0, 0 };
|
||||
|
|
102
xio-socketpair.c
Normal file
102
xio-socketpair.c
Normal file
|
@ -0,0 +1,102 @@
|
|||
/* source: xio-socketpair.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 opening addresses of socketpair type */
|
||||
|
||||
#include "xiosysincludes.h"
|
||||
#include "xioopen.h"
|
||||
|
||||
#include "xio-named.h"
|
||||
|
||||
#include "xio-socketpair.h"
|
||||
|
||||
|
||||
#if WITH_SOCKETPAIR
|
||||
|
||||
static int xioopen_socketpair(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *xfd, groups_t groups, int dummy1, int dummy2, int dummy3);
|
||||
|
||||
|
||||
const struct addrdesc xioaddr_socketpair = { "SOCKETPAIR", 3, xioopen_socketpair, GROUP_FD|GROUP_SOCKET, 0, 0, 0 HELP(":<filename>") };
|
||||
|
||||
|
||||
/* open a socketpair */
|
||||
static int xioopen_socketpair(
|
||||
int argc,
|
||||
const char *argv[],
|
||||
struct opt *opts,
|
||||
int xioflags,
|
||||
xiofile_t *xfd,
|
||||
groups_t groups ,
|
||||
int dummy1,
|
||||
int dummy2,
|
||||
int dummy3)
|
||||
{
|
||||
struct single *sfd;
|
||||
struct opt *opts2;
|
||||
int pf = PF_UNIX;
|
||||
int protocol = 0;
|
||||
int filedes[2];
|
||||
int numleft;
|
||||
int result;
|
||||
|
||||
if (argc != 1) {
|
||||
Error2("%s: wrong number of parameters (%d instead of 1)", argv[0], argc-1);
|
||||
}
|
||||
|
||||
sfd = &xfd->stream;
|
||||
sfd->para.bipipe.socktype = SOCK_DGRAM;
|
||||
if (applyopts_single(sfd, opts, PH_INIT) < 0) return -1;
|
||||
applyopts(-1, opts, PH_INIT);
|
||||
retropt_int(opts, OPT_PROTOCOL_FAMILY, &pf);
|
||||
retropt_int(opts, OPT_SO_TYPE, &sfd->para.bipipe.socktype);
|
||||
retropt_int(opts, OPT_SO_PROTOTYPE, &protocol);
|
||||
|
||||
if (Socketpair(pf, sfd->para.bipipe.socktype, protocol, filedes) != 0) {
|
||||
Error5("socketpair(%d, %d, %d, %p): %s", pf, sfd->para.bipipe.socktype, protocol, filedes, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
Info2("socketpair({%d,%d})", filedes[0], filedes[1]);
|
||||
|
||||
sfd->tag = XIO_TAG_RDWR;
|
||||
if (sfd->para.bipipe.socktype == SOCK_STREAM) {
|
||||
sfd->dtype = XIOREAD_STREAM|XIOWRITE_PIPE;
|
||||
} else {
|
||||
sfd->dtype = XIOREAD_RECV|XIOREAD_RECV_NOCHECK|XIOWRITE_PIPE;
|
||||
}
|
||||
sfd->fd = filedes[0];
|
||||
sfd->para.bipipe.fdout = filedes[1];
|
||||
applyopts_cloexec(sfd->fd, opts);
|
||||
applyopts_cloexec(sfd->para.bipipe.fdout, opts);
|
||||
|
||||
/* one-time and input-direction options, no second application */
|
||||
retropt_bool(opts, OPT_IGNOREEOF, &sfd->ignoreeof);
|
||||
|
||||
/* here we copy opts! */
|
||||
if ((opts2 = copyopts(opts, GROUP_SOCKET)) == NULL) {
|
||||
return STAT_NORETRY;
|
||||
}
|
||||
|
||||
/* apply options to first FD */
|
||||
if ((result = applyopts(sfd->fd, opts, PH_ALL)) < 0) {
|
||||
return result;
|
||||
}
|
||||
if ((result = applyopts_single(sfd, opts, PH_ALL)) < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* apply options to second FD */
|
||||
if ((result = applyopts(sfd->para.bipipe.fdout, opts2, PH_ALL)) < 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if ((numleft = leftopts(opts)) > 0) {
|
||||
Error1("%d option(s) could not be used", numleft);
|
||||
showleft(opts);
|
||||
}
|
||||
Notice("writing to and reading from unnamed socketpair");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* WITH_SOCKETPAIR */
|
10
xio-socketpair.h
Normal file
10
xio-socketpair.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
/* source: xio-socketpair.h */
|
||||
/* Copyright Gerhard Rieger and contributors (see file CHANGES) */
|
||||
/* Published under the GNU General Public License V.2, see file COPYING */
|
||||
|
||||
#ifndef __xio_socketpair_h_included
|
||||
#define __xio_socketpair_h_included 1
|
||||
|
||||
const extern struct addrdesc xioaddr_socketpair;
|
||||
|
||||
#endif /* !defined(__xio_socketpair_h_included) */
|
4
xio.h
4
xio.h
|
@ -61,6 +61,7 @@ struct opt;
|
|||
#define XIOREAD_RECV_ONESHOT 0x0008 /* give EOF after first packet */
|
||||
#define XIOREAD_RECV_SKIPIP 0x0010 /* recv, skip IPv4 header */
|
||||
#define XIOREAD_RECV_FROM 0x0020 /* remember peer for replying */
|
||||
#define XIOREAD_RECV_NOCHECK 0x0040 /* do not check peer */
|
||||
|
||||
/* combinations */
|
||||
#define XIODATA_MASK (XIODATA_READMASK|XIODATA_WRITEMASK)
|
||||
|
@ -211,6 +212,7 @@ typedef struct single {
|
|||
union {
|
||||
struct {
|
||||
int fdout; /* use fd for output */
|
||||
int socktype;
|
||||
} bipipe;
|
||||
#if _WITH_SOCKET
|
||||
struct {
|
||||
|
@ -242,8 +244,8 @@ typedef struct single {
|
|||
} socket;
|
||||
#endif /* _WITH_SOCKET */
|
||||
struct {
|
||||
pid_t pid; /* child PID, with EXEC: */
|
||||
int fdout; /* use fd for output if two pipes */
|
||||
pid_t pid; /* child PID, with EXEC: */
|
||||
struct timeval sitout_eio;
|
||||
} exec;
|
||||
#if WITH_READLINE
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "xio-creat.h"
|
||||
#include "xio-gopen.h"
|
||||
#include "xio-pipe.h"
|
||||
#include "xio-socketpair.h"
|
||||
#if _WITH_SOCKET
|
||||
#include "xio-socket.h"
|
||||
#include "xio-listen.h"
|
||||
|
|
|
@ -193,6 +193,9 @@ const struct addrname addressnames[] = {
|
|||
{ "SOCKET-RECVFROM", &xioaddr_socket_recvfrom },
|
||||
{ "SOCKET-SENDTO", &xioaddr_socket_sendto },
|
||||
#endif
|
||||
#if WITH_SOCKETPAIR
|
||||
{ "SOCKETPAIR", &xioaddr_socketpair },
|
||||
#endif
|
||||
#if WITH_SOCKS4
|
||||
{ "SOCKS", &xioaddr_socks4_connect },
|
||||
{ "SOCKS4", &xioaddr_socks4_connect },
|
||||
|
|
|
@ -152,7 +152,6 @@ enum e_func {
|
|||
#define GROUP_FILE GROUP_REG
|
||||
#define GROUP_SOCKET 0x00000020
|
||||
#define GROUP_READLINE 0x00000040
|
||||
|
||||
#define GROUP_NAMED 0x00000100 /* file system entry */
|
||||
#define GROUP_OPEN 0x00000200 /* flags for open() */
|
||||
#define GROUP_EXEC 0x00000400 /* program or script execution */
|
||||
|
|
24
xioread.c
24
xioread.c
|
@ -134,7 +134,27 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) {
|
|||
|
||||
#if _WITH_SOCKET
|
||||
case XIOREAD_RECV:
|
||||
if (pipe->dtype & XIOREAD_RECV_FROM) {
|
||||
if (pipe->dtype & XIOREAD_RECV_NOCHECK) {
|
||||
/* No need to check peer address */
|
||||
do {
|
||||
bytes =
|
||||
Recv(pipe->fd, buff, bufsiz, 0);
|
||||
} while (bytes < 0 && errno == EINTR);
|
||||
if (bytes < 0) {
|
||||
_errno = errno;
|
||||
Error3("recvfrom(%d, %p, "F_Zu", 0", pipe->fd, buff, bufsiz);
|
||||
errno = _errno;
|
||||
return -1;
|
||||
}
|
||||
Notice1("received packet with "F_Zu" bytes", bytes);
|
||||
if (bytes == 0) {
|
||||
if (!pipe->para.socket.null_eof) {
|
||||
errno = EAGAIN; return -1;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
} else if (pipe->dtype & XIOREAD_RECV_FROM) {
|
||||
/* Receiving packets in addresses of RECVFROM types, the sender address
|
||||
has already been determined in OPEN phase. */
|
||||
Debug1("%s(): XIOREAD_RECV and XIOREAD_RECV_FROM (peer checks already done)",
|
||||
|
@ -375,7 +395,7 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) {
|
|||
return -1;
|
||||
#endif /* !(WITH_RAWIP || WITH_UDP || WITH_UNIX) */
|
||||
|
||||
} else /* ~XIOREAD_RECV_FROM */ {
|
||||
} else /* ~(XIOREAD_RECV_FROM|XIOREAD_RECV_FROM) */ {
|
||||
/* Receiving packets without planning to answer to the sender, but we
|
||||
might need sender info for some checks, thus we use recvfrom() */
|
||||
struct msghdr msgh = {0};
|
||||
|
|
|
@ -114,7 +114,11 @@ ssize_t xiowrite(xiofile_t *file, const void *buff, size_t bytes) {
|
|||
#endif /* _WITH_SOCKET */
|
||||
|
||||
case XIOWRITE_PIPE:
|
||||
if (pipe->para.bipipe.socktype == SOCK_STREAM) {
|
||||
writt = Write(pipe->para.bipipe.fdout, buff, bytes);
|
||||
} else {
|
||||
writt = Send(pipe->para.bipipe.fdout, buff, bytes, 0);
|
||||
}
|
||||
_errno = errno;
|
||||
if (writt < 0) {
|
||||
Error4("write(%d, %p, "F_Zu"): %s",
|
||||
|
|
Loading…
Reference in a new issue