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

nfqws2: desync orchestration luacalls

This commit is contained in:
bol-van
2025-12-02 17:49:23 +03:00
parent 69b08f0a36
commit 04ceb589e0
4 changed files with 138 additions and 48 deletions

View File

@@ -37,6 +37,29 @@ function pktdebug(ctx, desync)
end
-- copy instance identification and args from execution plan to desync table
function apply_execution_plan(desync, plan)
desync.func = plan.func
desync.func_n = plan.func_n
desync.func_instance = plan.func_instance
desync.arg = plan.arg
end
-- this function demonstrates how to stop execution of upcoming desync instances and take over their job
-- this can be used, for example, for orchestrating conditional processing without modifying of desync functions code
-- test case : nfqws2 --qnum 200 --debug --lua-init=@zapret-lib.lua --lua-desync=desync_orchestrator_example --lua-desync=pass --lua-desync=pass
function desync_orchestrator_example(ctx, desync)
local plan = execution_plan(ctx)
if #plan>0 then
DLOG("orchestrator: taking over upcoming desync instances")
local desync_copy = deepcopy(desync)
execution_plan_cancel(ctx)
for i=1,#plan do
apply_execution_plan(desync_copy, plan[i])
DLOG("orchestrator: executing '"..desync_copy.func_instance.."'")
_G[plan[i].func](ctx, desync_copy)
end
end
end
-- prepare standard rawsend options from desync
-- repeats - how many time send the packet
@@ -1031,4 +1054,3 @@ function ipfrag2(dis, ipfrag_options)
return {dis1,dis2}
end

View File

