NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/48725: recvmmsg erroneous EAGAIN on nonblocking socket when all msgs aren't filled
>Number: 48725
>Category: kern
>Synopsis: recvmmsg erroneous EAGAIN on nonblocking socket when all msgs
>aren't filled
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Mon Apr 07 15:15:00 +0000 2014
>Originator: Sean Boudreau
>Release: 6.99.39
>Organization:
NetBSD
>Environment:
NetBSD 6.99.39 NetBSD 6.99.39 (seanb) #4: Wed Apr 2 11:39:05 EDT 2014
seanb@:/home/seanb/cvs_netbsd/HEAD/src/sys/arch/i386/compile/obj/seanb i386
>Description:
An erroneous EAGAIN can be returned when receiving on a non-blocking socket
with recvmmsg with a mmsg array containing multiple members. This occurs when
some, but not all of the mmsg array members are filled with data.
>How-To-Repeat:
#include <errno.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <time.h>
#include <poll.h>
#include <err.h>
#define MAX_PACKETS 2
#define BUFSIZE 2048
void *
runRecvThread(void *arg)
{
struct pollfd pfd;
int ret, fd;
struct mmsghdr msgs[MAX_PACKETS];
struct iovec iovecs[MAX_PACKETS];
char bufs[MAX_PACKETS][BUFSIZE+1];
int retval, i;
fd = *(int *)arg;
pfd.fd = fd;
pfd.events = POLLIN;
pfd.revents = 0;
memset(msgs, 0, sizeof(msgs));
for (i = 0; i < MAX_PACKETS; i++){
iovecs[i].iov_base = bufs[i];
iovecs[i].iov_len = BUFSIZE;
msgs[i].msg_hdr.msg_name = NULL;
msgs[i].msg_hdr.msg_namelen = 0;
msgs[i].msg_hdr.msg_control = NULL;
msgs[i].msg_hdr.msg_controllen = 0;
msgs[i].msg_hdr.msg_flags = 0;
msgs[i].msg_hdr.msg_iovlen = 1;
msgs[i].msg_hdr.msg_iov = &iovecs[i];
msgs[i].msg_hdr.msg_iovlen = 1;
}
for (;;) {
ret = poll(&pfd, 1, -1);
if (ret == 1 && (pfd.revents & POLLIN)) {
retval = recvmmsg(fd, msgs, MAX_PACKETS, 0, 0);
if (retval == -1)
err(1, "recvmmsg");
printf("got data %d\n", retval);
for (i = 0; i < retval; i++)
printf("\t%d %s\n", i, bufs[i]);
} else {
errx(1, "unexpected return from poll: %d\n", ret);
}
}
}
int
main(int argc, char *argv[])
{
int fds[2];
pthread_t recvT;
if (socketpair(AF_LOCAL, SOCK_DGRAM, 0, fds) == -1)
err(1, "socketpair");
fcntl(fds[1], F_SETFL, fcntl(fds[1], F_GETFL, 0) | O_NONBLOCK);
pthread_create(&recvT, NULL, &runRecvThread, &fds[1]);
for (;;) {
sleep(1);
send(fds[0], "data\n", sizeof("data\n"), 0);
}
pthread_join(recvT, NULL);
return 0;
}
>Fix:
Home |
Main Index |
Thread Index |
Old Index