mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 23:42:34 +00:00
Corrected handling of IP_RECVERR
This commit is contained in:
parent
bc32acb5fe
commit
d84c22be7a
6 changed files with 177 additions and 28 deletions
4
CHANGES
4
CHANGES
|
@ -50,6 +50,10 @@ Corrections:
|
||||||
|
|
||||||
Print a message when readbytes option causes EOF
|
Print a message when readbytes option causes EOF
|
||||||
|
|
||||||
|
The ip-recverr option had no effect. Corrected and improved its
|
||||||
|
handling of ancilliary messages, so it is able to analyze ICMP error
|
||||||
|
packets (Linux only?)
|
||||||
|
|
||||||
Testing:
|
Testing:
|
||||||
Prevent the TIMESTAMP tests from sporadically failing due do seconds
|
Prevent the TIMESTAMP tests from sporadically failing due do seconds
|
||||||
overflow
|
overflow
|
||||||
|
|
35
filan.c
35
filan.c
|
@ -35,6 +35,7 @@ bool filan_rawoutput;
|
||||||
|
|
||||||
int sockoptan(int fd, const struct sockopt *optname, int socklay, FILE *outfile);
|
int sockoptan(int fd, const struct sockopt *optname, int socklay, FILE *outfile);
|
||||||
int tcpan(int fd, FILE *outfile);
|
int tcpan(int fd, FILE *outfile);
|
||||||
|
int tcpan2(int fd, FILE *outfile);
|
||||||
const char *getfiletypestring(int st_mode);
|
const char *getfiletypestring(int st_mode);
|
||||||
|
|
||||||
static int printtime(FILE *outfile, time_t time);
|
static int printtime(FILE *outfile, time_t time);
|
||||||
|
@ -895,10 +896,44 @@ int tcpan(int fd, FILE *outfile) {
|
||||||
sockoptan(fd, optname, SOL_TCP, outfile);
|
sockoptan(fd, optname, SOL_TCP, outfile);
|
||||||
++optname;
|
++optname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tcpan2(fd, outfile);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* WITH_TCP */
|
#endif /* WITH_TCP */
|
||||||
|
|
||||||
|
#if WITH_TCP
|
||||||
|
|
||||||
|
int tcpan2(int fd, FILE *outfile) {
|
||||||
|
struct tcp_info tcpinfo;
|
||||||
|
socklen_t tcpinfolen = sizeof(tcpinfo);
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = Getsockopt(fd, SOL_TCP, TCP_INFO, &tcpinfo, &tcpinfolen);
|
||||||
|
if (result < 0) {
|
||||||
|
Debug4("getsockopt(%d, SOL_TCP, TCP_INFO, %p, {"F_socklen"}): %s",
|
||||||
|
fd, &tcpinfo, sizeof(tcpinfo), strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
fprintf(outfile, "%s={%u}\t", "TCPI_STATE", tcpinfo.tcpi_state);
|
||||||
|
#if 0 /* on BSD these components are prefixed with __ - I get tired... */
|
||||||
|
fprintf(outfile, "%s={%u}\t", "TCPI_CA_STATE", tcpinfo.tcpi_ca_state);
|
||||||
|
fprintf(outfile, "%s={%u}\t", "TCPI_RETRANSMITS", tcpinfo.tcpi_retransmits);
|
||||||
|
fprintf(outfile, "%s={%u}\t", "TCPI_PROBES", tcpinfo.tcpi_probes);
|
||||||
|
fprintf(outfile, "%s={%u}\t", "TCPI_BACKOFF", tcpinfo.tcpi_backoff);
|
||||||
|
#endif
|
||||||
|
fprintf(outfile, "%s={%u}\t", "TCPI_OPTIONS", tcpinfo.tcpi_options);
|
||||||
|
fprintf(outfile, "%s={%u}\t", "TCPI_SND_WSCALE", tcpinfo.tcpi_snd_wscale);
|
||||||
|
fprintf(outfile, "%s={%u}\t", "TCPI_RCV_WSCALE", tcpinfo.tcpi_rcv_wscale);
|
||||||
|
//fprintf(outfile, "%s={%u}\t", "TCPI_DELIVERY_RATE_APP_LIMITED", tcpinfo.tcpi_delivery_rate_app_limited);
|
||||||
|
//fprintf(outfile, "%s={%u}\t", "TCPI_FASTOPEN_CLIENT_FAIL", tcpinfo.tcpi_fastopen_client_fail);
|
||||||
|
// fprintf(outfile, "%s={%u}\t", "TCPI_", tcpinfo.tcpi_);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* WITH_TCP */
|
||||||
|
|
||||||
|
|
||||||
#if _WITH_SOCKET
|
#if _WITH_SOCKET
|
||||||
int sockoptan(int fd, const struct sockopt *optname, int socklay, FILE *outfile) {
|
int sockoptan(int fd, const struct sockopt *optname, int socklay, FILE *outfile) {
|
||||||
|
|
87
xio-ip.c
87
xio-ip.c
|
@ -464,16 +464,16 @@ int xiogetaddrinfo(const char *node, const char *service,
|
||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA)
|
#if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA)
|
||||||
/* converts the ancillary message in *cmsg into a form useable for further
|
/* Converts the ancillary message in *cmsg into a form useable for further
|
||||||
processing. knows the specifics of common message types.
|
processing. knows the specifics of common message types.
|
||||||
these are valid for IPv4 and IPv6
|
These are valid for IPv4 and IPv6
|
||||||
returns the number of resulting syntax elements in *num
|
Returns the number of resulting syntax elements in *num
|
||||||
returns a sequence of \0 terminated type strings in *typbuff
|
Returns a sequence of \0 terminated type strings in *typbuff
|
||||||
returns a sequence of \0 terminated name strings in *nambuff
|
Returns a sequence of \0 terminated name strings in *nambuff
|
||||||
returns a sequence of \0 terminated value strings in *valbuff
|
Returns a sequence of \0 terminated value strings in *valbuff
|
||||||
the respective len parameters specify the available space in the buffers
|
The respective len parameters specify the available space in the buffers
|
||||||
returns STAT_OK on success
|
Returns STAT_OK on success
|
||||||
returns STAT_WARNING if a buffer was too short and data truncated.
|
Returns STAT_WARNING if a buffer was too short and data truncated.
|
||||||
*/
|
*/
|
||||||
int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
|
int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
|
||||||
char *typbuff, int typlen,
|
char *typbuff, int typlen,
|
||||||
|
@ -519,14 +519,31 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
|
||||||
'\0',
|
'\0',
|
||||||
inet4addr_info(ntohl(pktinfo->ipi_addr.s_addr),
|
inet4addr_info(ntohl(pktinfo->ipi_addr.s_addr),
|
||||||
scratch3, sizeof(scratch3)));
|
scratch3, sizeof(scratch3)));
|
||||||
|
Notice3("Ancillary message: interface \"%s\", locaddr=%s, dstaddr=%s",
|
||||||
|
xiogetifname(pktinfo->ipi_ifindex, scratch1, -1),
|
||||||
|
#if HAVE_PKTINFO_IPI_SPEC_DST
|
||||||
|
inet4addr_info(ntohl(pktinfo->ipi_spec_dst.s_addr),
|
||||||
|
scratch2, sizeof(scratch2)),
|
||||||
|
#else
|
||||||
|
"",
|
||||||
|
#endif
|
||||||
|
inet4addr_info(ntohl(pktinfo->ipi_addr.s_addr),
|
||||||
|
scratch3, sizeof(scratch3)));
|
||||||
}
|
}
|
||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
#endif /* defined(IP_PKTINFO) && HAVE_STRUCT_IN_PKTINFO */
|
#endif /* defined(IP_PKTINFO) && HAVE_STRUCT_IN_PKTINFO */
|
||||||
#endif /* WITH_IP4 */
|
#endif /* WITH_IP4 */
|
||||||
#if defined(IP_RECVERR) && HAVE_STRUCT_SOCK_EXTENDED_ERR
|
#if defined(IP_RECVERR) && HAVE_STRUCT_SOCK_EXTENDED_ERR
|
||||||
case IP_RECVERR: {
|
case IP_RECVERR: {
|
||||||
struct sock_extended_err *err =
|
struct xio_extended_err {
|
||||||
(struct sock_extended_err *)CMSG_DATA(cmsg);
|
struct sock_extended_err see;
|
||||||
|
__u32 data0;
|
||||||
|
__u32 data1;
|
||||||
|
__u32 data2;
|
||||||
|
__u32 data3;
|
||||||
|
} ;
|
||||||
|
struct xio_extended_err *err =
|
||||||
|
(struct xio_extended_err *)CMSG_DATA(cmsg);
|
||||||
*num = 6;
|
*num = 6;
|
||||||
typbuff[0] = '\0'; strncat(typbuff, "IP_RECVERR", typlen-1);
|
typbuff[0] = '\0'; strncat(typbuff, "IP_RECVERR", typlen-1);
|
||||||
snprintf(nambuff, namlen, "%s%c%s%c%s%c%s%c%s%c%s",
|
snprintf(nambuff, namlen, "%s%c%s%c%s%c%s%c%s%c%s",
|
||||||
|
@ -537,8 +554,33 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
|
||||||
"IP_RECVERR_TYPE", '\0', "IP_RECVERR_CODE", '\0',
|
"IP_RECVERR_TYPE", '\0', "IP_RECVERR_CODE", '\0',
|
||||||
"IP_RECVERR_INFO", '\0', "IP_RECVERR_DATA");
|
"IP_RECVERR_INFO", '\0', "IP_RECVERR_DATA");
|
||||||
snprintf(valbuff, vallen, "%u%c%u%c%u%c%u%c%u%c%u",
|
snprintf(valbuff, vallen, "%u%c%u%c%u%c%u%c%u%c%u",
|
||||||
err->ee_errno, '\0', err->ee_origin, '\0', err->ee_type, '\0',
|
err->see.ee_errno, '\0', err->see.ee_origin, '\0', err->see.ee_type, '\0',
|
||||||
err->ee_code, '\0', err->ee_info, '\0', err->ee_data);
|
err->see.ee_code, '\0', err->see.ee_info, '\0', err->see.ee_data);
|
||||||
|
/* semantic part */
|
||||||
|
switch (err->see.ee_origin) {
|
||||||
|
char addrbuff[40];
|
||||||
|
#if WITH_IP4
|
||||||
|
case SO_EE_ORIGIN_ICMP:
|
||||||
|
if (1) {
|
||||||
|
inet4addr_info(ntohl(err->data1), addrbuff, sizeof(addrbuff));
|
||||||
|
Notice6("received ICMP from %s, type %d, code %d, info %d, data %d, resulting in errno %d",
|
||||||
|
addrbuff, err->see.ee_type, err->see.ee_code, err->see.ee_info, err->see.ee_data, err->see.ee_errno);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif /* WITH_IP4 */
|
||||||
|
#if WITH_IP6
|
||||||
|
case SO_EE_ORIGIN_ICMP6:
|
||||||
|
if (1) {
|
||||||
|
Notice5("received ICMP type %d, code %d, info %d, data %d, resulting in errno %d",
|
||||||
|
err->see.ee_type, err->see.ee_code, err->see.ee_info, err->see.ee_data, err->see.ee_errno);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif /* WITH_IP6 */
|
||||||
|
default:
|
||||||
|
Notice6("received error message origin %d, type %d, code %d, info %d, data %d, generating errno %d",
|
||||||
|
err->see.ee_origin, err->see.ee_type, err->see.ee_code, err->see.ee_info, err->see.ee_data, err->see.ee_errno);
|
||||||
|
break;
|
||||||
|
}
|
||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
}
|
}
|
||||||
#endif /* defined(IP_RECVERR) && HAVE_STRUCT_SOCK_EXTENDED_ERR */
|
#endif /* defined(IP_RECVERR) && HAVE_STRUCT_SOCK_EXTENDED_ERR */
|
||||||
|
@ -553,6 +595,7 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
|
||||||
valbuff[0] = '\0';
|
valbuff[0] = '\0';
|
||||||
strncat(valbuff,
|
strncat(valbuff,
|
||||||
xiosubstr(scratch1, sadl->sdl_data, 0, sadl->sdl_nlen), vallen-1);
|
xiosubstr(scratch1, sadl->sdl_data, 0, sadl->sdl_nlen), vallen-1);
|
||||||
|
Notice1("IP_RECVIF: %s", valbuff);
|
||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
}
|
}
|
||||||
#endif /* defined(IP_RECVIF) */
|
#endif /* defined(IP_RECVIF) */
|
||||||
|
@ -564,6 +607,7 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
|
||||||
nambuff[0] = '\0'; strncat(nambuff, "dstaddr", namlen-1);
|
nambuff[0] = '\0'; strncat(nambuff, "dstaddr", namlen-1);
|
||||||
envbuff[0] = '\0'; strncat(envbuff, "IP_DSTADDR", envlen-1);
|
envbuff[0] = '\0'; strncat(envbuff, "IP_DSTADDR", envlen-1);
|
||||||
inet4addr_info(ntohl(*(uint32_t *)CMSG_DATA(cmsg)), valbuff, vallen);
|
inet4addr_info(ntohl(*(uint32_t *)CMSG_DATA(cmsg)), valbuff, vallen);
|
||||||
|
Notice1("IP_RECVDSTADDR: %s", valbuff);
|
||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
#endif
|
#endif
|
||||||
#endif /* WITH_IP4 */
|
#endif /* WITH_IP4 */
|
||||||
|
@ -571,9 +615,12 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
|
||||||
#ifdef IP_RECVOPTS
|
#ifdef IP_RECVOPTS
|
||||||
case IP_RECVOPTS:
|
case IP_RECVOPTS:
|
||||||
#endif
|
#endif
|
||||||
cmsgtype = "IP_OPTIONS"; cmsgname = "options"; cmsgctr = -1; break;
|
cmsgtype = "IP_OPTIONS"; cmsgname = "options"; cmsgctr = -1;
|
||||||
|
/*!!!*/
|
||||||
|
break;
|
||||||
case IP_TOS:
|
case IP_TOS:
|
||||||
cmsgtype = "IP_TOS"; cmsgname = "tos"; cmsgctr = msglen; break;
|
cmsgtype = "IP_TOS"; cmsgname = "tos"; cmsgctr = msglen;
|
||||||
|
break;
|
||||||
case IP_TTL: /* Linux */
|
case IP_TTL: /* Linux */
|
||||||
#ifdef IP_RECVTTL
|
#ifdef IP_RECVTTL
|
||||||
case IP_RECVTTL: /* FreeBSD */
|
case IP_RECVTTL: /* FreeBSD */
|
||||||
|
@ -581,7 +628,7 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
|
||||||
cmsgtype = "IP_TTL"; cmsgname = "ttl"; cmsgctr = msglen; break;
|
cmsgtype = "IP_TTL"; cmsgname = "ttl"; cmsgctr = msglen; break;
|
||||||
}
|
}
|
||||||
/* when we come here we provide a single parameter
|
/* when we come here we provide a single parameter
|
||||||
with type in cmsgtype, name in cmsgname, value length in msglen */
|
with name in cmsgname, value length in msglen */
|
||||||
*num = 1;
|
*num = 1;
|
||||||
if (strlen(cmsgtype) >= typlen) rc = STAT_WARNING;
|
if (strlen(cmsgtype) >= typlen) rc = STAT_WARNING;
|
||||||
typbuff[0] = '\0'; strncat(typbuff, cmsgtype, typlen-1);
|
typbuff[0] = '\0'; strncat(typbuff, cmsgtype, typlen-1);
|
||||||
|
@ -595,9 +642,13 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
|
||||||
}
|
}
|
||||||
switch (cmsgctr) {
|
switch (cmsgctr) {
|
||||||
case sizeof(char):
|
case sizeof(char):
|
||||||
snprintf(valbuff, vallen, "%u", *(unsigned char *)CMSG_DATA(cmsg)); break;
|
snprintf(valbuff, vallen, "%u", *(unsigned char *)CMSG_DATA(cmsg));
|
||||||
|
Notice2("Ancillary message: %s=%u", cmsgname, *(unsigned char *)CMSG_DATA(cmsg));
|
||||||
|
break;
|
||||||
case sizeof(int):
|
case sizeof(int):
|
||||||
snprintf(valbuff, vallen, "%u", (*(unsigned int *)CMSG_DATA(cmsg))); break;
|
snprintf(valbuff, vallen, "%u", (*(unsigned int *)CMSG_DATA(cmsg)));
|
||||||
|
Notice2("Ancillary message: %s=%u", cmsgname, *(unsigned int *)CMSG_DATA(cmsg));
|
||||||
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); break;
|
xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); break;
|
||||||
default: break;
|
default: break;
|
||||||
|
|
63
xio-socket.c
63
xio-socket.c
|
@ -693,6 +693,49 @@ int xioopen_socket_datagram(int argc, const char *argv[], struct opt *opts,
|
||||||
|
|
||||||
#endif /* WITH_GENERICSOCKET */
|
#endif /* WITH_GENERICSOCKET */
|
||||||
|
|
||||||
|
int xiogetpacketinfo(int fd)
|
||||||
|
{
|
||||||
|
#if defined(MSG_ERRQUEUE)
|
||||||
|
int _errno = errno;
|
||||||
|
char peername[256];
|
||||||
|
union sockaddr_union _peername;
|
||||||
|
/* union sockaddr_union _sockname; */
|
||||||
|
union sockaddr_union *pa = &_peername; /* peer address */
|
||||||
|
/* union sockaddr_union *la = &_sockname; */ /* local address */
|
||||||
|
socklen_t palen = sizeof(_peername); /* peer address size */
|
||||||
|
char ctrlbuff[1024]; /* ancillary messages */
|
||||||
|
struct msghdr msgh = {0};
|
||||||
|
|
||||||
|
msgh.msg_name = pa;
|
||||||
|
msgh.msg_namelen = palen;
|
||||||
|
#if HAVE_STRUCT_MSGHDR_MSGCONTROL
|
||||||
|
msgh.msg_control = ctrlbuff;
|
||||||
|
#endif
|
||||||
|
#if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN
|
||||||
|
msgh.msg_controllen = sizeof(ctrlbuff);
|
||||||
|
#endif
|
||||||
|
if (xiogetpacketsrc(fd,
|
||||||
|
&msgh,
|
||||||
|
MSG_ERRQUEUE
|
||||||
|
#ifdef MSG_TRUNC
|
||||||
|
|MSG_TRUNC
|
||||||
|
#endif
|
||||||
|
) >= 0
|
||||||
|
) {
|
||||||
|
palen = msgh.msg_namelen;
|
||||||
|
|
||||||
|
Notice1("receiving packet from %s"/*"src"*/,
|
||||||
|
sockaddr_info(&pa->soa, palen, peername, sizeof(peername))/*,
|
||||||
|
sockaddr_info(&la->soa, sockname, sizeof(sockname))*/);
|
||||||
|
|
||||||
|
xiodopacketinfo(&msgh, true, true);
|
||||||
|
}
|
||||||
|
errno = _errno;
|
||||||
|
#endif /* defined(MSG_ERRQUEUE) */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* a subroutine that is common to all socket addresses that want to connect
|
/* a subroutine that is common to all socket addresses that want to connect
|
||||||
to a peer address.
|
to a peer address.
|
||||||
|
@ -919,6 +962,10 @@ int _xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen,
|
||||||
errno = _errno;
|
errno = _errno;
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
|
/* try to find details about error, especially from ICMP */
|
||||||
|
xiogetpacketinfo(xfd->fd);
|
||||||
|
|
||||||
|
/* continue mainstream */
|
||||||
Msg4(level, "connect(%d, %s, "F_Zd"): %s",
|
Msg4(level, "connect(%d, %s, "F_Zd"): %s",
|
||||||
xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
|
xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)),
|
||||||
themlen, strerror(errno));
|
themlen, strerror(errno));
|
||||||
|
@ -1408,7 +1455,13 @@ int _xioopen_dgram_recvfrom(struct single *xfd, int xioflags,
|
||||||
#if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN
|
#if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN
|
||||||
msgh.msg_controllen = sizeof(ctrlbuff);
|
msgh.msg_controllen = sizeof(ctrlbuff);
|
||||||
#endif
|
#endif
|
||||||
if (xiogetpacketsrc(xfd->fd, &msgh) < 0) {
|
if (xiogetpacketsrc(xfd->fd,
|
||||||
|
&msgh,
|
||||||
|
MSG_PEEK
|
||||||
|
#ifdef MSG_TRUNC
|
||||||
|
|MSG_TRUNC
|
||||||
|
#endif
|
||||||
|
) < 0) {
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
palen = msgh.msg_namelen;
|
palen = msgh.msg_namelen;
|
||||||
|
@ -1626,7 +1679,7 @@ int retropt_socket_pf(struct opt *opts, int *pf) {
|
||||||
/* this function calls recvmsg(..., MSG_PEEK, ...) to obtain information about
|
/* this function calls recvmsg(..., MSG_PEEK, ...) to obtain information about
|
||||||
the arriving packet. in msgh the msg_name pointer must refer to an (empty)
|
the arriving packet. in msgh the msg_name pointer must refer to an (empty)
|
||||||
sockaddr storage. */
|
sockaddr storage. */
|
||||||
int xiogetpacketsrc(int fd, struct msghdr *msgh) {
|
int xiogetpacketsrc(int fd, struct msghdr *msgh, int flags) {
|
||||||
char peekbuff[1];
|
char peekbuff[1];
|
||||||
#if HAVE_STRUCT_IOVEC
|
#if HAVE_STRUCT_IOVEC
|
||||||
struct iovec iovec;
|
struct iovec iovec;
|
||||||
|
@ -1641,11 +1694,7 @@ int xiogetpacketsrc(int fd, struct msghdr *msgh) {
|
||||||
#if HAVE_STRUCT_MSGHDR_MSGFLAGS
|
#if HAVE_STRUCT_MSGHDR_MSGFLAGS
|
||||||
msgh->msg_flags = 0;
|
msgh->msg_flags = 0;
|
||||||
#endif
|
#endif
|
||||||
if (Recvmsg(fd, msgh, MSG_PEEK
|
if (Recvmsg(fd, msgh, flags) < 0) {
|
||||||
#ifdef MSG_TRUNC
|
|
||||||
|MSG_TRUNC
|
|
||||||
#endif
|
|
||||||
) < 0) {
|
|
||||||
Warn1("recvmsg(): %s", strerror(errno));
|
Warn1("recvmsg(): %s", strerror(errno));
|
||||||
return STAT_RETRYLATER;
|
return STAT_RETRYLATER;
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ int _xioopen_dgram_recv(struct single *xfd, int xioflags,
|
||||||
extern
|
extern
|
||||||
int xiodopacketinfo(struct msghdr *msgh, bool withlog, bool withenv);
|
int xiodopacketinfo(struct msghdr *msgh, bool withlog, bool withenv);
|
||||||
extern
|
extern
|
||||||
int xiogetpacketsrc(int fd, struct msghdr *msgh);
|
int xiogetpacketsrc(int fd, struct msghdr *msgh, int flags);
|
||||||
extern
|
extern
|
||||||
int xiocheckpeer(xiosingle_t *xfd,
|
int xiocheckpeer(xiosingle_t *xfd,
|
||||||
union sockaddr_union *pa, union sockaddr_union *la);
|
union sockaddr_union *pa, union sockaddr_union *la);
|
||||||
|
|
14
xioread.c
14
xioread.c
|
@ -128,7 +128,12 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) {
|
||||||
#if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN
|
#if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN
|
||||||
msgh.msg_controllen = sizeof(ctrlbuff);
|
msgh.msg_controllen = sizeof(ctrlbuff);
|
||||||
#endif
|
#endif
|
||||||
if (xiogetpacketsrc(pipe->fd, &msgh) < 0) {
|
if (xiogetpacketsrc(pipe->fd, &msgh,
|
||||||
|
MSG_PEEK
|
||||||
|
#ifdef MSG_TRUNC
|
||||||
|
|MSG_TRUNC
|
||||||
|
#endif
|
||||||
|
) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
do {
|
do {
|
||||||
|
@ -325,7 +330,12 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) {
|
||||||
#if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN
|
#if HAVE_STRUCT_MSGHDR_MSGCONTROLLEN
|
||||||
msgh.msg_controllen = sizeof(ctrlbuff);
|
msgh.msg_controllen = sizeof(ctrlbuff);
|
||||||
#endif
|
#endif
|
||||||
if (xiogetpacketsrc(pipe->fd, &msgh) < 0) {
|
if (xiogetpacketsrc(pipe->fd, &msgh,
|
||||||
|
MSG_PEEK
|
||||||
|
#ifdef MSG_TRUNC
|
||||||
|
|MSG_TRUNC
|
||||||
|
#endif
|
||||||
|
) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
xiodopacketinfo(&msgh, true, false);
|
xiodopacketinfo(&msgh, true, false);
|
||||||
|
|
Loading…
Reference in a new issue