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

zapret-antidpi: oob

This commit is contained in:
bol-van
2026-01-15 20:02:53 +03:00
parent 93d81ca4b2
commit 67a8ee47e3
3 changed files with 103 additions and 2 deletions

View File

@@ -183,3 +183,5 @@ v0.8.1
0.8.5
* nfqws2: do not require / in the beginning of URI in http
* zapret-lib: rawsend_dissect_segmented support URG
* zapret-antidpi: oob

View File

@@ -511,11 +511,10 @@ function multisplit(ctx, desync)
end
end
-- internal function for code deduplication. do not call directly
function pos_normalize(pos, low, hi)
return (pos>=low and pos<hi) and (pos-low+1) or nil
end
-- internal function for code deduplication. do not call directly
function pos_array_normalize(pos, low, hi)
-- remove positions outside of hi,low range. normalize others to low
local i=1
@@ -1055,6 +1054,94 @@ function tcpseg(ctx, desync)
end
end
-- nfqws1 : not available
-- tpws : close analog is "--split-pos=.. --oob" but works not the same way
-- arg : char=c - oob char
-- arg : byte=c - oob byte
-- arg : drop_ack - drop original first ACK packet
-- arg : urp - urgent pointer position marker, 'b' or 'e'. default - 0
function oob(ctx, desync)
if not desync.track then return end
if not desync.dis.tcp then
instance_cutoff_shim(ctx, desync)
return
end
if desync.outgoing then
-- direct pos - outgoing
local pos = pos_get(desync, 's', false)
if pos<=1 then
local dseq = u32add(desync.dis.tcp.th_seq, -1)
DLOG("oob: decreasing outgoing seq : "..desync.dis.tcp.th_seq.." => "..dseq)
desync.dis.tcp.th_seq = dseq
end
if pos==0 then
return VERDICT_MODIFY
elseif pos==1 then
local data = desync.reasm_data or desync.dis.payload
if not desync.arg.drop_ack and #data==0 then
DLOG("oob: sending empty ACK")
if not rawsend_dissect(desync.dis) then return end
end
if #data>0 then
local oob = desync.arg.char or (desync.arg.byte and bu8(desync.arg.byte) or nil) or "\x00"
local dis_oob = deepcopy(desync.dis)
local urp
if not desync.arg.urp or desync.arg.urp=='b' then
urp = 1
dis_oob.tcp.th_urp = 0
elseif desync.arg.urp=='e' then
urp = #data+1
dis_oob.tcp.th_urp = urp
else
urp = resolve_pos(data, desync.l7payload, desync.arg.urp)
DLOG("oob: resolved urp marker to "..urp-1)
if not urp then
DLOG("oob: cannot resolve urp marker '"..desync.arg.urp.."'")
instance_cutoff_shim(ctx, desync)
return
end
dis_oob.tcp.th_urp = urp
end
DLOG("oob: th_urp "..dis_oob.tcp.th_urp)
-- one byte OOB payload
dis_oob.payload = string.sub(data, 1, urp-1) .. oob .. string.sub(data, urp)
dis_oob.tcp.th_flags = bitor(dis_oob.tcp.th_flags, TH_URG)
DLOG("oob: sending OOB")
if not rawsend_dissect_segmented(desync, dis_oob, desync.tcp_mss, desync_opts(desync)) then
instance_cutoff_shim(ctx, desync)
return
end
if not desync.replay then
instance_cutoff_shim(ctx, desync)
end
end
return VERDICT_DROP
else
-- drop replay and cutoff
if desync.replay then
DLOG("oob: dropping replay piece")
if desync.replay_piece_last then
instance_cutoff_shim(ctx, desync)
end
return VERDICT_DROP
end
instance_cutoff_shim(ctx, desync)
end
else
-- reverse pos - outgoing
local pos = pos_get(desync, 's', true)
if pos>1 then
DLOG("oob: unexpected outgoing position "..pos)
instance_cutoff_shim(ctx, desync)
return
end
local dack = u32add(desync.dis.tcp.th_ack, 1)
DLOG("oob: increasing incoming ack : "..desync.dis.tcp.th_ack.." => "..dack)
desync.dis.tcp.th_ack = dack
return VERDICT_MODIFY
end
end
-- nfqws1 : "--dpi-desync=udplen"
-- standard args : direction, payload
-- arg : min=N . do not act on payloads smaller than N bytes

View File

@@ -310,6 +310,7 @@ function pos_str(desync, pos)
return pos.mode..pos_get(desync, pos.mode)
end
-- convert array a to packed string using 'packer' function. only numeric indexes starting from 1, order preserved
function barray(a, packer)
if a then
@@ -1075,6 +1076,8 @@ function rawsend_dissect_segmented(desync, dis, mss, options)
local extra_len = l3l4_extra_len(discopy)
if extra_len >= mss then return false end
local max_data = mss - extra_len
local urp = dis.tcp.th_urp
local oob = bitand(dis.tcp.th_flags, TH_URG)~=0
if #discopy.payload > max_data then
local pos=1
local len
@@ -1083,6 +1086,15 @@ function rawsend_dissect_segmented(desync, dis, mss, options)
while pos <= #payload do
len = #payload - pos + 1
if len > max_data then len = max_data end
if oob then
if urp>=pos and urp<(pos+len)then
discopy.tcp.th_flags = bitor(dis.tcp.th_flags, TH_URG)
discopy.tcp.th_urp = urp-pos+1
else
discopy.tcp.th_flags = bitand(dis.tcp.th_flags, bitnot(TH_URG))
discopy.tcp.th_urp = 0
end
end
discopy.payload = string.sub(payload,pos,pos+len-1)
apply_ip_id(desync, discopy, options and options.ipid)
if not rawsend_dissect_ipfrag(discopy, options) then