diff --git a/nfq/desync.c b/nfq/desync.c index efb9b22..a46071d 100644 --- a/nfq/desync.c +++ b/nfq/desync.c @@ -840,7 +840,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint uint8_t *p, *phost=NULL; const uint8_t *rdata_payload = dis->data_payload; size_t rlen_payload = dis->len_payload; - size_t split_pos; + size_t split_pos, seqovl_pos; size_t multisplit_pos[MAX_SPLITS]; int multisplit_count; int i; @@ -1165,6 +1165,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint DLOG("all multisplit pos are outside of this packet\n"); } } + seqovl_pos = ResolvePos(rdata_payload, rlen_payload, l7proto, &dp->seqovl); } else if (dp->desync_mode==DESYNC_FAKEDSPLIT || dp->desync_mode==DESYNC_FAKEDDISORDER || dp->desync_mode2==DESYNC_FAKEDSPLIT || dp->desync_mode2==DESYNC_FAKEDDISORDER) { @@ -1186,12 +1187,15 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint DLOG("normalized regular split pos : %zu\n",split_pos); else DLOG("regular split pos is outside of this packet\n"); + seqovl_pos = ResolvePos(rdata_payload, rlen_payload, l7proto, &dp->seqovl); } else { multisplit_count=0; - split_pos = 0; + split_pos = seqovl_pos = 0; } + seqovl_pos = pos_normalize(seqovl_pos,reasm_offset,dis->len_payload); + if (seqovl_pos) DLOG("normalized seqovl pos : %zu\n",seqovl_pos); // we do not need reasm buffer anymore reasm_orig_cancel(ctrack); @@ -1283,7 +1287,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint // do seqovl only to the first packet // otherwise it's prone to race condition on server side // what happens first : server pushes socket buffer to process or another packet with seqovl arrives - seqovl = i==0 ? dp->desync_seqovl : 0; + seqovl = i==0 ? seqovl_pos : 0; #ifdef __linux__ // only linux return error if MTU is exceeded for(;;seqovl=0) @@ -1356,11 +1360,11 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint // real observations revealed that server can receive overlap junk instead of real data if (i==0) { - if (dp->desync_seqovl>=from) + if (seqovl_pos>=from) DLOG("seqovl>=split_pos (%u>=%zu). cancelling seqovl for part %d.\n",seqovl,from,i+2); else { - seqovl = dp->desync_seqovl; + seqovl = seqovl_pos; seg_len = to-from+seqovl; if (seg_len>sizeof(ovlseg)) { @@ -1397,13 +1401,13 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint size_t seg_len; unsigned int seqovl; - if (dp->desync_seqovl>=split_pos) + if (seqovl_pos>=split_pos) { - DLOG("seqovl>=split_pos (%u>=%zu). cancelling seqovl.\n",dp->desync_seqovl,split_pos); + DLOG("seqovl>=split_pos (%u>=%zu). cancelling seqovl.\n",seqovl_pos,split_pos); seqovl = 0; } else - seqovl = dp->desync_seqovl; + seqovl = seqovl_pos; if (split_poslen_payload) { @@ -1484,7 +1488,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint if (!rawsend_rep(dp->desync_repeats,(struct sockaddr *)&dst, desync_fwmark, ifout , fakeseg, fakeseg_len)) return verdict; - unsigned int seqovl = dp->desync_seqovl; + unsigned int seqovl = seqovl_pos; #ifdef __linux__ // only linux return error if MTU is exceeded for(;;seqovl=0) diff --git a/nfq/nfqws.c b/nfq/nfqws.c index 20e4e30..f8b74a4 100644 --- a/nfq/nfqws.c +++ b/nfq/nfqws.c @@ -855,6 +855,7 @@ static void SplitDebug(void) dp = &dpl->dp; for(int x=0;xsplit_count;x++) DLOG("profile %d multisplit %s %d\n",dp->n,posmarker_name(dp->splits[x].marker),dp->splits[x].pos); + if (!PROTO_POS_EMPTY(&dp->seqovl)) DLOG("profile %d seqovl %s %d\n",dp->n,posmarker_name(dp->seqovl.marker),dp->seqovl.pos); } } @@ -1055,7 +1056,7 @@ static void exithelp(void) "\t\t\t\t\t\t; markers: method,host,endhost,sld,endsld,midsld,sniext\n" "\t\t\t\t\t\t; full list is only used by multisplit and multidisorder\n" "\t\t\t\t\t\t; fakedsplit/fakeddisorder use first l7-protocol-compatible parameter if present, first abs value otherwise\n" - " --dpi-desync-split-seqovl=\t\t; use sequence overlap before first sent original split segment\n" + " --dpi-desync-split-seqovl=N|-N|marker+N|marker-N ; use sequence overlap before first sent original split segment\n" " --dpi-desync-split-seqovl-pattern=|0xHEX ; pattern for the fake part of overlap\n" " --dpi-desync-ipfrag-pos-tcp=<8..%u>\t\t; ip frag position starting from the transport header. multiple of 8, default %u.\n" " --dpi-desync-ipfrag-pos-udp=<8..%u>\t\t; ip frag position starting from the transport header. multiple of 8, default %u.\n" @@ -1589,9 +1590,9 @@ int main(int argc, char **argv) dp->split_count++; break; case 26: /* dpi-desync-split-seqovl */ - if (sscanf(optarg,"%u",&dp->desync_seqovl)<1) + if (!parse_split_pos(optarg, &dp->seqovl)) { - DLOG_ERR("dpi-desync-split-seqovl is not valid\n"); + DLOG_ERR("Invalid argument for dpi-desync-split-seqovl\n"); exit_clean(1); } break; diff --git a/nfq/params.h b/nfq/params.h index b6b912b..630d20d 100644 --- a/nfq/params.h +++ b/nfq/params.h @@ -55,11 +55,12 @@ struct desync_profile char hostspell[4]; enum dpi_desync_mode desync_mode0,desync_mode,desync_mode2; bool desync_retrans,desync_skip_nosni,desync_any_proto; - unsigned int desync_repeats,desync_seqovl,desync_ipfrag_pos_tcp,desync_ipfrag_pos_udp; + unsigned int desync_repeats,desync_ipfrag_pos_tcp,desync_ipfrag_pos_udp; // multisplit struct proto_pos splits[MAX_SPLITS]; int split_count; + struct proto_pos seqovl; char desync_start_mode, desync_cutoff_mode; // n - packets, d - data packets, s - relative sequence unsigned int desync_start, desync_cutoff;