nfqws2: limit delayed packet queue to 64 packets (anti-ddos)

This commit is contained in:
bol-van
2026-07-04 12:37:12 +03:00
parent bc6b8c64a4
commit 8d34a4b7a2
8 changed files with 43 additions and 28 deletions
+1
View File
@@ -311,3 +311,4 @@ v0.9.4.3
1.0.3
* nfqws2: accept string or function in timer_set(). remember function as a function, not as a string.
* nfqws2: limit delayed packet queue to 64 packets (anti-ddos)
+1 -1
View File
@@ -106,7 +106,7 @@ static void ConntrackInitTrack(t_ctrack *t)
t->l7proto = L7_UNKNOWN;
t->reasm_client_payload = L7P_UNKNOWN;
t->pos.client.scale = t->pos.server.scale = 0;
rawpacket_queue_init(&t->delayed);
rawpacket_queue_init(&t->delayed, RAW_PACKET_QUEUE_DELAYED_MAX);
lua_newtable(params.L);
t->lua_state = luaL_ref(params.L, LUA_REGISTRYINDEX);
lua_newtable(params.L);
+3 -1
View File
@@ -29,6 +29,8 @@
#define RETRANS_COUNTER_STOP ((uint8_t)-1)
#define RAW_PACKET_QUEUE_DELAYED_MAX 64
typedef union {
struct in_addr ip;
struct in6_addr ip6;
@@ -82,7 +84,7 @@ typedef struct
t_l7payload reasm_client_payload; // payload type being reassembled
t_reassemble reasm_client;
struct rawpacket_tailhead delayed;
struct rawpacket_queue delayed;
} t_ctrack;
typedef struct
+1 -1
View File
@@ -2048,7 +2048,7 @@ bool rawsend_rp(const struct rawpacket *rp)
{
return rawsend((struct sockaddr*)&rp->dst,rp->fwmark,rp->ifout,rp->packet,rp->len);
}
bool rawsend_queue(struct rawpacket_tailhead *q)
bool rawsend_queue(struct rawpacket_queue *q)
{
struct rawpacket *rp;
bool b;
+1 -1
View File
@@ -147,7 +147,7 @@ bool rawsend_preinit(bool bind_fix4, bool bind_fix6);
bool rawsend(const struct sockaddr* dst,uint32_t fwmark,const char *ifout,const void *data,size_t len);
bool rawsend_rp(const struct rawpacket *rp);
// return trues if all packets were send successfully
bool rawsend_queue(struct rawpacket_tailhead *q);
bool rawsend_queue(struct rawpacket_queue *q);
// cleans up socket autocreated by rawsend
void rawsend_cleanup(void);
bool rawsend_rep(int repeats, const struct sockaddr* dst, uint32_t fwmark, const char *ifout, const void *data, size_t len);
+5 -2
View File
@@ -705,7 +705,7 @@ static bool check_pos_range(const t_ctrack_position *pos, const struct packet_ra
}
static bool replay_queue(struct rawpacket_tailhead *q);
static bool replay_queue(struct rawpacket_queue *q);
static bool ipcache_put_hostname(const struct in_addr *a4, const struct in6_addr *a6, const char *hostname, bool hostname_is_ip)
{
@@ -1583,7 +1583,10 @@ static uint8_t dpi_desync_tcp_packet_play(
}
else
{
// likely exceeded packet limit or unlikely out of memory
DLOG_ERR("rawpacket_queue failed !\n");
reasm_client_cancel(ps.ctrack);
ps.l7payload = L7P_UNKNOWN; // middle packet may be not L7P_TLS_CLIENT_HELLO
goto rediscover;
}
if (ReasmIsFull(&ps.ctrack->reasm_client))
@@ -2194,7 +2197,7 @@ uint8_t dpi_desync_packet(uint32_t fwmark, const char *ifin, const char *ifout,
static bool replay_queue(struct rawpacket_tailhead *q)
static bool replay_queue(struct rawpacket_queue *q)
{
struct rawpacket *rp;
size_t offset;
+19 -16
View File
@@ -4,37 +4,40 @@
#include "packet_queue.h"
void rawpacket_queue_init(struct rawpacket_tailhead *q)
void rawpacket_queue_init(struct rawpacket_queue *q, unsigned int max_packets)
{
TAILQ_INIT(q);
TAILQ_INIT(&q->q);
q->max_packets = max_packets;
}
void rawpacket_free(struct rawpacket *rp)
{
if (rp) free(rp->packet);
free(rp);
}
struct rawpacket *rawpacket_dequeue(struct rawpacket_tailhead *q)
struct rawpacket *rawpacket_dequeue(struct rawpacket_queue *q)
{
struct rawpacket *rp;
rp = TAILQ_FIRST(q);
if (rp) TAILQ_REMOVE(q, rp, next);
rp = TAILQ_FIRST(&q->q);
if (rp) TAILQ_REMOVE(&q->q, rp, next);
return rp;
}
void rawpacket_queue_destroy(struct rawpacket_tailhead *q)
void rawpacket_queue_destroy(struct rawpacket_queue *q)
{
struct rawpacket *rp;
while((rp = rawpacket_dequeue(q))) rawpacket_free(rp);
}
struct rawpacket *rawpacket_queue(
struct rawpacket_tailhead *q,
struct rawpacket_queue *q,
const struct sockaddr_storage* dst,
uint32_t fwmark_orig,uint32_t fwmark,
const char *ifin,const char *ifout,
const void *data,size_t len,size_t len_payload,
uint32_t fwmark_orig, uint32_t fwmark,
const char *ifin, const char *ifout,
const void *data, size_t len, size_t len_payload,
const t_ctrack_positions *tpos,
bool server_side)
{
if (q->max_packets && rawpacket_queue_count(q)>=q->max_packets) return NULL;
struct rawpacket *rp = malloc(sizeof(struct rawpacket));
if (!rp) return NULL;
@@ -44,7 +47,7 @@ struct rawpacket *rawpacket_queue(
free(rp);
return NULL;
}
rp->dst = *dst;
rp->fwmark_orig = fwmark_orig;
rp->fwmark = fwmark;
@@ -70,19 +73,19 @@ struct rawpacket *rawpacket_queue(
rp->tpos_present = false;
rp->server_side = server_side;
TAILQ_INSERT_TAIL(q, rp, next);
TAILQ_INSERT_TAIL(&q->q, rp, next);
return rp;
}
unsigned int rawpacket_queue_count(const struct rawpacket_tailhead *q)
unsigned int rawpacket_queue_count(const struct rawpacket_queue *q)
{
const struct rawpacket *rp;
unsigned int ct=0;
TAILQ_FOREACH(rp, q, next) ct++;
TAILQ_FOREACH(rp, &q->q, next) ct++;
return ct;
}
bool rawpacket_queue_empty(const struct rawpacket_tailhead *q)
bool rawpacket_queue_empty(const struct rawpacket_queue *q)
{
return !TAILQ_FIRST(q);
return !TAILQ_FIRST(&q->q);
}
+12 -6
View File
@@ -23,10 +23,16 @@ struct rawpacket
};
TAILQ_HEAD(rawpacket_tailhead, rawpacket);
void rawpacket_queue_init(struct rawpacket_tailhead *q);
void rawpacket_queue_destroy(struct rawpacket_tailhead *q);
bool rawpacket_queue_empty(const struct rawpacket_tailhead *q);
unsigned int rawpacket_queue_count(const struct rawpacket_tailhead *q);
struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sockaddr_storage* dst,uint32_t fwmark_orig,uint32_t fwmark,const char *ifin,const char *ifout,const void *data,size_t len,size_t len_payload,const t_ctrack_positions *tpos,bool server_side);
struct rawpacket *rawpacket_dequeue(struct rawpacket_tailhead *q);
struct rawpacket_queue
{
struct rawpacket_tailhead q;
unsigned int max_packets;
};
void rawpacket_queue_init(struct rawpacket_queue *q, unsigned int max_packets);
void rawpacket_queue_destroy(struct rawpacket_queue *q);
bool rawpacket_queue_empty(const struct rawpacket_queue *q);
unsigned int rawpacket_queue_count(const struct rawpacket_queue *q);
struct rawpacket *rawpacket_queue(struct rawpacket_queue *q,const struct sockaddr_storage* dst,uint32_t fwmark_orig,uint32_t fwmark,const char *ifin,const char *ifout,const void *data,size_t len,size_t len_payload,const t_ctrack_positions *tpos,bool server_side);
struct rawpacket *rawpacket_dequeue(struct rawpacket_queue *q);
void rawpacket_free(struct rawpacket *rp);