Template
1
0
mirror of https://github.com/bol-van/zapret2.git synced 2026-03-22 17:25:47 +00:00

nfqws2: rewrite autohostlist udp failure detector logic

This commit is contained in:
bol-van
2025-12-11 15:19:31 +03:00
parent 912aadf6ca
commit 7708021587
9 changed files with 66 additions and 27 deletions

View File

@@ -323,23 +323,50 @@ static void auto_hostlist_failed(struct desync_profile *dp, const char *hostname
}
}
}
static void fill_client_ip_port(const struct sockaddr *client, char *client_ip_port, size_t client_ip_port_size)
{
if (*params.hostlist_auto_debuglog)
ntop46_port((struct sockaddr*)client, client_ip_port, client_ip_port_size);
else
*client_ip_port = 0;
}
static void process_retrans_fail(t_ctrack *ctrack, uint8_t proto, const struct sockaddr *client)
{
if (params.server) return; // no autohostlists in server mode
char client_ip_port[48];
if (*params.hostlist_auto_debuglog)
ntop46_port((struct sockaddr*)client, client_ip_port, sizeof(client_ip_port));
else
*client_ip_port = 0;
fill_client_ip_port(client, client_ip_port, sizeof(client_ip_port));
if (ctrack && ctrack->dp && ctrack->hostname && auto_hostlist_retrans(ctrack, proto, ctrack->dp->hostlist_auto_retrans_threshold, client_ip_port, ctrack->l7proto))
{
HOSTLIST_DEBUGLOG_APPEND("%s : profile %u (%s) : client %s : proto %s : retrans threshold reached", ctrack->hostname, ctrack->dp->n, PROFILE_NAME(ctrack->dp), client_ip_port, l7proto_str(ctrack->l7proto));
auto_hostlist_failed(ctrack->dp, ctrack->hostname, ctrack->hostname_is_ip, client_ip_port, ctrack->l7proto);
}
}
static void process_udp_fail(t_ctrack *ctrack, const t_ctrack_positions *tpos, const struct sockaddr *client)
{
// no autohostlists in server mode
if (!params.server && ctrack && ctrack->dp && ctrack->hostname && ctrack->hostname_ah_check &&
!ctrack->failure_detect_finalized && ctrack->dp->hostlist_auto_udp_out)
{
if (!tpos) tpos = &ctrack->pos;
//printf("UDP_POS %u %u\n",tpos->client.pcounter, tpos->server.pcounter);
if (tpos->server.pcounter > ctrack->dp->hostlist_auto_udp_in)
// success
ctrack->failure_detect_finalized = true;
else if (tpos->client.pcounter >= ctrack->dp->hostlist_auto_udp_out)
{
// failure
char client_ip_port[48];
ctrack->failure_detect_finalized = true;
fill_client_ip_port(client, client_ip_port, sizeof(client_ip_port));
HOSTLIST_DEBUGLOG_APPEND("%s : profile %u (%s) : client %s : proto %s : udp_in %u<=%u udp_out %u>=%u",
ctrack->hostname, ctrack->dp->n, PROFILE_NAME(ctrack->dp), client_ip_port, l7proto_str(ctrack->l7proto),
tpos->server.pcounter, ctrack->dp->hostlist_auto_udp_in,
tpos->client.pcounter, ctrack->dp->hostlist_auto_udp_out);
auto_hostlist_failed(ctrack->dp, ctrack->hostname, ctrack->hostname_is_ip, client_ip_port, ctrack->l7proto);
}
}
}
static bool send_delayed(t_ctrack *ctrack)
{
@@ -1101,10 +1128,7 @@ static uint8_t dpi_desync_tcp_packet_play(
if (rseq)
{
char client_ip_port[48];
if (*params.hostlist_auto_debuglog)
ntop46_port((struct sockaddr*)&dst, client_ip_port, sizeof(client_ip_port));
else
*client_ip_port = 0;
fill_client_ip_port((struct sockaddr*)&dst, client_ip_port, sizeof(client_ip_port));
if (seq_within(ctrack->pos.server.seq_last, ctrack->pos.server.seq0 + 1, ctrack->pos.server.seq0 + dp->hostlist_auto_incoming_maxseq))
{
bool bFail = false;
@@ -1776,20 +1800,14 @@ static uint8_t dpi_desync_udp_packet_play(
else
{
if (ctrack_replay)
{
ctrack_replay->hostname_ah_check = dp->hostlist_auto && !bCheckExcluded;
if (ctrack_replay->hostname_ah_check)
{
// first request is not retrans
if (!bDiscoveredHostname && !reasm_offset)
process_retrans_fail(ctrack_replay, IPPROTO_UDP, (struct sockaddr*)&src);
}
}
}
}
}
}
process_udp_fail(ctrack_replay, tpos, (struct sockaddr*)&src);
} // len_payload
if (bCheckDone && !bCheckResult)
{
DLOG("not applying tampering because of negative hostlist check\n");

View File

@@ -1436,6 +1436,8 @@ static void exithelp(void)
" --hostlist-auto-retrans-threshold=<int>\t\t; how many request retransmissions cause attempt to fail (default : %d)\n"
" --hostlist-auto-retrans-maxseq=<int>\t\t\t; count retransmissions only within this relative sequence (default : %u)\n"
" --hostlist-auto-incoming-maxseq=<int>\t\t\t; treat tcp connection as successful if incoming relative sequence exceedes this threshold (default : %u)\n"
" --hostlist-auto-udp-out=<int>\t\t\t\t; udp failure condition : sent at least `udp_out` packets (default : %u)\n"
" --hostlist-auto-udp-in=<int>\t\t\t\t; udp failure condition : received not more than `udp_in` packets (default : %u)\n"
" --hostlist-auto-debug=<logfile>\t\t\t; debug auto hostlist positives (global parameter)\n"
"\nLUA PACKET PASS MODE:\n"
" --payload=type[,type]\t\t\t\t\t; set payload types following LUA functions should process : %s\n"
@@ -1453,6 +1455,7 @@ static void exithelp(void)
HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT, HOSTLIST_AUTO_FAIL_TIME_DEFAULT,
HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT,
HOSTLIST_AUTO_RETRANS_MAXSEQ, HOSTLIST_AUTO_INCOMING_MAXSEQ,
HOSTLIST_AUTO_UDP_OUT, HOSTLIST_AUTO_UDP_IN,
all_payloads
);
exit(1);
@@ -1551,6 +1554,8 @@ enum opt_indices {
IDX_HOSTLIST_AUTO_RETRANS_THRESHOLD,
IDX_HOSTLIST_AUTO_RETRANS_MAXSEQ,
IDX_HOSTLIST_AUTO_INCOMING_MAXSEQ,
IDX_HOSTLIST_AUTO_UDP_IN,
IDX_HOSTLIST_AUTO_UDP_OUT,
IDX_HOSTLIST_AUTO_DEBUG,
IDX_NEW,
IDX_SKIP,
@@ -1637,6 +1642,8 @@ static const struct option long_options[] = {
[IDX_HOSTLIST_AUTO_RETRANS_THRESHOLD] = {"hostlist-auto-retrans-threshold", required_argument, 0, 0},
[IDX_HOSTLIST_AUTO_RETRANS_MAXSEQ] = {"hostlist-auto-retrans-maxseq", required_argument, 0, 0},
[IDX_HOSTLIST_AUTO_INCOMING_MAXSEQ] = {"hostlist-auto-incoming-maxseq", required_argument, 0, 0},
[IDX_HOSTLIST_AUTO_UDP_IN] = {"hostlist-auto-udp-in", required_argument, 0, 0},
[IDX_HOSTLIST_AUTO_UDP_OUT] = {"hostlist-auto-udp-out", required_argument, 0, 0},
[IDX_HOSTLIST_AUTO_DEBUG] = {"hostlist-auto-debug", required_argument, 0, 0},
[IDX_NEW] = {"new", no_argument, 0, 0},
[IDX_SKIP] = {"skip", no_argument, 0, 0},
@@ -2091,6 +2098,12 @@ int main(int argc, char **argv)
case IDX_HOSTLIST_AUTO_INCOMING_MAXSEQ:
dp->hostlist_auto_incoming_maxseq = (uint32_t)atoi(optarg);
break;
case IDX_HOSTLIST_AUTO_UDP_OUT:
dp->hostlist_auto_udp_out = atoi(optarg);
break;
case IDX_HOSTLIST_AUTO_UDP_IN:
dp->hostlist_auto_udp_in = atoi(optarg);
break;
case IDX_HOSTLIST_AUTO_DEBUG:
{
FILE *F = fopen(optarg, "a+t");

View File

@@ -344,6 +344,8 @@ void dp_init(struct desync_profile *dp)
dp->hostlist_auto_retrans_threshold = HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT;
dp->hostlist_auto_retrans_maxseq = HOSTLIST_AUTO_RETRANS_MAXSEQ;
dp->hostlist_auto_incoming_maxseq = HOSTLIST_AUTO_INCOMING_MAXSEQ;
dp->hostlist_auto_udp_out = HOSTLIST_AUTO_UDP_OUT;
dp->hostlist_auto_udp_in = HOSTLIST_AUTO_UDP_IN;
dp->filter_ipv4 = dp->filter_ipv6 = true;
}
static void dp_clear_dynamic(struct desync_profile *dp)

View File

@@ -32,6 +32,8 @@
#define HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT 3
#define HOSTLIST_AUTO_RETRANS_MAXSEQ 65536
#define HOSTLIST_AUTO_INCOMING_MAXSEQ 4096
#define HOSTLIST_AUTO_UDP_OUT 4
#define HOSTLIST_AUTO_UDP_IN 1
#define IPCACHE_LIFETIME 7200
@@ -80,6 +82,7 @@ struct desync_profile
// pointer to autohostlist. NULL if no autohostlist for the profile.
struct hostlist_file *hostlist_auto;
int hostlist_auto_fail_threshold, hostlist_auto_fail_time, hostlist_auto_retrans_threshold;
int hostlist_auto_udp_in, hostlist_auto_udp_out;
uint32_t hostlist_auto_retrans_maxseq, hostlist_auto_incoming_maxseq;
hostfail_pool *hostlist_auto_fail_counters;