int DecodeUDP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { SCPerfCounterIncr(dtv->counter_udp, tv->sc_perf_pca); if (unlikely(DecodeUDPPacket(tv, p,pkt,len) < 0)) { p->udph = NULL; return TM_ECODE_FAILED; } SCLogDebug("UDP sp: %" PRIu32 " -> dp: %" PRIu32 " - HLEN: %" PRIu32 " LEN: %" PRIu32 "", UDP_GET_SRC_PORT(p), UDP_GET_DST_PORT(p), UDP_HEADER_LEN, p->payload_len); if (unlikely(DecodeTeredo(tv, dtv, p, p->payload, p->payload_len, pq) == TM_ECODE_OK)) { /* Here we have a Teredo packet and don't need to handle app * layer */ FlowHandlePacket(tv, p); return TM_ECODE_OK; } /* Flow is an integral part of us */ FlowHandlePacket(tv, p); /* handle the app layer part of the UDP packet payload */ if (unlikely(p->flow != NULL)) { AppLayerHandleUdp(&dtv->udp_dp_ctx, p->flow, p); } return TM_ECODE_OK; }
static TmEcode FlowWorker(ThreadVars *tv, Packet *p, void *data, PacketQueue *preq, PacketQueue *unused) { FlowWorkerThreadData *fw = data; void *detect_thread = SC_ATOMIC_GET(fw->detect_thread); SCLogDebug("packet %"PRIu64, p->pcap_cnt); /* update time */ if (!(PKT_IS_PSEUDOPKT(p))) { TimeSetByThread(tv->id, &p->ts); } /* handle Flow */ if (p->flags & PKT_WANTS_FLOW) { FLOWWORKER_PROFILING_START(p, PROFILE_FLOWWORKER_FLOW); FlowHandlePacket(tv, fw->dtv, p); if (likely(p->flow != NULL)) { DEBUG_ASSERT_FLOW_LOCKED(p->flow); if (FlowUpdate(p) == TM_ECODE_DONE) { FLOWLOCK_UNLOCK(p->flow); return TM_ECODE_OK; } } /* Flow is now LOCKED */ FLOWWORKER_PROFILING_END(p, PROFILE_FLOWWORKER_FLOW); /* if PKT_WANTS_FLOW is not set, but PKT_HAS_FLOW is, then this is a * pseudo packet created by the flow manager. */ } else if (p->flags & PKT_HAS_FLOW) { FLOWLOCK_WRLOCK(p->flow); } SCLogDebug("packet %"PRIu64" has flow? %s", p->pcap_cnt, p->flow ? "yes" : "no"); /* handle TCP and app layer */ if (p->flow && PKT_IS_TCP(p)) { SCLogDebug("packet %"PRIu64" is TCP. Direction %s", p->pcap_cnt, PKT_IS_TOSERVER(p) ? "TOSERVER" : "TOCLIENT"); DEBUG_ASSERT_FLOW_LOCKED(p->flow); /* if detect is disabled, we need to apply file flags to the flow * here on the first packet. */ if (detect_thread == NULL && ((PKT_IS_TOSERVER(p) && (p->flowflags & FLOW_PKT_TOSERVER_FIRST)) || (PKT_IS_TOCLIENT(p) && (p->flowflags & FLOW_PKT_TOCLIENT_FIRST)))) { DisableDetectFlowFileFlags(p->flow); } FLOWWORKER_PROFILING_START(p, PROFILE_FLOWWORKER_STREAM); StreamTcp(tv, p, fw->stream_thread, &fw->pq, NULL); FLOWWORKER_PROFILING_END(p, PROFILE_FLOWWORKER_STREAM); if (FlowChangeProto(p->flow)) { StreamTcpDetectLogFlush(tv, fw->stream_thread, p->flow, p, &fw->pq); } /* Packets here can safely access p->flow as it's locked */ SCLogDebug("packet %"PRIu64": extra packets %u", p->pcap_cnt, fw->pq.len); Packet *x; while ((x = PacketDequeue(&fw->pq))) { SCLogDebug("packet %"PRIu64" extra packet %p", p->pcap_cnt, x); // TODO do we need to call StreamTcp on these pseudo packets or not? //StreamTcp(tv, x, fw->stream_thread, &fw->pq, NULL); if (detect_thread != NULL) { FLOWWORKER_PROFILING_START(x, PROFILE_FLOWWORKER_DETECT); Detect(tv, x, detect_thread, NULL, NULL); FLOWWORKER_PROFILING_END(x, PROFILE_FLOWWORKER_DETECT); } // Outputs OutputLoggerLog(tv, x, fw->output_thread); /* put these packets in the preq queue so that they are * by the other thread modules before packet 'p'. */ PacketEnqueue(preq, x); } /* handle the app layer part of the UDP packet payload */ } else if (p->flow && p->proto == IPPROTO_UDP) { FLOWWORKER_PROFILING_START(p, PROFILE_FLOWWORKER_APPLAYERUDP); AppLayerHandleUdp(tv, fw->stream_thread->ra_ctx->app_tctx, p, p->flow); FLOWWORKER_PROFILING_END(p, PROFILE_FLOWWORKER_APPLAYERUDP); } /* handle Detect */ DEBUG_ASSERT_FLOW_LOCKED(p->flow); SCLogDebug("packet %"PRIu64" calling Detect", p->pcap_cnt); if (detect_thread != NULL) { FLOWWORKER_PROFILING_START(p, PROFILE_FLOWWORKER_DETECT); Detect(tv, p, detect_thread, NULL, NULL); FLOWWORKER_PROFILING_END(p, PROFILE_FLOWWORKER_DETECT); } // Outputs. OutputLoggerLog(tv, p, fw->output_thread); /* Release tcp segments. Done here after alerting can use them. */ if (p->flow != NULL && p->proto == IPPROTO_TCP) { FLOWWORKER_PROFILING_START(p, PROFILE_FLOWWORKER_TCPPRUNE); StreamTcpPruneSession(p->flow, p->flowflags & FLOW_PKT_TOSERVER ? STREAM_TOSERVER : STREAM_TOCLIENT); FLOWWORKER_PROFILING_END(p, PROFILE_FLOWWORKER_TCPPRUNE); } if (p->flow) { DEBUG_ASSERT_FLOW_LOCKED(p->flow); FLOWLOCK_UNLOCK(p->flow); } return TM_ECODE_OK; }