mirror of
https://github.com/bol-van/zapret.git
synced 2025-05-06 10:40:48 +05:00
nfqws: autottl cache, --dup-autottl, --orig-autottl
This commit is contained in:
parent
5b625fa709
commit
5cc888cd2c
@ -482,7 +482,11 @@ nfqws: multiple mods for multiple TLS fakes
|
|||||||
init.d: remove 50-discord
|
init.d: remove 50-discord
|
||||||
blockcheck: use tpws --fix-seg on linux for multiple splits
|
blockcheck: use tpws --fix-seg on linux for multiple splits
|
||||||
|
|
||||||
v70.7
|
v71
|
||||||
|
|
||||||
nfqws,tpws: debug tls version, alpn, ech
|
nfqws,tpws: debug tls version, alpn, ech
|
||||||
nfqws: --dpi-desync-fake-tls=! means default tls fake
|
nfqws: --dpi-desync-fake-tls=! means default tls fake
|
||||||
|
nfqws: --dup*
|
||||||
|
nfqws: --orig*
|
||||||
|
nfqws: autottl cache
|
||||||
|
nfqws: autottl disable path length check
|
||||||
|
@ -77,7 +77,8 @@ typedef struct
|
|||||||
bool req_seq_present,req_seq_finalized,req_seq_abandoned;
|
bool req_seq_present,req_seq_finalized,req_seq_abandoned;
|
||||||
uint32_t req_seq_start,req_seq_end; // sequence interval of the request (to track retransmissions)
|
uint32_t req_seq_start,req_seq_end; // sequence interval of the request (to track retransmissions)
|
||||||
|
|
||||||
uint8_t incoming_ttl, autottl;
|
uint8_t incoming_ttl, desync_autottl, orig_autottl, dup_autottl;
|
||||||
|
bool b_autottl_discovered;
|
||||||
|
|
||||||
bool b_cutoff; // mark for deletion
|
bool b_cutoff; // mark for deletion
|
||||||
bool b_wssize_cutoff, b_desync_cutoff, b_dup_cutoff, b_orig_mod_cutoff;
|
bool b_wssize_cutoff, b_desync_cutoff, b_dup_cutoff, b_orig_mod_cutoff;
|
||||||
|
@ -1832,17 +1832,15 @@ bool rawsend_queue(struct rawpacket_tailhead *q)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// return guessed fake ttl value. 0 means unsuccessfull, should not perform autottl fooling
|
uint8_t hop_count_guess(uint8_t ttl)
|
||||||
// ttl = TTL of incoming packet
|
|
||||||
uint8_t autottl_guess(uint8_t ttl, const autottl *attl)
|
|
||||||
{
|
{
|
||||||
uint8_t orig, path, fake;
|
|
||||||
int d;
|
|
||||||
|
|
||||||
// 18.65.168.125 ( cloudfront ) 255
|
// 18.65.168.125 ( cloudfront ) 255
|
||||||
// 157.254.246.178 128
|
// 157.254.246.178 128
|
||||||
// 1.1.1.1 64
|
// 1.1.1.1 64
|
||||||
// guess original ttl. consider path lengths less than 32 hops
|
// guess original ttl. consider path lengths less than 32 hops
|
||||||
|
|
||||||
|
uint8_t orig;
|
||||||
|
|
||||||
if (ttl>223)
|
if (ttl>223)
|
||||||
orig=255;
|
orig=255;
|
||||||
else if (ttl<128 && ttl>96)
|
else if (ttl<128 && ttl>96)
|
||||||
@ -1852,15 +1850,22 @@ uint8_t autottl_guess(uint8_t ttl, const autottl *attl)
|
|||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
path = orig - ttl;
|
return orig - ttl;
|
||||||
|
}
|
||||||
|
// return guessed fake ttl value. 0 means unsuccessfull, should not perform autottl fooling
|
||||||
|
uint8_t autottl_eval(uint8_t hop_count, const autottl *attl)
|
||||||
|
{
|
||||||
|
uint8_t fake;
|
||||||
|
int d;
|
||||||
|
|
||||||
d = (int)path + attl->delta;
|
d = (int)hop_count + attl->delta;
|
||||||
if (d<attl->min) fake=attl->min;
|
if (d<attl->min) fake=attl->min;
|
||||||
else if (d>attl->max) fake=attl->max;
|
else if (d>attl->max) fake=attl->max;
|
||||||
else fake=(uint8_t)d;
|
else fake=(uint8_t)d;
|
||||||
|
|
||||||
if (attl->delta<0 && fake>=path || attl->delta>=0 && fake<path)
|
// path length check disabled
|
||||||
return 0;
|
// if (attl->delta<0 && fake>=hop_count || attl->delta>=0 && fake<hop_count)
|
||||||
|
// return 0;
|
||||||
|
|
||||||
return fake;
|
return fake;
|
||||||
}
|
}
|
||||||
|
@ -261,13 +261,10 @@ typedef struct
|
|||||||
int8_t delta;
|
int8_t delta;
|
||||||
uint8_t min, max;
|
uint8_t min, max;
|
||||||
} autottl;
|
} autottl;
|
||||||
#define AUTOTTL_DEFAULT_DELTA -1
|
|
||||||
#define AUTOTTL_DEFAULT_MIN 3
|
|
||||||
#define AUTOTTL_DEFAULT_MAX 20
|
|
||||||
#define AUTOTTL_ENABLED(a) (!!(a).delta)
|
#define AUTOTTL_ENABLED(a) (!!(a).delta)
|
||||||
#define AUTOTTL_SET_DEFAULT(a) {(a).delta=AUTOTTL_DEFAULT_DELTA; (a).min=AUTOTTL_DEFAULT_MIN; (a).max=AUTOTTL_DEFAULT_MAX;}
|
|
||||||
|
|
||||||
uint8_t autottl_guess(uint8_t ttl, const autottl *attl);
|
uint8_t hop_count_guess(uint8_t ttl);
|
||||||
|
uint8_t autottl_eval(uint8_t hop_count, const autottl *attl);
|
||||||
void do_nat(bool bOutbound, struct ip *ip, struct ip6_hdr *ip6, struct tcphdr *tcphdr, struct udphdr *udphdr, const struct sockaddr_in *target4, const struct sockaddr_in6 *target6);
|
void do_nat(bool bOutbound, struct ip *ip, struct ip6_hdr *ip6, struct tcphdr *tcphdr, struct udphdr *udphdr, const struct sockaddr_in *target4, const struct sockaddr_in6 *target6);
|
||||||
|
|
||||||
void verdict_tcp_csum_fix(uint8_t verdict, struct tcphdr *tcphdr, size_t transport_len, struct ip *ip, struct ip6_hdr *ip6hdr);
|
void verdict_tcp_csum_fix(uint8_t verdict, struct tcphdr *tcphdr, size_t transport_len, struct ip *ip, struct ip6_hdr *ip6hdr);
|
||||||
|
146
nfq/desync.c
146
nfq/desync.c
@ -745,21 +745,57 @@ static size_t pos_normalize(size_t split_pos, size_t reasm_offset, size_t len_pa
|
|||||||
return (split_pos>reasm_offset && (split_pos-reasm_offset)<len_payload) ? split_pos-reasm_offset : 0;
|
return (split_pos>reasm_offset && (split_pos-reasm_offset)<len_payload) ? split_pos-reasm_offset : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void autottl_discover(t_ctrack *ctrack, bool bIpv6)
|
static uint8_t autottl_guess(autottl *attl, uint8_t hop_count, const char *attl_kind)
|
||||||
{
|
{
|
||||||
if (ctrack && ctrack->incoming_ttl)
|
|
||||||
{
|
|
||||||
autottl *attl = bIpv6 ? &ctrack->dp->desync_autottl6 : &ctrack->dp->desync_autottl;
|
|
||||||
if (AUTOTTL_ENABLED(*attl))
|
if (AUTOTTL_ENABLED(*attl))
|
||||||
{
|
{
|
||||||
ctrack->autottl = autottl_guess(ctrack->incoming_ttl, attl);
|
uint8_t autottl = autottl_eval(hop_count, attl);
|
||||||
if (ctrack->autottl)
|
if (autottl)
|
||||||
DLOG("autottl: guessed %u\n",ctrack->autottl);
|
DLOG("%s autottl: guessed %u\n",attl_kind,autottl);
|
||||||
else
|
else
|
||||||
DLOG("autottl: could not guess\n");
|
DLOG("%s autottl: could not guess\n",attl_kind);
|
||||||
|
return autottl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ctrack->autottl = 0;
|
return 0;
|
||||||
|
}
|
||||||
|
static void autottl_discover(t_ctrack *ctrack, const struct in_addr *a4, const struct in6_addr *a6, const char *iface)
|
||||||
|
{
|
||||||
|
if (ctrack && params.autottl_present && !ctrack->b_autottl_discovered)
|
||||||
|
{
|
||||||
|
ip_cache_item *ipc = ipcacheTouch(¶ms.ipcache,a4,a6,iface);
|
||||||
|
if (!ipc)
|
||||||
|
{
|
||||||
|
DLOG_ERR("ipcache: out of memory\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ctrack->incoming_ttl)
|
||||||
|
{
|
||||||
|
uint8_t old_hops = ipc->hops;
|
||||||
|
ipc->hops = hop_count_guess(ctrack->incoming_ttl);
|
||||||
|
DLOG("incoming hops guessed %u\n", ipc->hops);
|
||||||
|
if (old_hops!=ipc->hops)
|
||||||
|
DLOG("updated autottl cache\n");
|
||||||
|
}
|
||||||
|
else if (ipc->hops)
|
||||||
|
DLOG("using cached hops %u\n", ipc->hops);
|
||||||
|
else
|
||||||
|
DLOG("hop count unknown\n");
|
||||||
|
if (ipc->hops)
|
||||||
|
{
|
||||||
|
ctrack->desync_autottl = autottl_guess(a6 ? &ctrack->dp->desync_autottl6 : &ctrack->dp->desync_autottl, ipc->hops, "desync");
|
||||||
|
ctrack->orig_autottl = autottl_guess(a6 ? &ctrack->dp->orig_autottl6 : &ctrack->dp->orig_autottl, ipc->hops, "orig");
|
||||||
|
ctrack->dup_autottl = autottl_guess(a6 ? &ctrack->dp->dup_autottl6 : &ctrack->dp->dup_autottl, ipc->hops, "dup");
|
||||||
|
}
|
||||||
|
ctrack->b_autottl_discovered = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void autottl_rediscover(t_ctrack *ctrack, const struct in_addr *a4, const struct in6_addr *a6, const char *iface)
|
||||||
|
{
|
||||||
|
if (ctrack)
|
||||||
|
{
|
||||||
|
ctrack->b_autottl_discovered = false;
|
||||||
|
autottl_discover(ctrack,a4,a6,iface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -837,8 +873,8 @@ static bool runtime_tls_mod(int fake_n,const struct fake_tls_mod_cache *modcache
|
|||||||
uint8_t orig_mod(const struct desync_profile *dp, const t_ctrack *ctrack, struct dissect *dis)
|
uint8_t orig_mod(const struct desync_profile *dp, const t_ctrack *ctrack, struct dissect *dis)
|
||||||
{
|
{
|
||||||
uint8_t ttl,ttl_orig;
|
uint8_t ttl,ttl_orig;
|
||||||
|
|
||||||
ttl = dis->ip6 ? dp->orig_mod_ttl6 : dp->orig_mod_ttl;
|
ttl = (ctrack && ctrack->orig_autottl) ? ctrack->orig_autottl : dis->ip6 ? dp->orig_mod_ttl6 : dp->orig_mod_ttl;
|
||||||
if (ttl && check_orig_mod_interval(dp,ctrack))
|
if (ttl && check_orig_mod_interval(dp,ctrack))
|
||||||
{
|
{
|
||||||
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
||||||
@ -893,14 +929,13 @@ static bool tcp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c
|
|||||||
bool sack,DF;
|
bool sack,DF;
|
||||||
|
|
||||||
extract_endpoints(dis->ip, dis->ip6, dis->tcp, NULL, &src, &dst);
|
extract_endpoints(dis->ip, dis->ip6, dis->tcp, NULL, &src, &dst);
|
||||||
|
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
||||||
|
|
||||||
verdict_tcp_csum_fix(verdict, dis->tcp, dis->transport_len, dis->ip, dis->ip6);
|
verdict_tcp_csum_fix(verdict, dis->tcp, dis->transport_len, dis->ip, dis->ip6);
|
||||||
|
|
||||||
if (dp->dup_repeats && check_dup_interval(dp,ctrack))
|
if (dp->dup_repeats && check_dup_interval(dp,ctrack))
|
||||||
{
|
{
|
||||||
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
ttl_fake = (ctrack && ctrack->dup_autottl) ? ctrack->dup_autottl : (dis->ip6 ? (dp->dup_ttl6 ? dp->dup_ttl6 : ttl_orig) : (dp->dup_ttl ? dp->dup_ttl : ttl_orig));
|
||||||
ttl_fake = dis->ip6 ? dp->dup_ttl6 : dp->dup_ttl;
|
|
||||||
if (!ttl_fake) ttl_fake = ttl_orig;
|
|
||||||
|
|
||||||
if (dp->dup_fooling_mode)
|
if (dp->dup_fooling_mode)
|
||||||
{
|
{
|
||||||
@ -910,20 +945,19 @@ static bool tcp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c
|
|||||||
sack = tcp_has_sack(dis->tcp);
|
sack = tcp_has_sack(dis->tcp);
|
||||||
nmss = tcp_find_mss(dis->tcp);
|
nmss = tcp_find_mss(dis->tcp);
|
||||||
ip_id = IP4_IP_ID_FIX(dis->ip);
|
ip_id = IP4_IP_ID_FIX(dis->ip);
|
||||||
DF = ip_has_df(dis->ip);
|
|
||||||
|
|
||||||
len = sizeof(pkt);
|
len = sizeof(pkt);
|
||||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst,
|
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst,
|
||||||
flags_orig, sack, nmss,
|
flags_orig, sack, nmss,
|
||||||
dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
dis->tcp->th_seq, dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps,
|
||||||
DF,ttl_fake,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
ip_has_df(dis->ip),ttl_fake,IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||||
dp->dup_fooling_mode,dp->dup_badseq_increment,dp->dup_badseq_ack_increment,
|
dp->dup_fooling_mode,dp->dup_badseq_increment,dp->dup_badseq_ack_increment,
|
||||||
dis->data_payload, dis->len_payload, pkt, &len))
|
dis->data_payload, dis->len_payload, pkt, &len))
|
||||||
{
|
{
|
||||||
DLOG_ERR("dup: packet reconstruct failed\n");
|
DLOG_ERR("dup: packet reconstruct failed\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
DLOG("sending %u dups with packet reconstruct\n", dp->dup_repeats);
|
DLOG("sending %u dups with packet reconstruct. ttl %u => %u\n", dp->dup_repeats, ttl_orig, ttl_fake);
|
||||||
|
|
||||||
// send dups
|
// send dups
|
||||||
for (k=0;k<dp->dup_repeats;k++)
|
for (k=0;k<dp->dup_repeats;k++)
|
||||||
@ -941,7 +975,7 @@ static bool tcp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c
|
|||||||
DLOG("NOT sending original because of dup_replace\n");
|
DLOG("NOT sending original because of dup_replace\n");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DLOG("sending original\n", dp->dup_repeats);
|
DLOG("sending original ttl %u\n", ttl_orig);
|
||||||
if (!rawsend((struct sockaddr *)&dst, fwmark, ifout , dis->data_pkt, dis->len_pkt))
|
if (!rawsend((struct sockaddr *)&dst, fwmark, ifout , dis->data_pkt, dis->len_pkt))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -949,7 +983,7 @@ static bool tcp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c
|
|||||||
}
|
}
|
||||||
if (bForceSend)
|
if (bForceSend)
|
||||||
{
|
{
|
||||||
DLOG("sending original\n", dp->dup_repeats);
|
DLOG("sending original ttl %u\n", ttl_orig);
|
||||||
if (!rawsend((struct sockaddr *)&dst, fwmark, ifout , dis->data_pkt, dis->len_pkt))
|
if (!rawsend((struct sockaddr *)&dst, fwmark, ifout , dis->data_pkt, dis->len_pkt))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
@ -968,18 +1002,15 @@ static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c
|
|||||||
uint16_t ip_id;
|
uint16_t ip_id;
|
||||||
struct sockaddr_storage src, dst;
|
struct sockaddr_storage src, dst;
|
||||||
uint8_t ttl_orig,ttl_fake;
|
uint8_t ttl_orig,ttl_fake;
|
||||||
bool DF;
|
|
||||||
|
|
||||||
extract_endpoints(dis->ip, dis->ip6, NULL, dis->udp, &src, &dst);
|
extract_endpoints(dis->ip, dis->ip6, NULL, dis->udp, &src, &dst);
|
||||||
|
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
||||||
|
|
||||||
verdict_udp_csum_fix(verdict, dis->udp, dis->transport_len, dis->ip, dis->ip6);
|
verdict_udp_csum_fix(verdict, dis->udp, dis->transport_len, dis->ip, dis->ip6);
|
||||||
|
|
||||||
if (dp->dup_repeats && check_dup_interval(dp,ctrack))
|
if (dp->dup_repeats && check_dup_interval(dp,ctrack))
|
||||||
{
|
{
|
||||||
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
ttl_fake = (ctrack && ctrack->dup_autottl) ? ctrack->dup_autottl : (dis->ip6 ? (dp->dup_ttl6 ? dp->dup_ttl6 : ttl_orig) : (dp->dup_ttl ? dp->dup_ttl : ttl_orig));
|
||||||
ttl_fake = dis->ip6 ? dp->dup_ttl6 : dp->dup_ttl;
|
|
||||||
if (!ttl_fake) ttl_fake = ttl_orig;
|
|
||||||
DF = ip_has_df(dis->ip);
|
|
||||||
|
|
||||||
if (dp->dup_fooling_mode)
|
if (dp->dup_fooling_mode)
|
||||||
{
|
{
|
||||||
@ -987,7 +1018,7 @@ static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c
|
|||||||
|
|
||||||
len = sizeof(pkt);
|
len = sizeof(pkt);
|
||||||
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst,
|
if (!prepare_udp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst,
|
||||||
DF,ttl_fake, IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
ip_has_df(dis->ip),ttl_fake, IP4_TOS(dis->ip),ip_id,IP6_FLOW(dis->ip6),
|
||||||
dp->dup_fooling_mode, NULL, 0, 0,
|
dp->dup_fooling_mode, NULL, 0, 0,
|
||||||
dis->data_payload, dis->len_payload, pkt, &len))
|
dis->data_payload, dis->len_payload, pkt, &len))
|
||||||
{
|
{
|
||||||
@ -995,7 +1026,7 @@ static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
DLOG("sending %u dups with packet reconstruct\n", dp->dup_repeats);
|
DLOG("sending %u dups with packet reconstruct. ttl %u => %u\n", dp->dup_repeats, ttl_orig, ttl_fake);
|
||||||
|
|
||||||
// send dups
|
// send dups
|
||||||
for (k=0;k<dp->dup_repeats;k++)
|
for (k=0;k<dp->dup_repeats;k++)
|
||||||
@ -1013,7 +1044,7 @@ static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c
|
|||||||
DLOG("NOT sending original because of dup_replace\n");
|
DLOG("NOT sending original because of dup_replace\n");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DLOG("sending original\n", dp->dup_repeats);
|
DLOG("sending original ttl %u\n", ttl_orig);
|
||||||
if (!rawsend((struct sockaddr *)&dst, fwmark, ifout , dis->data_pkt, dis->len_pkt))
|
if (!rawsend((struct sockaddr *)&dst, fwmark, ifout , dis->data_pkt, dis->len_pkt))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1021,7 +1052,7 @@ static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c
|
|||||||
}
|
}
|
||||||
if (bForceSend)
|
if (bForceSend)
|
||||||
{
|
{
|
||||||
DLOG("sending original\n", dp->dup_repeats);
|
DLOG("sending original ttl %u\n", ttl_orig);
|
||||||
if (!rawsend((struct sockaddr *)&dst, fwmark, ifout , dis->data_pkt, dis->len_pkt))
|
if (!rawsend((struct sockaddr *)&dst, fwmark, ifout , dis->data_pkt, dis->len_pkt))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
@ -1030,7 +1061,7 @@ static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint32_t fwmark, const char *ifout, struct dissect *dis)
|
static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint32_t fwmark, const char *ifin, const char *ifout, struct dissect *dis)
|
||||||
{
|
{
|
||||||
uint8_t verdict=VERDICT_PASS;
|
uint8_t verdict=VERDICT_PASS;
|
||||||
|
|
||||||
@ -1121,10 +1152,10 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
||||||
if (!ctrack->incoming_ttl)
|
if (!ctrack->incoming_ttl)
|
||||||
{
|
{
|
||||||
DLOG("incoming TTL %u\n",ttl_orig);
|
|
||||||
ctrack->incoming_ttl = ttl_orig;
|
ctrack->incoming_ttl = ttl_orig;
|
||||||
|
DLOG("incoming TTL %u\n",ttl_orig);
|
||||||
|
autottl_rediscover(ctrack,dis->ip ? &dis->ip->ip_src : NULL,dis->ip6 ? &dis->ip6->ip6_src : NULL , ifin);
|
||||||
}
|
}
|
||||||
if (!ctrack->autottl) autottl_discover(ctrack,!!dis->ip6);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// process reply packets for auto hostlist mode
|
// process reply packets for auto hostlist mode
|
||||||
@ -1178,6 +1209,8 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
return verdict; // nothing to do. do not waste cpu
|
return verdict; // nothing to do. do not waste cpu
|
||||||
}
|
}
|
||||||
|
|
||||||
|
autottl_discover(ctrack,dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , ifout);
|
||||||
|
|
||||||
if (orig_mod(dp,ctrack,dis)) // ttl can change !
|
if (orig_mod(dp,ctrack,dis)) // ttl can change !
|
||||||
verdict = VERDICT_MODIFY;
|
verdict = VERDICT_MODIFY;
|
||||||
|
|
||||||
@ -1207,7 +1240,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
} // !replay
|
} // !replay
|
||||||
|
|
||||||
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim;
|
||||||
ttl_fake = (ctrack_replay && ctrack_replay->autottl) ? ctrack_replay->autottl : (dis->ip6 ? (dp->desync_ttl6 ? dp->desync_ttl6 : ttl_orig) : (dp->desync_ttl ? dp->desync_ttl : ttl_orig));
|
ttl_fake = (ctrack_replay && ctrack_replay->desync_autottl) ? ctrack_replay->desync_autottl : (dis->ip6 ? (dp->desync_ttl6 ? dp->desync_ttl6 : ttl_orig) : (dp->desync_ttl ? dp->desync_ttl : ttl_orig));
|
||||||
flags_orig = *((uint8_t*)dis->tcp+13);
|
flags_orig = *((uint8_t*)dis->tcp+13);
|
||||||
scale_factor = tcp_find_scale_factor(dis->tcp);
|
scale_factor = tcp_find_scale_factor(dis->tcp);
|
||||||
timestamps = tcp_find_timestamps(dis->tcp);
|
timestamps = tcp_find_timestamps(dis->tcp);
|
||||||
@ -1368,7 +1401,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
if (!ReasmIsEmpty(&ctrack->reasm_orig))
|
if (!ReasmIsEmpty(&ctrack->reasm_orig))
|
||||||
{
|
{
|
||||||
verdict_tcp_csum_fix(verdict, dis->tcp, dis->transport_len, dis->ip, dis->ip6);
|
verdict_tcp_csum_fix(verdict, dis->tcp, dis->transport_len, dis->ip, dis->ip6);
|
||||||
if (rawpacket_queue(&ctrack->delayed, &dst, desync_fwmark, ifout, dis->data_pkt, dis->len_pkt, dis->len_payload))
|
if (rawpacket_queue(&ctrack->delayed, &dst, desync_fwmark, ifin, ifout, dis->data_pkt, dis->len_pkt, dis->len_payload))
|
||||||
{
|
{
|
||||||
DLOG("DELAY desync until reasm is complete (#%u)\n", rawpacket_queue_count(&ctrack->delayed));
|
DLOG("DELAY desync until reasm is complete (#%u)\n", rawpacket_queue_count(&ctrack->delayed));
|
||||||
}
|
}
|
||||||
@ -1455,10 +1488,14 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
if (dp!=dp_prev)
|
if (dp!=dp_prev)
|
||||||
{
|
{
|
||||||
DLOG("desync profile changed by revealed l7 protocol or hostname !\n");
|
DLOG("desync profile changed by revealed l7 protocol or hostname !\n");
|
||||||
// rediscover autottl
|
autottl_rediscover(ctrack_replay,dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , ifout);
|
||||||
autottl_discover(ctrack_replay,!!dis->ip6);
|
|
||||||
// re-evaluate start/cutoff limiters
|
// re-evaluate start/cutoff limiters
|
||||||
if (!replay)
|
if (replay)
|
||||||
|
{
|
||||||
|
if (orig_mod(dp,ctrack_replay,dis)) // ttl can change !
|
||||||
|
verdict = VERDICT_MODIFY;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
maybe_cutoff(ctrack, IPPROTO_TCP);
|
maybe_cutoff(ctrack, IPPROTO_TCP);
|
||||||
if (orig_mod(dp,ctrack,dis)) // ttl can change !
|
if (orig_mod(dp,ctrack,dis)) // ttl can change !
|
||||||
@ -1509,7 +1546,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
DLOG("applying tampering to unknown protocol\n");
|
DLOG("applying tampering to unknown protocol\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
ttl_fake = (ctrack_replay && ctrack_replay->autottl) ? ctrack_replay->autottl : (dis->ip6 ? (dp->desync_ttl6 ? dp->desync_ttl6 : ttl_orig) : (dp->desync_ttl ? dp->desync_ttl : ttl_orig));
|
ttl_fake = (ctrack_replay && ctrack_replay->desync_autottl) ? ctrack_replay->desync_autottl : (dis->ip6 ? (dp->desync_ttl6 ? dp->desync_ttl6 : ttl_orig) : (dp->desync_ttl ? dp->desync_ttl : ttl_orig));
|
||||||
if ((l7proto == HTTP) && (dp->hostcase || dp->hostnospace || dp->domcase || dp->methodeol) && HttpFindHost(&phost,dis->data_payload,dis->len_payload))
|
if ((l7proto == HTTP) && (dp->hostcase || dp->hostnospace || dp->domcase || dp->methodeol) && HttpFindHost(&phost,dis->data_payload,dis->len_payload))
|
||||||
{
|
{
|
||||||
if (dp->hostcase)
|
if (dp->hostcase)
|
||||||
@ -2207,7 +2244,7 @@ static bool quic_reasm_cancel(t_ctrack *ctrack, const char *reason)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint32_t fwmark, const char *ifout, struct dissect *dis)
|
static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint32_t fwmark, const char *ifin, const char *ifout, struct dissect *dis)
|
||||||
{
|
{
|
||||||
uint8_t verdict=VERDICT_PASS;
|
uint8_t verdict=VERDICT_PASS;
|
||||||
|
|
||||||
@ -2294,12 +2331,14 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
{
|
{
|
||||||
DLOG("incoming TTL %u\n",ttl_orig);
|
DLOG("incoming TTL %u\n",ttl_orig);
|
||||||
ctrack->incoming_ttl = ttl_orig;
|
ctrack->incoming_ttl = ttl_orig;
|
||||||
|
autottl_rediscover(ctrack,dis->ip ? &dis->ip->ip_src : NULL,dis->ip6 ? &dis->ip6->ip6_src : NULL , ifin);
|
||||||
}
|
}
|
||||||
if (!ctrack->autottl) autottl_discover(ctrack,!!dis->ip6);
|
|
||||||
}
|
}
|
||||||
return verdict; // nothing to do. do not waste cpu
|
return verdict; // nothing to do. do not waste cpu
|
||||||
}
|
}
|
||||||
|
|
||||||
|
autottl_discover(ctrack,dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , ifout);
|
||||||
|
|
||||||
if (orig_mod(dp,ctrack,dis)) // ttl can change !
|
if (orig_mod(dp,ctrack,dis)) // ttl can change !
|
||||||
verdict = VERDICT_MODIFY;
|
verdict = VERDICT_MODIFY;
|
||||||
|
|
||||||
@ -2384,7 +2423,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
if (!ReasmIsEmpty(&ctrack->reasm_orig))
|
if (!ReasmIsEmpty(&ctrack->reasm_orig))
|
||||||
{
|
{
|
||||||
verdict_udp_csum_fix(verdict, dis->udp, dis->transport_len, dis->ip, dis->ip6);
|
verdict_udp_csum_fix(verdict, dis->udp, dis->transport_len, dis->ip, dis->ip6);
|
||||||
if (rawpacket_queue(&ctrack->delayed, &dst, desync_fwmark, ifout, dis->data_pkt, dis->len_pkt, dis->len_payload))
|
if (rawpacket_queue(&ctrack->delayed, &dst, desync_fwmark, ifin, ifout, dis->data_pkt, dis->len_pkt, dis->len_payload))
|
||||||
{
|
{
|
||||||
DLOG("DELAY desync until reasm is complete (#%u)\n", rawpacket_queue_count(&ctrack->delayed));
|
DLOG("DELAY desync until reasm is complete (#%u)\n", rawpacket_queue_count(&ctrack->delayed));
|
||||||
}
|
}
|
||||||
@ -2433,7 +2472,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
verdict_udp_csum_fix(verdict, dis->udp, dis->transport_len, dis->ip, dis->ip6);
|
verdict_udp_csum_fix(verdict, dis->udp, dis->transport_len, dis->ip, dis->ip6);
|
||||||
if (rawpacket_queue(&ctrack->delayed, &dst, desync_fwmark, ifout, dis->data_pkt, dis->len_pkt, dis->len_payload))
|
if (rawpacket_queue(&ctrack->delayed, &dst, desync_fwmark, ifin, ifout, dis->data_pkt, dis->len_pkt, dis->len_payload))
|
||||||
{
|
{
|
||||||
DLOG("DELAY desync until reasm is complete (#%u)\n", rawpacket_queue_count(&ctrack->delayed));
|
DLOG("DELAY desync until reasm is complete (#%u)\n", rawpacket_queue_count(&ctrack->delayed));
|
||||||
}
|
}
|
||||||
@ -2554,10 +2593,14 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
if (dp!=dp_prev)
|
if (dp!=dp_prev)
|
||||||
{
|
{
|
||||||
DLOG("desync profile changed by revealed l7 protocol or hostname !\n");
|
DLOG("desync profile changed by revealed l7 protocol or hostname !\n");
|
||||||
// rediscover autottl
|
autottl_rediscover(ctrack_replay,dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , ifout);
|
||||||
autottl_discover(ctrack_replay,!!dis->ip6);
|
|
||||||
// re-evaluate start/cutoff limiters
|
// re-evaluate start/cutoff limiters
|
||||||
if (!replay)
|
if (replay)
|
||||||
|
{
|
||||||
|
if (orig_mod(dp,ctrack_replay,dis)) // ttl can change !
|
||||||
|
verdict = VERDICT_MODIFY;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
maybe_cutoff(ctrack, IPPROTO_UDP);
|
maybe_cutoff(ctrack, IPPROTO_UDP);
|
||||||
if (orig_mod(dp,ctrack,dis)) // ttl can change !
|
if (orig_mod(dp,ctrack,dis)) // ttl can change !
|
||||||
@ -2619,7 +2662,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ttl_fake = (ctrack_replay && ctrack_replay->autottl) ? ctrack_replay->autottl : (dis->ip6 ? (dp->desync_ttl6 ? dp->desync_ttl6 : ttl_orig) : (dp->desync_ttl ? dp->desync_ttl : ttl_orig));
|
ttl_fake = (ctrack_replay && ctrack_replay->desync_autottl) ? ctrack_replay->desync_autottl : (dis->ip6 ? (dp->desync_ttl6 ? dp->desync_ttl6 : ttl_orig) : (dp->desync_ttl ? dp->desync_ttl : ttl_orig));
|
||||||
|
|
||||||
uint32_t fooling_orig = FOOL_NONE;
|
uint32_t fooling_orig = FOOL_NONE;
|
||||||
|
|
||||||
@ -2832,7 +2875,7 @@ static void packet_debug(bool replay, const struct dissect *dis)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t dpi_desync_packet_play(bool replay, size_t reasm_offset, uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt)
|
static uint8_t dpi_desync_packet_play(bool replay, size_t reasm_offset, uint32_t fwmark, const char *ifin, const char *ifout, uint8_t *data_pkt, size_t *len_pkt)
|
||||||
{
|
{
|
||||||
struct dissect dis;
|
struct dissect dis;
|
||||||
uint8_t verdict = VERDICT_PASS;
|
uint8_t verdict = VERDICT_PASS;
|
||||||
@ -2846,14 +2889,14 @@ static uint8_t dpi_desync_packet_play(bool replay, size_t reasm_offset, uint32_t
|
|||||||
case IPPROTO_TCP:
|
case IPPROTO_TCP:
|
||||||
if (dis.tcp)
|
if (dis.tcp)
|
||||||
{
|
{
|
||||||
verdict = dpi_desync_tcp_packet_play(replay, reasm_offset, fwmark, ifout, &dis);
|
verdict = dpi_desync_tcp_packet_play(replay, reasm_offset, fwmark, ifin, ifout, &dis);
|
||||||
verdict_tcp_csum_fix(verdict, dis.tcp, dis.transport_len, dis.ip, dis.ip6);
|
verdict_tcp_csum_fix(verdict, dis.tcp, dis.transport_len, dis.ip, dis.ip6);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IPPROTO_UDP:
|
case IPPROTO_UDP:
|
||||||
if (dis.udp)
|
if (dis.udp)
|
||||||
{
|
{
|
||||||
verdict = dpi_desync_udp_packet_play(replay, reasm_offset, fwmark, ifout, &dis);
|
verdict = dpi_desync_udp_packet_play(replay, reasm_offset, fwmark, ifin, ifout, &dis);
|
||||||
verdict_udp_csum_fix(verdict, dis.udp, dis.transport_len, dis.ip, dis.ip6);
|
verdict_udp_csum_fix(verdict, dis.udp, dis.transport_len, dis.ip, dis.ip6);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2862,9 +2905,10 @@ static uint8_t dpi_desync_packet_play(bool replay, size_t reasm_offset, uint32_t
|
|||||||
}
|
}
|
||||||
return verdict;
|
return verdict;
|
||||||
}
|
}
|
||||||
uint8_t dpi_desync_packet(uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt)
|
uint8_t dpi_desync_packet(uint32_t fwmark, const char *ifin, const char *ifout, uint8_t *data_pkt, size_t *len_pkt)
|
||||||
{
|
{
|
||||||
return dpi_desync_packet_play(false, 0, fwmark, ifout, data_pkt, len_pkt);
|
ipcachePurgeRateLimited(¶ms.ipcache, params.autottl_cache_lifetime);
|
||||||
|
return dpi_desync_packet_play(false, 0, fwmark, ifin, ifout, data_pkt, len_pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2878,7 +2922,7 @@ static bool replay_queue(struct rawpacket_tailhead *q)
|
|||||||
for (i=1,offset=0 ; (rp=rawpacket_dequeue(q)) ; offset+=rp->len_payload, rawpacket_free(rp), i++)
|
for (i=1,offset=0 ; (rp=rawpacket_dequeue(q)) ; offset+=rp->len_payload, rawpacket_free(rp), i++)
|
||||||
{
|
{
|
||||||
DLOG("REPLAYING delayed packet #%u offset %zu\n",i,offset);
|
DLOG("REPLAYING delayed packet #%u offset %zu\n",i,offset);
|
||||||
uint8_t verdict = dpi_desync_packet_play(true, offset, rp->fwmark, rp->ifout, rp->packet, &rp->len);
|
uint8_t verdict = dpi_desync_packet_play(true, offset, rp->fwmark, rp->ifin, rp->ifout, rp->packet, &rp->len);
|
||||||
switch(verdict & VERDICT_MASK)
|
switch(verdict & VERDICT_MASK)
|
||||||
{
|
{
|
||||||
case VERDICT_MODIFY:
|
case VERDICT_MODIFY:
|
||||||
|
@ -52,4 +52,4 @@ bool desync_valid_second_stage(enum dpi_desync_mode mode);
|
|||||||
bool desync_valid_second_stage_tcp(enum dpi_desync_mode mode);
|
bool desync_valid_second_stage_tcp(enum dpi_desync_mode mode);
|
||||||
bool desync_valid_second_stage_udp(enum dpi_desync_mode mode);
|
bool desync_valid_second_stage_udp(enum dpi_desync_mode mode);
|
||||||
|
|
||||||
uint8_t dpi_desync_packet(uint32_t fwmark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt);
|
uint8_t dpi_desync_packet(uint32_t fwmark, const char *ifin, const char *ifout, uint8_t *data_pkt, size_t *len_pkt);
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
#define UNARY_PLUS(v) (v>0 ? "+" : "")
|
||||||
|
|
||||||
// this saves memory. sockaddr_storage is larger than required. it can be 128 bytes. sockaddr_in6 is 28 bytes.
|
// this saves memory. sockaddr_storage is larger than required. it can be 128 bytes. sockaddr_in6 is 28 bytes.
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
|
136
nfq/nfqws.c
136
nfq/nfqws.c
@ -99,7 +99,11 @@ static void onusr2(int sig)
|
|||||||
printf("\nDESYNC PROFILE %d\n",dpl->dp.n);
|
printf("\nDESYNC PROFILE %d\n",dpl->dp.n);
|
||||||
HostFailPoolDump(dpl->dp.hostlist_auto_fail_counters);
|
HostFailPoolDump(dpl->dp.hostlist_auto_fail_counters);
|
||||||
}
|
}
|
||||||
|
if (params.autottl_present)
|
||||||
|
{
|
||||||
|
printf("\nAUTOTTL IP CACHE\n");
|
||||||
|
ipcachePrint(¶ms.ipcache);
|
||||||
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +115,7 @@ static void pre_desync(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t processPacketData(uint32_t *mark, const char *ifout, uint8_t *data_pkt, size_t *len_pkt)
|
static uint8_t processPacketData(uint32_t *mark, const char *ifin, const char *ifout, uint8_t *data_pkt, size_t *len_pkt)
|
||||||
{
|
{
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
if (*mark & params.desync_fwmark)
|
if (*mark & params.desync_fwmark)
|
||||||
@ -120,7 +124,7 @@ static uint8_t processPacketData(uint32_t *mark, const char *ifout, uint8_t *dat
|
|||||||
return VERDICT_PASS;
|
return VERDICT_PASS;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return dpi_desync_packet(*mark, ifout, data_pkt, len_pkt);
|
return dpi_desync_packet(*mark, ifin, ifout, data_pkt, len_pkt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -154,8 +158,8 @@ static int nfq_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_da
|
|||||||
size_t len;
|
size_t len;
|
||||||
struct nfqnl_msg_packet_hdr *ph;
|
struct nfqnl_msg_packet_hdr *ph;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
uint32_t ifidx;
|
uint32_t ifidx_out, ifidx_in;
|
||||||
char ifout[IFNAMSIZ+1];
|
char ifout[IFNAMSIZ], ifin[IFNAMSIZ];
|
||||||
|
|
||||||
ph = nfq_get_msg_packet_hdr(nfa);
|
ph = nfq_get_msg_packet_hdr(nfa);
|
||||||
id = ph ? ntohl(ph->packet_id) : 0;
|
id = ph ? ntohl(ph->packet_id) : 0;
|
||||||
@ -163,27 +167,20 @@ static int nfq_cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_da
|
|||||||
uint32_t mark = nfq_get_nfmark(nfa);
|
uint32_t mark = nfq_get_nfmark(nfa);
|
||||||
ilen = nfq_get_payload(nfa, &data);
|
ilen = nfq_get_payload(nfa, &data);
|
||||||
|
|
||||||
|
ifidx_out = nfq_get_outdev(nfa);
|
||||||
*ifout=0;
|
*ifout=0;
|
||||||
if (params.bind_fix4 || params.bind_fix6)
|
if (ifidx_out) if_indextoname(ifidx_out,ifout);
|
||||||
{
|
|
||||||
char ifin[IFNAMSIZ+1];
|
|
||||||
uint32_t ifidx_in;
|
|
||||||
|
|
||||||
ifidx = nfq_get_outdev(nfa);
|
ifidx_in = nfq_get_indev(nfa);
|
||||||
if (ifidx) if_indextoname(ifidx,ifout);
|
*ifin=0;
|
||||||
*ifin=0;
|
if (ifidx_in) if_indextoname(ifidx_in,ifin);
|
||||||
ifidx_in = nfq_get_indev(nfa);
|
|
||||||
if (ifidx_in) if_indextoname(ifidx_in,ifin);
|
DLOG("packet: id=%d len=%d mark=%08X ifin=%s(%u) ifout=%s(%u)\n", id, ilen, mark, ifin, ifidx_in, ifout, ifidx_out);
|
||||||
|
|
||||||
DLOG("packet: id=%d len=%d mark=%08X ifin=%s(%u) ifout=%s(%u)\n", id, ilen, mark, ifin, ifidx_in, ifout, ifidx);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
// save some syscalls
|
|
||||||
DLOG("packet: id=%d len=%d mark=%08X\n", id, ilen, mark);
|
|
||||||
if (ilen >= 0)
|
if (ilen >= 0)
|
||||||
{
|
{
|
||||||
len = ilen;
|
len = ilen;
|
||||||
uint8_t verdict = processPacketData(&mark, ifout, data, &len);
|
uint8_t verdict = processPacketData(&mark, ifin, ifout, data, &len);
|
||||||
switch(verdict & VERDICT_MASK)
|
switch(verdict & VERDICT_MASK)
|
||||||
{
|
{
|
||||||
case VERDICT_MODIFY:
|
case VERDICT_MODIFY:
|
||||||
@ -437,7 +434,7 @@ static int dvt_main(void)
|
|||||||
ReloadCheck();
|
ReloadCheck();
|
||||||
|
|
||||||
DLOG("packet: id=%u len=%zu\n", id, len);
|
DLOG("packet: id=%u len=%zu\n", id, len);
|
||||||
verdict = processPacketData(&mark, NULL, buf, &len);
|
verdict = processPacketData(&mark, NULL, NULL, buf, &len);
|
||||||
switch (verdict & VERDICT_MASK)
|
switch (verdict & VERDICT_MASK)
|
||||||
{
|
{
|
||||||
case VERDICT_PASS:
|
case VERDICT_PASS:
|
||||||
@ -484,7 +481,7 @@ static int win_main(const char *windivert_filter)
|
|||||||
uint8_t packet[16384];
|
uint8_t packet[16384];
|
||||||
uint32_t mark;
|
uint32_t mark;
|
||||||
WINDIVERT_ADDRESS wa;
|
WINDIVERT_ADDRESS wa;
|
||||||
char ifout[22];
|
char ifname[IFNAMSIZ];
|
||||||
|
|
||||||
pre_desync();
|
pre_desync();
|
||||||
|
|
||||||
@ -550,8 +547,8 @@ static int win_main(const char *windivert_filter)
|
|||||||
|
|
||||||
ReloadCheck();
|
ReloadCheck();
|
||||||
|
|
||||||
*ifout=0;
|
*ifname=0;
|
||||||
if (wa.Outbound) snprintf(ifout,sizeof(ifout),"%u.%u", wa.Network.IfIdx, wa.Network.SubIfIdx);
|
snprintf(ifname,sizeof(ifname),"%u.%u", wa.Network.IfIdx, wa.Network.SubIfIdx);
|
||||||
DLOG("packet: id=%u len=%zu %s IPv6=%u IPChecksum=%u TCPChecksum=%u UDPChecksum=%u IfIdx=%u.%u\n", id, len, wa.Outbound ? "outbound" : "inbound", wa.IPv6, wa.IPChecksum, wa.TCPChecksum, wa.UDPChecksum, wa.Network.IfIdx, wa.Network.SubIfIdx);
|
DLOG("packet: id=%u len=%zu %s IPv6=%u IPChecksum=%u TCPChecksum=%u UDPChecksum=%u IfIdx=%u.%u\n", id, len, wa.Outbound ? "outbound" : "inbound", wa.IPv6, wa.IPChecksum, wa.TCPChecksum, wa.UDPChecksum, wa.Network.IfIdx, wa.Network.SubIfIdx);
|
||||||
if (wa.Impostor)
|
if (wa.Impostor)
|
||||||
{
|
{
|
||||||
@ -567,7 +564,7 @@ static int win_main(const char *windivert_filter)
|
|||||||
{
|
{
|
||||||
mark=0;
|
mark=0;
|
||||||
// pseudo interface id IfIdx.SubIfIdx
|
// pseudo interface id IfIdx.SubIfIdx
|
||||||
verdict = processPacketData(&mark, ifout, packet, &len);
|
verdict = processPacketData(&mark, ifname, ifname, packet, &len);
|
||||||
}
|
}
|
||||||
switch (verdict & VERDICT_MASK)
|
switch (verdict & VERDICT_MASK)
|
||||||
{
|
{
|
||||||
@ -690,11 +687,14 @@ static void load_file_or_exit(const char *filename, void *buf, size_t *size)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool parse_autottl(const char *s, autottl *t)
|
static bool parse_autottl(const char *s, autottl *t, int8_t def_delta, uint8_t def_min, uint8_t def_max)
|
||||||
{
|
{
|
||||||
bool neg=true;
|
bool neg=true;
|
||||||
unsigned int delta,min,max;
|
unsigned int delta,min,max;
|
||||||
AUTOTTL_SET_DEFAULT(*t);
|
|
||||||
|
t->delta = def_delta;
|
||||||
|
t->min = def_min;
|
||||||
|
t->max = def_max;
|
||||||
if (s)
|
if (s)
|
||||||
{
|
{
|
||||||
max = t->max;
|
max = t->max;
|
||||||
@ -1416,6 +1416,7 @@ static void exithelp(void)
|
|||||||
" --bind-fix6\t\t\t\t\t; apply outgoing interface selection fix for generated ipv6 packets\n"
|
" --bind-fix6\t\t\t\t\t; apply outgoing interface selection fix for generated ipv6 packets\n"
|
||||||
#endif
|
#endif
|
||||||
" --ctrack-timeouts=S:E:F[:U]\t\t\t; internal conntrack timeouts for TCP SYN, ESTABLISHED, FIN stages, UDP timeout. default %u:%u:%u:%u\n"
|
" --ctrack-timeouts=S:E:F[:U]\t\t\t; internal conntrack timeouts for TCP SYN, ESTABLISHED, FIN stages, UDP timeout. default %u:%u:%u:%u\n"
|
||||||
|
" --autottl-cache-lifetime=<int>\t\t\t; time in seconds to keep cached hop count (default %u)\n"
|
||||||
#ifdef __CYGWIN__
|
#ifdef __CYGWIN__
|
||||||
"\nWINDIVERT FILTER:\n"
|
"\nWINDIVERT FILTER:\n"
|
||||||
" --wf-iface=<int>[.<int>]\t\t\t; numeric network interface and subinterface indexes\n"
|
" --wf-iface=<int>[.<int>]\t\t\t; numeric network interface and subinterface indexes\n"
|
||||||
@ -1456,12 +1457,16 @@ static void exithelp(void)
|
|||||||
" --wssize-cutoff=[n|d|s]N\t\t\t; apply server wsize only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n"
|
" --wssize-cutoff=[n|d|s]N\t\t\t; apply server wsize only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n"
|
||||||
" --orig-ttl=<int>\t\t\t\t; set TTL for original packets\n"
|
" --orig-ttl=<int>\t\t\t\t; set TTL for original packets\n"
|
||||||
" --orig-ttl6=<int>\t\t\t\t; set ipv6 hop limit for original packets. by default ttl value is used\n"
|
" --orig-ttl6=<int>\t\t\t\t; set ipv6 hop limit for original packets. by default ttl value is used\n"
|
||||||
|
" --orig-autottl=[<delta>[:<min>[-<max>]]]\t; auto ttl mode for both ipv4 and ipv6. default: +%d:%u-%u\n"
|
||||||
|
" --orig-autottl6=[<delta>[:<min>[-<max>]]]\t; overrides --orig-autottl for ipv6 only\n"
|
||||||
" --orig-mod-start=[n|d|s]N\t\t\t; apply orig TTL mod to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N\n"
|
" --orig-mod-start=[n|d|s]N\t\t\t; apply orig TTL mod to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N\n"
|
||||||
" --orig-mod-cutoff=[n|d|s]N\t\t\t; apply orig TTL mod to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n"
|
" --orig-mod-cutoff=[n|d|s]N\t\t\t; apply orig TTL mod to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n"
|
||||||
" --dup=<int>\t\t\t\t\t; duplicate original packets. send N dups before original.\n"
|
" --dup=<int>\t\t\t\t\t; duplicate original packets. send N dups before original.\n"
|
||||||
" --dup-replace=[0|1]\t\t\t\t; 1 or no argument means do not send original, only dups\n"
|
" --dup-replace=[0|1]\t\t\t\t; 1 or no argument means do not send original, only dups\n"
|
||||||
" --dup-ttl=<int>\t\t\t\t; set TTL for dups\n"
|
" --dup-ttl=<int>\t\t\t\t; set TTL for dups\n"
|
||||||
" --dup-ttl6=<int>\t\t\t\t; set ipv6 hop limit for dups. by default ttl value is used\n"
|
" --dup-ttl6=<int>\t\t\t\t; set ipv6 hop limit for dups. by default ttl value is used\n"
|
||||||
|
" --dup-autottl=[<delta>[:<min>[-<max>]]]\t; auto ttl mode for both ipv4 and ipv6. default: %d:%u-%u\n"
|
||||||
|
" --dup-autottl6=[<delta>[:<min>[-<max>]]]\t; overrides --dup-autottl for ipv6 only\n"
|
||||||
" --dup-fooling=<mode>[,<mode>]\t\t\t; can use multiple comma separated values. modes : none md5sig badseq badsum datanoack hopbyhop hopbyhop2\n"
|
" --dup-fooling=<mode>[,<mode>]\t\t\t; can use multiple comma separated values. modes : none md5sig badseq badsum datanoack hopbyhop hopbyhop2\n"
|
||||||
" --dup-badseq-increment=<int|0xHEX>\t\t; badseq fooling seq signed increment for dup. default %d\n"
|
" --dup-badseq-increment=<int|0xHEX>\t\t; badseq fooling seq signed increment for dup. default %d\n"
|
||||||
" --dup-badack-increment=<int|0xHEX>\t\t; badseq fooling ackseq signed increment for dup. default %d\n"
|
" --dup-badack-increment=<int|0xHEX>\t\t; badseq fooling ackseq signed increment for dup. default %d\n"
|
||||||
@ -1515,12 +1520,15 @@ static void exithelp(void)
|
|||||||
" --dpi-desync-start=[n|d|s]N\t\t\t; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N\n"
|
" --dpi-desync-start=[n|d|s]N\t\t\t; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) greater or equal than N\n"
|
||||||
" --dpi-desync-cutoff=[n|d|s]N\t\t\t; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n",
|
" --dpi-desync-cutoff=[n|d|s]N\t\t\t; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n",
|
||||||
CTRACK_T_SYN, CTRACK_T_EST, CTRACK_T_FIN, CTRACK_T_UDP,
|
CTRACK_T_SYN, CTRACK_T_EST, CTRACK_T_FIN, CTRACK_T_UDP,
|
||||||
|
AUTOTTL_CACHE_LIFETIME,
|
||||||
HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT, HOSTLIST_AUTO_FAIL_TIME_DEFAULT, HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT,
|
HOSTLIST_AUTO_FAIL_THRESHOLD_DEFAULT, HOSTLIST_AUTO_FAIL_TIME_DEFAULT, HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT,
|
||||||
|
AUTOTTL_DEFAULT_ORIG_DELTA,AUTOTTL_DEFAULT_ORIG_MIN,AUTOTTL_DEFAULT_ORIG_MAX,
|
||||||
|
AUTOTTL_DEFAULT_DUP_DELTA,AUTOTTL_DEFAULT_DUP_MIN,AUTOTTL_DEFAULT_DUP_MAX,
|
||||||
BADSEQ_INCREMENT_DEFAULT, BADSEQ_ACK_INCREMENT_DEFAULT,
|
BADSEQ_INCREMENT_DEFAULT, BADSEQ_ACK_INCREMENT_DEFAULT,
|
||||||
#if defined(__linux__) || defined(SO_USER_COOKIE)
|
#if defined(__linux__) || defined(SO_USER_COOKIE)
|
||||||
DPI_DESYNC_FWMARK_DEFAULT,DPI_DESYNC_FWMARK_DEFAULT,
|
DPI_DESYNC_FWMARK_DEFAULT,DPI_DESYNC_FWMARK_DEFAULT,
|
||||||
#endif
|
#endif
|
||||||
AUTOTTL_DEFAULT_DELTA,AUTOTTL_DEFAULT_MIN,AUTOTTL_DEFAULT_MAX,
|
AUTOTTL_DEFAULT_DESYNC_DELTA,AUTOTTL_DEFAULT_DESYNC_MIN,AUTOTTL_DEFAULT_DESYNC_MAX,
|
||||||
DPI_DESYNC_MAX_FAKE_LEN, IPFRAG_UDP_DEFAULT,
|
DPI_DESYNC_MAX_FAKE_LEN, IPFRAG_UDP_DEFAULT,
|
||||||
DPI_DESYNC_MAX_FAKE_LEN, IPFRAG_TCP_DEFAULT,
|
DPI_DESYNC_MAX_FAKE_LEN, IPFRAG_TCP_DEFAULT,
|
||||||
BADSEQ_INCREMENT_DEFAULT, BADSEQ_ACK_INCREMENT_DEFAULT,
|
BADSEQ_INCREMENT_DEFAULT, BADSEQ_ACK_INCREMENT_DEFAULT,
|
||||||
@ -1610,6 +1618,7 @@ enum opt_indices {
|
|||||||
IDX_WSSIZE,
|
IDX_WSSIZE,
|
||||||
IDX_WSSIZE_CUTOFF,
|
IDX_WSSIZE_CUTOFF,
|
||||||
IDX_CTRACK_TIMEOUTS,
|
IDX_CTRACK_TIMEOUTS,
|
||||||
|
IDX_AUTOTTL_CACHE_LIFETIME,
|
||||||
IDX_HOSTCASE,
|
IDX_HOSTCASE,
|
||||||
IDX_HOSTSPELL,
|
IDX_HOSTSPELL,
|
||||||
IDX_HOSTNOSPACE,
|
IDX_HOSTNOSPACE,
|
||||||
@ -1624,6 +1633,8 @@ enum opt_indices {
|
|||||||
IDX_DUP,
|
IDX_DUP,
|
||||||
IDX_DUP_TTL,
|
IDX_DUP_TTL,
|
||||||
IDX_DUP_TTL6,
|
IDX_DUP_TTL6,
|
||||||
|
IDX_DUP_AUTOTTL,
|
||||||
|
IDX_DUP_AUTOTTL6,
|
||||||
IDX_DUP_FOOLING,
|
IDX_DUP_FOOLING,
|
||||||
IDX_DUP_BADSEQ_INCREMENT,
|
IDX_DUP_BADSEQ_INCREMENT,
|
||||||
IDX_DUP_BADACK_INCREMENT,
|
IDX_DUP_BADACK_INCREMENT,
|
||||||
@ -1632,6 +1643,8 @@ enum opt_indices {
|
|||||||
IDX_DUP_CUTOFF,
|
IDX_DUP_CUTOFF,
|
||||||
IDX_ORIG_TTL,
|
IDX_ORIG_TTL,
|
||||||
IDX_ORIG_TTL6,
|
IDX_ORIG_TTL6,
|
||||||
|
IDX_ORIG_AUTOTTL,
|
||||||
|
IDX_ORIG_AUTOTTL6,
|
||||||
IDX_ORIG_MOD_START,
|
IDX_ORIG_MOD_START,
|
||||||
IDX_ORIG_MOD_CUTOFF,
|
IDX_ORIG_MOD_CUTOFF,
|
||||||
IDX_DPI_DESYNC_TTL,
|
IDX_DPI_DESYNC_TTL,
|
||||||
@ -1723,6 +1736,7 @@ static const struct option long_options[] = {
|
|||||||
[IDX_WSSIZE] = {"wssize", required_argument, 0, 0},
|
[IDX_WSSIZE] = {"wssize", required_argument, 0, 0},
|
||||||
[IDX_WSSIZE_CUTOFF] = {"wssize-cutoff", required_argument, 0, 0},
|
[IDX_WSSIZE_CUTOFF] = {"wssize-cutoff", required_argument, 0, 0},
|
||||||
[IDX_CTRACK_TIMEOUTS] = {"ctrack-timeouts", required_argument, 0, 0},
|
[IDX_CTRACK_TIMEOUTS] = {"ctrack-timeouts", required_argument, 0, 0},
|
||||||
|
[IDX_AUTOTTL_CACHE_LIFETIME] = {"autottl-cache-lifetime", required_argument, 0, 0},
|
||||||
[IDX_HOSTCASE] = {"hostcase", no_argument, 0, 0},
|
[IDX_HOSTCASE] = {"hostcase", no_argument, 0, 0},
|
||||||
[IDX_HOSTSPELL] = {"hostspell", required_argument, 0, 0},
|
[IDX_HOSTSPELL] = {"hostspell", required_argument, 0, 0},
|
||||||
[IDX_HOSTNOSPACE] = {"hostnospace", no_argument, 0, 0},
|
[IDX_HOSTNOSPACE] = {"hostnospace", no_argument, 0, 0},
|
||||||
@ -1737,6 +1751,8 @@ static const struct option long_options[] = {
|
|||||||
[IDX_DUP] = {"dup", required_argument, 0, 0},
|
[IDX_DUP] = {"dup", required_argument, 0, 0},
|
||||||
[IDX_DUP_TTL] = {"dup-ttl", required_argument, 0, 0},
|
[IDX_DUP_TTL] = {"dup-ttl", required_argument, 0, 0},
|
||||||
[IDX_DUP_TTL6] = {"dup-ttl6", required_argument, 0, 0},
|
[IDX_DUP_TTL6] = {"dup-ttl6", required_argument, 0, 0},
|
||||||
|
[IDX_DUP_AUTOTTL] = {"dup-autottl", optional_argument, 0, 0},
|
||||||
|
[IDX_DUP_AUTOTTL6] = {"dup-autottl6", optional_argument, 0, 0},
|
||||||
[IDX_DUP_FOOLING] = {"dup-fooling", required_argument, 0, 0},
|
[IDX_DUP_FOOLING] = {"dup-fooling", required_argument, 0, 0},
|
||||||
[IDX_DUP_BADSEQ_INCREMENT] = {"dup-badseq-increment", required_argument, 0, 0},
|
[IDX_DUP_BADSEQ_INCREMENT] = {"dup-badseq-increment", required_argument, 0, 0},
|
||||||
[IDX_DUP_BADACK_INCREMENT] = {"dup-badack-increment", required_argument, 0, 0},
|
[IDX_DUP_BADACK_INCREMENT] = {"dup-badack-increment", required_argument, 0, 0},
|
||||||
@ -1745,6 +1761,8 @@ static const struct option long_options[] = {
|
|||||||
[IDX_DUP_CUTOFF] = {"dup-cutoff", required_argument, 0, 0},
|
[IDX_DUP_CUTOFF] = {"dup-cutoff", required_argument, 0, 0},
|
||||||
[IDX_ORIG_TTL] = {"orig-ttl", required_argument, 0, 0},
|
[IDX_ORIG_TTL] = {"orig-ttl", required_argument, 0, 0},
|
||||||
[IDX_ORIG_TTL6] = {"orig-ttl6", required_argument, 0, 0},
|
[IDX_ORIG_TTL6] = {"orig-ttl6", required_argument, 0, 0},
|
||||||
|
[IDX_ORIG_AUTOTTL] = {"orig-autottl", optional_argument, 0, 0},
|
||||||
|
[IDX_ORIG_AUTOTTL6] = {"orig-autottl6", optional_argument, 0, 0},
|
||||||
[IDX_ORIG_MOD_START] = {"orig-mod-start", required_argument, 0, 0},
|
[IDX_ORIG_MOD_START] = {"orig-mod-start", required_argument, 0, 0},
|
||||||
[IDX_ORIG_MOD_CUTOFF] = {"orig-mod-cutoff", required_argument, 0, 0},
|
[IDX_ORIG_MOD_CUTOFF] = {"orig-mod-cutoff", required_argument, 0, 0},
|
||||||
[IDX_DPI_DESYNC_TTL] = {"dpi-desync-ttl", required_argument, 0, 0},
|
[IDX_DPI_DESYNC_TTL] = {"dpi-desync-ttl", required_argument, 0, 0},
|
||||||
@ -1872,7 +1890,8 @@ int main(int argc, char **argv)
|
|||||||
params.ctrack_t_est = CTRACK_T_EST;
|
params.ctrack_t_est = CTRACK_T_EST;
|
||||||
params.ctrack_t_fin = CTRACK_T_FIN;
|
params.ctrack_t_fin = CTRACK_T_FIN;
|
||||||
params.ctrack_t_udp = CTRACK_T_UDP;
|
params.ctrack_t_udp = CTRACK_T_UDP;
|
||||||
|
params.autottl_cache_lifetime = AUTOTTL_CACHE_LIFETIME;
|
||||||
|
|
||||||
LIST_INIT(¶ms.hostlists);
|
LIST_INIT(¶ms.hostlists);
|
||||||
LIST_INIT(¶ms.ipsets);
|
LIST_INIT(¶ms.ipsets);
|
||||||
|
|
||||||
@ -2025,6 +2044,13 @@ int main(int argc, char **argv)
|
|||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case IDX_AUTOTTL_CACHE_LIFETIME:
|
||||||
|
if (sscanf(optarg, "%u", ¶ms.autottl_cache_lifetime)!=1)
|
||||||
|
{
|
||||||
|
DLOG_ERR("invalid autottl-cache-lifetime value\n");
|
||||||
|
exit_clean(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case IDX_HOSTCASE:
|
case IDX_HOSTCASE:
|
||||||
dp->hostcase = true;
|
dp->hostcase = true;
|
||||||
break;
|
break;
|
||||||
@ -2130,6 +2156,22 @@ int main(int argc, char **argv)
|
|||||||
case IDX_DUP_TTL6:
|
case IDX_DUP_TTL6:
|
||||||
dp->dup_ttl6 = (uint8_t)atoi(optarg);
|
dp->dup_ttl6 = (uint8_t)atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
case IDX_DUP_AUTOTTL:
|
||||||
|
if (!parse_autottl(optarg, &dp->dup_autottl, AUTOTTL_DEFAULT_DUP_DELTA, AUTOTTL_DEFAULT_DUP_MIN, AUTOTTL_DEFAULT_DUP_MAX))
|
||||||
|
{
|
||||||
|
DLOG_ERR("dup-autottl value error\n");
|
||||||
|
exit_clean(1);
|
||||||
|
}
|
||||||
|
params.autottl_present=true;
|
||||||
|
break;
|
||||||
|
case IDX_DUP_AUTOTTL6:
|
||||||
|
if (!parse_autottl(optarg, &dp->dup_autottl6, AUTOTTL_DEFAULT_DUP_DELTA, AUTOTTL_DEFAULT_DUP_MIN, AUTOTTL_DEFAULT_DUP_MAX))
|
||||||
|
{
|
||||||
|
DLOG_ERR("dup-autottl6 value error\n");
|
||||||
|
exit_clean(1);
|
||||||
|
}
|
||||||
|
params.autottl_present=true;
|
||||||
|
break;
|
||||||
case IDX_DUP_REPLACE:
|
case IDX_DUP_REPLACE:
|
||||||
dp->dup_replace = optarg ? !!atoi(optarg) : true;
|
dp->dup_replace = optarg ? !!atoi(optarg) : true;
|
||||||
break;
|
break;
|
||||||
@ -2175,6 +2217,22 @@ int main(int argc, char **argv)
|
|||||||
case IDX_ORIG_TTL6:
|
case IDX_ORIG_TTL6:
|
||||||
dp->orig_mod_ttl6 = (uint8_t)atoi(optarg);
|
dp->orig_mod_ttl6 = (uint8_t)atoi(optarg);
|
||||||
break;
|
break;
|
||||||
|
case IDX_ORIG_AUTOTTL:
|
||||||
|
if (!parse_autottl(optarg, &dp->orig_autottl, AUTOTTL_DEFAULT_ORIG_DELTA, AUTOTTL_DEFAULT_ORIG_MIN, AUTOTTL_DEFAULT_ORIG_MAX))
|
||||||
|
{
|
||||||
|
DLOG_ERR("orig-autottl value error\n");
|
||||||
|
exit_clean(1);
|
||||||
|
}
|
||||||
|
params.autottl_present=true;
|
||||||
|
break;
|
||||||
|
case IDX_ORIG_AUTOTTL6:
|
||||||
|
if (!parse_autottl(optarg, &dp->orig_autottl6, AUTOTTL_DEFAULT_ORIG_DELTA, AUTOTTL_DEFAULT_ORIG_MIN, AUTOTTL_DEFAULT_ORIG_MAX))
|
||||||
|
{
|
||||||
|
DLOG_ERR("orig-autottl6 value error\n");
|
||||||
|
exit_clean(1);
|
||||||
|
}
|
||||||
|
params.autottl_present=true;
|
||||||
|
break;
|
||||||
case IDX_ORIG_MOD_CUTOFF:
|
case IDX_ORIG_MOD_CUTOFF:
|
||||||
if (!parse_cutoff(optarg, &dp->orig_mod_cutoff, &dp->orig_mod_cutoff_mode))
|
if (!parse_cutoff(optarg, &dp->orig_mod_cutoff, &dp->orig_mod_cutoff_mode))
|
||||||
{
|
{
|
||||||
@ -2197,18 +2255,20 @@ int main(int argc, char **argv)
|
|||||||
dp->desync_ttl6 = (uint8_t)atoi(optarg);
|
dp->desync_ttl6 = (uint8_t)atoi(optarg);
|
||||||
break;
|
break;
|
||||||
case IDX_DPI_DESYNC_AUTOTTL:
|
case IDX_DPI_DESYNC_AUTOTTL:
|
||||||
if (!parse_autottl(optarg, &dp->desync_autottl))
|
if (!parse_autottl(optarg, &dp->desync_autottl, AUTOTTL_DEFAULT_DESYNC_DELTA, AUTOTTL_DEFAULT_DESYNC_MIN, AUTOTTL_DEFAULT_DESYNC_MAX))
|
||||||
{
|
{
|
||||||
DLOG_ERR("dpi-desync-autottl value error\n");
|
DLOG_ERR("dpi-desync-autottl value error\n");
|
||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
|
params.autottl_present=true;
|
||||||
break;
|
break;
|
||||||
case IDX_DPI_DESYNC_AUTOTTL6:
|
case IDX_DPI_DESYNC_AUTOTTL6:
|
||||||
if (!parse_autottl(optarg, &dp->desync_autottl6))
|
if (!parse_autottl(optarg, &dp->desync_autottl6, AUTOTTL_DEFAULT_DESYNC_DELTA, AUTOTTL_DEFAULT_DESYNC_MIN, AUTOTTL_DEFAULT_DESYNC_MAX))
|
||||||
{
|
{
|
||||||
DLOG_ERR("dpi-desync-autottl6 value error\n");
|
DLOG_ERR("dpi-desync-autottl6 value error\n");
|
||||||
exit_clean(1);
|
exit_clean(1);
|
||||||
}
|
}
|
||||||
|
params.autottl_present=true;
|
||||||
break;
|
break;
|
||||||
case IDX_DPI_DESYNC_FOOLING:
|
case IDX_DPI_DESYNC_FOOLING:
|
||||||
if (!parse_fooling(optarg,&dp->desync_fooling_mode))
|
if (!parse_fooling(optarg,&dp->desync_fooling_mode))
|
||||||
@ -2789,10 +2849,20 @@ int main(int argc, char **argv)
|
|||||||
if (dp->dup_ttl6 == 0xFF) dp->dup_ttl6=dp->dup_ttl;
|
if (dp->dup_ttl6 == 0xFF) dp->dup_ttl6=dp->dup_ttl;
|
||||||
if (dp->orig_mod_ttl6 == 0xFF) dp->orig_mod_ttl6=dp->orig_mod_ttl;
|
if (dp->orig_mod_ttl6 == 0xFF) dp->orig_mod_ttl6=dp->orig_mod_ttl;
|
||||||
if (!AUTOTTL_ENABLED(dp->desync_autottl6)) dp->desync_autottl6 = dp->desync_autottl;
|
if (!AUTOTTL_ENABLED(dp->desync_autottl6)) dp->desync_autottl6 = dp->desync_autottl;
|
||||||
|
if (!AUTOTTL_ENABLED(dp->orig_autottl6)) dp->orig_autottl6 = dp->orig_autottl;
|
||||||
|
if (!AUTOTTL_ENABLED(dp->dup_autottl6)) dp->dup_autottl6 = dp->dup_autottl;
|
||||||
if (AUTOTTL_ENABLED(dp->desync_autottl))
|
if (AUTOTTL_ENABLED(dp->desync_autottl))
|
||||||
DLOG("profile %d autottl ipv4 %d:%u-%u\n",dp->n,dp->desync_autottl.delta,dp->desync_autottl.min,dp->desync_autottl.max);
|
DLOG("profile %d desync autottl ipv4 %s%d:%u-%u\n",dp->n,UNARY_PLUS(dp->desync_autottl.delta),dp->desync_autottl.delta,dp->desync_autottl.min,dp->desync_autottl.max);
|
||||||
if (AUTOTTL_ENABLED(dp->desync_autottl6))
|
if (AUTOTTL_ENABLED(dp->desync_autottl6))
|
||||||
DLOG("profile %d autottl ipv6 %d:%u-%u\n",dp->n,dp->desync_autottl6.delta,dp->desync_autottl6.min,dp->desync_autottl6.max);
|
DLOG("profile %d desync autottl ipv6 %s%d:%u-%u\n",dp->n,UNARY_PLUS(dp->desync_autottl6.delta),dp->desync_autottl6.delta,dp->desync_autottl6.min,dp->desync_autottl6.max);
|
||||||
|
if (AUTOTTL_ENABLED(dp->orig_autottl))
|
||||||
|
DLOG("profile %d orig autottl ipv4 %s%d:%u-%u\n",dp->n,UNARY_PLUS(dp->orig_autottl.delta),dp->orig_autottl.delta,dp->orig_autottl.min,dp->orig_autottl.max);
|
||||||
|
if (AUTOTTL_ENABLED(dp->orig_autottl6))
|
||||||
|
DLOG("profile %d orig autottl ipv6 %s%d:%u-%u\n",dp->n,UNARY_PLUS(dp->orig_autottl6.delta),dp->orig_autottl6.delta,dp->orig_autottl6.min,dp->orig_autottl6.max);
|
||||||
|
if (AUTOTTL_ENABLED(dp->dup_autottl))
|
||||||
|
DLOG("profile %d dup autottl ipv4 %s%d:%u-%u\n",dp->n,UNARY_PLUS(dp->dup_autottl.delta),dp->dup_autottl.delta,dp->dup_autottl.min,dp->dup_autottl.max);
|
||||||
|
if (AUTOTTL_ENABLED(dp->dup_autottl6))
|
||||||
|
DLOG("profile %d dup autottl ipv6 %s%d:%u-%u\n",dp->n,UNARY_PLUS(dp->dup_autottl6.delta),dp->dup_autottl6.delta,dp->dup_autottl6.min,dp->dup_autottl6.max);
|
||||||
split_compat(dp);
|
split_compat(dp);
|
||||||
if (!dp_fake_defaults(dp))
|
if (!dp_fake_defaults(dp))
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "packet_queue.h"
|
#include "packet_queue.h"
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ void rawpacket_queue_destroy(struct rawpacket_tailhead *q)
|
|||||||
while((rp = rawpacket_dequeue(q))) rawpacket_free(rp);
|
while((rp = rawpacket_dequeue(q))) rawpacket_free(rp);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sockaddr_storage* dst,uint32_t fwmark,const char *ifout,const void *data,size_t len,size_t len_payload)
|
struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sockaddr_storage* dst,uint32_t fwmark,const char *ifin,const char *ifout,const void *data,size_t len,size_t len_payload)
|
||||||
{
|
{
|
||||||
struct rawpacket *rp = malloc(sizeof(struct rawpacket));
|
struct rawpacket *rp = malloc(sizeof(struct rawpacket));
|
||||||
if (!rp) return NULL;
|
if (!rp) return NULL;
|
||||||
@ -39,13 +40,14 @@ struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sock
|
|||||||
|
|
||||||
rp->dst = *dst;
|
rp->dst = *dst;
|
||||||
rp->fwmark = fwmark;
|
rp->fwmark = fwmark;
|
||||||
if (ifout)
|
if (ifin)
|
||||||
{
|
snprintf(rp->ifin,sizeof(rp->ifin),"%s",ifin);
|
||||||
strncpy(rp->ifout,ifout,sizeof(rp->ifout));
|
|
||||||
rp->ifout[sizeof(rp->ifout)-1]=0;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
rp->ifout[0]=0;
|
*rp->ifin = 0;
|
||||||
|
if (ifout)
|
||||||
|
snprintf(rp->ifout,sizeof(rp->ifout),"%s",ifout);
|
||||||
|
else
|
||||||
|
*rp->ifout = 0;
|
||||||
memcpy(rp->packet,data,len);
|
memcpy(rp->packet,data,len);
|
||||||
rp->len=len;
|
rp->len=len;
|
||||||
rp->len_payload=len_payload;
|
rp->len_payload=len_payload;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
struct rawpacket
|
struct rawpacket
|
||||||
{
|
{
|
||||||
struct sockaddr_storage dst;
|
struct sockaddr_storage dst;
|
||||||
char ifout[IFNAMSIZ+1];
|
char ifin[IFNAMSIZ], ifout[IFNAMSIZ];
|
||||||
uint32_t fwmark;
|
uint32_t fwmark;
|
||||||
size_t len, len_payload;
|
size_t len, len_payload;
|
||||||
uint8_t *packet;
|
uint8_t *packet;
|
||||||
@ -21,6 +21,6 @@ void rawpacket_queue_init(struct rawpacket_tailhead *q);
|
|||||||
void rawpacket_queue_destroy(struct rawpacket_tailhead *q);
|
void rawpacket_queue_destroy(struct rawpacket_tailhead *q);
|
||||||
bool rawpacket_queue_empty(const struct rawpacket_tailhead *q);
|
bool rawpacket_queue_empty(const struct rawpacket_tailhead *q);
|
||||||
unsigned int rawpacket_queue_count(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,const char *ifout,const void *data,size_t len,size_t len_payload);
|
struct rawpacket *rawpacket_queue(struct rawpacket_tailhead *q,const struct sockaddr_storage* dst,uint32_t fwmark,const char *ifin,const char *ifout,const void *data,size_t len,size_t len_payload);
|
||||||
struct rawpacket *rawpacket_dequeue(struct rawpacket_tailhead *q);
|
struct rawpacket *rawpacket_dequeue(struct rawpacket_tailhead *q);
|
||||||
void rawpacket_free(struct rawpacket *rp);
|
void rawpacket_free(struct rawpacket *rp);
|
||||||
|
18
nfq/params.h
18
nfq/params.h
@ -36,6 +36,18 @@
|
|||||||
#define HOSTLIST_AUTO_FAIL_TIME_DEFAULT 60
|
#define HOSTLIST_AUTO_FAIL_TIME_DEFAULT 60
|
||||||
#define HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT 3
|
#define HOSTLIST_AUTO_RETRANS_THRESHOLD_DEFAULT 3
|
||||||
|
|
||||||
|
#define AUTOTTL_CACHE_LIFETIME 86400
|
||||||
|
#define AUTOTTL_DEFAULT_DESYNC_DELTA -1
|
||||||
|
#define AUTOTTL_DEFAULT_DESYNC_MIN 3
|
||||||
|
#define AUTOTTL_DEFAULT_DESYNC_MAX 20
|
||||||
|
#define AUTOTTL_DEFAULT_ORIG_DELTA +5
|
||||||
|
#define AUTOTTL_DEFAULT_ORIG_MIN 3
|
||||||
|
#define AUTOTTL_DEFAULT_ORIG_MAX 64
|
||||||
|
#define AUTOTTL_DEFAULT_DUP_DELTA -1
|
||||||
|
#define AUTOTTL_DEFAULT_DUP_MIN 3
|
||||||
|
#define AUTOTTL_DEFAULT_DUP_MAX 64
|
||||||
|
|
||||||
|
|
||||||
#define MAX_SPLITS 64
|
#define MAX_SPLITS 64
|
||||||
|
|
||||||
#define FAKE_TLS_MOD_SAVE_MASK 0x0F
|
#define FAKE_TLS_MOD_SAVE_MASK 0x0F
|
||||||
@ -89,10 +101,12 @@ struct desync_profile
|
|||||||
uint8_t dup_ttl, dup_ttl6;
|
uint8_t dup_ttl, dup_ttl6;
|
||||||
uint32_t dup_fooling_mode;
|
uint32_t dup_fooling_mode;
|
||||||
uint32_t dup_badseq_increment, dup_badseq_ack_increment;
|
uint32_t dup_badseq_increment, dup_badseq_ack_increment;
|
||||||
|
autottl dup_autottl, dup_autottl6;
|
||||||
|
|
||||||
char orig_mod_start_mode, orig_mod_cutoff_mode; // n - packets, d - data packets, s - relative sequence
|
char orig_mod_start_mode, orig_mod_cutoff_mode; // n - packets, d - data packets, s - relative sequence
|
||||||
unsigned int orig_mod_start, orig_mod_cutoff;
|
unsigned int orig_mod_start, orig_mod_cutoff;
|
||||||
uint8_t orig_mod_ttl, orig_mod_ttl6;
|
uint8_t orig_mod_ttl, orig_mod_ttl6;
|
||||||
|
autottl orig_autottl, orig_autottl6;
|
||||||
|
|
||||||
char desync_start_mode, desync_cutoff_mode; // n - packets, d - data packets, s - relative sequence
|
char desync_start_mode, desync_cutoff_mode; // n - packets, d - data packets, s - relative sequence
|
||||||
unsigned int desync_start, desync_cutoff;
|
unsigned int desync_start, desync_cutoff;
|
||||||
@ -182,6 +196,10 @@ struct params_s
|
|||||||
|
|
||||||
unsigned int ctrack_t_syn, ctrack_t_est, ctrack_t_fin, ctrack_t_udp;
|
unsigned int ctrack_t_syn, ctrack_t_est, ctrack_t_fin, ctrack_t_udp;
|
||||||
t_conntrack conntrack;
|
t_conntrack conntrack;
|
||||||
|
|
||||||
|
unsigned int autottl_cache_lifetime;
|
||||||
|
bool autottl_present;
|
||||||
|
ip_cache ipcache;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct params_s params;
|
extern struct params_s params;
|
||||||
|
207
nfq/pools.c
207
nfq/pools.c
@ -579,3 +579,210 @@ bool blob_collection_empty(const struct blob_collection_head *head)
|
|||||||
{
|
{
|
||||||
return !LIST_FIRST(head);
|
return !LIST_FIRST(head);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void ipcache_item_touch(ip_cache_item *item)
|
||||||
|
{
|
||||||
|
time(&item->last);
|
||||||
|
}
|
||||||
|
static void ipcache_item_init(ip_cache_item *item)
|
||||||
|
{
|
||||||
|
ipcache_item_touch(item);
|
||||||
|
item->hops = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ipcache4Destroy(ip_cache4 **ipcache)
|
||||||
|
{
|
||||||
|
ip_cache4 *elem, *tmp;
|
||||||
|
HASH_ITER(hh, *ipcache, elem, tmp)
|
||||||
|
{
|
||||||
|
HASH_DEL(*ipcache, elem);
|
||||||
|
free(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void ipcache4Key(ip4if *key, const struct in_addr *a, const char *iface)
|
||||||
|
{
|
||||||
|
memset(key,0,sizeof(*key)); // make sure everything is zero
|
||||||
|
key->addr = *a;
|
||||||
|
if (iface) snprintf(key->iface,sizeof(key->iface),"%s",iface);
|
||||||
|
}
|
||||||
|
static ip_cache4 *ipcache4Find(ip_cache4 *ipcache, const struct in_addr *a, const char *iface)
|
||||||
|
{
|
||||||
|
ip_cache4 *entry;
|
||||||
|
struct ip4if key;
|
||||||
|
|
||||||
|
ipcache4Key(&key,a,iface);
|
||||||
|
HASH_FIND(hh, ipcache, &key, sizeof(key), entry);
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
static ip_cache4 *ipcache4Add(ip_cache4 **ipcache, const struct in_addr *a, const char *iface)
|
||||||
|
{
|
||||||
|
// avoid dups
|
||||||
|
ip_cache4 *entry = ipcache4Find(*ipcache,a,iface);
|
||||||
|
if (entry) return entry; // already included
|
||||||
|
|
||||||
|
entry = malloc(sizeof(ip_cache4));
|
||||||
|
if (!entry) return NULL;
|
||||||
|
ipcache4Key(&entry->key,a,iface);
|
||||||
|
|
||||||
|
oom = false;
|
||||||
|
HASH_ADD(hh, *ipcache, key, sizeof(entry->key), entry);
|
||||||
|
if (oom) { free(entry); return NULL; }
|
||||||
|
|
||||||
|
ipcache_item_init(&entry->data);
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
static void ipcache4Print(ip_cache4 *ipcache)
|
||||||
|
{
|
||||||
|
char s_ip[16];
|
||||||
|
time_t now;
|
||||||
|
ip_cache4 *ipc, *tmp;
|
||||||
|
|
||||||
|
time(&now);
|
||||||
|
HASH_ITER(hh, ipcache , ipc, tmp)
|
||||||
|
{
|
||||||
|
*s_ip=0;
|
||||||
|
inet_ntop(AF_INET, &ipc->key.addr, s_ip, sizeof(s_ip));
|
||||||
|
printf("%s iface=%s : hops %u now=last+%llu\n", s_ip, ipc->key.iface, ipc->data.hops, (unsigned long long)(now-ipc->data.last));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ipcache6Destroy(ip_cache6 **ipcache)
|
||||||
|
{
|
||||||
|
ip_cache6 *elem, *tmp;
|
||||||
|
HASH_ITER(hh, *ipcache, elem, tmp)
|
||||||
|
{
|
||||||
|
HASH_DEL(*ipcache, elem);
|
||||||
|
free(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void ipcache6Key(ip6if *key, const struct in6_addr *a, const char *iface)
|
||||||
|
{
|
||||||
|
memset(key,0,sizeof(*key)); // make sure everything is zero
|
||||||
|
key->addr = *a;
|
||||||
|
if (iface) snprintf(key->iface,sizeof(key->iface),"%s",iface);
|
||||||
|
}
|
||||||
|
static ip_cache6 *ipcache6Find(ip_cache6 *ipcache, const struct in6_addr *a, const char *iface)
|
||||||
|
{
|
||||||
|
ip_cache6 *entry;
|
||||||
|
ip6if key;
|
||||||
|
|
||||||
|
ipcache6Key(&key,a,iface);
|
||||||
|
HASH_FIND(hh, ipcache, &key, sizeof(key), entry);
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
static ip_cache6 *ipcache6Add(ip_cache6 **ipcache, const struct in6_addr *a, const char *iface)
|
||||||
|
{
|
||||||
|
// avoid dups
|
||||||
|
ip_cache6 *entry = ipcache6Find(*ipcache,a,iface);
|
||||||
|
if (entry) return entry; // already included
|
||||||
|
|
||||||
|
entry = malloc(sizeof(ip_cache6));
|
||||||
|
if (!entry) return NULL;
|
||||||
|
ipcache6Key(&entry->key,a,iface);
|
||||||
|
|
||||||
|
oom = false;
|
||||||
|
HASH_ADD(hh, *ipcache, key, sizeof(entry->key), entry);
|
||||||
|
if (oom) { free(entry); return NULL; }
|
||||||
|
|
||||||
|
ipcache_item_init(&entry->data);
|
||||||
|
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
static void ipcache6Print(ip_cache6 *ipcache)
|
||||||
|
{
|
||||||
|
char s_ip[40];
|
||||||
|
time_t now;
|
||||||
|
ip_cache6 *ipc, *tmp;
|
||||||
|
|
||||||
|
time(&now);
|
||||||
|
HASH_ITER(hh, ipcache , ipc, tmp)
|
||||||
|
{
|
||||||
|
*s_ip=0;
|
||||||
|
inet_ntop(AF_INET6, &ipc->key.addr, s_ip, sizeof(s_ip));
|
||||||
|
printf("%s iface=%s : hops %u now=last+%llu\n", s_ip, ipc->key.iface, ipc->data.hops, (unsigned long long)(now-ipc->data.last));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipcacheDestroy(ip_cache *ipcache)
|
||||||
|
{
|
||||||
|
ipcache4Destroy(&ipcache->ipcache4);
|
||||||
|
ipcache6Destroy(&ipcache->ipcache6);
|
||||||
|
}
|
||||||
|
void ipcachePrint(ip_cache *ipcache)
|
||||||
|
{
|
||||||
|
ipcache4Print(ipcache->ipcache4);
|
||||||
|
ipcache6Print(ipcache->ipcache6);
|
||||||
|
}
|
||||||
|
|
||||||
|
ip_cache_item *ipcacheTouch(ip_cache *ipcache, const struct in_addr *a4, const struct in6_addr *a6, const char *iface)
|
||||||
|
{
|
||||||
|
ip_cache4 *ipcache4;
|
||||||
|
ip_cache6 *ipcache6;
|
||||||
|
if (a4)
|
||||||
|
{
|
||||||
|
if ((ipcache4 = ipcache4Add(&ipcache->ipcache4,a4,iface)))
|
||||||
|
{
|
||||||
|
ipcache_item_touch(&ipcache4->data);
|
||||||
|
return &ipcache4->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (a6)
|
||||||
|
{
|
||||||
|
if ((ipcache6 = ipcache6Add(&ipcache->ipcache6,a6,iface)))
|
||||||
|
{
|
||||||
|
ipcache_item_touch(&ipcache6->data);
|
||||||
|
return &ipcache6->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ipcache4_purge(ip_cache4 **ipcache, time_t lifetime)
|
||||||
|
{
|
||||||
|
ip_cache4 *elem, *tmp;
|
||||||
|
time_t now = time(NULL);
|
||||||
|
HASH_ITER(hh, *ipcache, elem, tmp)
|
||||||
|
{
|
||||||
|
if (now >= (elem->data.last + lifetime))
|
||||||
|
{
|
||||||
|
HASH_DEL(*ipcache, elem);
|
||||||
|
free(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void ipcache6_purge(ip_cache6 **ipcache, time_t lifetime)
|
||||||
|
{
|
||||||
|
ip_cache6 *elem, *tmp;
|
||||||
|
time_t now = time(NULL);
|
||||||
|
HASH_ITER(hh, *ipcache, elem, tmp)
|
||||||
|
{
|
||||||
|
if (now >= (elem->data.last + lifetime))
|
||||||
|
{
|
||||||
|
HASH_DEL(*ipcache, elem);
|
||||||
|
free(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void ipcache_purge(ip_cache *ipcache, time_t lifetime)
|
||||||
|
{
|
||||||
|
if (lifetime) // 0 = no expire
|
||||||
|
{
|
||||||
|
ipcache4_purge(&ipcache->ipcache4, lifetime);
|
||||||
|
ipcache6_purge(&ipcache->ipcache6, lifetime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static time_t ipcache_purge_prev=0;
|
||||||
|
void ipcachePurgeRateLimited(ip_cache *ipcache, time_t lifetime)
|
||||||
|
{
|
||||||
|
time_t now = time(NULL);
|
||||||
|
// do not purge too often to save resources
|
||||||
|
if (ipcache_purge_prev != now)
|
||||||
|
{
|
||||||
|
ipcache_purge(ipcache, lifetime);
|
||||||
|
ipcache_purge_prev = now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
40
nfq/pools.h
40
nfq/pools.h
@ -3,6 +3,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
|
#include <net/if.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
@ -161,3 +162,42 @@ struct blob_item *blob_collection_add(struct blob_collection_head *head);
|
|||||||
struct blob_item *blob_collection_add_blob(struct blob_collection_head *head, const void *data, size_t size, size_t size_reserve);
|
struct blob_item *blob_collection_add_blob(struct blob_collection_head *head, const void *data, size_t size, size_t size_reserve);
|
||||||
void blob_collection_destroy(struct blob_collection_head *head);
|
void blob_collection_destroy(struct blob_collection_head *head);
|
||||||
bool blob_collection_empty(const struct blob_collection_head *head);
|
bool blob_collection_empty(const struct blob_collection_head *head);
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct ip4if
|
||||||
|
{
|
||||||
|
char iface[IFNAMSIZ];
|
||||||
|
struct in_addr addr;
|
||||||
|
} ip4if;
|
||||||
|
typedef struct ip6if
|
||||||
|
{
|
||||||
|
char iface[IFNAMSIZ];
|
||||||
|
struct in6_addr addr;
|
||||||
|
} ip6if;
|
||||||
|
typedef struct ip_cache_item
|
||||||
|
{
|
||||||
|
time_t last;
|
||||||
|
uint8_t hops;
|
||||||
|
} ip_cache_item;
|
||||||
|
typedef struct ip_cache4
|
||||||
|
{
|
||||||
|
ip4if key;
|
||||||
|
ip_cache_item data;
|
||||||
|
UT_hash_handle hh; /* makes this structure hashable */
|
||||||
|
} ip_cache4;
|
||||||
|
typedef struct ip_cache6
|
||||||
|
{
|
||||||
|
ip6if key;
|
||||||
|
ip_cache_item data;
|
||||||
|
UT_hash_handle hh; /* makes this structure hashable */
|
||||||
|
} ip_cache6;
|
||||||
|
typedef struct ip_cache
|
||||||
|
{
|
||||||
|
ip_cache4 *ipcache4;
|
||||||
|
ip_cache6 *ipcache6;
|
||||||
|
} ip_cache;
|
||||||
|
|
||||||
|
ip_cache_item *ipcacheTouch(ip_cache *ipcache, const struct in_addr *a4, const struct in6_addr *a6, const char *iface);
|
||||||
|
void ipcachePurgeRateLimited(ip_cache *ipcache, time_t lifetime);
|
||||||
|
void ipcacheDestroy(ip_cache *ipcache);
|
||||||
|
void ipcachePrint(ip_cache *ipcache);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user