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:
@@ -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
|
||||
|
||||
|
||||
@@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
101
nfq2/lua.c
101
nfq2/lua.c
@@ -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},
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user