/** \brief a initialized packet * * \warning Use *only* at init, not at packet runtime */ void PacketPoolStorePacket(Packet *p) { if (RingBufferIsFull(ringbuffer)) { exit(1); } RingBufferMrMwPut(ringbuffer, (void *)p); SCLogDebug("buffersize %u", RingBufferSize(ringbuffer)); }
/** \brief Return packet to Packet pool * */ void PacketPoolReturnPacket(Packet *p) { PACKET_RECYCLE(p); RingBufferMrMwPut(ringbuffer, (void *)p); }
void TmqhOutputPacketpool(ThreadVars *t, Packet *p) { int proot = 0; SCEnter(); SCLogDebug("Packet %p, p->root %p, alloced %s", p, p->root, p->flags & PKT_ALLOC ? "true" : "false"); /** \todo make this a callback * Release tcp segments. Done here after alerting can use them. */ if (p->flow != NULL && p->proto == IPPROTO_TCP) { SCMutexLock(&p->flow->m); StreamTcpPruneSession(p->flow, p->flowflags & FLOW_PKT_TOSERVER ? STREAM_TOSERVER : STREAM_TOCLIENT); SCMutexUnlock(&p->flow->m); } if (IS_TUNNEL_PKT(p)) { SCLogDebug("Packet %p is a tunnel packet: %s", p,p->root ? "upper layer" : "tunnel root"); /* get a lock to access root packet fields */ SCMutex *m = p->root ? &p->root->tunnel_mutex : &p->tunnel_mutex; SCMutexLock(m); if (IS_TUNNEL_ROOT_PKT(p)) { SCLogDebug("IS_TUNNEL_ROOT_PKT == TRUE"); if (TUNNEL_PKT_TPR(p) == 0) { SCLogDebug("TUNNEL_PKT_TPR(p) == 0, no more tunnel packet " "depending on this root"); /* if this packet is the root and there are no * more tunnel packets, return it to the pool */ /* fall through */ } else { SCLogDebug("tunnel root Packet %p: TUNNEL_PKT_TPR(p) > 0, so " "packets are still depending on this root, setting " "p->tunnel_verdicted == 1", p); /* if this is the root and there are more tunnel * packets, return this to the pool. It's still referenced * by the tunnel packets, and we will return it * when we handle them */ SET_TUNNEL_PKT_VERDICTED(p); SCMutexUnlock(m); PACKET_PROFILING_END(p); SCReturn; } } else { SCLogDebug("NOT IS_TUNNEL_ROOT_PKT, so tunnel pkt"); /* the p->root != NULL here seems unnecessary: IS_TUNNEL_PKT checks * that p->tunnel_pkt == 1, IS_TUNNEL_ROOT_PKT checks that + * p->root == NULL. So when we are here p->root can only be * non-NULL, right? CLANG thinks differently. May be a FP, but * better safe than sorry. VJ */ if (p->root != NULL && IS_TUNNEL_PKT_VERDICTED(p->root) && TUNNEL_PKT_TPR(p) == 1) { SCLogDebug("p->root->tunnel_verdicted == 1 && TUNNEL_PKT_TPR(p) == 1"); /* the root is ready and we are the last tunnel packet, * lets enqueue them both. */ TUNNEL_DECR_PKT_TPR_NOLOCK(p); /* handle the root */ SCLogDebug("setting proot = 1 for root pkt, p->root %p " "(tunnel packet %p)", p->root, p); proot = 1; /* fall through */ } else { /* root not ready yet, so get rid of the tunnel pkt only */ SCLogDebug("NOT p->root->tunnel_verdicted == 1 && " "TUNNEL_PKT_TPR(p) == 1 (%" PRIu32 ")", TUNNEL_PKT_TPR(p)); TUNNEL_DECR_PKT_TPR_NOLOCK(p); /* fall through */ } } SCMutexUnlock(m); SCLogDebug("tunnel stuff done, move on (proot %d)", proot); } FlowDecrUsecnt(p->flow); /* we're done with the tunnel root now as well */ if (proot == 1) { SCLogDebug("getting rid of root pkt... alloc'd %s", p->root->flags & PKT_ALLOC ? "true" : "false"); FlowDecrUsecnt(p->root->flow); /* if p->root uses extended data, free them */ if (p->root->ReleaseData) { if (p->root->ReleaseData(t, p->root) == TM_ECODE_FAILED) { SCLogWarning(SC_ERR_INVALID_ACTION, "Unable to release packet data"); } } if (p->root->ext_pkt) { if (!(p->root->flags & PKT_ZERO_COPY)) { SCFree(p->root->ext_pkt); } p->root->ext_pkt = NULL; } if (p->root->flags & PKT_ALLOC) { PACKET_CLEANUP(p->root); SCFree(p->root); p->root = NULL; } else { PACKET_RECYCLE(p->root); RingBufferMrMwPut(ringbuffer, (void *)p->root); } } if (p->ReleaseData) { if (p->ReleaseData(t, p) == TM_ECODE_FAILED) { SCLogWarning(SC_ERR_INVALID_ACTION, "Unable to release packet data"); } } /* if p uses extended data, free them */ if (p->ext_pkt) { if (!(p->flags & PKT_ZERO_COPY)) { SCFree(p->ext_pkt); } p->ext_pkt = NULL; } PACKET_PROFILING_END(p); SCLogDebug("getting rid of tunnel pkt... alloc'd %s (root %p)", p->flags & PKT_ALLOC ? "true" : "false", p->root); if (p->flags & PKT_ALLOC) { PACKET_CLEANUP(p); SCFree(p); } else { PACKET_RECYCLE(p); RingBufferMrMwPut(ringbuffer, (void *)p); } SCReturn; }