Template
1
0
mirror of https://github.com/bol-van/zapret2.git synced 2026-03-14 06:13:09 +00:00

nfqws2,zapret-lib: check tcp seq overflow

This commit is contained in:
bol-van
2025-12-15 10:59:29 +03:00
parent 322b050e45
commit d06e4f4c82
7 changed files with 33 additions and 25 deletions

View File

@@ -106,3 +106,7 @@ v0.7.2
* zapret-auto: add success detector logic
* nfqws2: clean lua cutoff on profile change
* zapret-auto: separate hostkey function
v0.7.2
* nfqws2, zapret-lib : check tcp sequence range overflow

View File

@@ -234,6 +234,12 @@ function desync_orchestrator_example(ctx, desync)
return replay_execution_plan(desync)
end
-- if seq is over 2G s and p position comparision can be wrong
function pos_counter_overflow(desync, mode, reverse)
if not desync.track or not desync.track.tcp or (mode~='s' and mode~='p') then return false end
local track_pos = reverse and desync.track.pos.reverse or desync.track.pos.direct
return track_pos.tcp.seq_over_2G
end
-- these functions duplicate range check logic from C code
-- mode must be n,d,b,s,x,a
-- pos is {mode,pos}
@@ -265,7 +271,7 @@ function pos_get(desync, mode, reverse)
return 0
end
function pos_check_from(desync, range)
if range.from.mode == 'x' then return false end
if range.from.mode == 'x' or pos_counter_overflow(desync, range.from.mode) then return false end
if range.from.mode ~= 'a' then
if desync.track then
return pos_get(desync, range.from.mode) >= range.from.pos
@@ -277,7 +283,7 @@ function pos_check_from(desync, range)
end
function pos_check_to(desync, range)
local ps
if range.to.mode == 'x' then return false end
if range.to.mode == 'x' or pos_counter_overflow(desync, range.to.mode) then return false end
if range.to.mode ~= 'a' then
if desync.track then
ps = pos_get(desync, range.to.mode)

View File

@@ -155,6 +155,11 @@ static void ConntrackApplyPos(const struct tcphdr *tcp, t_ctrack *t, bool bRever
if (direct->scale != SCALE_NONE) direct->winsize_calc <<= direct->scale;
if (mss && !direct->mss) direct->mss = mss;
if (scale != SCALE_NONE) direct->scale = scale;
if (!direct->seq_over_2G && ((direct->seq_last - direct->seq0) & 0x80000000))
direct->seq_over_2G = true;
if (!reverse->seq_over_2G && ((reverse->seq_last - reverse->seq0) & 0x80000000))
reverse->seq_over_2G = true;
}
// non-tcp packets are passed with tcphdr=NULL but len_payload filled
@@ -208,19 +213,7 @@ static void ConntrackFeedPacket(t_ctrack *t, bool bReverse, const struct tcphdr
ConntrackApplyPos(tcphdr, t, bReverse, len_payload);
}
else
{
if (bReverse)
{
t->pos.server.seq_last = t->pos.server.pos;
t->pos.server.pos += len_payload;
}
else
{
t->pos.client.seq_last = t->pos.client.pos;
t->pos.client.pos += len_payload;
}
}
clock_gettime(CLOCK_REALTIME, &t->pos.t_last);
// make sure t_start gets exactly the same value as first t_last
if (!t->t_start.tv_sec) t->t_start = t->pos.t_last;

View File

@@ -17,17 +17,18 @@ typedef struct
uint64_t pcounter; // packet counter
uint64_t pdcounter; // data packet counter (with payload)
uint64_t pbcounter; // transferred byte counter. includes retransmissions. it's not the same as relative seq.
// 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 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
// tcp only state, not used in udp
uint32_t seq0; // starting seq and ack
uint16_t winsize; // last seen window size
uint16_t mss;
uint32_t winsize_calc; // calculated window size
uint8_t scale; // last seen window scale factor. SCALE_NONE if none
bool seq_over_2G;
} t_ctrack_position;
typedef struct

