diff --git a/extend.c b/extend.c index 9c34c56..5ce77ad 100644 --- a/extend.c +++ b/extend.c @@ -212,6 +212,12 @@ static bool check_proto_tcp(int proto, char *buffer, ssize_t n) } +static bool check_round(int nr[2], int r) +{ + return (!nr[1] && r <= 1) || (r >= nr[0] && r <= nr[1]); +} + + static int on_trigger(int type, struct poolhd *pool, struct eval *val) { int m = val->pair->attempt + 1; @@ -435,31 +441,35 @@ ssize_t tcp_send_hook(struct eval *remote, char *buffer, size_t bfsize, ssize_t n) { ssize_t sn = -1; + int skip = remote->flag != FLAG_CONN; - if (remote->flag != FLAG_CONN - || remote->pair->round_count > params.repeats) { + if (!skip) { + struct eval *client = remote->pair; + + if (client->recv_count == n + && setup_conn(client, buffer, n) < 0) { + return -1; + } + int m = client->attempt, r = client->round_count; + if (!check_round(params.dp[m].rounds, r)) { + skip = 1; + } + else { + LOG((m ? LOG_S : LOG_L), "desync TCP, m=%d, r=%d\n", m, r); + + ssize_t offset = remote->pair->round_sent; + if (!offset && remote->round_count) offset = -1; + + sn = desync(remote->fd, buffer, bfsize, n, + offset, (struct sockaddr *)&remote->in6, m); + } + } + if (skip) { sn = send(remote->fd, buffer, n, 0); if (sn < 0 && get_e() == EAGAIN) { return 0; } - remote->pair->round_sent += sn; - return sn; } - struct eval *client = remote->pair; - - if (client->recv_count == n - && setup_conn(client, buffer, n) < 0) { - return -1; - } - int m = client->attempt; - LOG((m ? LOG_S : LOG_L), "desync TCP, m=%d\n", m); - - ssize_t offset = client->round_sent; - if (!offset && remote->round_count) offset = -1; - - sn = desync(remote->fd, buffer, bfsize, n, - offset, (struct sockaddr *)&remote->in6, m); - remote->pair->round_sent += sn; return sn; } @@ -497,7 +507,8 @@ ssize_t tcp_recv_hook(struct poolhd *pool, struct eval *val, val->pair->round_sent = 0; } if (val->flag == FLAG_CONN - && val->round_count >= params.repeats + && check_round( + params.dp[val->pair->attempt].rounds, val->round_count) && cancel_setup(val)) { return -1; } @@ -510,10 +521,7 @@ ssize_t udp_hook(struct eval *val, { struct eval *pair = val->pair->pair; - if (pair->round_count > params.repeats) { - return send(val->fd, buffer, n, 0); - } - int m = val->attempt; + int m = pair->attempt, r = pair->round_count; if (!m) { for (; m < params.dp_count; m++) { struct desync_params *dp = ¶ms.dp[m]; @@ -526,9 +534,12 @@ ssize_t udp_hook(struct eval *val, if (m >= params.dp_count) { return -1; } - val->attempt = m; + pair->attempt = m; } - LOG(LOG_S, "desync UDP, m=%d\n", m); + if (!check_round(params.dp[m].rounds, r)) { + return send(val->fd, buffer, n, 0); + } + LOG(LOG_S, "desync UDP, m=%d, r=%d\n", m, r); return desync_udp(val->fd, buffer, bfsize, n, &dst->sa, m); } diff --git a/main.c b/main.c index 3a8bb90..f38db60 100644 --- a/main.c +++ b/main.c @@ -54,7 +54,6 @@ struct params params = { .laddr = { .sin6_family = AF_INET }, - .repeats = 1, .debug = 0, .auto_level = AUTO_NOBUFF }; @@ -81,13 +80,13 @@ const char help_text[] = { " Detect: torst,redirect,ssl_err,none\n" " -L, --auto-mode <0|1> 1 - handle trigger after several packets\n" " -u, --cache-ttl Lifetime of cached desync params for IP\n" - " -R, --repeats Number of requests to which desync will be applied\n" #ifdef TIMEOUT_SUPPORT " -T, --timeout Timeout waiting for response, after which trigger auto\n" #endif " -K, --proto Protocol whitelist: tls,http,udp\n" " -H, --hosts Hosts whitelist, filename or :string\n" " -V, --pf Ports range whitelist\n" + " -R, --round Number of request to which desync will be applied\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" @@ -136,7 +135,6 @@ const struct option options[] = { #endif {"auto", 1, 0, 'A'}, {"auto-mode", 1, 0, 'L'}, - {"repeats", 1, 0, 'R'}, {"cache-ttl", 1, 0, 'u'}, #ifdef TIMEOUT_SUPPORT {"timeout", 1, 0, 'T'}, @@ -144,6 +142,7 @@ const struct option options[] = { {"proto", 1, 0, 'K'}, {"hosts", 1, 0, 'H'}, {"pf", 1, 0, 'V'}, + {"repeats", 1, 0, 'R'}, {"split", 1, 0, 's'}, {"disorder", 1, 0, 'd'}, {"oob", 1, 0, 'o'}, @@ -620,14 +619,6 @@ int main(int argc, char **argv) params.auto_level = val; break; - case 'R': - val = strtol(optarg, &end, 0); - if (val < 1 || val > INT_MAX || *end) - invalid = 1; - else - params.repeats = val; - break; - case 'A': if (!(dp->hosts || dp->proto || dp->pf[0] || dp->detect)) { all_limited = 0; @@ -881,6 +872,24 @@ int main(int argc, char **argv) } break; + case 'R': + val = strtol(optarg, &end, 0); + if (val <= 0 || val > INT_MAX) + invalid = 1; + else { + dp->rounds[0] = val; + if (*end == '-') { + val = strtol(end + 1, &end, 0); + if (val <= 0 || val > INT_MAX) + invalid = 1; + } + if (*end) + invalid = 1; + else + dp->rounds[1] = val; + } + break; + case 'g': val = strtol(optarg, &end, 0); if (val <= 0 || val > 255 || *end) diff --git a/params.h b/params.h index 1fdade9..c30d857 100644 --- a/params.h +++ b/params.h @@ -89,6 +89,7 @@ struct desync_params { int detect; struct mphdr *hosts; uint16_t pf[2]; + int rounds[2]; char *file_ptr; ssize_t file_size; @@ -118,8 +119,6 @@ struct params { struct mphdr *mempool; char *protect_path; - - int repeats; }; extern struct params params;