Loading docs/changes.txt +5 −1 Original line number Diff line number Diff line Loading @@ -482,7 +482,11 @@ nfqws: multiple mods for multiple TLS fakes init.d: remove 50-discord blockcheck: use tpws --fix-seg on linux for multiple splits v70.7 v71 nfqws,tpws: debug tls version, alpn, ech nfqws: --dpi-desync-fake-tls=! means default tls fake nfqws: --dup* nfqws: --orig* nfqws: autottl cache nfqws: autottl disable path length check nfq/conntrack.h +2 −1 Original line number Diff line number Diff line Loading @@ -77,7 +77,8 @@ typedef struct 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) 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_wssize_cutoff, b_desync_cutoff, b_dup_cutoff, b_orig_mod_cutoff; Loading nfq/darkmagic.c +15 −10 Original line number Diff line number Diff line Loading @@ -1832,17 +1832,15 @@ bool rawsend_queue(struct rawpacket_tailhead *q) } // return guessed fake ttl value. 0 means unsuccessfull, should not perform autottl fooling // ttl = TTL of incoming packet uint8_t autottl_guess(uint8_t ttl, const autottl *attl) uint8_t hop_count_guess(uint8_t ttl) { uint8_t orig, path, fake; int d; // 18.65.168.125 ( cloudfront ) 255 // 157.254.246.178 128 // 1.1.1.1 64 // guess original ttl. consider path lengths less than 32 hops uint8_t orig; if (ttl>223) orig=255; else if (ttl<128 && ttl>96) Loading @@ -1852,15 +1850,22 @@ uint8_t autottl_guess(uint8_t ttl, const autottl *attl) else 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; else if (d>attl->max) fake=attl->max; else fake=(uint8_t)d; if (attl->delta<0 && fake>=path || attl->delta>=0 && fake<path) return 0; // path length check disabled // if (attl->delta<0 && fake>=hop_count || attl->delta>=0 && fake<hop_count) // return 0; return fake; } Loading nfq/darkmagic.h +2 −5 Original line number Diff line number Diff line Loading @@ -261,13 +261,10 @@ typedef struct int8_t delta; uint8_t min, max; } autottl; #define AUTOTTL_DEFAULT_DELTA -1 #define AUTOTTL_DEFAULT_MIN 3 #define AUTOTTL_DEFAULT_MAX 20 #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 verdict_tcp_csum_fix(uint8_t verdict, struct tcphdr *tcphdr, size_t transport_len, struct ip *ip, struct ip6_hdr *ip6hdr); Loading nfq/desync.c +95 −51 Original line number Diff line number Diff line Loading @@ -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; } 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)) { ctrack->autottl = autottl_guess(ctrack->incoming_ttl, attl); if (ctrack->autottl) DLOG("autottl: guessed %u\n",ctrack->autottl); uint8_t autottl = autottl_eval(hop_count, attl); if (autottl) DLOG("%s autottl: guessed %u\n",attl_kind,autottl); else DLOG("autottl: could not guess\n"); DLOG("%s autottl: could not guess\n",attl_kind); return autottl; } 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); } } Loading Loading @@ -838,7 +874,7 @@ uint8_t orig_mod(const struct desync_profile *dp, const t_ctrack *ctrack, struct { 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)) { ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim; Loading Loading @@ -893,14 +929,13 @@ static bool tcp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c bool sack,DF; 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); 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 = dis->ip6 ? dp->dup_ttl6 : dp->dup_ttl; if (!ttl_fake) ttl_fake = ttl_orig; 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)); if (dp->dup_fooling_mode) { Loading @@ -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); nmss = tcp_find_mss(dis->tcp); ip_id = IP4_IP_ID_FIX(dis->ip); DF = ip_has_df(dis->ip); len = sizeof(pkt); if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, sack, nmss, 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, dis->data_payload, dis->len_payload, pkt, &len)) { DLOG_ERR("dup: packet reconstruct failed\n"); 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 for (k=0;k<dp->dup_repeats;k++) Loading @@ -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"); 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)) return false; } Loading @@ -949,7 +983,7 @@ static bool tcp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c } 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)) return false; return true; Loading @@ -968,18 +1002,15 @@ static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c uint16_t ip_id; struct sockaddr_storage src, dst; uint8_t ttl_orig,ttl_fake; bool DF; 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); 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 = dis->ip6 ? dp->dup_ttl6 : dp->dup_ttl; if (!ttl_fake) ttl_fake = ttl_orig; DF = ip_has_df(dis->ip); 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)); if (dp->dup_fooling_mode) { Loading @@ -987,7 +1018,7 @@ static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c len = sizeof(pkt); 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, dis->data_payload, dis->len_payload, pkt, &len)) { Loading @@ -995,7 +1026,7 @@ static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c 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 for (k=0;k<dp->dup_repeats;k++) Loading @@ -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"); 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)) return false; } Loading @@ -1021,7 +1052,7 @@ static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c } 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)) return false; return true; Loading @@ -1030,7 +1061,7 @@ static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c 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; Loading Loading @@ -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; if (!ctrack->incoming_ttl) { DLOG("incoming TTL %u\n",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 Loading Loading @@ -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 } 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 ! verdict = VERDICT_MODIFY; Loading Loading @@ -1207,7 +1240,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint } // !replay 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); scale_factor = tcp_find_scale_factor(dis->tcp); timestamps = tcp_find_timestamps(dis->tcp); Loading Loading @@ -1368,7 +1401,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint if (!ReasmIsEmpty(&ctrack->reasm_orig)) { 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)); } Loading Loading @@ -1455,10 +1488,14 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint if (dp!=dp_prev) { DLOG("desync profile changed by revealed l7 protocol or hostname !\n"); // rediscover autottl autottl_discover(ctrack_replay,!!dis->ip6); autottl_rediscover(ctrack_replay,dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , ifout); // 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); if (orig_mod(dp,ctrack,dis)) // ttl can change ! Loading Loading @@ -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"); } 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 (dp->hostcase) Loading Loading @@ -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; Loading Loading @@ -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); 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 } 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 ! verdict = VERDICT_MODIFY; Loading Loading @@ -2384,7 +2423,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint if (!ReasmIsEmpty(&ctrack->reasm_orig)) { 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)); } Loading Loading @@ -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); 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)); } Loading Loading @@ -2554,10 +2593,14 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint if (dp!=dp_prev) { DLOG("desync profile changed by revealed l7 protocol or hostname !\n"); // rediscover autottl autottl_discover(ctrack_replay,!!dis->ip6); autottl_rediscover(ctrack_replay,dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , ifout); // 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); if (orig_mod(dp,ctrack,dis)) // ttl can change ! Loading Loading @@ -2619,7 +2662,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint 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; Loading Loading @@ -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; uint8_t verdict = VERDICT_PASS; Loading @@ -2846,14 +2889,14 @@ static uint8_t dpi_desync_packet_play(bool replay, size_t reasm_offset, uint32_t case IPPROTO_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); } break; case IPPROTO_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); } break; Loading @@ -2862,9 +2905,10 @@ static uint8_t dpi_desync_packet_play(bool replay, size_t reasm_offset, uint32_t } 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); } Loading @@ -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++) { 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) { case VERDICT_MODIFY: Loading Loading
docs/changes.txt +5 −1 Original line number Diff line number Diff line Loading @@ -482,7 +482,11 @@ nfqws: multiple mods for multiple TLS fakes init.d: remove 50-discord blockcheck: use tpws --fix-seg on linux for multiple splits v70.7 v71 nfqws,tpws: debug tls version, alpn, ech nfqws: --dpi-desync-fake-tls=! means default tls fake nfqws: --dup* nfqws: --orig* nfqws: autottl cache nfqws: autottl disable path length check
nfq/conntrack.h +2 −1 Original line number Diff line number Diff line Loading @@ -77,7 +77,8 @@ typedef struct 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) 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_wssize_cutoff, b_desync_cutoff, b_dup_cutoff, b_orig_mod_cutoff; Loading
nfq/darkmagic.c +15 −10 Original line number Diff line number Diff line Loading @@ -1832,17 +1832,15 @@ bool rawsend_queue(struct rawpacket_tailhead *q) } // return guessed fake ttl value. 0 means unsuccessfull, should not perform autottl fooling // ttl = TTL of incoming packet uint8_t autottl_guess(uint8_t ttl, const autottl *attl) uint8_t hop_count_guess(uint8_t ttl) { uint8_t orig, path, fake; int d; // 18.65.168.125 ( cloudfront ) 255 // 157.254.246.178 128 // 1.1.1.1 64 // guess original ttl. consider path lengths less than 32 hops uint8_t orig; if (ttl>223) orig=255; else if (ttl<128 && ttl>96) Loading @@ -1852,15 +1850,22 @@ uint8_t autottl_guess(uint8_t ttl, const autottl *attl) else 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; else if (d>attl->max) fake=attl->max; else fake=(uint8_t)d; if (attl->delta<0 && fake>=path || attl->delta>=0 && fake<path) return 0; // path length check disabled // if (attl->delta<0 && fake>=hop_count || attl->delta>=0 && fake<hop_count) // return 0; return fake; } Loading
nfq/darkmagic.h +2 −5 Original line number Diff line number Diff line Loading @@ -261,13 +261,10 @@ typedef struct int8_t delta; uint8_t min, max; } autottl; #define AUTOTTL_DEFAULT_DELTA -1 #define AUTOTTL_DEFAULT_MIN 3 #define AUTOTTL_DEFAULT_MAX 20 #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 verdict_tcp_csum_fix(uint8_t verdict, struct tcphdr *tcphdr, size_t transport_len, struct ip *ip, struct ip6_hdr *ip6hdr); Loading
nfq/desync.c +95 −51 Original line number Diff line number Diff line Loading @@ -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; } 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)) { ctrack->autottl = autottl_guess(ctrack->incoming_ttl, attl); if (ctrack->autottl) DLOG("autottl: guessed %u\n",ctrack->autottl); uint8_t autottl = autottl_eval(hop_count, attl); if (autottl) DLOG("%s autottl: guessed %u\n",attl_kind,autottl); else DLOG("autottl: could not guess\n"); DLOG("%s autottl: could not guess\n",attl_kind); return autottl; } 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); } } Loading Loading @@ -838,7 +874,7 @@ uint8_t orig_mod(const struct desync_profile *dp, const t_ctrack *ctrack, struct { 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)) { ttl_orig = dis->ip ? dis->ip->ip_ttl : dis->ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim; Loading Loading @@ -893,14 +929,13 @@ static bool tcp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c bool sack,DF; 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); 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 = dis->ip6 ? dp->dup_ttl6 : dp->dup_ttl; if (!ttl_fake) ttl_fake = ttl_orig; 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)); if (dp->dup_fooling_mode) { Loading @@ -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); nmss = tcp_find_mss(dis->tcp); ip_id = IP4_IP_ID_FIX(dis->ip); DF = ip_has_df(dis->ip); len = sizeof(pkt); if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, sack, nmss, 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, dis->data_payload, dis->len_payload, pkt, &len)) { DLOG_ERR("dup: packet reconstruct failed\n"); 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 for (k=0;k<dp->dup_repeats;k++) Loading @@ -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"); 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)) return false; } Loading @@ -949,7 +983,7 @@ static bool tcp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c } 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)) return false; return true; Loading @@ -968,18 +1002,15 @@ static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c uint16_t ip_id; struct sockaddr_storage src, dst; uint8_t ttl_orig,ttl_fake; bool DF; 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); 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 = dis->ip6 ? dp->dup_ttl6 : dp->dup_ttl; if (!ttl_fake) ttl_fake = ttl_orig; DF = ip_has_df(dis->ip); 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)); if (dp->dup_fooling_mode) { Loading @@ -987,7 +1018,7 @@ static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c len = sizeof(pkt); 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, dis->data_payload, dis->len_payload, pkt, &len)) { Loading @@ -995,7 +1026,7 @@ static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c 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 for (k=0;k<dp->dup_repeats;k++) Loading @@ -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"); 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)) return false; } Loading @@ -1021,7 +1052,7 @@ static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c } 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)) return false; return true; Loading @@ -1030,7 +1061,7 @@ static bool udp_orig_send(uint8_t verdict, uint32_t fwmark, const char *ifout, c 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; Loading Loading @@ -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; if (!ctrack->incoming_ttl) { DLOG("incoming TTL %u\n",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 Loading Loading @@ -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 } 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 ! verdict = VERDICT_MODIFY; Loading Loading @@ -1207,7 +1240,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint } // !replay 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); scale_factor = tcp_find_scale_factor(dis->tcp); timestamps = tcp_find_timestamps(dis->tcp); Loading Loading @@ -1368,7 +1401,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint if (!ReasmIsEmpty(&ctrack->reasm_orig)) { 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)); } Loading Loading @@ -1455,10 +1488,14 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint if (dp!=dp_prev) { DLOG("desync profile changed by revealed l7 protocol or hostname !\n"); // rediscover autottl autottl_discover(ctrack_replay,!!dis->ip6); autottl_rediscover(ctrack_replay,dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , ifout); // 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); if (orig_mod(dp,ctrack,dis)) // ttl can change ! Loading Loading @@ -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"); } 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 (dp->hostcase) Loading Loading @@ -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; Loading Loading @@ -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); 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 } 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 ! verdict = VERDICT_MODIFY; Loading Loading @@ -2384,7 +2423,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint if (!ReasmIsEmpty(&ctrack->reasm_orig)) { 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)); } Loading Loading @@ -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); 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)); } Loading Loading @@ -2554,10 +2593,14 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint if (dp!=dp_prev) { DLOG("desync profile changed by revealed l7 protocol or hostname !\n"); // rediscover autottl autottl_discover(ctrack_replay,!!dis->ip6); autottl_rediscover(ctrack_replay,dis->ip ? &dis->ip->ip_dst : NULL,dis->ip6 ? &dis->ip6->ip6_dst : NULL , ifout); // 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); if (orig_mod(dp,ctrack,dis)) // ttl can change ! Loading Loading @@ -2619,7 +2662,7 @@ static uint8_t dpi_desync_udp_packet_play(bool replay, size_t reasm_offset, uint 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; Loading Loading @@ -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; uint8_t verdict = VERDICT_PASS; Loading @@ -2846,14 +2889,14 @@ static uint8_t dpi_desync_packet_play(bool replay, size_t reasm_offset, uint32_t case IPPROTO_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); } break; case IPPROTO_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); } break; Loading @@ -2862,9 +2905,10 @@ static uint8_t dpi_desync_packet_play(bool replay, size_t reasm_offset, uint32_t } 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); } Loading @@ -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++) { 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) { case VERDICT_MODIFY: Loading