View File

@@ -505,7 +505,10 @@ static uint8_t ct_new_postnat_fix(const t_ctrack *ctrack, const struct dissect *
return VERDICT_DROP;
}
static bool pos_overflow(const t_ctrack_position *pos, char mode)
{
return (mode=='s' || mode=='p') && pos && pos->seq_over_2G;
}
static uint64_t pos_get(const t_ctrack_position *pos, char mode)
{
if (pos)
@@ -524,7 +527,7 @@ static uint64_t pos_get(const t_ctrack_position *pos, char mode)
static bool check_pos_from(const t_ctrack_position *pos, const struct packet_range *range)
{
uint64_t ps;
if (range->from.mode == 'x') return false;
if ((range->from.mode == 'x') || pos_overflow(pos,range->from.mode)) return false;
if (range->from.mode != 'a')
{
if (pos)
@@ -540,7 +543,7 @@ static bool check_pos_from(const t_ctrack_position *pos, const struct packet_ran
static bool check_pos_to(const t_ctrack_position *pos, const struct packet_range *range)
{
uint64_t ps;
if (range->to.mode == 'x') return false;
if (range->to.mode == 'x' || pos_overflow(pos,range->to.mode)) return false;
if (range->to.mode != 'a')
{
if (pos)
@@ -754,10 +757,12 @@ static uint8_t desync(
DLOG("* lua '%s' : voluntary cutoff\n", instance);
else if (check_pos_cutoff(pos, range))
{
DLOG("* lua '%s' : %s pos %c%llu %c%llu is beyond range %c%u%c%c%u (ctrack %s)\n",
DLOG("* lua '%s' : %s pos %c%llu %c%llu overflow %u %u is beyond range %c%u%c%c%u (ctrack %s)\n",
instance, sDirection,
range->from.mode, pos_get(pos, range->from.mode),
range->to.mode, pos_get(pos, range->to.mode),
pos_overflow(pos, range->from.mode),
pos_overflow(pos, range->to.mode),
range->from.mode, range->from.pos,
range->upper_cutoff ? '<' : '-',
range->to.mode, range->to.pos,

View File

@@ -13,10 +13,8 @@
#ifdef __linux__
#define DPI_DESYNC_FWMARK_DEFAULT 0x40000000
#elif defined(SO_USER_COOKIE)
#define DPI_DESYNC_FWMARK_DEFAULT 512
#else
#define DPI_DESYNC_FWMARK_DEFAULT 0
#define DPI_DESYNC_FWMARK_DEFAULT 512
#endif
uint8_t dpi_desync_packet(uint32_t fwmark, const char *ifin, const char *ifout, const uint8_t *data_pkt, size_t len_pkt, uint8_t *mod_pkt, size_t *len_mod_pkt);

View File

@@ -1282,7 +1282,7 @@ void lua_pushf_ctrack_pos(const t_ctrack *ctrack, const t_ctrack_position *pos)
if (ctrack->ipproto == IPPROTO_TCP)
{
lua_pushliteral(params.L, "tcp");
lua_createtable(params.L, 0, 10);
lua_createtable(params.L, 0, 11);
lua_pushf_lint("seq0", pos->seq0);
lua_pushf_lint("seq", pos->seq_last);
lua_pushf_lint("rseq", pos->seq_last - pos->seq0);
@@ -1293,6 +1293,7 @@ void lua_pushf_ctrack_pos(const t_ctrack *ctrack, const t_ctrack_position *pos)
lua_pushf_int("winsize_calc", pos->winsize_calc);
lua_pushf_int("scale", pos->scale);
lua_pushf_int("mss", pos->mss);
lua_pushf_bool("seq_over_2G", pos->seq_over_2G);
lua_rawset(params.L,-3);
}