This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.
Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
On Wed, Jan 10, 2001 at 03:31:22PM +0100, Andreas Jaeger wrote: > > + ret = recvmsg (cu->cu_sock, &msg, MSG_ERRQUEUE); > > + if ((ret == 0 > > + || (ret == outlen > > + && memcmp (cbuf + 256, cu->cu_outbuf, outlen) == 0)) > > Andi Kleen told me that ret == 0 doesn't make sense since that would > mean that the error queue is empty. I'm not sure about this, try the program below, recvmsg will return 0 but will fill cmsg with the IP_RECVERR with ee_errno EHOSTUNREACH and other stuff. > The outlen check is also wrong > since ICMP can shorten packages. > > He advices to use: > if ((ret >= SUNRPC_MIN_HDR && memcpy(cbuf+256,cu->cu_outbuf,outlen) == 0) ^^^^^^ ret ?? > where SUNRPC_MIN_HDR is a minimal value we will use for comparison. What about if (ret >= 0 && memcpy(cbuf+256,cu->cu_outbuf,ret) == 0 && (msg.msg_flags & MSG_ERRQUEUE) && ((msg.msg_namelen == 0 && ret >= 12) || (msg.msg_namelen == sizeof (err_addr) && err_addr.sin_family == AF_INET && memcmp (&err_addr.sin_addr, &cu->cu_raddr.sin_addr, sizeof (err_addr.sin_addr)) == 0 && err_addr.sin_port == cu->cu_raddr.sin_port))) ? I believe 12 is the minimal rpc header length (one LONG procedure number, two LONGs auth_none ah_cred and ah_verf), for 2.4 kernels it is IMHO enough to check msg_name (of course it is better to check the payload if it has been sent back in ICMP), but for 2.2 kernels which don't fill msg_name I believe at least those 12 bytes should be checked. Comments? This program prints 0 for me but fills cmsg: #include <stdio.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <sys/poll.h> #include <sys/uio.h> int main(void) { int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); int dontblock = 1; char buf[56]; struct sockaddr_in sin, serr; struct pollfd pfd; int on, i; socklen_t ss; struct iovec iov; struct msghdr msg; struct cmsghdr *cmsg; struct sock_extended_err *e; char cbuf[8192]; on = 1; setsockopt(fd, SOL_IP, IP_RECVERR, &on, sizeof(on)); bindresvport (fd, (struct sockaddr_in *) 0); ioctl (fd, FIONBIO, (char *) &dontblock); for (i = 0; i < 56; i++) buf[i] = '0' + i; memset (&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(27); sin.sin_addr.s_addr = inet_addr("207.175.42.76"); sendto (fd, buf, 56, 0, &sin, sizeof(sin)); pfd.fd = fd; pfd.events = POLLIN; poll(&pfd, 1, 1000); iov.iov_base = buf; iov.iov_len = sizeof(buf); msg.msg_name = (void *)&serr; msg.msg_namelen = sizeof(serr); msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_flags = 0; msg.msg_control = cbuf; msg.msg_controllen = 128; memset(buf, 0, 56); printf ("%d\n", recvmsg(fd, &msg, MSG_ERRQUEUE)); } Jakub
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |