diff --git a/desync.c b/desync.c index b65176a..4f69f39 100644 --- a/desync.c +++ b/desync.c @@ -457,16 +457,19 @@ ssize_t desync(int sfd, char *buffer, size_t bfsize, } else if (type == IS_HTTPS && dp.tlsrec_n) { long lp = 0; - for (int i = 0; i < dp.tlsrec_n; i++) { - struct part part = dp.tlsrec[i]; - - long pos = i * 5; - pos += gen_offset(part.pos, - part.flag, n - pos, lp, type, host_pos, len); - - if (part.pos < 0 || part.flag) { - pos -= 5; + struct part part; + int i = 0, r = 0, rc = 0; + + for (; r > 0 || i < dp.tlsrec_n; rc++, r--) { + if (!r) { + part = dp.tlsrec[i]; + r = part.r; i++; } + long pos = rc * 5; + pos += gen_offset(part.pos, + part.flag, n - pos - 5, lp, type, host_pos - 5, len); + + pos += part.s * (part.r - r); if (pos < lp) { LOG(LOG_E, "tlsrec cancel: %ld < %ld\n", pos, lp); break; @@ -488,20 +491,26 @@ ssize_t desync(int sfd, char *buffer, size_t bfsize, } #endif long lp = offset; + struct part part; + int i = 0, r = 0; - for (int i = 0; i < dp.parts_n; i++) { - struct part part = dp.parts[i]; - - long pos = gen_offset(part.pos, + for (; r > 0 || i < dp.parts_n; r--) { + if (!r) { + part = dp.parts[i]; + r = part.r; i++; + } + long pos = gen_offset(part.pos, part.flag, n, lp, type, host_pos, len); + pos += part.s * (part.r - r); + // after EAGAIN if (offset && pos <= offset) { continue; } else if (pos < 0 || pos > n || pos < lp) { LOG(LOG_E, "split cancel: pos=%ld-%ld, n=%zd\n", lp, pos, n); - continue; + break; } // send part ssize_t s = 0; diff --git a/main.c b/main.c index 00b74b7..ace467b 100644 --- a/main.c +++ b/main.c @@ -86,14 +86,14 @@ const char help_text[] = { " -K, --proto Protocol whitelist: tls,http,udp\n" " -H, --hosts Hosts whitelist, filename or :string\n" " -V, --pf Ports range whitelist\n" - " -s, --split Split packet at n\n" - " +s - add SNI offset\n" - " +h - add HTTP Host offset\n" - " -d, --disorder Split and send reverse order\n" - " -o, --oob Split and send as OOB data\n" - " -q, --disoob Split and send reverse order as OOB data\n" + " -s, --split Position format: offset[:repeats:skip][+flag1[flag2]]\n" + " Flags: +s - SNI offset, +h - HTTP host offset\n" + " Additional flags: +e - end, +m - middle, +r - random\n" + " -d, --disorder Split and send reverse order\n" + " -o, --oob Split and send as OOB data\n" + " -q, --disoob Split and send reverse order as OOB data\n" #ifdef FAKE_SUPPORT - " -f, --fake Split and send fake packet\n" + " -f, --fake Split and send fake packet\n" " -t, --ttl TTL of fake packets, default 8\n" #ifdef __linux__ " -k, --ip-opt[=f|:str] IP options of fake packets\n" @@ -105,7 +105,7 @@ const char help_text[] = { #endif " -e, --oob-data Set custom OOB data\n" " -M, --mod-http Modify HTTP: hcsmix,dcsmix,rmspace\n" - " -r, --tlsrec Make TLS record at position\n" + " -r, --tlsrec Make TLS record at position\n" " -a, --udp-fake UDP fakes count, default 0\n" #ifdef __linux__ " -Y, --drop-sack Drop packets with SACK extension\n" @@ -376,6 +376,22 @@ int parse_offset(struct part *part, const char *str) { char *end = 0; long val = strtol(str, &end, 0); + + while (*end == ':') { + long rs = strtol(end + 1, &end, 0); + if (rs < 0 || rs > INT_MAX) { + return -1; + } + if (!part->r) { + if (!rs) + return -1; + part->r = rs; + } + else { + part->s = rs; + break; + } + } if (*end == '+') { switch (*(end + 1)) { case 's': diff --git a/params.h b/params.h index 7f93c0a..c715496 100644 --- a/params.h +++ b/params.h @@ -55,6 +55,7 @@ struct part { int m; int flag; long pos; + int r, s; }; struct packet {