mirror of
https://github.com/bol-van/zapret2.git
synced 2026-03-14 06:13:09 +00:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b6ea88a23 | ||
|
|
59235827c4 | ||
|
|
7073e1fd77 | ||
|
|
340261da72 | ||
|
|
937aa91e5d | ||
|
|
dbf673e24a | ||
|
|
61b0a70fa7 | ||
|
|
d985bb316f | ||
|
|
59b3734643 | ||
|
|
37f45a132f | ||
|
|
4d753ecdc6 | ||
|
|
272f086639 | ||
|
|
d9ae16e56f | ||
|
|
46d4208c76 | ||
|
|
2a4195070f | ||
|
|
8e974e78e2 | ||
|
|
7df42bc486 | ||
|
|
7c12f60e1e | ||
|
|
4c7a3d08d8 | ||
|
|
e146fc24c5 | ||
|
|
6165c13468 | ||
|
|
f7b3946ec2 |
29
.github/workflows/build.yml
vendored
29
.github/workflows/build.yml
vendored
@@ -490,17 +490,28 @@ jobs:
|
||||
pattern: zapret2-*
|
||||
|
||||
- name: Install upx
|
||||
uses: crazy-max/ghaction-upx@v3
|
||||
with:
|
||||
install-only: true
|
||||
version: v5.1.0
|
||||
shell: bash
|
||||
env:
|
||||
VER_OLD: 4.2.4
|
||||
VER_NEW: 5.1.0
|
||||
run: |
|
||||
# old upx works for old kernels like 2.6.26
|
||||
# new upx crashes on ~<3.10 but required for riscv64
|
||||
curl -Lo - https://github.com/upx/upx/releases/download/v$VER_OLD/upx-$VER_OLD-amd64_linux.tar.xz | tar -Jx upx-$VER_OLD-amd64_linux/upx
|
||||
sudo cp upx-$VER_OLD-amd64_linux/upx /usr/local/bin/upx_old
|
||||
curl -Lo - https://github.com/upx/upx/releases/download/v$VER_NEW/upx-$VER_NEW-amd64_linux.tar.xz | tar -Jx upx-$VER_NEW-amd64_linux/upx
|
||||
sudo cp upx-$VER_NEW-amd64_linux/upx /usr/local/bin/upx_new
|
||||
rm -r upx-$VER_OLD-amd64_linux/upx upx-$VER_NEW-amd64_linux/upx
|
||||
|
||||
- name: Prepare binaries
|
||||
shell: bash
|
||||
run: |
|
||||
cd ${{ steps.bins.outputs.download-path }}
|
||||
run_upx() {
|
||||
upx --best --lzma $@ || true
|
||||
run_upx_old() {
|
||||
upx_old --best --lzma $@ || true
|
||||
}
|
||||
run_upx_new() {
|
||||
upx_new --best --lzma $@ || true
|
||||
}
|
||||
run_dir() {
|
||||
for f in $dir/* ; do
|
||||
@@ -508,8 +519,10 @@ jobs:
|
||||
case $f in
|
||||
*.tar.xz )
|
||||
tar -C $dir -xvf $f && rm $f
|
||||
if [[ $dir =~ linux ]] && [[ $dir != *-linux-mips64 ]] && [[ $dir != *-linux-lexra ]]; then
|
||||
run_upx $dir/*
|
||||
if [[ $dir = *-linux-riscv64 ]]; then
|
||||
run_upx_new $dir/*
|
||||
elif [[ $dir =~ linux ]] && [[ $dir != *-linux-mips64 ]] && [[ $dir != *-linux-lexra ]]; then
|
||||
run_upx_old $dir/*
|
||||
fi
|
||||
;;
|
||||
*.zip )
|
||||
|
||||
@@ -252,4 +252,10 @@ v0.9.4
|
||||
v0.9.4.2
|
||||
|
||||
* builder_linux: simple scripts to build static linux bins for any supported architecture
|
||||
* zapret-auto: incompatible change. cond_code "code" parameter => "cond_code". to avoid collision with luaexec
|
||||
* zapret-auto: incompatible change. cond_lua "code" parameter => "cond_code". to avoid collision with luaexec
|
||||
|
||||
v0.9.4.3
|
||||
|
||||
* nfqws2: fix broken wifi ssid update
|
||||
* github: revert to upx 4.2.4 for all archs except riscv64
|
||||
* zapret-lib: apply_fooling throws error if tcp_ts,tcp_seq,tcp_ack,ip_ttl,ip6_ttl,ip_autottl,ip6_autottl are empty or invalid
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
REGISTER sip:192.168.1.1 SIP/2.0
|
||||
Via: SIP/2.0/UDP 192.168.1.2:42931;rport;branch=z9hG4bKPj3fd2e8713ffcd90c43f6ce69f6c98461
|
||||
Max-Forwards: 50
|
||||
From: <sip:703@192.168.1.1>;tag=ca565d7bd4e24a6d80c631d395ee117e
|
||||
To: <sip:703@192.168.1.1>
|
||||
Call-ID: dfec38302b8cea3d83c1452527c895c1
|
||||
CSeq: 26139 REGISTER
|
||||
User-Agent: MicroSIP/3.21.5
|
||||
Contact: <sip:703@192.168.1.2:42931;ob>
|
||||
Expires: 300
|
||||
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
|
||||
Content-Length: 0
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
WEBSERVER_DEFAULT_STRATEGY="
|
||||
--server
|
||||
--payload http_reply,tls_server_hello --lua-desync=fake:blob=0x00000000000000000000000000000000:badsum:repeats=2 --lua-desync=multisplit
|
||||
--payload empty --lua-desync=synack_split"
|
||||
--payload=http_reply,tls_server_hello --lua-desync=fake:blob=0x00000000000000000000000000000000:badsum:repeats=2 --lua-desync=multisplit
|
||||
--payload=empty --lua-desync=synack_split"
|
||||
|
||||
# can override in config :
|
||||
NFQWS_OPT_DESYNC_WEBSERVER="${NFQWS_OPT_DESYNC_WEBSERVER:-$WEBSERVER_DEFAULT_STRATEGY}"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22)
|
||||
|
||||
# can override in config :
|
||||
NFQWS_OPT_DESYNC_DHT="${NFQWS_OPT_DESYNC_DHT:---payload dht --lua-desync=dht_dn}"
|
||||
NFQWS_OPT_DESYNC_DHT="${NFQWS_OPT_DESYNC_DHT:---payload=dht --lua-desync=dht_dn}"
|
||||
# set it to "keepalive" to fool all packets, not just the first. or set number of packets to be fooled.
|
||||
NFQWS_OPT_DHT_PKT_OUT=${NFQWS_OPT_DHT_PKT_OUT:-20}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22)
|
||||
|
||||
# can override in config :
|
||||
NFQWS_OPT_DESYNC_DISCORD_MEDIA="${NFQWS_OPT_DESYNC_DISCORD_MEDIA:---payload discord_ip_discovery --lua-desync=fake:blob=0x00000000000000000000000000000000:repeats=2}"
|
||||
NFQWS_OPT_DESYNC_DISCORD_MEDIA="${NFQWS_OPT_DESYNC_DISCORD_MEDIA:---payload=discord_ip_discovery --lua-desync=fake:blob=0x00000000000000000000000000000000:repeats=2}"
|
||||
DISCORD_MEDIA_PORT_RANGE="${DISCORD_MEDIA_PORT_RANGE:-50000-50099}"
|
||||
|
||||
alloc_dnum DNUM_DISCORD_MEDIA
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# this custom script demonstrates how to launch extra nfqws instance limited by ipset
|
||||
|
||||
# can override in config :
|
||||
NFQWS2_MY1_OPT="${NFQWS2_MY1_OPT:---filter-udp=* --payload known,unknown --lua-desync=fake:blob=0x00000000000000000000000000000000:repeats=2:payload=all --new --filter-tcp=* --payload=known,unknown --lua-desync=multisplit}"
|
||||
NFQWS2_MY1_OPT="${NFQWS2_MY1_OPT:---filter-udp=* --payload=known,unknown --lua-desync=fake:blob=0x00000000000000000000000000000000:repeats=2:payload=all --new --filter-tcp=* --payload=known,unknown --lua-desync=multisplit}"
|
||||
NFQWS2_MY1_SUBNETS4="${NFQWS2_MY1_SUBNETS4:-173.194.0.0/16 108.177.0.0/17 74.125.0.0/16 64.233.160.0/19 172.217.0.0/16}"
|
||||
NFQWS2_MY1_SUBNETS6="${NFQWS2_MY1_SUBNETS6:-2a00:1450::/29}"
|
||||
NFQWS2_MY1_PORTS_TCP=${NFQWS2_MY1_PORTS_TCP:-$NFQWS2_PORTS_TCP}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22)
|
||||
|
||||
# can override in config :
|
||||
NFQWS_OPT_DESYNC_QUIC="${NFQWS_OPT_DESYNC_QUIC:---payload quic_initial --lua-desync=fake:blob=fake_default_quic:repeats=2}"
|
||||
NFQWS_OPT_DESYNC_QUIC="${NFQWS_OPT_DESYNC_QUIC:---payload=quic_initial --lua-desync=fake:blob=fake_default_quic:repeats=2}"
|
||||
|
||||
alloc_dnum DNUM_QUIC4ALL
|
||||
alloc_qnum QNUM_QUIC4ALL
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22)
|
||||
|
||||
# can override in config :
|
||||
NFQWS_OPT_DESYNC_STUN="${NFQWS_OPT_DESYNC_STUN:---payload stun --lua-desync=fake:blob=0x00000000000000000000000000000000:repeats=2}"
|
||||
NFQWS_OPT_DESYNC_STUN="${NFQWS_OPT_DESYNC_STUN:---payload=stun --lua-desync=fake:blob=0x00000000000000000000000000000000:repeats=2}"
|
||||
|
||||
alloc_dnum DNUM_STUN4ALL
|
||||
alloc_qnum QNUM_STUN4ALL
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# NOTE: @ih requires nft 1.0.1+ and updated kernel version. it's confirmed to work on 5.15 (openwrt 23) and not work on 5.10 (openwrt 22)
|
||||
|
||||
# can override in config :
|
||||
NFQWS_OPT_DESYNC_WG="${NFQWS_OPT_DESYNC_WG:---payload wireguard_initiation,wireguard_response,wireguard_cookie --lua-desync=fake:blob=0x00000000000000000000000000000000:repeats=2}"
|
||||
NFQWS_OPT_DESYNC_WG="${NFQWS_OPT_DESYNC_WG:---payload=wireguard_initiation,wireguard_response,wireguard_cookie --lua-desync=fake:blob=0x00000000000000000000000000000000:repeats=2}"
|
||||
|
||||
alloc_dnum DNUM_WG4ALL
|
||||
alloc_qnum QNUM_WG4ALL
|
||||
|
||||
@@ -729,14 +729,15 @@ function hostfakesplit(ctx, desync)
|
||||
local midhost
|
||||
if desync.arg.midhost then
|
||||
midhost = resolve_pos(data,desync.l7payload,desync.arg.midhost)
|
||||
if not midhost then
|
||||
if midhost then
|
||||
DLOG("hosfakesplit: midhost marker resolved to "..midhost)
|
||||
if midhost<=pos[1] or midhost>pos[2] then
|
||||
DLOG("hostfakesplit: midhost is not inside the host range")
|
||||
midhost = nil
|
||||
end
|
||||
else
|
||||
DLOG("hostfakesplit: cannot resolve midhost marker '"..desync.arg.midhost.."'")
|
||||
end
|
||||
DLOG("hosfakesplit: midhost marker resolved to "..midhost)
|
||||
if midhost<=pos[1] or midhost>pos[2] then
|
||||
DLOG("hostfakesplit: midhost is not inside the host range")
|
||||
midhost = nil
|
||||
end
|
||||
end
|
||||
-- if present apply ipfrag only to real host parts. fakes and parts outside of the host must be visible to DPI.
|
||||
if midhost then
|
||||
@@ -942,7 +943,7 @@ function fakeddisorder(ctx, desync)
|
||||
local opts_orig = {rawsend = rawsend_opts_base(desync), reconstruct = {}, ipfrag = {}, ipid = desync.arg, fooling = {tcp_ts_up = desync.arg.tcp_ts_up}}
|
||||
local opts_fake = {rawsend = rawsend_opts(desync), reconstruct = reconstruct_opts(desync), ipfrag = {}, ipid = desync.arg, fooling = desync.arg}
|
||||
|
||||
fakepat = desync.arg.pattern and blob(desync,desync.arg.pattern) or "\x00"
|
||||
local fakepat = desync.arg.pattern and blob(desync,desync.arg.pattern) or "\x00"
|
||||
|
||||
-- second fake
|
||||
fake = pattern(fakepat,pos,#data-pos+1)
|
||||
|
||||
@@ -96,7 +96,7 @@ function detect_payload_str(ctx, desync)
|
||||
error("detect_payload_str: missing 'pattern'")
|
||||
end
|
||||
local data = desync.reasm_data or desync.dis.payload
|
||||
local b = string.find(data,desync.arg.pattern,1,true)
|
||||
local b = data and string.find(data,desync.arg.pattern,1,true)
|
||||
if b then
|
||||
DLOG("detect_payload_str: detected '"..desync.arg.payload.."'")
|
||||
if desync.arg.payload then desync.l7payload = desync.arg.payload end
|
||||
@@ -337,9 +337,8 @@ end
|
||||
|
||||
-- convert array a to packed string using 'packer' function. only numeric indexes starting from 1, order preserved
|
||||
function barray(a, packer)
|
||||
local sa={}
|
||||
if a then
|
||||
local s=""
|
||||
local sa={}
|
||||
for i=1,#a do
|
||||
sa[i] = packer(a[i])
|
||||
end
|
||||
@@ -348,16 +347,16 @@ function barray(a, packer)
|
||||
end
|
||||
-- convert table a to packed string using 'packer' function. any indexes, any order
|
||||
function btable(a, packer)
|
||||
local sa={}
|
||||
if a then
|
||||
local s=""
|
||||
local sa={}
|
||||
local i=1
|
||||
for k,v in pairs(a) do
|
||||
sa[k] = packer(v)
|
||||
sa[i] = packer(v)
|
||||
i=i+1
|
||||
end
|
||||
return table.concat(sa)
|
||||
end
|
||||
end
|
||||
|
||||
-- sequence comparision functions. they work only within 2G interval
|
||||
-- seq1>=seq2
|
||||
function seq_ge(seq1, seq2)
|
||||
@@ -876,7 +875,11 @@ function apply_fooling(desync, dis, fooling_options)
|
||||
if type(desync.track.lua_state.autottl_cache)~="table" then desync.track.lua_state.autottl_cache={} end
|
||||
if type(desync.track.lua_state.autottl_cache[desync.func_instance])~="table" then desync.track.lua_state.autottl_cache[desync.func_instance]={} end
|
||||
if not desync.track.lua_state.autottl_cache[desync.func_instance].autottl_found then
|
||||
desync.track.lua_state.autottl_cache[desync.func_instance].autottl = autottl(desync.track.incoming_ttl,parse_autottl(arg_autottl))
|
||||
attl = parse_autottl(arg_autottl)
|
||||
if not attl then
|
||||
error("apply_fooling: invalid autottl value '"..arg_autottl.."'")
|
||||
end
|
||||
desync.track.lua_state.autottl_cache[desync.func_instance].autottl = autottl(desync.track.incoming_ttl,attl)
|
||||
if desync.track.lua_state.autottl_cache[desync.func_instance].autottl then
|
||||
desync.track.lua_state.autottl_cache[desync.func_instance].autottl_found = true
|
||||
DLOG("apply_fooling: discovered autottl "..desync.track.lua_state.autottl_cache[desync.func_instance].autottl)
|
||||
@@ -891,8 +894,11 @@ function apply_fooling(desync, dis, fooling_options)
|
||||
DLOG("apply_fooling: cannot apply autottl because incoming ttl unknown")
|
||||
end
|
||||
end
|
||||
if not ttl and tonumber(arg_ttl) then
|
||||
if not ttl and arg_ttl then
|
||||
ttl = tonumber(arg_ttl)
|
||||
if not ttl or ttl<0 or ttl>255 then
|
||||
error("apply_fooling: ip_ttl and ip6_ttl require valid value")
|
||||
end
|
||||
end
|
||||
--io.stderr:write("TTL "..tostring(ttl).."\n")
|
||||
return ttl
|
||||
@@ -909,11 +915,19 @@ function apply_fooling(desync, dis, fooling_options)
|
||||
-- use current packet if dissect not given
|
||||
if not dis then dis = desync.dis end
|
||||
if dis.tcp then
|
||||
if tonumber(fooling_options.tcp_seq) then
|
||||
dis.tcp.th_seq = u32add(dis.tcp.th_seq, fooling_options.tcp_seq)
|
||||
if fooling_options.tcp_seq then
|
||||
if tonumber(fooling_options.tcp_seq) then
|
||||
dis.tcp.th_seq = u32add(dis.tcp.th_seq, fooling_options.tcp_seq)
|
||||
else
|
||||
error("apply_fooling: tcp_seq requires increment parameter. there's no default value.")
|
||||
end
|
||||
end
|
||||
if tonumber(fooling_options.tcp_ack) then
|
||||
dis.tcp.th_ack = u32add(dis.tcp.th_ack, fooling_options.tcp_ack)
|
||||
if fooling_options.tcp_ack then
|
||||
if tonumber(fooling_options.tcp_ack) then
|
||||
dis.tcp.th_ack = u32add(dis.tcp.th_ack, fooling_options.tcp_ack)
|
||||
else
|
||||
error("apply_fooling: tcp_ack requires increment parameter. there's no default value.")
|
||||
end
|
||||
end
|
||||
if fooling_options.tcp_flags_unset then
|
||||
dis.tcp.th_flags = bitand(dis.tcp.th_flags, bitnot(parse_tcp_flags(fooling_options.tcp_flags_unset)))
|
||||
@@ -928,12 +942,16 @@ function apply_fooling(desync, dis, fooling_options)
|
||||
end
|
||||
end
|
||||
end
|
||||
if tonumber(fooling_options.tcp_ts) then
|
||||
local idx = find_tcp_option(dis.tcp.options,TCP_KIND_TS)
|
||||
if idx and (dis.tcp.options[idx].data and #dis.tcp.options[idx].data or 0)==8 then
|
||||
dis.tcp.options[idx].data = bu32(u32add(u32(dis.tcp.options[idx].data),fooling_options.tcp_ts))..string.sub(dis.tcp.options[idx].data,5)
|
||||
if fooling_options.tcp_ts then
|
||||
if tonumber(fooling_options.tcp_ts) then
|
||||
local idx = find_tcp_option(dis.tcp.options,TCP_KIND_TS)
|
||||
if idx and (dis.tcp.options[idx].data and #dis.tcp.options[idx].data or 0)==8 then
|
||||
dis.tcp.options[idx].data = bu32(u32add(u32(dis.tcp.options[idx].data),fooling_options.tcp_ts))..string.sub(dis.tcp.options[idx].data,5)
|
||||
else
|
||||
DLOG("apply_fooling: timestamp tcp option not present or invalid")
|
||||
end
|
||||
else
|
||||
DLOG("apply_fooling: timestamp tcp option not present or invalid")
|
||||
error("apply_fooling: tcp_ts requires increment parameter. there's no default value.")
|
||||
end
|
||||
end
|
||||
if fooling_options.tcp_md5 then
|
||||
@@ -1619,9 +1637,9 @@ function gzip_file(filename, data, expected_ratio, level, memlevel, compress_blo
|
||||
if not gz then
|
||||
error("gzip_file: stream init error")
|
||||
end
|
||||
local off=1, block_size
|
||||
local off=1
|
||||
repeat
|
||||
block_size = #data-off+1
|
||||
local block_size = #data-off+1
|
||||
if block_size>compress_block_size then block_size=compress_block_size end
|
||||
local comp, eof = gzip_deflate(gz, string.sub(data,off,off+block_size-1), block_size / expected_ratio)
|
||||
if not comp then
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
function pcap_write_header(file)
|
||||
-- big endian, nanoseconds in timestamps, ver 2.4, max packet size - 0x4000 (16384), 0x65 - l3 packets without l2
|
||||
file:write("\xA1\xB2\x3C\x4D\x00\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x00\x65")
|
||||
-- big endian, nanoseconds in timestamps, ver 2.4, max packet size - 0xFFFF (65535), 0x65 - l3 packets without l2
|
||||
file:write("\xA1\xB2\x3C\x4D\x00\x02\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x65")
|
||||
end
|
||||
function pcap_write_packet(file, raw)
|
||||
local sec, nsec = clock_gettime();
|
||||
@@ -34,6 +34,7 @@ function pcap(ctx, desync)
|
||||
if not f then
|
||||
error("pcap: could not write to '".._G[fn_cache_name].."'")
|
||||
end
|
||||
pcap_write(f, raw_packet(ctx))
|
||||
local raw = ctx and raw_packet(ctx) or reconstruct_dissect(desync.dis)
|
||||
pcap_write(f, raw)
|
||||
f:close()
|
||||
end
|
||||
|
||||
@@ -148,7 +148,7 @@ static void ConntrackApplyPos(t_ctrack *t, bool bReverse, const struct dissect *
|
||||
if (scale != SCALE_NONE) direct->scale = scale;
|
||||
direct->mss = tcp_find_mss(dis->tcp);
|
||||
}
|
||||
else if (direct->scale != SCALE_NONE)
|
||||
else
|
||||
// apply scale only outside of the SYN stage
|
||||
direct->winsize_calc <<= direct->scale;
|
||||
|
||||
@@ -172,9 +172,6 @@ static void ConntrackApplyPos(t_ctrack *t, bool bReverse, const struct dissect *
|
||||
|
||||
static void ConntrackFeedPacket(t_ctrack *t, bool bReverse, const struct dissect *dis)
|
||||
{
|
||||
uint8_t scale;
|
||||
uint16_t mss;
|
||||
|
||||
if (bReverse)
|
||||
{
|
||||
t->pos.server.pcounter++;
|
||||
@@ -370,8 +367,8 @@ void ConntrackPoolDump(const t_conntrack *p)
|
||||
t->track.pos.client.seq0, t->track.pos.client.seq_last - t->track.pos.client.seq0, t->track.pos.client.pos - t->track.pos.client.seq0,
|
||||
t->track.pos.server.seq0, t->track.pos.server.seq_last - t->track.pos.server.seq0, t->track.pos.server.pos - t->track.pos.server.seq0,
|
||||
t->track.pos.client.mss, t->track.pos.server.mss,
|
||||
t->track.pos.client.winsize, t->track.pos.client.scale == SCALE_NONE ? -1 : t->track.pos.client.scale,
|
||||
t->track.pos.server.winsize, t->track.pos.server.scale == SCALE_NONE ? -1 : t->track.pos.server.scale);
|
||||
t->track.pos.client.winsize, t->track.pos.client.scale,
|
||||
t->track.pos.server.winsize, t->track.pos.server.scale);
|
||||
else
|
||||
printf("rseq=%u client.pos=%u rack=%u server.pos=%u",
|
||||
t->track.pos.client.seq_last, t->track.pos.client.pos,
|
||||
|
||||
@@ -29,7 +29,7 @@ typedef struct
|
||||
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
|
||||
uint8_t scale; // last seen window scale factor
|
||||
bool rseq_over_2G;
|
||||
} t_ctrack_position;
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ uint32_t net32_add(uint32_t netorder_value, uint32_t cpuorder_increment)
|
||||
{
|
||||
return htonl(ntohl(netorder_value)+cpuorder_increment);
|
||||
}
|
||||
uint32_t net16_add(uint16_t netorder_value, uint16_t cpuorder_increment)
|
||||
uint16_t net16_add(uint16_t netorder_value, uint16_t cpuorder_increment)
|
||||
{
|
||||
return htons(ntohs(netorder_value)+cpuorder_increment);
|
||||
}
|
||||
@@ -229,7 +229,7 @@ uint16_t family_from_proto(uint8_t l3proto)
|
||||
{
|
||||
case IPPROTO_IP: return AF_INET;
|
||||
case IPPROTO_IPV6: return AF_INET6;
|
||||
default: return -1;
|
||||
default: return AF_UNSPEC;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -557,11 +557,15 @@ void proto_dissect_l3l4(const uint8_t *data, size_t len, struct dissect *dis, bo
|
||||
dis->data_pkt = data;
|
||||
dis->len_pkt = len;
|
||||
|
||||
uint16_t iplen;
|
||||
|
||||
if (proto_check_ipv4(data, len) && (no_payload_check || proto_check_ipv4_payload(data, len)))
|
||||
{
|
||||
dis->ip = (const struct ip *) data;
|
||||
dis->proto = dis->ip->ip_p;
|
||||
p = data;
|
||||
iplen = ntohs(((struct ip*)data)->ip_len);
|
||||
if (iplen<len) dis->len_pkt = len = iplen;
|
||||
proto_skip_ipv4(&data, &len, &dis->frag, &dis->frag_off);
|
||||
dis->len_l3 = data-p;
|
||||
}
|
||||
@@ -569,6 +573,8 @@ void proto_dissect_l3l4(const uint8_t *data, size_t len, struct dissect *dis, bo
|
||||
{
|
||||
dis->ip6 = (const struct ip6_hdr *) data;
|
||||
p = data;
|
||||
iplen = ntohs(((struct ip6_hdr*)data)->ip6_ctlun.ip6_un1.ip6_un1_plen) + sizeof(struct ip6_hdr);
|
||||
if (iplen<len) dis->len_pkt = len = iplen;
|
||||
proto_skip_ipv6(&data, &len, &dis->proto, &dis->frag, &dis->frag_off);
|
||||
dis->len_l3 = data-p;
|
||||
}
|
||||
@@ -2154,8 +2160,8 @@ static uint8_t *find_ie(uint8_t *buf, size_t len, uint8_t ie)
|
||||
{
|
||||
if (len<(2+buf[1])) break;
|
||||
if (buf[0]==ie) return buf;
|
||||
buf+=buf[1]+2;
|
||||
len-=buf[1]+2;
|
||||
buf+=buf[1]+2;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -2238,6 +2244,7 @@ static bool scan_info(struct mnl_socket* nl, uint16_t wlan_family_id, struct wla
|
||||
// wlan_info does not return ssid since kernel 5.19
|
||||
// it's used to enumerate all wifi interfaces then call scan_info on each
|
||||
if (!wlan_info(nl, wlan_family_id, &wc_all, false)) return false;
|
||||
w->count=0;
|
||||
for(int i=0;i<wc_all.count;i++)
|
||||
if (!netlink_genl_simple_transact(nl, wlan_family_id, NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0, scan_prepare, (void*)&wc_all.wlan[i].ifindex, scan_info_cb, w))
|
||||
return false;
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
|
||||
// returns netorder value
|
||||
uint32_t net32_add(uint32_t netorder_value, uint32_t cpuorder_increment);
|
||||
uint32_t net16_add(uint16_t netorder_value, uint16_t cpuorder_increment);
|
||||
uint16_t net16_add(uint16_t netorder_value, uint16_t cpuorder_increment);
|
||||
|
||||
#define SCALE_NONE ((uint8_t)-1)
|
||||
|
||||
|
||||
@@ -1648,9 +1648,12 @@ static const uint8_t *dns_extract_name(const uint8_t *a, const uint8_t *b, const
|
||||
{
|
||||
size_t nl, off;
|
||||
const uint8_t *p;
|
||||
bool bptr = (*a & 0xC0)==0xC0;
|
||||
bool bptr;
|
||||
uint8_t x,y;
|
||||
|
||||
if (!name_size) return NULL;
|
||||
|
||||
bptr = (*a & 0xC0)==0xC0;
|
||||
if (bptr)
|
||||
{
|
||||
if (a+1>=e) return NULL;
|
||||
@@ -1665,66 +1668,115 @@ static const uint8_t *dns_extract_name(const uint8_t *a, const uint8_t *b, const
|
||||
if (p>=e) return NULL;
|
||||
for (nl=0; *p ;)
|
||||
{
|
||||
if (nl)
|
||||
{
|
||||
if (nl>=name_size) return NULL;
|
||||
name[nl++] = '.';
|
||||
}
|
||||
// do not support mixed ptr+real
|
||||
if ((*p & 0xC0) || (p+*p+1)>=e || (*p+1)>=(name_size-nl)) return NULL;
|
||||
if (nl) name[nl++] = '.';
|
||||
for(y=*p++,x=0 ; x<y ; x++,p++) name[nl+x] = tolower(*p);
|
||||
nl += y;
|
||||
}
|
||||
if (nl>=name_size) return NULL;
|
||||
name[nl] = 0;
|
||||
return bptr ? a+2 : p+1;
|
||||
}
|
||||
static bool dns_skip_name(const uint8_t **a, size_t *len)
|
||||
{
|
||||
// 11 higher bits indicate pointer
|
||||
// lazy skip name. mixed compressed/uncompressed names are supported
|
||||
for(;;)
|
||||
{
|
||||
if (*len<2) return false;
|
||||
if ((**a & 0xC0)==0xC0)
|
||||
{
|
||||
// pointer is the end
|
||||
(*a)+=2; (*len)-=2;
|
||||
break;
|
||||
}
|
||||
if (!**a)
|
||||
{
|
||||
// zero length is the end
|
||||
(*a)++; (*len)--;
|
||||
break;
|
||||
}
|
||||
if (*len<(**a+1)) return false;
|
||||
*len-=**a+1;
|
||||
*a+=**a+1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool feed_dns_response(const uint8_t *a, size_t len)
|
||||
{
|
||||
if (!params.cache_hostname) return true;
|
||||
|
||||
// check of minimum header length and response flag
|
||||
uint16_t k, off, dlen, qcount = a[4]<<8 | a[5], acount = a[6]<<8 | a[7];
|
||||
uint16_t k, typ, off, dlen, qcount = a[4]<<8 | a[5], acount = a[6]<<8 | a[7];
|
||||
char s_ip[INET6_ADDRSTRLEN];
|
||||
const uint8_t *b = a, *p;
|
||||
const uint8_t *e = b + len;
|
||||
size_t nl;
|
||||
char name[256] = "";
|
||||
|
||||
if (len<12 || !(a[2]&0x80)) return false;
|
||||
a+=12; len-=12;
|
||||
for(k=0;k<qcount;k++)
|
||||
if (!qcount || len<12 || !(a[2]&0x80)) return false;
|
||||
if (!acount)
|
||||
{
|
||||
DLOG("skipping DNS response without answer\n");
|
||||
return false;
|
||||
}
|
||||
a+=12; len-=12;
|
||||
for(k=0,*name = 0 ; k<qcount ; k++)
|
||||
{
|
||||
if (*name) return false; // we do not support multiple queries with names
|
||||
// remember original query name
|
||||
if (!(p = dns_extract_name(a, b, e, name, sizeof(name)))) return false;
|
||||
len -= p-a;
|
||||
if ((len<4) || p[2] || p[3]!=1) return false;
|
||||
typ = pntoh16(p);
|
||||
// must be A or AAAA query. others are not interesting
|
||||
if ((len<4) || p[0] || p[1]!=1 && p[1]!=28 || p[2] || p[3]!=1) return false;
|
||||
if (typ!=1 && typ!=28)
|
||||
{
|
||||
DLOG("skipping DNS query type %u for '%s'\n", typ, name);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
DLOG("DNS query type %u for '%s'\n", typ, name);
|
||||
}
|
||||
// skip type, class
|
||||
a=p+4; len-=4;
|
||||
}
|
||||
if (!*name) return false;
|
||||
for(k=0;k<acount;k++)
|
||||
{
|
||||
// 11 higher bits indicate pointer
|
||||
if (len<12 || (*a & 0xC0)!=0xC0) return false;
|
||||
|
||||
dlen = a[10]<<8 | a[11];
|
||||
if (len<(dlen+12)) return false;
|
||||
if (a[4]==0 && a[5]==1 && a[2]==0) // IN class and higher byte of type = 0
|
||||
if (!dns_skip_name(&a,&len)) return false;
|
||||
if (len<10) return false;
|
||||
dlen = a[8]<<8 | a[9];
|
||||
if (len<(dlen+10)) return false;
|
||||
if (a[2]==0 && a[3]==1) // IN class
|
||||
{
|
||||
switch(a[3])
|
||||
typ = pntoh16(a);
|
||||
switch(typ)
|
||||
{
|
||||
case 1: // A
|
||||
if (dlen!=4) break;
|
||||
if (params.debug && inet_ntop(AF_INET, a+12, s_ip, sizeof(s_ip)))
|
||||
DLOG("DNS response : %s\n", s_ip);
|
||||
ipcache_put_hostname((struct in_addr *)(a+12), NULL, name, false);
|
||||
if (params.debug && inet_ntop(AF_INET, a+10, s_ip, sizeof(s_ip)))
|
||||
DLOG("DNS response type %u : %s\n", typ, s_ip);
|
||||
ipcache_put_hostname((struct in_addr *)(a+10), NULL, name, false);
|
||||
break;
|
||||
case 28: // AAAA
|
||||
if (dlen!=16) break;
|
||||
if (params.debug && inet_ntop(AF_INET6, a+12, s_ip, sizeof(s_ip)))
|
||||
DLOG("DNS response : %s\n", s_ip);
|
||||
ipcache_put_hostname(NULL, (struct in6_addr *)(a+12), name, false);
|
||||
if (params.debug && inet_ntop(AF_INET6, a+10, s_ip, sizeof(s_ip)))
|
||||
DLOG("DNS response type %u : %s\n", typ, s_ip);
|
||||
ipcache_put_hostname(NULL, (struct in6_addr *)(a+10), name, false);
|
||||
break;
|
||||
default:
|
||||
DLOG("skipping DNS response type %u\n", typ);
|
||||
}
|
||||
}
|
||||
len -= 12+dlen; a += 12+dlen;
|
||||
len -= 10+dlen; a += 10+dlen;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1891,7 +1943,7 @@ rediscover_cancel:
|
||||
|
||||
ps.verdict = desync(ps.dp, fwmark, ifin, ifout, ps.bReverseFixed, ps.ctrack_replay, tpos, ps.l7payload, ps.l7proto, dis, ps.sdip4, ps.sdip6, ps.sdport, mod_pkt, len_mod_pkt, replay_piece, replay_piece_count, reasm_offset, NULL, 0, data_decrypt, len_decrypt);
|
||||
pass:
|
||||
return (!ps.bReverse && (ps.verdict & VERDICT_MASK) == VERDICT_DROP) ? ct_new_postnat_fix(ps.ctrack, dis, mod_pkt, len_mod_pkt) : ps.verdict;
|
||||
return (!ps.bReverseFixed && (ps.verdict & VERDICT_MASK) == VERDICT_DROP) ? ct_new_postnat_fix(ps.ctrack, dis, mod_pkt, len_mod_pkt) : ps.verdict;
|
||||
}
|
||||
|
||||
// conntrack is supported only for RELATED icmp
|
||||
|
||||
@@ -180,7 +180,7 @@ void str_cidr4(char *s, size_t s_len, const struct cidr4 *cidr)
|
||||
}
|
||||
void print_cidr4(const struct cidr4 *cidr)
|
||||
{
|
||||
char s[19];
|
||||
char s[INET_ADDRSTRLEN+4];
|
||||
str_cidr4(s,sizeof(s),cidr);
|
||||
printf("%s",s);
|
||||
}
|
||||
@@ -193,7 +193,7 @@ void str_cidr6(char *s, size_t s_len, const struct cidr6 *cidr)
|
||||
}
|
||||
void print_cidr6(const struct cidr6 *cidr)
|
||||
{
|
||||
char s[INET_ADDRSTRLEN+4];
|
||||
char s[INET6_ADDRSTRLEN+4];
|
||||
str_cidr6(s,sizeof(s),cidr);
|
||||
printf("%s",s);
|
||||
}
|
||||
|
||||
@@ -8,8 +8,10 @@ static bool addpool(hostlist_pool **hostlist, char **s, const char *end, int *ct
|
||||
{
|
||||
char *p=*s;
|
||||
|
||||
for (; p<end && (*p==' ' || *p=='\t') ; p++);
|
||||
*s = p;
|
||||
// comment line ?
|
||||
if ( *p != '#' && *p != ';' && *p != '/' && *p != '\r' && *p != '\n')
|
||||
if (p<end && *p != '#' && *p != ';' && *p != '/' && *p != '\r' && *p != '\n')
|
||||
{
|
||||
// advance until eol lowering all chars
|
||||
uint32_t flags = 0;
|
||||
@@ -64,18 +66,21 @@ bool AppendHostList(hostlist_pool **hostlist, const char *filename)
|
||||
{
|
||||
DLOG_CONDUP("zlib compression detected. uncompressed size : %zu\n", zsize);
|
||||
|
||||
p = zbuf;
|
||||
e = zbuf + zsize;
|
||||
while(p<e)
|
||||
if (zbuf)
|
||||
{
|
||||
if (!addpool(hostlist,&p,e,&ct))
|
||||
p = zbuf;
|
||||
e = zbuf + zsize;
|
||||
while(p<e)
|
||||
{
|
||||
DLOG_ERR("Not enough memory to store host list : %s\n", filename);
|
||||
free(zbuf);
|
||||
return false;
|
||||
if (!addpool(hostlist,&p,e,&ct))
|
||||
{
|
||||
DLOG_ERR("Not enough memory to store host list : %s\n", filename);
|
||||
free(zbuf);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
free(zbuf);
|
||||
}
|
||||
free(zbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
73
nfq2/ipset.c
73
nfq2/ipset.c
@@ -11,36 +11,42 @@ static bool addpool(ipset *ips, char **s, const char *end, int *ct)
|
||||
struct cidr4 c4;
|
||||
struct cidr6 c6;
|
||||
|
||||
for (p=*s; p<end && *p && *p!=' ' && *p!='\t' && *p!='\r' && *p != '\n'; p++);
|
||||
|
||||
// comment line
|
||||
if (!(**s == '#' || **s == ';' || **s == '/' || **s == '\r' || **s == '\n' ))
|
||||
for (p=*s; p<end && (*p==' ' || *p=='\t') ; p++);
|
||||
if (p<end)
|
||||
{
|
||||
l = p-*s;
|
||||
if (l>=sizeof(cidr)) l=sizeof(cidr)-1;
|
||||
memcpy(cidr,*s,l);
|
||||
cidr[l]=0;
|
||||
// comment line
|
||||
if (!(*p == '#' || *p == ';' || *p == '/' || *p == '\r' || *p == '\n' ))
|
||||
{
|
||||
*s=p;
|
||||
// advance to the token's end
|
||||
for (; p<end && *p && *p!=' ' && *p!='\t' && *p!='\r' && *p != '\n'; p++);
|
||||
|
||||
if (parse_cidr4(cidr,&c4))
|
||||
{
|
||||
if (!ipset4AddCidr(&ips->ips4, &c4))
|
||||
l = p-*s;
|
||||
if (l>=sizeof(cidr)) l=sizeof(cidr)-1;
|
||||
memcpy(cidr,*s,l);
|
||||
cidr[l]=0;
|
||||
|
||||
if (parse_cidr4(cidr,&c4))
|
||||
{
|
||||
ipsetDestroy(ips);
|
||||
return false;
|
||||
if (!ipset4AddCidr(&ips->ips4, &c4))
|
||||
{
|
||||
ipsetDestroy(ips);
|
||||
return false;
|
||||
}
|
||||
if (ct) (*ct)++;
|
||||
}
|
||||
if (ct) (*ct)++;
|
||||
}
|
||||
else if (parse_cidr6(cidr,&c6))
|
||||
{
|
||||
if (!ipset6AddCidr(&ips->ips6, &c6))
|
||||
else if (parse_cidr6(cidr,&c6))
|
||||
{
|
||||
ipsetDestroy(ips);
|
||||
return false;
|
||||
if (!ipset6AddCidr(&ips->ips6, &c6))
|
||||
{
|
||||
ipsetDestroy(ips);
|
||||
return false;
|
||||
}
|
||||
if (ct) (*ct)++;
|
||||
}
|
||||
if (ct) (*ct)++;
|
||||
else
|
||||
DLOG_ERR("bad ip or subnet : %s\n",cidr);
|
||||
}
|
||||
else
|
||||
DLOG_ERR("bad ip or subnet : %s\n",cidr);
|
||||
}
|
||||
|
||||
// skip remaining non-eol chars
|
||||
@@ -81,18 +87,21 @@ static bool AppendIpset(ipset *ips, const char *filename)
|
||||
{
|
||||
DLOG_CONDUP("zlib compression detected. uncompressed size : %zu\n", zsize);
|
||||
|
||||
p = zbuf;
|
||||
e = zbuf + zsize;
|
||||
while(p<e)
|
||||
if (zbuf)
|
||||
{
|
||||
if (!addpool(ips,&p,e,&ct))
|
||||
p = zbuf;
|
||||
e = zbuf + zsize;
|
||||
while(p<e)
|
||||
{
|
||||
DLOG_ERR("Not enough memory to store ipset : %s\n", filename);
|
||||
free(zbuf);
|
||||
return false;
|
||||
if (!addpool(ips,&p,e,&ct))
|
||||
{
|
||||
DLOG_ERR("Not enough memory to store ipset : %s\n", filename);
|
||||
free(zbuf);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
free(zbuf);
|
||||
}
|
||||
free(zbuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -104,7 +113,7 @@ static bool AppendIpset(ipset *ips, const char *filename)
|
||||
{
|
||||
DLOG_CONDUP("loading plain text list\n");
|
||||
|
||||
while (fgets(s, sizeof(s)-1, F))
|
||||
while (fgets_safe(s, sizeof(s)-1, F))
|
||||
{
|
||||
p = s;
|
||||
if (!addpool(ips,&p,p+strlen(p),&ct))
|
||||
|
||||
63
nfq2/nfqws.c
63
nfq2/nfqws.c
@@ -43,6 +43,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/ioctl.h>
|
||||
#include <libnetfilter_queue/libnetfilter_queue.h>
|
||||
#define NF_DROP 0
|
||||
#define NF_ACCEPT 1
|
||||
@@ -240,6 +241,13 @@ static int write_pidfile(FILE **Fpid)
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
struct nfq_cb_data
|
||||
{
|
||||
uint8_t *mod;
|
||||
int sock;
|
||||
};
|
||||
|
||||
// cookie must point to mod buffer with size RECONSTRUCT_MAX_SIZE
|
||||
static int nfq_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *cookie)
|
||||
{
|
||||
@@ -247,11 +255,10 @@ static int nfq_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_da
|
||||
size_t len;
|
||||
struct nfqnl_msg_packet_hdr *ph;
|
||||
uint8_t *data;
|
||||
uint32_t ifidx_out, ifidx_in;
|
||||
char ifout[IFNAMSIZ], ifin[IFNAMSIZ];
|
||||
size_t modlen;
|
||||
uint8_t *mod = (uint8_t*)cookie;
|
||||
struct nfq_cb_data *cbdata = (struct nfq_cb_data*)cookie;
|
||||
uint32_t mark;
|
||||
struct ifreq ifr_in, ifr_out;
|
||||
|
||||
ph = nfq_get_msg_packet_hdr(nfa);
|
||||
id = ph ? ntohl(ph->packet_id) : 0;
|
||||
@@ -259,15 +266,21 @@ static int nfq_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_da
|
||||
mark = nfq_get_nfmark(nfa);
|
||||
ilen = nfq_get_payload(nfa, &data);
|
||||
|
||||
ifidx_out = nfq_get_outdev(nfa);
|
||||
*ifout = 0;
|
||||
if (ifidx_out) if_indextoname(ifidx_out, ifout);
|
||||
// if_indextoname creates socket, calls ioctl, closes socket
|
||||
// code below prevents socket() and close() syscalls on every packet
|
||||
// this saves CPU 5-10 times
|
||||
|
||||
ifidx_in = nfq_get_indev(nfa);
|
||||
*ifin = 0;
|
||||
if (ifidx_in) if_indextoname(ifidx_in, ifin);
|
||||
*ifr_out.ifr_name = 0;
|
||||
ifr_out.ifr_ifindex = nfq_get_outdev(nfa);
|
||||
if (ifr_out.ifr_ifindex && ioctl(cbdata->sock, SIOCGIFNAME, &ifr_out)<0)
|
||||
DLOG_PERROR("ioctl(SIOCGIFNAME)");
|
||||
|
||||
DLOG("\npacket: id=%d len=%d mark=%08X ifin=%s(%u) ifout=%s(%u)\n", id, ilen, mark, ifin, ifidx_in, ifout, ifidx_out);
|
||||
*ifr_in.ifr_name = 0;
|
||||
ifr_in.ifr_ifindex = nfq_get_indev(nfa);
|
||||
if (ifr_in.ifr_ifindex && ioctl(cbdata->sock, SIOCGIFNAME, &ifr_in)<0)
|
||||
DLOG_PERROR("ioctl(SIOCGIFNAME)");
|
||||
|
||||
DLOG("\npacket: id=%d len=%d mark=%08X ifin=%s(%u) ifout=%s(%u)\n", id, ilen, mark, ifr_in.ifr_name, ifr_in.ifr_ifindex, ifr_out.ifr_name, ifr_out.ifr_ifindex);
|
||||
|
||||
if (ilen >= 0)
|
||||
{
|
||||
@@ -277,12 +290,12 @@ static int nfq_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_da
|
||||
// to support increased sizes use separate mod buffer
|
||||
// this is not a problem because only LUA code can trigger VERDICT_MODIFY (and postnat workaround too, once a connection if first packet is dropped)
|
||||
// in case of VERIDCT_MODIFY packet is always reconstructed from dissect, so no difference where to save the data => no performance loss
|
||||
uint8_t verdict = processPacketData(&mark, ifin, ifout, data, len, mod, &modlen);
|
||||
uint8_t verdict = processPacketData(&mark, ifr_in.ifr_name, ifr_out.ifr_name, data, len, cbdata->mod, &modlen);
|
||||
switch (verdict & VERDICT_MASK)
|
||||
{
|
||||
case VERDICT_MODIFY:
|
||||
DLOG("packet: id=%d pass modified. len %zu => %zu\n", id, len, modlen);
|
||||
return nfq_set_verdict2(qh, id, NF_ACCEPT, mark, (uint32_t)modlen, mod);
|
||||
return nfq_set_verdict2(qh, id, NF_ACCEPT, mark, (uint32_t)modlen, cbdata->mod);
|
||||
case VERDICT_DROP:
|
||||
DLOG("packet: id=%d drop\n", id);
|
||||
return nfq_set_verdict2(qh, id, NF_DROP, mark, 0, NULL);
|
||||
@@ -306,7 +319,7 @@ static void nfq_deinit(struct nfq_handle **h, struct nfq_q_handle **qh)
|
||||
*h = NULL;
|
||||
}
|
||||
}
|
||||
static bool nfq_init(struct nfq_handle **h, struct nfq_q_handle **qh, uint8_t *mod_buffer)
|
||||
static bool nfq_init(struct nfq_handle **h, struct nfq_q_handle **qh, struct nfq_cb_data *cbdata)
|
||||
{
|
||||
nfq_deinit(h, qh);
|
||||
|
||||
@@ -343,7 +356,7 @@ static bool nfq_init(struct nfq_handle **h, struct nfq_q_handle **qh, uint8_t *m
|
||||
}
|
||||
|
||||
DLOG_CONDUP("binding this socket to queue '%u'\n", params.qnum);
|
||||
*qh = nfq_create_queue(*h, params.qnum, &nfq_cb, mod_buffer);
|
||||
*qh = nfq_create_queue(*h, params.qnum, &nfq_cb, cbdata);
|
||||
if (!*qh) {
|
||||
DLOG_PERROR("nfq_create_queue()");
|
||||
goto exiterr;
|
||||
@@ -365,6 +378,8 @@ static bool nfq_init(struct nfq_handle **h, struct nfq_q_handle **qh, uint8_t *m
|
||||
// dot not fail. not supported in old linuxes <3.6
|
||||
}
|
||||
|
||||
nfnl_rcvbufsiz(nfq_nfnlh(*h), Q_RCVBUF);
|
||||
|
||||
int yes = 1, fd = nfq_fd(*h);
|
||||
|
||||
#if defined SOL_NETLINK && defined NETLINK_NO_ENOBUFS
|
||||
@@ -387,6 +402,8 @@ static void notify_ready(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
// extra space for netlink headers
|
||||
#define NFQ_MAX_RECV_SIZE (RECONSTRUCT_MAX_SIZE+4096)
|
||||
static int nfq_main(void)
|
||||
{
|
||||
struct nfq_handle *h = NULL;
|
||||
@@ -395,6 +412,7 @@ static int nfq_main(void)
|
||||
ssize_t rd;
|
||||
FILE *Fpid = NULL;
|
||||
uint8_t *buf=NULL, *mod=NULL;
|
||||
struct nfq_cb_data cbdata = { .sock = -1 };
|
||||
|
||||
if (*params.pidfile && !(Fpid = fopen(params.pidfile, "w")))
|
||||
{
|
||||
@@ -436,13 +454,19 @@ static int nfq_main(void)
|
||||
goto exok;
|
||||
}
|
||||
|
||||
if (!(buf = malloc(RECONSTRUCT_MAX_SIZE)) || !(mod = malloc(RECONSTRUCT_MAX_SIZE)))
|
||||
if (!(buf = malloc(NFQ_MAX_RECV_SIZE)) || !(cbdata.mod = malloc(RECONSTRUCT_MAX_SIZE)))
|
||||
{
|
||||
DLOG_ERR("out of memory\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!nfq_init(&h, &qh, mod))
|
||||
if ((cbdata.sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
{
|
||||
DLOG_PERROR("socket");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!nfq_init(&h, &qh, &cbdata))
|
||||
goto err;
|
||||
|
||||
#ifdef HAS_FILTER_SSID
|
||||
@@ -466,7 +490,7 @@ static int nfq_main(void)
|
||||
do
|
||||
{
|
||||
if (bQuit) goto quit;
|
||||
while ((rd = recv(fd, buf, RECONSTRUCT_MAX_SIZE, 0)) >= 0)
|
||||
while ((rd = recv(fd, buf, NFQ_MAX_RECV_SIZE, 0)) >= 0)
|
||||
{
|
||||
if (!rd)
|
||||
{
|
||||
@@ -481,7 +505,7 @@ static int nfq_main(void)
|
||||
DLOG_ERR("cannot get wlan info\n");
|
||||
#endif
|
||||
int r = nfq_handle_packet(h, (char *)buf, (int)rd);
|
||||
if (r) DLOG_ERR("nfq_handle_packet error %d\n", r);
|
||||
if (r<0) DLOG_ERR("nfq_handle_packet result %d, errno %d : %s\n", r, errno, strerror(errno));
|
||||
if (bQuit) goto quit;
|
||||
}
|
||||
if (errno==EINTR)
|
||||
@@ -496,7 +520,8 @@ static int nfq_main(void)
|
||||
exok:
|
||||
res=0;
|
||||
ex:
|
||||
free(mod);
|
||||
free(cbdata.mod);
|
||||
if (cbdata.sock>=0) close(cbdata.sock);
|
||||
free(buf);
|
||||
nfq_deinit(&h, &qh);
|
||||
lua_shutdown();
|
||||
|
||||
@@ -116,7 +116,7 @@ static char log_buf[4096];
|
||||
static size_t log_buf_sz=0;
|
||||
static void syslog_log_function(int priority, const char *line)
|
||||
{
|
||||
syslog(priority,"%s",log_buf);
|
||||
syslog(priority,"%s",line);
|
||||
}
|
||||
|
||||
static int DLOG_FILENAME(const char *filename, const char *format, ...)
|
||||
@@ -405,7 +405,7 @@ static struct desync_profile_list *desync_profile_entry_alloc()
|
||||
struct desync_profile_list *dp_list_add(struct desync_profile_list_head *head)
|
||||
{
|
||||
struct desync_profile_list *entry = desync_profile_entry_alloc();
|
||||
if (!entry) return false;
|
||||
if (!entry) return NULL;
|
||||
|
||||
struct desync_profile_list *tail, *item;
|
||||
LIST_TAIL(head, tail, item);
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
|
||||
#define RAW_SNDBUF (64*1024) // in bytes
|
||||
|
||||
#define Q_MAXLEN 1024 // in packets
|
||||
#define Q_MAXLEN 4096 // in packets
|
||||
#define Q_RCVBUF (1024*1024) // in bytes
|
||||
|
||||
#define HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT 3
|
||||
#define HOSTLIST_AUTO_FAIL_TIME_DEFAULT 60
|
||||
|
||||
@@ -493,7 +493,6 @@ void kavl_bit_destroy(struct kavl_bit_elem **hdr)
|
||||
if (!e) break;
|
||||
kavl_bit_destroy_elem(e);
|
||||
}
|
||||
free(*hdr);
|
||||
}
|
||||
struct kavl_bit_elem *kavl_bit_add(struct kavl_bit_elem **hdr, void *data, unsigned int bitlen, size_t struct_size)
|
||||
{
|
||||
|
||||
@@ -1445,7 +1445,7 @@ bool IsStunMessage(const uint8_t *data, size_t len)
|
||||
(data[0]&0xC0)==0 && // 2 most significant bits must be zeroes
|
||||
(data[3]&3)==0 && // length must be a multiple of 4
|
||||
pntoh32(data+4)==0x2112A442 && // magic cookie
|
||||
pntoh16(data+2)==(len-20);
|
||||
pntoh16(data+2)<=(len-20);
|
||||
}
|
||||
#if defined(__GNUC__) && !defined(__llvm__)
|
||||
__attribute__((optimize ("no-strict-aliasing")))
|
||||
@@ -1460,7 +1460,7 @@ bool IsMTProto(const uint8_t *data, size_t len)
|
||||
return !memcmp(decrypt+56,"\xEF\xEF\xEF\xEF",4);
|
||||
*/
|
||||
// this way requires only one AES instead of 4
|
||||
uint8_t decrypt[16] __attribute__((aligned)), iv[16];
|
||||
uint8_t decrypt[16] __attribute__((aligned(16))), iv[16] __attribute__((aligned(16)));
|
||||
aes_context ctx;
|
||||
|
||||
memcpy(iv, data+40, 16);
|
||||
|
||||
Reference in New Issue
Block a user