summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/imudp/imudp.c56
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;