mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +00:00
Use PACKET_IGNORE_OUTGOING when available; a few corrections and renamings for raw sockets and ancillary messages
This commit is contained in:
parent
47af17dbf2
commit
11d1e9e11f
12 changed files with 185 additions and 42 deletions
6
CHANGES
6
CHANGES
|
@ -108,6 +108,10 @@ Porting:
|
|||
Removed Config/ because its contents have not been maintained for many
|
||||
years.
|
||||
|
||||
Try to not receive outgoing packets on raw (PF_PACKET) sockets - use
|
||||
PACKET_IGNORE_OUTGOING socket options when available.
|
||||
Test: INTERFACE_IGNOREOUTGOING
|
||||
|
||||
Testing:
|
||||
Removed obselete parts from test.sh
|
||||
|
||||
|
@ -117,6 +121,8 @@ Documentation:
|
|||
Added doc for option ipv6-join-group (ipv6-add-membership)
|
||||
Thanks to Martin Buck for sending the patch.
|
||||
|
||||
Renamed xiogetpacketsrc() to xiogetancillary()
|
||||
|
||||
####################### V 1.7.4.5 (not released):
|
||||
|
||||
Corrections:
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
"1.7.4.5+"
|
||||
"1.7.4.5+vlans"
|
||||
|
|
|
@ -285,8 +285,8 @@
|
|||
/* Define if you have the <linux/vm_sockets.h> header file. */
|
||||
#undef HAVE_LINUX_VM_SOCKETS_H
|
||||
|
||||
/* Define if you have the <netpacket/packet.h> header file. */
|
||||
#undef HAVE_NETPACKET_PACKET_H
|
||||
/* Define if you have the <linux/if_packet.h> header file. */
|
||||
#undef HAVE_LINUX_IF_PACKET_H
|
||||
|
||||
/* Define if you have the <netinet/if_ether.h> header file. */
|
||||
#undef HAVE_NETINET_IF_ETHER_H
|
||||
|
|
|
@ -321,10 +321,10 @@ AC_ARG_ENABLE(interface, [ --disable-interface disable network interface suppo
|
|||
esac],
|
||||
[AC_MSG_RESULT(yes); WITH_INTERFACE=1 ])
|
||||
if test "$WITH_INTERFACE"; then
|
||||
AC_CHECK_HEADER(netpacket/packet.h,
|
||||
AC_DEFINE(HAVE_NETPACKET_PACKET_H),
|
||||
AC_CHECK_HEADER(linux/if_packet.h,
|
||||
AC_DEFINE(HAVE_LINUX_IF_PACKET_H),
|
||||
[WITH_INTERFACE=;
|
||||
AC_MSG_WARN([include file netpacket/packet.h not found, disabling interface])])
|
||||
AC_MSG_WARN([include file linux/if_packet.h not found, disabling interface])])
|
||||
fi
|
||||
if test "$WITH_INTERFACE"; then
|
||||
AC_CHECK_HEADER(netinet/if_ether.h,
|
||||
|
|
|
@ -389,7 +389,7 @@ label(ADDRESS_IP_SENDTO)dit(bf(tt(IP-SENDTO:<host>:<protocol>)))
|
|||
label(ADDRESS_INTERFACE)dit(bf(tt(INTERFACE:<interface>)))
|
||||
Communicates with a network connected on an interface using raw packets
|
||||
including link level data. link(<interface>)(TYPE_INTERFACE) is the name of
|
||||
the network interface. Currently only available on Linux.
|
||||
the network interface. Currently only available on Linux.nl()
|
||||
Option groups: link(FD)(GROUP_FD),link(SOCKET)(GROUP_SOCKET) nl()
|
||||
Useful options:
|
||||
link(pf)(OPTION_PROTOCOL_FAMILY),
|
||||
|
|
|
@ -141,8 +141,8 @@
|
|||
#if HAVE_LINUX_ERRQUEUE_H
|
||||
#include <linux/errqueue.h> /* struct sock_extended_err */
|
||||
#endif
|
||||
#if HAVE_NETPACKET_PACKET_H
|
||||
#include <netpacket/packet.h>
|
||||
#if HAVE_LINUX_IF_PACKET_H
|
||||
#include <linux/if_packet.h>
|
||||
#endif
|
||||
#if HAVE_NETINET_IF_ETHER_H
|
||||
#include <netinet/if_ether.h>
|
||||
|
|
117
test.sh
117
test.sh
|
@ -760,7 +760,8 @@ testaddrs () {
|
|||
local a A;
|
||||
for a in $@; do
|
||||
A=$(echo "$a" |tr 'a-z' 'A-Z')
|
||||
if ! $SOCAT $A /dev/null 2>&1 </dev/null |grep -q "E unknown device/address"; then
|
||||
# the ::::: forces syntax errer and prevents the address from doing anything
|
||||
if ! $SOCAT $A::::: /dev/null 2>&1 </dev/null |grep -q "E unknown device/address"; then
|
||||
shift
|
||||
continue
|
||||
fi
|
||||
|
@ -9468,9 +9469,10 @@ elif ! grep "ancillary message: $SCM_TYPE: $SCM_NAME=$SCM_VALUE\$" ${te}0 >/dev/
|
|||
listFAIL="$listFAIL $N"
|
||||
else
|
||||
$PRINTF "$OK\n"
|
||||
if [ -n "$debug" ]; then
|
||||
grep " $LEVELS " "${te}0"; echo; grep " $LEVELS " "${te}1";
|
||||
fi
|
||||
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
|
||||
if [ "$DEBUG" ]; then grep " $LEVELS " "${te}0" >&2; fi
|
||||
if [ "$VERBOSE" ]; then echo "echo XYZ |$CMD1"; fi
|
||||
if [ "$DEBUG" ]; then grep " $LEVELS " "${te}1" >&2; fi
|
||||
numOK=$((numOK+1))
|
||||
fi
|
||||
else # option is not supported
|
||||
|
@ -9716,9 +9718,10 @@ elif ! expr "$(cat "$tf")" : "$SCM_VALUE\$" >/dev/null; then
|
|||
listFAIL="$listFAIL $N"
|
||||
else
|
||||
$PRINTF "$OK\n"
|
||||
if [ -n "$debug" ]; then
|
||||
cat "${te}0"; echo; cat "${te}1";
|
||||
fi
|
||||
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
|
||||
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
|
||||
if [ "$VERBOSE" ]; then echo "{ echo XYZ; sleep 0.1; } |$CMD1"; fi
|
||||
if [ "$DEBUG" ]; then cat "${te}1" >&2; fi
|
||||
numOK=$((numOK+1))
|
||||
fi
|
||||
else # option is not supported
|
||||
|
@ -13148,7 +13151,6 @@ fi
|
|||
fi ;; # NUMCOND, feats
|
||||
esac
|
||||
N=$((N+1))
|
||||
set +vx
|
||||
|
||||
# test the DTLS server feature
|
||||
NAME=OPENSSL_DTLS_SERVER
|
||||
|
@ -15590,6 +15592,99 @@ esac
|
|||
N=$((N+1))
|
||||
|
||||
|
||||
# Socats INTERFACE address has to ignore outgoing packets if possible.
|
||||
# On Linux is uses socket option PACKET_IGNORE_OUTGOING or it queries per
|
||||
# packet the PACKET_OUTGOING flag of struct sockaddr_ll.sll_pkttype
|
||||
NAME=INTERFACE_IGNOREOUTGOING
|
||||
case "$TESTS" in
|
||||
*%$N%*|*%functions%*|*%interface%*|*%tun%*|*%root%*|*%$NAME%*)
|
||||
TEST="$NAME: INTERFACE ignores outgoing packets"
|
||||
#idea: create a TUN interface and hook with INTERFACE.
|
||||
# Send a packet out the interface, should not be seen by INTERFACE
|
||||
if ! eval $NUMCOND; then :;
|
||||
elif [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}must be root${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif ! $(type ping >/dev/null 2>&1); then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}ping not available${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif ! feat=$(testfeats TUN STDIO INTERFACE); then
|
||||
$PRINTF "test $F_n $TEST... ${YELLOW}$feat not available${NORMAL}\n" $N
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif ! A=$(testaddrs - TUN STDIO INTERFACE); 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 iff-up tun-type tun-name ) >/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"
|
||||
tl="$td/test$N.lock"
|
||||
da="$(date) $RANDOM"
|
||||
TUNNET=10.255.255
|
||||
TUNNAME=tun9
|
||||
CMD0="$TRACE $SOCAT $opts -L $tl TUN:$TUNNET.1/24,iff-up=1,tun-type=tun,tun-name=$TUNNAME -"
|
||||
CMD1="$TRACE $SOCAT $opts -u INTERFACE:$TUNNAME -"
|
||||
CMD2="ping -c 1 -w 1 -b $TUNNET.255"
|
||||
printf "test $F_n $TEST... " $N
|
||||
sleep 1 |$CMD0 2>"${te}0" >/dev/null &
|
||||
pid0="$!"
|
||||
#waitinterface "$TUNNAME"
|
||||
usleep $MICROS
|
||||
$CMD1 >"${tf}1" 2>"${te}1" &
|
||||
pid1="$!"
|
||||
usleep $MICROS
|
||||
$CMD2 2>"${te}2" 1>&2
|
||||
kill $pid1 2>/dev/null
|
||||
usleep $MICROS
|
||||
kill $pid0 2>/dev/null
|
||||
wait
|
||||
if [ $? -ne 0 ]; then
|
||||
$PRINTF "$FAILED: $TRACE $SOCAT:\n"
|
||||
echo "$CMD0 &"
|
||||
cat "${te}0" >&2
|
||||
echo "$CMD1"
|
||||
cat "${te}1" >&2
|
||||
echo "$CMD2"
|
||||
cat "${te}2" >&2
|
||||
numCANT=$((numCANT+1))
|
||||
listCANT="$listCANT $N"
|
||||
elif test -s "${tf}1"; then
|
||||
$PRINTF "$FAILED\n"
|
||||
echo "$CMD0 &"
|
||||
cat "${te}0" >&2
|
||||
echo "$CMD1"
|
||||
cat "${te}1" >&2
|
||||
echo "$CMD2"
|
||||
cat "${te}2" >&2
|
||||
numFAIL=$((numFAIL+1))
|
||||
listFAIL="$listFAIL $N"
|
||||
else
|
||||
$PRINTF "$OK\n"
|
||||
if [ "$VERBOSE" ]; then echo "$CMD0 &"; fi
|
||||
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
|
||||
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, feats
|
||||
esac
|
||||
PORT=$((PORT+1))
|
||||
N=$((N+1))
|
||||
|
||||
# end of common tests
|
||||
|
||||
##################################################################################
|
||||
|
@ -15694,9 +15789,11 @@ if [ "$OPT_EXPECT_FAIL" ]; then
|
|||
grep "^< " "$td/failed.diff" |awk '{print($2);}' >"$td/ok.unexp"
|
||||
ln -s "$td/ok.unexp" .
|
||||
echo "OK unexpected: $(cat "$td/ok.unexp" |xargs echo)"
|
||||
else
|
||||
touch "$td/failed.diff"
|
||||
fi
|
||||
listFAIL=$(cat "$td/failed.lst" |xargs echo)
|
||||
numFAIL="$(wc -l "$td/failed.lst" |awk '{print($1);}')"
|
||||
#listFAIL=$(cat "$td/failed.lst" |xargs echo)
|
||||
#numFAIL="$(wc -l "$td/failed.lst" |awk '{print($1);}')"
|
||||
|
||||
! test -s "$td/failed.unexp"
|
||||
exit
|
||||
|
|
|
@ -111,13 +111,14 @@ int _xioopen_interface(const char *ifname,
|
|||
_xiointerface_apply_iff(xfd->fd, ifname, xfd->para.interface.iff_opts);
|
||||
|
||||
#ifdef PACKET_IGNORE_OUTGOING
|
||||
/* Raw socket may even provide packets that are outbound - we are not
|
||||
/* Raw socket might also provide packets that are outbound - we are not
|
||||
interested in these and disable this "feature" in kernel if possible */
|
||||
if (Setsockopt(xfd->fd, SOL_PACKET, PACKET_IGNORE_OUTGOING, &one, sizeof(one)) < 0) {
|
||||
Warn2("setsockopt(%d, SOL_PACKET, PACKET_IGNORE_OUTGOING, {1}): %s",
|
||||
xfd->fd, strerror(errno));
|
||||
}
|
||||
#endif
|
||||
#endif /*defined(PACKET_IGNORE_OUTGOING) */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
12
xio-socket.c
12
xio-socket.c
|
@ -25,6 +25,7 @@
|
|||
#endif /* WITH_IP6 */
|
||||
#include "xio-ip.h"
|
||||
#include "xio-listen.h"
|
||||
#include "xio-interface.h"
|
||||
#include "xio-ipapp.h" /*! not clean */
|
||||
#include "xio-tcpwrap.h"
|
||||
|
||||
|
@ -733,7 +734,7 @@ int xiogetpacketinfo(int fd)
|
|||
#if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN
|
||||
msgh.msg_controllen = sizeof(ctrlbuff);
|
||||
#endif
|
||||
if (xiogetpacketsrc(fd,
|
||||
if (xiogetancillary(fd,
|
||||
&msgh,
|
||||
MSG_ERRQUEUE
|
||||
#ifdef MSG_TRUNC
|
||||
|
@ -1078,7 +1079,7 @@ int _xioopen_dgram_sendto(/* them is already in xfd->peersa */
|
|||
applyopts_named(us->un.sun_path, opts, PH_LATE);
|
||||
}
|
||||
#endif
|
||||
applyopts(xfd->fd, opts, PH_LATE);
|
||||
/*applyopts(xfd->fd, opts, PH_LATE);*/
|
||||
|
||||
/* xfd->dtype = DATA_RECVFROM; *//* no, the caller must set this (ev _SKIPIP) */
|
||||
Notice1("successfully prepared local socket %s",
|
||||
|
@ -1244,7 +1245,7 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
|||
#if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN
|
||||
msgh.msg_controllen = sizeof(ctrlbuff);
|
||||
#endif
|
||||
while ((rc = xiogetpacketsrc(xfd->fd,
|
||||
while ((rc = xiogetancillary(xfd->fd,
|
||||
&msgh,
|
||||
MSG_PEEK
|
||||
#ifdef MSG_TRUNC
|
||||
|
@ -1431,8 +1432,9 @@ int retropt_socket_pf(struct opt *opts, int *pf) {
|
|||
In msgh the msg_name pointer must refer to an (empty) sockaddr storage.
|
||||
Returns STAT_OK on success, or STAT_RETRYLATER when an error occurred,
|
||||
including EINTR.
|
||||
(recvmsg() retrieves just meta info, not the data)
|
||||
*/
|
||||
int xiogetpacketsrc(int fd, struct msghdr *msgh, int flags) {
|
||||
int xiogetancillary(int fd, struct msghdr *msgh, int flags) {
|
||||
char peekbuff[1];
|
||||
#if HAVE_STRUCT_IOVEC
|
||||
struct iovec iovec;
|
||||
|
@ -1473,6 +1475,8 @@ int xiodopacketinfo(struct msghdr *msgh, bool withlog, bool withenv) {
|
|||
char valbuff[256], *valp;
|
||||
char envbuff[256], *envp;
|
||||
|
||||
Info3("ancillary message in xiodopacketinfo(): len="F_Zu", level=%d, type=%d",
|
||||
cmsg->cmsg_len, cmsg->cmsg_level, cmsg->cmsg_type);
|
||||
if (withlog) {
|
||||
xiodump(CMSG_DATA(cmsg),
|
||||
cmsg->cmsg_len-((char *)CMSG_DATA(cmsg)-(char *)cmsg),
|
||||
|
|
|
@ -84,6 +84,7 @@ extern
|
|||
char *xiogetifname(int ind, char *val, int ins);
|
||||
|
||||
extern int retropt_socket_pf(struct opt *opts, int *pf);
|
||||
extern int xiogetancillary(int fd, struct msghdr *msgh, int flags);
|
||||
|
||||
extern int xioopen_connect(struct single *fd,
|
||||
union sockaddr_union *us, size_t uslen,
|
||||
|
|
|
@ -81,7 +81,10 @@ int xioclose1(struct single *pipe) {
|
|||
#if WITH_INTERFACE
|
||||
case END_INTERFACE:
|
||||
{
|
||||
_xiointerface_set_iff(pipe->fd, pipe->para.interface.name, pipe->para.interface.save_iff);
|
||||
if (pipe->para.interface.name[0] != '\0') {
|
||||
_xiointerface_set_iff(pipe->fd, pipe->para.interface.name,
|
||||
pipe->para.interface.save_iff);
|
||||
}
|
||||
if (Close(pipe->fd) < 0) {
|
||||
Info2("close(%d): %s", pipe->fd, strerror(errno)); } break;
|
||||
}
|
||||
|
|
63
xioread.c
63
xioread.c
|
@ -42,7 +42,7 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) {
|
|||
|
||||
if (pipe->readbytes) {
|
||||
if (pipe->actbytes == 0) {
|
||||
Info("xioread(): readbytes consumed, inserting EOF");
|
||||
Info1("xioread(%d, ...): readbytes consumed, inserting EOF", pipe->fd);
|
||||
return 0; /* EOF by count */
|
||||
}
|
||||
|
||||
|
@ -135,6 +135,10 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) {
|
|||
#if _WITH_SOCKET
|
||||
case XIOREAD_RECV:
|
||||
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)",
|
||||
__func__);
|
||||
#if WITH_RAWIP || WITH_UDP || WITH_UNIX
|
||||
struct msghdr msgh = {0};
|
||||
union sockaddr_union from = {{0}};
|
||||
|
@ -151,8 +155,7 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) {
|
|||
#if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN
|
||||
msgh.msg_controllen = sizeof(ctrlbuff);
|
||||
#endif
|
||||
|
||||
while ((rc = xiogetpacketsrc(pipe->fd, &msgh,
|
||||
while ((rc = xiogetancillary(pipe->fd, &msgh,
|
||||
MSG_PEEK
|
||||
#ifdef MSG_TRUNC
|
||||
|MSG_TRUNC
|
||||
|
@ -161,6 +164,9 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) {
|
|||
errno == EINTR) ;
|
||||
if (rc < 0) return -1;
|
||||
|
||||
/* Note: we do not call xiodopacketinfo() and xiocheckpeer() here because
|
||||
that already happened in xioopen() / _xioopen_dgram_recvfrom() ... */
|
||||
|
||||
do {
|
||||
bytes =
|
||||
Recvfrom(pipe->fd, buff, bufsiz, 0, &from.soa, &fromlen);
|
||||
|
@ -175,16 +181,22 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) {
|
|||
errno = _errno;
|
||||
return -1;
|
||||
}
|
||||
/* on packet type we also receive outgoing packets, this is not desired
|
||||
*/
|
||||
#if defined(PF_PACKET) && defined(PACKET_OUTGOING)
|
||||
|
||||
#if defined(PF_PACKET) && !defined(PACKET_IGNORE_OUTGOING) && defined(PACKET_OUTGOING)
|
||||
/* In future versions there may be an option that controls receiving of
|
||||
outgoing packets, but currently it is hardcoded that we try to avoid
|
||||
them - either by once setting socket option PACKET_IGNORE_OUTGOING
|
||||
when available, otherwise by checking flag PACKET_OUTGOING per packet.
|
||||
*/
|
||||
if (from.soa.sa_family == PF_PACKET) {
|
||||
if ((from.ll.sll_pkttype & PACKET_OUTGOING)
|
||||
== 0) {
|
||||
errno = EAGAIN; return -1;
|
||||
if ((from.ll.sll_pkttype & PACKET_OUTGOING) != 0) {
|
||||
Info2("%s(fd=%d): ignoring outgoing packet", __func__, pipe->fd);
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
Debug2("%s(fd=%d): packet is not outgoing - process it", __func__, pipe->fd);
|
||||
}
|
||||
#endif /* defined(PF_PACKET) && defined(PACKET_OUTGOING) */
|
||||
#endif /* defined(PF_PACKET) && !defined(PACKET_IGNORE_OUTGOING) && defined(PACKET_OUTGOING) */
|
||||
|
||||
Notice2("received packet with "F_Zu" bytes from %s",
|
||||
bytes,
|
||||
|
@ -336,19 +348,24 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) {
|
|||
continue;
|
||||
}
|
||||
#endif
|
||||
#else /* !WITH_RAWIP */
|
||||
#else /* !(WITH_RAWIP || WITH_UDP || WITH_UNIX) */
|
||||
Fatal("address requires raw sockets, but they are not compiled in");
|
||||
return -1;
|
||||
#endif /* !WITH_RAWIP || WITH_UDP || WITH_UNIX */
|
||||
#endif /* !(WITH_RAWIP || WITH_UDP || WITH_UNIX) */
|
||||
|
||||
} else /* ~XIOREAD_RECV_FROM */ {
|
||||
union sockaddr_union from; socklen_t fromlen = sizeof(from);
|
||||
char infobuff[256];
|
||||
/* 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};
|
||||
union sockaddr_union from = {{ 0 }};
|
||||
socklen_t fromlen = sizeof(from);
|
||||
char infobuff[256];
|
||||
char ctrlbuff[1024]; /* ancillary messages */
|
||||
int rc;
|
||||
|
||||
socket_init(pipe->para.socket.la.soa.sa_family, &from);
|
||||
Debug1("%s(): XIOREAD_RECV and not XIOREAD_RECV_FROM (peer checks to be done)",
|
||||
__func__);
|
||||
|
||||
/* get source address */
|
||||
msgh.msg_name = &from;
|
||||
msgh.msg_namelen = fromlen;
|
||||
|
@ -358,7 +375,7 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) {
|
|||
#if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN
|
||||
msgh.msg_controllen = sizeof(ctrlbuff);
|
||||
#endif
|
||||
while ((rc = xiogetpacketsrc(pipe->fd, &msgh,
|
||||
while ((rc = xiogetancillary(pipe->fd, &msgh,
|
||||
MSG_PEEK
|
||||
#ifdef MSG_TRUNC
|
||||
|MSG_TRUNC
|
||||
|
@ -390,9 +407,23 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) {
|
|||
errno = _errno;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(PF_PACKET) && !defined(PACKET_IGNORE_OUTGOING) && defined(PACKET_OUTGOING)
|
||||
/* For remarks see similar section above */
|
||||
if (from.soa.sa_family == PF_PACKET) {
|
||||
if ((from.ll.sll_pkttype & PACKET_OUTGOING) != 0) {
|
||||
Info2("%s(fd=%d): ignoring outgoing packet", __func__, pipe->fd);
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
Debug2("%s(fd=%d): packet is not outgoing - process it", __func__, pipe->fd);
|
||||
}
|
||||
#endif /* defined(PF_PACKET) && !defined(PACKET_IGNORE_OUTGOING) && defined(PACKET_OUTGOING) */
|
||||
|
||||
Notice2("received packet with "F_Zu" bytes from %s",
|
||||
bytes,
|
||||
sockaddr_info(&from.soa, fromlen, infobuff, sizeof(infobuff)));
|
||||
|
||||
if (bytes == 0) {
|
||||
if (!pipe->para.socket.null_eof) {
|
||||
errno = EAGAIN; return -1;
|
||||
|
|
Loading…
Reference in a new issue