From 6e85c9650dae8448045a3bfa301c9ac15509c61f Mon Sep 17 00:00:00 2001 From: bol-van Date: Thu, 19 Feb 2026 17:38:46 +0300 Subject: [PATCH] nfqws2: use tcp seq for reasm_offset --- nfq2/conntrack.c | 2 +- nfq2/conntrack.h | 1 - nfq2/conntrack_base.h | 5 +++-- nfq2/desync.c | 25 ++++++++++++++++++++----- nfq2/lua.c | 2 +- nfq2/packet_queue.c | 10 +++++++++- nfq2/packet_queue.h | 3 ++- 7 files changed, 36 insertions(+), 12 deletions(-) diff --git a/nfq2/conntrack.c b/nfq2/conntrack.c index 8bdffdc..2f455c2 100644 --- a/nfq2/conntrack.c +++ b/nfq2/conntrack.c @@ -288,7 +288,7 @@ static bool ConntrackPoolFeedPool(t_conntrack_pool **pp, const struct dissect *d } return false; ok: - ctr->track.ipproto = proto; + ctr->track.pos.ipproto = proto; if (ctrack) *ctrack = &ctr->track; if (bReverse) *bReverse = b_rev; return true; diff --git a/nfq2/conntrack.h b/nfq2/conntrack.h index 62467b8..6a266ae 100644 --- a/nfq2/conntrack.h +++ b/nfq2/conntrack.h @@ -53,7 +53,6 @@ typedef struct { typedef struct { bool bCheckDone, bCheckResult, bCheckExcluded; // hostlist check result cache - uint8_t ipproto; struct timespec t_start; diff --git a/nfq2/conntrack_base.h b/nfq2/conntrack_base.h index d3d6ca2..a581676 100644 --- a/nfq2/conntrack_base.h +++ b/nfq2/conntrack_base.h @@ -21,10 +21,10 @@ typedef struct uint32_t ip6flow; // tcp only state, not used in udp - uint32_t pos; // TCP: seq_last+payload, ack_last+payload UDP: sum of all seen payload lenghts including current + uint32_t pos; // seq_last+payload, ack_last+payload uint32_t uppos; // max seen position. useful to detect retransmissions uint32_t uppos_prev; // previous max seen position. useful to detect retransmissions - uint32_t seq_last; // TCP: last seen seq and ack UDP: sum of all seen payload lenghts NOT including current + uint32_t seq_last; // last seen seq and ack uint32_t seq0; // starting seq and ack uint16_t winsize; // last seen window size uint16_t mss; @@ -38,5 +38,6 @@ typedef struct struct timespec t_last; t_connstate state; t_ctrack_position client, server; + uint8_t ipproto; } t_ctrack_positions; diff --git a/nfq2/desync.c b/nfq2/desync.c index ced24de..5937904 100644 --- a/nfq2/desync.c +++ b/nfq2/desync.c @@ -1581,7 +1581,7 @@ static uint8_t dpi_desync_tcp_packet_play( if (!ReasmIsEmpty(&ps.ctrack->reasm_client)) { - if (rawpacket_queue(&ps.ctrack->delayed, &ps.dst, fwmark, desync_fwmark, ifin, ifout, dis->data_pkt, dis->len_pkt, dis->len_payload, &ps.ctrack->pos)) + if (rawpacket_queue(&ps.ctrack->delayed, &ps.dst, fwmark, desync_fwmark, ifin, ifout, dis->data_pkt, dis->len_pkt, dis->len_payload, &ps.ctrack->pos, false)) { DLOG("DELAY desync until reasm is complete (#%u)\n", rawpacket_queue_count(&ps.ctrack->delayed)); } @@ -1810,7 +1810,7 @@ static uint8_t dpi_desync_udp_packet_play( } if (!ReasmIsEmpty(&ps.ctrack->reasm_client)) { - if (rawpacket_queue(&ps.ctrack->delayed, &ps.dst, fwmark, desync_fwmark, ifin, ifout, dis->data_pkt, dis->len_pkt, dis->len_payload, &ps.ctrack->pos)) + if (rawpacket_queue(&ps.ctrack->delayed, &ps.dst, fwmark, desync_fwmark, ifin, ifout, dis->data_pkt, dis->len_pkt, dis->len_payload, &ps.ctrack->pos, false)) { DLOG("DELAY desync until reasm is complete (#%u)\n", rawpacket_queue_count(&ps.ctrack->delayed)); } @@ -1850,7 +1850,7 @@ static uint8_t dpi_desync_udp_packet_play( if (!reasm_client_start(ps.ctrack, IPPROTO_UDP, UDP_MAX_REASM, UDP_MAX_REASM, clean, clean_len)) goto rediscover_cancel; } - if (rawpacket_queue(&ps.ctrack->delayed, &ps.dst, fwmark, desync_fwmark, ifin, ifout, dis->data_pkt, dis->len_pkt, dis->len_payload, &ps.ctrack->pos)) + if (rawpacket_queue(&ps.ctrack->delayed, &ps.dst, fwmark, desync_fwmark, ifin, ifout, dis->data_pkt, dis->len_pkt, dis->len_payload, &ps.ctrack->pos, false)) { DLOG("DELAY desync until reasm is complete (#%u)\n", rawpacket_queue_count(&ps.ctrack->delayed)); } @@ -2145,12 +2145,24 @@ static bool replay_queue(struct rawpacket_tailhead *q) struct rawpacket *rp; size_t offset; unsigned int i, count; - bool b = true; uint8_t mod[RECONSTRUCT_MAX_SIZE]; size_t modlen; + uint32_t seq0; + t_ctrack_position *pos; + bool b = true, bseq; - for (i = 0, offset = 0, count = rawpacket_queue_count(q); (rp = rawpacket_dequeue(q)); offset += rp->len_payload, rawpacket_free(rp), i++) + for (i = 0, offset = 0, count = rawpacket_queue_count(q); (rp = rawpacket_dequeue(q)); rawpacket_free(rp), i++) { + // TCP: track reasm_offset using sequence numbers + if ((bseq = rp->tpos_present && rp->tpos.ipproto==IPPROTO_TCP)) + { + pos = rp->server_side ? &rp->tpos.server : &rp->tpos.client; + if (i) + offset = pos->seq_last - seq0; + else + seq0 = pos->seq_last; + } + DLOG("REPLAYING delayed packet #%u offset %zu\n", i+1, offset); modlen = sizeof(mod); uint8_t verdict = dpi_desync_packet_play(i, count, offset, rp->fwmark_orig, rp->ifin, rp->ifout, rp->tpos_present ? &rp->tpos : NULL, rp->packet, rp->len, mod, &modlen); @@ -2168,6 +2180,9 @@ static bool replay_queue(struct rawpacket_tailhead *q) DLOG("DROPPING delayed packet #%u\n", i+1); break; } + + if (!bseq) + offset += rp->len_payload; } return b; } diff --git a/nfq2/lua.c b/nfq2/lua.c index a783bce..8748c5c 100644 --- a/nfq2/lua.c +++ b/nfq2/lua.c @@ -1658,7 +1658,7 @@ void lua_pushf_ctrack_pos(lua_State *L, const t_ctrack *ctrack, const t_ctrack_p lua_pushf_lint(L,"pdcounter", pos->pdcounter); lua_pushf_lint(L,"pbcounter", pos->pbcounter); if (pos->ip6flow) lua_pushf_int(L,"ip6_flow", pos->ip6flow); - if (ctrack->ipproto == IPPROTO_TCP) + if (ctrack->pos.ipproto == IPPROTO_TCP) { lua_pushliteral(L, "tcp"); lua_createtable(L, 0, 11); diff --git a/nfq2/packet_queue.c b/nfq2/packet_queue.c index a6e428e..c1b0836 100644 --- a/nfq2/packet_queue.c +++ b/nfq2/packet_queue.c @@ -26,7 +26,14 @@ void rawpacket_queue_destroy(struct rawpacket_tailhead *q) while((rp = rawpacket_dequeue(q))) rawpacket_free(rp); } -struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sockaddr_storage* dst,uint32_t fwmark_orig,uint32_t fwmark,const char *ifin,const char *ifout,const void *data,size_t len,size_t len_payload,const t_ctrack_positions *tpos) +struct rawpacket *rawpacket_queue( + struct rawpacket_tailhead *q, + const struct sockaddr_storage* dst, + uint32_t fwmark_orig,uint32_t fwmark, + const char *ifin,const char *ifout, + const void *data,size_t len,size_t len_payload, + const t_ctrack_positions *tpos, + bool server_side) { struct rawpacket *rp = malloc(sizeof(struct rawpacket)); if (!rp) return NULL; @@ -61,6 +68,7 @@ struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sock } else rp->tpos_present = false; + rp->server_side = server_side; TAILQ_INSERT_TAIL(q, rp, next); diff --git a/nfq2/packet_queue.h b/nfq2/packet_queue.h index bcde1b7..898991c 100644 --- a/nfq2/packet_queue.h +++ b/nfq2/packet_queue.h @@ -18,6 +18,7 @@ struct rawpacket uint8_t *packet; t_ctrack_positions tpos; bool tpos_present; + bool server_side; // true = reasm of packets from the server side TAILQ_ENTRY(rawpacket) next; }; TAILQ_HEAD(rawpacket_tailhead, rawpacket); @@ -26,6 +27,6 @@ void rawpacket_queue_init(struct rawpacket_tailhead *q); void rawpacket_queue_destroy(struct rawpacket_tailhead *q); bool rawpacket_queue_empty(const struct rawpacket_tailhead *q); unsigned int rawpacket_queue_count(const struct rawpacket_tailhead *q); -struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sockaddr_storage* dst,uint32_t fwmark_orig,uint32_t fwmark,const char *ifin,const char *ifout,const void *data,size_t len,size_t len_payload,const t_ctrack_positions *tpos); +struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sockaddr_storage* dst,uint32_t fwmark_orig,uint32_t fwmark,const char *ifin,const char *ifout,const void *data,size_t len,size_t len_payload,const t_ctrack_positions *tpos,bool server_side); struct rawpacket *rawpacket_dequeue(struct rawpacket_tailhead *q); void rawpacket_free(struct rawpacket *rp);