diff --git a/docs/changes.txt b/docs/changes.txt index 1c0d9d8..beb90ba 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -328,3 +328,5 @@ v0.9.4.3 * blockcheck2: use --wf-raw-filter in Windows instead of --ipset to limit target IP addresses * github, builder_linux: lua 5.5.1 * nfqws2: negate SSID/NLM filters +* nfqws2: desync function can explicitly return nil as a synonym of VERDICT_PASS +* zapret-lub: luaexec now passes returned verdict code diff --git a/docs/manual.en.md b/docs/manual.en.md index 5e0d00f..cb8c7f8 100644 --- a/docs/manual.en.md +++ b/docs/manual.en.md @@ -2493,6 +2493,8 @@ The code can address the `desync` table-it is temporarily assigned to a global v Example: `--lua-desync=luaexec:code="desync.rnd=brandom(math.random(5,10))"` +Verdict can be returned using "return" statement. + ### pass ``` diff --git a/docs/manual.md b/docs/manual.md index e120a5b..5643aa5 100644 --- a/docs/manual.md +++ b/docs/manual.md @@ -2653,6 +2653,8 @@ function luaexec(ctx, desync) Пример : `--lua-desync=luaexec:code="desync.rnd=brandom(math.random(5,10))"` +Функция может возвращать вердикт через return. + ### pass ``` diff --git a/lua/zapret-auto.lua b/lua/zapret-auto.lua index 2714771..c6999e2 100644 --- a/lua/zapret-auto.lua +++ b/lua/zapret-auto.lua @@ -420,7 +420,6 @@ function cond_lua(desync) _G[fname], err = load(desync.arg.cond_code, fname) if not _G[fname] then error(err) - return end end -- allow dynamic cond_code to access desync @@ -463,7 +462,7 @@ function condition(ctx, desync) return replay_execution_plan(desync) end -- execute further desync instances. --- each instance may have "cond" and "cond_neg" args. +-- each instance must have "cond" arg and may optionally have "cond_neg" arg. -- "cond" - condition function. "neg" - invert condition function result -- arg: instances - how many instances execute conditionally. all if not defined function per_instance_condition(ctx, desync) diff --git a/lua/zapret-lib.lua b/lua/zapret-lib.lua index 29c0389..031ca35 100644 --- a/lua/zapret-lib.lua +++ b/lua/zapret-lib.lua @@ -29,10 +29,12 @@ function luaexec(ctx, desync) end -- allow dynamic code to access desync _G.desync = desync - local res, err = pcall(_G[fname]) + local res, ret = pcall(_G[fname]) _G.desync = nil if not res then - error(err); + error(ret) + else + return ret and ret or VERDICT_PASS -- older nfqws2 failed if desync function returned explicit nil end end @@ -1607,7 +1609,11 @@ function tls_client_hello_mod(tls, options) end local idx_sni if options.sni_snt or options.sni_del_ext or options.sni_del or options.sni_first or options.sni_last then - idx_sni = array_field_search(tdis.handshake[TLS_HANDSHAKE_TYPE_CLIENT].dis.ext, "type", TLS_EXT_SERVER_NAME) + if tdis.handshake[TLS_HANDSHAKE_TYPE_CLIENT].dis.ext then + idx_sni = array_field_search(tdis.handshake[TLS_HANDSHAKE_TYPE_CLIENT].dis.ext, "type", TLS_EXT_SERVER_NAME) + else + tdis.handshake[TLS_HANDSHAKE_TYPE_CLIENT].dis.ext={} + end if not idx_sni then DLOG("tls_client_hello_mod: no SNI extension. adding") table.insert(tdis.handshake[TLS_HANDSHAKE_TYPE_CLIENT].dis.ext, 1, { type = TLS_EXT_SERVER_NAME, dis = { list = {} } } ) @@ -2441,7 +2447,7 @@ function tls_dissect_handshake(handshake, partialOK) handshake.dis = { type = typ , ver = u16(handshake.data, 5), name = tostring(TLS_HANDSHAKE_TYPE_NAMES[typ]) } -- random - if hlen<36 then return partialOK end + if hlen<38 then return partialOK end handshake.dis.random = string.sub(handshake.data, 7, 38) -- session_id @@ -2649,8 +2655,10 @@ function tls_reconstruct_handshake(handshake) end exts = exts .. bu16(handshake.dis.ext[i].type) .. bu16(#handshake.dis.ext[i].data) .. handshake.dis.ext[i].data end + handshake.data = bu8(handshake.type) .. bu24(#header + 2 + #exts) .. header .. bu16(#exts) .. exts + else + handshake.data = bu8(handshake.type) .. bu24(#header) .. header end - handshake.data = bu8(handshake.type) .. bu24(#header + 2 + #exts) .. header .. bu16(#exts) .. exts end end @@ -2701,11 +2709,10 @@ function tls_reconstruct(tdis) if not rec.data then return nil end end tls = barray(tdis.rec, function(a) return (#a.data > 0) and (bu8(a.type) .. bu16(a.ver) .. bu16(#a.data) .. a.data) or "" end) - elseif tdis.handshake and #tdis.handshake==1 then - -- without record layer - for k,handshake in pairs(tdis.handshake) do - tls = handshake.data - break + elseif tdis.handshake then + local i = next(tdis.handshake) + if i~=nil then + tls = tdis.handshake[i].data end end diff --git a/nfq2/conntrack.c b/nfq2/conntrack.c index e085df9..1eaad17 100644 --- a/nfq2/conntrack.c +++ b/nfq2/conntrack.c @@ -395,15 +395,6 @@ bool ReasmInit(t_reassemble *reasm, size_t size_requested, uint32_t seq_start) reasm->seq = seq_start; return true; } -bool ReasmResize(t_reassemble *reasm, size_t new_size) -{ - uint8_t *p = realloc(reasm->packet, new_size); - if (!p) return false; - reasm->packet = p; - reasm->size = new_size; - if (reasm->size_present > new_size) reasm->size_present = new_size; - return true; -} #define REASM_MAX_NEG 0x100000 bool ReasmFeed(t_reassemble *reasm, uint32_t seq, const void *payload, size_t len) { diff --git a/nfq2/darkmagic.c b/nfq2/darkmagic.c index 34689c1..ff32a60 100644 --- a/nfq2/darkmagic.c +++ b/nfq2/darkmagic.c @@ -377,8 +377,9 @@ bool proto_check_ipv4(const uint8_t *data, size_t len) { if (len < sizeof(struct ip)) return false; if (((struct ip*)data)->ip_v!=4) return false; + uint16_t iplen = ntohs(((struct ip*)data)->ip_len); uint8_t off = ((struct ip*)data)->ip_hl << 2; - return off>=sizeof(struct ip) && len>=off; + return off>=sizeof(struct ip) && iplen>=off && len>=off; } bool proto_check_ipv4_payload(const uint8_t *data, size_t len) { @@ -559,7 +560,7 @@ 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; + size_t iplen; if (proto_check_ipv4(data, len) && (no_payload_check || proto_check_ipv4_payload(data, len))) { diff --git a/nfq2/desync.c b/nfq2/desync.c index eb218d0..22fa113 100644 --- a/nfq2/desync.c +++ b/nfq2/desync.c @@ -814,20 +814,26 @@ static bool desync_get_result(uint8_t *verdict) DLOG_ERR("desync function returned more than one result : %d\n", rescount); goto err; } + // absence of the return value or nil mean VERDICT_PASS if (rescount) { - if (!lua_isinteger(params.L, -1)) + if (lua_isnil(params.L, -1)) + *verdict = VERDICT_PASS; + else { - DLOG_ERR("desync function returned non-int result\n"); - goto err; + if (!lua_isinteger(params.L, -1)) + { + DLOG_ERR("desync function returned non-int result\n"); + goto err; + } + lua_Integer lv = lua_tointeger(params.L, -1); + if (lv & ~VERDICT_MASK_VALID_LUA) + { + DLOG_ERR("desync function returned bad int result\n"); + goto err; + } + *verdict = (uint8_t)lv; } - lua_Integer lv = lua_tointeger(params.L, -1); - if (lv & ~VERDICT_MASK_VALID_LUA) - { - DLOG_ERR("desync function returned bad int result\n"); - goto err; - } - *verdict = (uint8_t)lv; } else *verdict = VERDICT_PASS; // default result if function returns nothing diff --git a/nfq2/nfqws.c b/nfq2/nfqws.c index 2165ec4..e9b6626 100644 --- a/nfq2/nfqws.c +++ b/nfq2/nfqws.c @@ -594,8 +594,9 @@ static int nfq_main(void) DLOG_ERR("recv: recv=%zd errno %d\n", rd, e); errno = e; DLOG_PERROR("recv"); + errno = e; // do not fail on ENOBUFS - } while (e == ENOBUFS); + } while (errno == ENOBUFS); err: res=1;