diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/imudp/imudp.c | 56 |
1 files changed, 33 insertions, 23 deletions
diff --git a/plugins/imudp/imudp.c b/plugins/imudp/imudp.c index 5792a999..f4830a47 100644 --- a/plugins/imudp/imudp.c +++ b/plugins/imudp/imudp.c @@ -127,6 +127,8 @@ finalize_it: /* This function is called to gather input. + * Note that udpLstnSocks must be non-NULL because otherwise we would not have + * indicated that we want to run (or we have a programming error ;)). -- rgerhards, 2008-10-02 */ BEGINrunInput int maxfds; @@ -154,17 +156,14 @@ CODESTARTrunInput maxfds = 0; FD_ZERO (&readfds); - /* Add the UDP listen sockets to the list of read descriptors. - */ - if(udpLstnSocks != NULL) { - for (i = 0; i < *udpLstnSocks; i++) { - if (udpLstnSocks[i+1] != -1) { - if(Debug) - net.debugListenInfo(udpLstnSocks[i+1], "UDP"); - FD_SET(udpLstnSocks[i+1], &readfds); - if(udpLstnSocks[i+1]>maxfds) maxfds=udpLstnSocks[i+1]; - } - } + /* Add the UDP listen sockets to the list of read descriptors. */ + for (i = 0; i < *udpLstnSocks; i++) { + if (udpLstnSocks[i+1] != -1) { + if(Debug) + net.debugListenInfo(udpLstnSocks[i+1], "UDP"); + FD_SET(udpLstnSocks[i+1], &readfds); + if(udpLstnSocks[i+1]>maxfds) maxfds=udpLstnSocks[i+1]; + } } if(Debug) { dbgprintf("--------imUDP calling select, active file descriptors (max %d): ", maxfds); @@ -177,13 +176,22 @@ CODESTARTrunInput /* wait for io to become ready */ nfds = select(maxfds+1, (fd_set *) &readfds, NULL, NULL, NULL); - if(udpLstnSocks != NULL) { - for (i = 0; nfds && i < *udpLstnSocks; i++) { - if (FD_ISSET(udpLstnSocks[i+1], &readfds)) { - socklen = sizeof(frominet); - l = recvfrom(udpLstnSocks[i+1], (char*) pRcvBuf, iMaxLine, 0, + for (i = 0; nfds && i < *udpLstnSocks; i++) { + if (FD_ISSET(udpLstnSocks[i+1], &readfds)) { + socklen = sizeof(frominet); + do { + /* we now try to read from the file descriptor until there + * is no more data. This is done in the hope to get better performance + * out of the system. However, this also means that a descriptor + * monopolizes processing while it contains data. This can lead to + * data loss in other descriptors. However, if the system is incapable of + * handling the workload, we will loss data in any case. So it doesn't really + * matter where the actual loss occurs - it is always random, because we depend + * on scheduling order. -- rgerhards, 2008-10-02 + */ + l = recvfrom(udpLstnSocks[i+1], (char*) pRcvBuf, iMaxLine, 0, (struct sockaddr *)&frominet, &socklen); - if (l > 0) { + if(l > 0) { if(net.cvthname(&frominet, fromHost, fromHostFQDN, fromHostIP) == RS_RET_OK) { dbgprintf("Message from inetd socket: #%d, host: %s\n", udpLstnSocks[i+1], fromHost); @@ -205,18 +213,20 @@ CODESTARTrunInput } } } - } else if (l < 0 && errno != EINTR && errno != EAGAIN) { + } else if(l < 0 && errno != EINTR && errno != EAGAIN) { char errStr[1024]; rs_strerror_r(errno, errStr, sizeof(errStr)); dbgprintf("INET socket error: %d = %s.\n", errno, errStr); errmsg.LogError(errno, NO_ERRCODE, "recvfrom inet"); /* should be harmless */ sleep(1); - } - --nfds; /* indicate we have processed one */ - } - } - } + } + } while(l > 0); /* Warning: do ... while()! */ + + --nfds; /* indicate we have processed one descriptor */ + } + } + /* end of a run, back to loop for next recv() */ } return iRet; |