Snort mailing list archives
[PATCH 1/1] daq_nfq: fix cfg->timeout usage and remove extra select call
From: Florian Westphal <fwestphal () astaro com>
Date: Fri, 17 Dec 2010 14:50:57 +0100
cfg->timeout is in milliseconds in snort, but was assigned to tv_sec; i.e. 16 minutes. Moreover, the call to select() is not needed at all, we can use RCV_TIMEOUT setsockopt to prevent recv() calls from blocking the daq caller for too long. Also, nfnetlink may return -ENOBUFS (to inform userspace that messages have been lost). daq_nfq does not need to care about this, so ignore ENOBUFS and tell the kernel to not notify us in the first place. --- os-daq-modules/daq_nfq.c | 75 ++++++++++++++++++++++++--------------------- 1 files changed, 40 insertions(+), 35 deletions(-) diff --git a/os-daq-modules/daq_nfq.c b/os-daq-modules/daq_nfq.c index 204dcd0..cdf6b7e 100644 --- a/os-daq-modules/daq_nfq.c +++ b/os-daq-modules/daq_nfq.c @@ -74,7 +74,6 @@ typedef struct volatile int count; int passive; uint32_t snaplen; - unsigned timeout; char error[DAQ_ERRBUF_SIZE]; DAQ_State state; @@ -182,7 +181,6 @@ static int nfq_daq_get_setup ( } impl->snaplen = cfg->snaplen ? cfg->snaplen : IP_MAXPACKET; - impl->timeout = cfg->timeout; impl->passive = ( cfg->mode == DAQ_MODE_PASSIVE ); return DAQ_SUCCESS; @@ -193,6 +191,8 @@ static int nfq_daq_get_setup ( static int nfq_daq_initialize ( const DAQ_Config_t* cfg, void** handle, char* errBuf, size_t errMax) { + struct timeval rcv_timeo = { 0 }; + if(cfg->name && *(cfg->name)) { snprintf(errBuf, errMax, "The nfq DAQ module does not support interface or readback mode!"); @@ -333,6 +333,26 @@ static int nfq_daq_initialize ( } } + if (cfg->timeout >= 1000) { + rcv_timeo.tv_sec = cfg->timeout / 1000; + } else { + rcv_timeo.tv_usec = cfg->timeout * 1000; + } + + if (cfg->timeout && setsockopt(impl->sock, SOL_SOCKET, SO_RCVTIMEO, + &rcv_timeo, sizeof(rcv_timeo))) { + snprintf(errBuf, errMax, + "%s: can't set receive timeout (%s)\n", + __FUNCTION__, strerror(errno)); + return DAQ_ERROR; + } + + // tell kernel that we do not need to know about queue overflows. + // Without this, read operations on the netlink socket will return + // ENOBUFS on queue overrun. + setsockopt(impl->sock, SOL_NETLINK, NETLINK_NO_ENOBUFS, &(int){1}, + sizeof(int)); + impl->state = DAQ_STATE_INITIALIZED; *handle = impl; @@ -468,9 +488,6 @@ static int nfq_daq_acquire ( NfqImpl *impl = (NfqImpl*)handle; int n = 0; - fd_set fdset; - struct timeval tv; - tv.tv_usec = 0; // If c is <= 0, don't limit the packets acquired. However, // impl->count = 0 has a special meaning, so interpret accordingly. @@ -480,42 +497,30 @@ static int nfq_daq_acquire ( while ( (impl->count < 0) || (n < impl->count) ) { - FD_ZERO(&fdset); - FD_SET(impl->sock, &fdset); + int len = recv(impl->sock, impl->buf, MSG_BUF_SIZE, 0); - // set this per call - tv.tv_sec = impl->timeout; - tv.tv_usec = 0; - - // at least ipq had a timeout! - if ( select(impl->sock+1, &fdset, NULL, NULL, &tv) < 0 ) + if ( len > 0) { - if ( errno == EINTR ) - break; - DPE(impl->error, "%s: select = %s", - __FUNCTION__, strerror(errno)); - return DAQ_ERROR; - } + int stat = nfq_handle_packet( + impl->nf_handle, (char*)impl->buf, len); - if (FD_ISSET(impl->sock, &fdset)) - { - int len = recv(impl->sock, impl->buf, MSG_BUF_SIZE, 0); + impl->stats.hw_packets_received++; - if ( len > 0) + if ( stat < 0 ) { - int stat = nfq_handle_packet( - impl->nf_handle, (char*)impl->buf, len); - - impl->stats.hw_packets_received++; - - if ( stat < 0 ) - { - DPE(impl->error, "%s: nfq_handle_packet = %s", - __FUNCTION__, strerror(errno)); - return DAQ_ERROR; - } - n++; + DPE(impl->error, "%s: nfq_handle_packet = %s", + __FUNCTION__, strerror(errno)); + return DAQ_ERROR; } + n++; + } else { + if ( errno == EINTR || errno == EAGAIN ) + break; + if ( errno == ENOBUFS ) + continue; /* should not happen, we set NO_ENOBUFS sockopt */ + DPE(impl->error, "%s: read = %s", + __FUNCTION__, strerror(errno)); + return DAQ_ERROR; } } return 0; -- 1.7.2.2 ------------------------------------------------------------------------------ Lotusphere 2011 Register now for Lotusphere 2011 and learn how to connect the dots, take your collaborative environment to the next level, and enter the era of Social Business. http://p.sf.net/sfu/lotusphere-d2d _______________________________________________ Snort-devel mailing list Snort-devel () lists sourceforge net https://lists.sourceforge.net/lists/listinfo/snort-devel
Current thread:
- [PATCH 1/1] daq_nfq: fix cfg->timeout usage and remove extra select call Florian Westphal (Dec 17)
- Re: [PATCH 1/1] daq_nfq: fix cfg->timeout usage and remove extra select call Russ Combs (Dec 17)
- Re: [PATCH 1/1] daq_nfq: fix cfg->timeout usage and remove extra select call Florian Westphal (Dec 17)
- Re: [PATCH 1/1] daq_nfq: fix cfg->timeout usage and remove extra select call Russ Combs (Dec 17)