@@ -638,10 +638,6 @@ err:
lua_pop(params.L, rescount);
return false;
}
static void desync_instance(const char *func, unsigned int dp_n, unsigned int func_n, char *instance, size_t inst_size)
{
snprintf(instance, inst_size, "%s_%u_%u", func, dp_n, func_n);
}
static uint8_t desync(
struct desync_profile *dp,
uint32_t fwmark,
@@ -659,7 +655,7 @@ static uint8_t desync(
struct func_list *func;
int ref_arg = LUA_NOREF, status;
bool b, b_cutoff_all, b_unwanted_payload;
t_lua_desync_context ctx = { .dp = dp, .ctrack = ctrack, .dis = dis };
t_lua_desync_context ctx = { .dp = dp, .ctrack = ctrack, .dis = dis, .cancel = false };
const char *sDirection = bIncoming ? "in" : "out";
struct packet_range *range;
size_t l;
@@ -681,14 +677,12 @@ static uint8_t desync(
}
if (LIST_FIRST(&dp->lua_desync))
{
unsigned int func_n;
b_cutoff_all = b_unwanted_payload = true;
func_n = 1;
ctx.func_n = 1;
LIST_FOREACH(func, &dp->lua_desync, next)
{
ctx.func = func->func;
desync_instance(func->func, dp->n, func_n, instance, sizeof(instance));
desync_instance(func->func, dp->n, ctx.func_n, instance, sizeof(instance));
ctx.instance = instance;
range = bIncoming ? &func->range_in : &func->range_out;
@@ -713,7 +707,7 @@ static uint8_t desync(
else
b_cutoff_all = false;
}
func_n++;
ctx.func_n++;
}
if (b_cutoff_all)
{
@@ -755,11 +749,11 @@ static uint8_t desync(
}
ref_arg = luaL_ref(params.L, LUA_REGISTRYINDEX);
func_n = 1;
ctx.func_n = 1;
LIST_FOREACH(func, &dp->lua_desync, next)
{
ctx.func = func->func;
desync_instance(func->func, dp->n, func_n, instance, sizeof(instance));
desync_instance(func->func, dp->n, ctx.func_n, instance, sizeof(instance));
ctx.instance = instance;
if (!lua_instance_cutoff_check(&ctx, bIncoming))
@@ -789,7 +783,7 @@ static uint8_t desync(
lua_rawgeti(params.L, LUA_REGISTRYINDEX, ref_arg);
lua_pushf_args(&func->args, -1);
lua_pushf_str("func", func->func);
lua_pushf_int("func_n", func_n);
lua_pushf_int("func_n", ctx.func_n);
lua_pushf_str("func_instance", instance);
int initial_stack_top = lua_gettop(params.L);
status = lua_pcall(params.L, 2, LUA_MULTRET, 0);
@@ -808,37 +802,6 @@ static uint8_t desync(
case VERDICT_DROP:
verdict = VERDICT_DROP;
}
if (ctrack)
{
// lua cutoff
lua_rawgeti(params.L, LUA_REGISTRYINDEX, ref_arg);
lua_getfield(params.L, -1, "track");
if (lua_istable(params.L, -1))
{
if (!ctrack->b_lua_in_cutoff)
{
lua_getfield(params.L, -1, "lua_in_cutoff");
if (lua_toboolean(params.L, -1))
{
ctrack->b_lua_in_cutoff = true;
DLOG("* lua in cutoff set\n");
}
lua_pop(params.L, 1);
}
if (!ctrack->b_lua_out_cutoff)
{
lua_getfield(params.L, -1, "lua_out_cutoff");
if (lua_toboolean(params.L, -1))
{
ctrack->b_lua_out_cutoff = true;
DLOG("* lua out cutoff set\n");
}
lua_pop(params.L, 1);
}
}
lua_pop(params.L, 2);
}
}
else
DLOG("* lua '%s' : payload_type '%s' does not satisfy filter\n", instance, l7payload_str(l7payload));
@@ -852,7 +815,8 @@ static uint8_t desync(
range->upper_cutoff ? '<' : '-',
range->to.mode, range->to.pos);
}
func_n++;
if (ctx.cancel) break;
ctx.func_n++;
}
}

View File

@@ -19,6 +19,11 @@
#include "crypto/aes-ctr.h"
void desync_instance(const char *func, unsigned int dp_n, unsigned int func_n, char *instance, size_t inst_size)
{
snprintf(instance, inst_size, "%s_%u_%u", func, dp_n, func_n);
}
static void lua_check_argc(lua_State *L, const char *where, int argc)
{
int num_args = lua_gettop(L);
@@ -639,7 +644,7 @@ static int luacall_instance_cutoff(lua_State *L)
int argc=lua_gettop(L);
bool bIn,bOut;
if (argc>=2)
if (argc>=2 && lua_type(L,2)!=LUA_TNIL)
{
luaL_checktype(L,2,LUA_TBOOLEAN);
bOut = lua_toboolean(L,2);
@@ -705,6 +710,94 @@ bool lua_instance_cutoff_check(const t_lua_desync_context *ctx, bool bIn)
return b;
}
static int luacall_lua_cutoff(lua_State *L)
{
lua_check_argc_range(L,"lua_cutoff",1,2);
LUA_STACK_GUARD_ENTER(L)
t_lua_desync_context *ctx;
if (!lua_islightuserdata(L,1))
luaL_error(L, "lua_cutoff expect desync context in the first argument");
ctx = lua_touserdata(L,1);
int argc=lua_gettop(L);
bool bIn,bOut;
if (argc>=2 && lua_type(L,2)!=LUA_TNIL)
{
luaL_checktype(L,2,LUA_TBOOLEAN);
bOut = lua_toboolean(L,2);
bIn = !bOut;
}
else
bIn = bOut = true;
if (ctx->ctrack)
{
DLOG("lua cutoff from '%s' in=%u out=%u\n",ctx->instance,bIn,bOut);
// lua cutoff is one way transition
if (bIn) ctx->ctrack->b_lua_in_cutoff = true;
if (bOut) ctx->ctrack->b_lua_out_cutoff = true;
}
else
DLOG("lua cutoff requested from '%s' in=%u out=%u but not possible without conntrack\n",ctx->instance,bIn,bOut);
LUA_STACK_GUARD_RETURN(L,0)
}
static int luacall_execution_plan(lua_State *L)
{
lua_check_argc(L,"execution_plan",1);
LUA_STACK_GUARD_ENTER(L)
const t_lua_desync_context *ctx;
if (!lua_islightuserdata(L,1))
luaL_error(L, "execution_plan expect desync context in the first argument");
ctx = lua_touserdata(L,1);
lua_newtable(L);
struct func_list *func;
char instance[256];
unsigned int n=1;
LIST_FOREACH(func, &ctx->dp->lua_desync, next)
{
if (n > ctx->func_n)
{
desync_instance(func->func, ctx->dp->n, n, instance, sizeof(instance));
lua_pushinteger(params.L, n - ctx->func_n);
lua_createtable(params.L, 0, 4);
lua_pushf_str("func", func->func);
lua_pushf_int("func_n", ctx->func_n);
lua_pushf_str("func_instance", instance);
lua_pushf_args(&func->args, -1);
lua_rawset(params.L,-3);
}
n++;
}
LUA_STACK_GUARD_RETURN(L,1)
}
static int luacall_execution_plan_cancel(lua_State *L)
{
lua_check_argc(L,"execution_plan_cancel",1);
t_lua_desync_context *ctx;
if (!lua_islightuserdata(L,1))
luaL_error(L, "execution_plan_cancel expect desync context in the first argument");
ctx = lua_touserdata(L,1);
DLOG("execution plan cancel from '%s'\n",ctx->instance);
ctx->cancel = true;
return 0;
}
static int luacall_raw_packet(lua_State *L)
{
lua_check_argc(L,"raw_packet",1);
@@ -2836,6 +2929,12 @@ static void lua_init_functions(void)
// voluntarily stop receiving packets
{"instance_cutoff",luacall_instance_cutoff},
// voluntarily stop receiving packets of the current connection for all instances
{"lua_cutoff",luacall_lua_cutoff},
// get info about upcoming desync instances and their arguments
{"execution_plan",luacall_execution_plan},
// cancel execution of upcoming desync instances and their arguments
{"execution_plan_cancel",luacall_execution_plan_cancel},
// get raw packet data
{"raw_packet",luacall_raw_packet},

View File

@@ -28,6 +28,9 @@
#define LUA_STACK_GUARD_RETURN(L,N) LUA_STACK_GUARD_LEAVE(L,N); return N;
void desync_instance(const char *func, unsigned int dp_n, unsigned int func_n, char *instance, size_t inst_size);
bool lua_test_init_script_files(void);
bool lua_init(void);
void lua_shutdown(void);
@@ -79,10 +82,12 @@ bool lua_reconstruct_udphdr(int idx, struct udphdr *udp);
bool lua_reconstruct_dissect(int idx, uint8_t *buf, size_t *len, bool badsum, bool ip6_preserve_next);
typedef struct {
unsigned int func_n;
const char *func, *instance;
const struct desync_profile *dp;
const t_ctrack *ctrack;
const struct dissect *dis;
t_ctrack *ctrack;
bool cancel;
} t_lua_desync_context;
bool lua_instance_cutoff_check(const t_lua_desync_context *ctx, bool bIn);