mirror of
https://github.com/bol-van/zapret.git
synced 2025-05-24 22:32:58 +03:00
nfqws: dpi-desync-repeats
This commit is contained in:
30
nfq/desync.c
30
nfq/desync.c
@@ -57,6 +57,16 @@ void desync_init()
|
||||
}
|
||||
|
||||
|
||||
// auto creates internal socket and uses it for subsequent calls
|
||||
static bool rawsend_rep(struct sockaddr* dst,uint32_t fwmark,const void *data,size_t len)
|
||||
{
|
||||
for (int i=0;i<params.desync_repeats;i++)
|
||||
if (!rawsend(dst,fwmark,data,len))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// result : true - drop original packet, false = dont drop
|
||||
packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struct iphdr *iphdr, struct ip6_hdr *ip6hdr, struct tcphdr *tcphdr, size_t len_tcp, uint8_t *data_payload, size_t len_payload)
|
||||
{
|
||||
@@ -182,7 +192,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(tcphdr->seq,split_pos), tcphdr->ack_seq, tcphdr->window, timestamps,
|
||||
ttl_orig,TCP_FOOL_NONE,
|
||||
data_payload+split_pos, len_payload-split_pos, newdata, &newlen) ||
|
||||
!rawsend((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@@ -196,7 +206,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->seq, tcphdr->ack_seq, tcphdr->window, timestamps,
|
||||
ttl_fake,params.desync_tcp_fooling_mode,
|
||||
zeropkt, split_pos, fakeseg, &fakeseg_len) ||
|
||||
!rawsend((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len))
|
||||
!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@@ -208,7 +218,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->seq, tcphdr->ack_seq, tcphdr->window, timestamps,
|
||||
ttl_orig,TCP_FOOL_NONE,
|
||||
data_payload, split_pos, newdata, &newlen) ||
|
||||
!rawsend((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@@ -216,7 +226,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (params.desync_mode==DESYNC_DISORDER)
|
||||
{
|
||||
DLOG("sending fake(2) 1st out-of-order tcp segment 0-%zu len=%zu\n",split_pos-1, split_pos)
|
||||
if (!rawsend((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len))
|
||||
if (!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len))
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -237,7 +247,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->seq, tcphdr->ack_seq, tcphdr->window, timestamps,
|
||||
ttl_fake,params.desync_tcp_fooling_mode,
|
||||
zeropkt, split_pos, fakeseg, &fakeseg_len) ||
|
||||
!rawsend((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len))
|
||||
!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@@ -248,7 +258,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->seq, tcphdr->ack_seq, tcphdr->window, timestamps,
|
||||
ttl_orig,TCP_FOOL_NONE,
|
||||
data_payload, split_pos, newdata, &newlen) ||
|
||||
!rawsend((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@@ -256,7 +266,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (params.desync_mode==DESYNC_SPLIT)
|
||||
{
|
||||
DLOG("sending fake(2) 1st tcp segment 0-%zu len=%zu\n",split_pos-1, split_pos)
|
||||
if (!rawsend((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len))
|
||||
if (!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len))
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -267,7 +277,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(tcphdr->seq,split_pos), tcphdr->ack_seq, tcphdr->window, timestamps,
|
||||
ttl_orig,TCP_FOOL_NONE,
|
||||
data_payload+split_pos, len_payload-split_pos, newdata, &newlen) ||
|
||||
!rawsend((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@@ -299,7 +309,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
return res;
|
||||
}
|
||||
|
||||
if (!rawsend((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
if (!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, newdata, newlen))
|
||||
return res;
|
||||
|
||||
if (params.desync_retrans)
|
||||
@@ -309,7 +319,7 @@ packet_process_result dpi_desync_packet(uint8_t *data_pkt, size_t len_pkt, struc
|
||||
DLOG("reinjecting original packet. len=%zu len_payload=%zu\n", len_pkt, len_payload)
|
||||
// if original packet was tampered earlier it needs checksum fixed
|
||||
if (res==modify) tcp_fix_checksum(tcphdr,len_tcp,iphdr,ip6hdr);
|
||||
if (!rawsend((struct sockaddr *)&dst, params.desync_fwmark, data_pkt, len_pkt))
|
||||
if (!rawsend_rep((struct sockaddr *)&dst, params.desync_fwmark, data_pkt, len_pkt))
|
||||
return res;
|
||||
}
|
||||
return drop;
|
||||
|
27
nfq/nfqws.c
27
nfq/nfqws.c
@@ -257,6 +257,7 @@ static void exithelp()
|
||||
" --dpi-desync-ttl=<int>\t\t\t; set ttl for desync packet\n"
|
||||
" --dpi-desync-fooling=<mode>[,<mode>]\t; can use multiple comma separated values. modes : none md5sig ts badseq badsum\n"
|
||||
" --dpi-desync-retrans=0|1\t\t; 0(default)=reinject original data packet after fake 1=drop original data packet to force its retransmission\n"
|
||||
" --dpi-desync-repeats=<N>\t\t; send every desync packet N times\n"
|
||||
" --dpi-desync-skip-nosni=0|1\t\t; 1(default)=do not act on ClientHello without SNI (ESNI ?)\n"
|
||||
" --dpi-desync-split-pos=<1..%u>\t; (for disorder only) split TCP packet at specified position\n"
|
||||
" --dpi-desync-any-protocol=0|1\t\t; 0(default)=desync only http and tls 1=desync any nonempty data packet\n"
|
||||
@@ -310,6 +311,7 @@ int main(int argc, char **argv)
|
||||
params.desync_fwmark = DPI_DESYNC_FWMARK_DEFAULT;
|
||||
params.desync_skip_nosni = true;
|
||||
params.desync_split_pos = 3;
|
||||
params.desync_repeats = 1;
|
||||
|
||||
const struct option long_options[] = {
|
||||
{"debug",optional_argument,0,0}, // optidx=0
|
||||
@@ -327,10 +329,11 @@ int main(int argc, char **argv)
|
||||
{"dpi-desync-ttl",required_argument,0,0}, // optidx=12
|
||||
{"dpi-desync-fooling",required_argument,0,0}, // optidx=13
|
||||
{"dpi-desync-retrans",optional_argument,0,0}, // optidx=14
|
||||
{"dpi-desync-skip-nosni",optional_argument,0,0},// optidx=15
|
||||
{"dpi-desync-split-pos",required_argument,0,0},// optidx=16
|
||||
{"dpi-desync-any-protocol",optional_argument,0,0},// optidx=17
|
||||
{"hostlist",required_argument,0,0}, // optidx=18
|
||||
{"dpi-desync-repeats",required_argument,0,0}, // optidx=15
|
||||
{"dpi-desync-skip-nosni",optional_argument,0,0},// optidx=16
|
||||
{"dpi-desync-split-pos",required_argument,0,0},// optidx=17
|
||||
{"dpi-desync-any-protocol",optional_argument,0,0},// optidx=18
|
||||
{"hostlist",required_argument,0,0}, // optidx=19
|
||||
{NULL,0,NULL,0}
|
||||
};
|
||||
if (argc < 2) exithelp();
|
||||
@@ -460,10 +463,18 @@ int main(int argc, char **argv)
|
||||
case 14: /* dpi-desync-retrans */
|
||||
params.desync_retrans = !optarg || atoi(optarg);
|
||||
break;
|
||||
case 15: /* dpi-desync-skip-nosni */
|
||||
case 15: /* dpi-desync-repeats */
|
||||
params.desync_repeats = atoi(optarg);
|
||||
if (params.desync_repeats<=0 || params.desync_repeats>20)
|
||||
{
|
||||
fprintf(stderr, "dpi-desync-repeats must be within 1..20\n");
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 16: /* dpi-desync-skip-nosni */
|
||||
params.desync_skip_nosni = !optarg || atoi(optarg);
|
||||
break;
|
||||
case 16: /* dpi-desync-split-pos */
|
||||
case 17: /* dpi-desync-split-pos */
|
||||
params.desync_split_pos = atoi(optarg);
|
||||
if (params.desync_split_pos<1 || params.desync_split_pos>DPI_DESYNC_MAX_FAKE_LEN)
|
||||
{
|
||||
@@ -471,10 +482,10 @@ int main(int argc, char **argv)
|
||||
exit_clean(1);
|
||||
}
|
||||
break;
|
||||
case 17: /* dpi-desync-any-protocol */
|
||||
case 18: /* dpi-desync-any-protocol */
|
||||
params.desync_any_proto = !optarg || atoi(optarg);
|
||||
break;
|
||||
case 18: /* hostlist */
|
||||
case 19: /* hostlist */
|
||||
if (!LoadHostList(¶ms.hostlist, optarg))
|
||||
exit_clean(1);
|
||||
strncpy(params.hostfile,optarg,sizeof(params.hostfile));
|
||||
|
@@ -19,7 +19,7 @@ struct params_s
|
||||
char hostspell[4];
|
||||
enum dpi_desync_mode desync_mode;
|
||||
bool desync_retrans,desync_skip_nosni,desync_any_proto;
|
||||
int desync_split_pos;
|
||||
int desync_repeats,desync_split_pos;
|
||||
uint8_t desync_ttl;
|
||||
uint8_t desync_tcp_fooling_mode;
|
||||
uint32_t desync_fwmark;
|
||||
|
102
nfq/strpool.c
102
nfq/strpool.c
@@ -6,71 +6,71 @@
|
||||
#undef uthash_nonfatal_oom
|
||||
#define uthash_nonfatal_oom(elt) ut_oom_recover(elt)
|
||||
|
||||
static bool oom=false;
|
||||
static bool oom = false;
|
||||
static void ut_oom_recover(strpool *elem)
|
||||
{
|
||||
oom=true;
|
||||
oom = true;
|
||||
}
|
||||
|
||||
// for zero terminated strings
|
||||
bool StrPoolAddStr(strpool **pp,const char *s)
|
||||
bool StrPoolAddStr(strpool **pp, const char *s)
|
||||
{
|
||||
strpool *elem;
|
||||
if (!(elem = (strpool*)malloc(sizeof(strpool))))
|
||||
return false;
|
||||
if (!(elem->str = strdup(s)))
|
||||
{
|
||||
free(elem);
|
||||
return false;
|
||||
}
|
||||
oom = false;
|
||||
HASH_ADD_KEYPTR( hh, *pp, elem->str, strlen(elem->str), elem );
|
||||
if (oom)
|
||||
{
|
||||
free(elem->str);
|
||||
free(elem);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
strpool *elem;
|
||||
if (!(elem = (strpool*)malloc(sizeof(strpool))))
|
||||
return false;
|
||||
if (!(elem->str = strdup(s)))
|
||||
{
|
||||
free(elem);
|
||||
return false;
|
||||
}
|
||||
oom = false;
|
||||
HASH_ADD_KEYPTR(hh, *pp, elem->str, strlen(elem->str), elem);
|
||||
if (oom)
|
||||
{
|
||||
free(elem->str);
|
||||
free(elem);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// for not zero terminated strings
|
||||
bool StrPoolAddStrLen(strpool **pp,const char *s,size_t slen)
|
||||
bool StrPoolAddStrLen(strpool **pp, const char *s, size_t slen)
|
||||
{
|
||||
strpool *elem;
|
||||
if (!(elem = (strpool*)malloc(sizeof(strpool))))
|
||||
return false;
|
||||
if (!(elem->str = malloc(slen+1)))
|
||||
{
|
||||
free(elem);
|
||||
return false;
|
||||
}
|
||||
memcpy(elem->str,s,slen);
|
||||
elem->str[slen]=0;
|
||||
oom = false;
|
||||
HASH_ADD_KEYPTR( hh, *pp, elem->str, strlen(elem->str), elem );
|
||||
if (oom)
|
||||
{
|
||||
free(elem->str);
|
||||
free(elem);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
strpool *elem;
|
||||
if (!(elem = (strpool*)malloc(sizeof(strpool))))
|
||||
return false;
|
||||
if (!(elem->str = malloc(slen + 1)))
|
||||
{
|
||||
free(elem);
|
||||
return false;
|
||||
}
|
||||
memcpy(elem->str, s, slen);
|
||||
elem->str[slen] = 0;
|
||||
oom = false;
|
||||
HASH_ADD_KEYPTR(hh, *pp, elem->str, strlen(elem->str), elem);
|
||||
if (oom)
|
||||
{
|
||||
free(elem->str);
|
||||
free(elem);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StrPoolCheckStr(strpool *p,const char *s)
|
||||
bool StrPoolCheckStr(strpool *p, const char *s)
|
||||
{
|
||||
strpool *elem;
|
||||
HASH_FIND_STR( p, s, elem);
|
||||
return elem!=NULL;
|
||||
strpool *elem;
|
||||
HASH_FIND_STR(p, s, elem);
|
||||
return elem != NULL;
|
||||
}
|
||||
|
||||
void StrPoolDestroy(strpool **p)
|
||||
{
|
||||
strpool *elem,*tmp;
|
||||
HASH_ITER(hh, *p, elem, tmp) {
|
||||
free(elem->str);
|
||||
HASH_DEL(*p, elem);
|
||||
free(elem);
|
||||
}
|
||||
*p = NULL;
|
||||
strpool *elem, *tmp;
|
||||
HASH_ITER(hh, *p, elem, tmp) {
|
||||
free(elem->str);
|
||||
HASH_DEL(*p, elem);
|
||||
free(elem);
|
||||
}
|
||||
*p = NULL;
|
||||
}
|
||||
|
Reference in New Issue
Block a user