diff --git a/src/decode.c b/src/decode.c index 2507dec1b8..b23edb1ff5 100644 --- a/src/decode.c +++ b/src/decode.c @@ -46,16 +46,16 @@ void DecodeTunnel(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt } /** - * \brief Get a pseudo packet for tunnels and defrag reassembly. We try to - * get a packet from the packet_q first, but if that is empty we alloc - * a packet that is free'd again after processing. + * \brief Get a packet. We try to get a packet from the packet_q first, but + * if that is empty we alloc a packet that is free'd again after + * processing. * * \retval p packet, NULL on error */ -static Packet *PacketGetPseudoPkt (void) -{ +Packet *PacketGetFromQueueOrAlloc(void) { Packet *p = NULL; + /* try the queue first */ SCMutexLock(&packet_q.mutex_q); p = PacketDequeue(&packet_q); SCMutexUnlock(&packet_q.mutex_q); @@ -90,7 +90,7 @@ static Packet *PacketGetPseudoPkt (void) Packet *PacketPseudoPktSetup(Packet *parent, uint8_t *pkt, uint16_t len, uint8_t proto) { /* get us a packet */ - Packet *p = PacketGetPseudoPkt(); + Packet *p = PacketGetFromQueueOrAlloc(); if (p == NULL) { return NULL; } diff --git a/src/decode.h b/src/decode.h index 16d2d4152b..7f81408e5d 100644 --- a/src/decode.h +++ b/src/decode.h @@ -488,6 +488,7 @@ typedef struct DecodeThreadVars_ void DecodeRegisterPerfCounters(DecodeThreadVars *, ThreadVars *); Packet *PacketPseudoPktSetup(Packet *parent, uint8_t *pkt, uint16_t len, uint8_t proto); +Packet *PacketGetFromQueueOrAlloc(void); /* decoder functions */ void DecodeEthernet(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *); diff --git a/src/source-nfq.c b/src/source-nfq.c index 33acdbd6bb..4398aa4642 100644 --- a/src/source-nfq.c +++ b/src/source-nfq.c @@ -204,7 +204,11 @@ static int NFQCallBack(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, ThreadVars *tv = ntv->tv; /* grab a packet */ - Packet *p = tv->tmqh_in(tv); + Packet *p = PacketGetFromQueueOrAlloc(); + if (p == NULL) { + return -1; + } + NFQSetupPkt(p, (void *)nfa); #ifdef COUNTERS @@ -399,8 +403,7 @@ void NFQRecvPkt(NFQThreadVars *t) { rv = recv(t->fd, buf, sizeof(buf), 0); if (rv < 0) { - if (errno == EINTR || errno == EWOULDBLOCK - ) { + if (errno == EINTR || errno == EWOULDBLOCK) { /* no error on timeout */ } else { #ifdef COUNTERS @@ -497,6 +500,15 @@ process_rv: TmEcode ReceiveNFQ(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) { NFQThreadVars *ntv = (NFQThreadVars *)data; + /* make sure we have at least one packet in the packet pool, to prevent + * us from 1) alloc'ing packets at line rate, 2) have a race condition + * for the nfq mutex lock with the verdict thread. */ + SCMutexLock(&packet_q.mutex_q); + if (packet_q.len == 0) { + SCondWait(&packet_q.cond_q, &packet_q.mutex_q); + } + SCMutexUnlock(&packet_q.mutex_q); + /* do our nfq magic */ NFQRecvPkt(ntv);