move detect to auto

This commit is contained in:
ruti 2024-04-04 04:19:40 +03:00
parent 50c350c6ae
commit f4599b0e15
4 changed files with 85 additions and 60 deletions

61
main.c
View File

@ -70,12 +70,12 @@ const char help_text[] = {
#ifdef TCP_FASTOPEN_CONNECT #ifdef TCP_FASTOPEN_CONNECT
" -F, --tfo Enable TCP Fast Open\n" " -F, --tfo Enable TCP Fast Open\n"
#endif #endif
" -A, --auto Try desync params after this option\n" " -A, --auto[=t,r,c,s,a] Try desync params after this option\n"
" Detect: torst,redirect,cl_err,sid_inv,alert\n"
" -u, --cache-ttl <sec> Lifetime of cached desync params for IP\n" " -u, --cache-ttl <sec> Lifetime of cached desync params for IP\n"
#ifdef TIMEOUT_SUPPORT #ifdef TIMEOUT_SUPPORT
" -T, --timeout <sec> Timeout waiting for response, after which trigger auto\n" " -T, --timeout <sec> Timeout waiting for response, after which trigger auto\n"
#endif #endif
" -D, --detect <r,c,s,a> Detect: redirect,cl_err,sid_inv,alert\n"
" -s, --split <n[+s]> Split packet at n\n" " -s, --split <n[+s]> Split packet at n\n"
" +s - add SNI offset\n" " +s - add SNI offset\n"
" +h - add HTTP Host offset\n" " +h - add HTTP Host offset\n"
@ -114,12 +114,11 @@ const struct option options[] = {
#ifdef TCP_FASTOPEN_CONNECT #ifdef TCP_FASTOPEN_CONNECT
{"tfo ", 0, 0, 'F'}, {"tfo ", 0, 0, 'F'},
#endif #endif
{"auto", 0, 0, 'A'}, {"auto", 2, 0, 'A'},
{"cache-ttl", 1, 0, 'u'}, {"cache-ttl", 1, 0, 'u'},
#ifdef TIMEOUT_SUPPORT #ifdef TIMEOUT_SUPPORT
{"timeout", 1, 0, 'T'}, {"timeout", 1, 0, 'T'},
#endif #endif
{"detect", 1, 0, 'D'},
{"split", 1, 0, 's'}, {"split", 1, 0, 's'},
{"disorder", 1, 0, 'd'}, {"disorder", 1, 0, 'd'},
{"oob", 1, 0, 'o'}, {"oob", 1, 0, 'o'},
@ -460,6 +459,35 @@ int main(int argc, char **argv)
clear_params(); clear_params();
return -1; return -1;
} }
if (!optarg) {
dp->detect |= DETECT_TORST;
break;
}
end = optarg;
while (end && !invalid) {
switch (*end) {
case 't':
dp->detect |= DETECT_TORST;
break;
case 'r':
dp->detect |= DETECT_HTTP_LOCAT;
break;
case 'c':
dp->detect |= DETECT_HTTP_CLERR;
break;
case 's':
dp->detect |= DETECT_TLS_INVSID;
break;
case 'a':
dp->detect |= DETECT_TLS_ALERT;
break;
default:
invalid = 1;
continue;
}
end = strchr(end, ',');
if (end) end++;
}
break; break;
case 'u': case 'u':
@ -483,31 +511,6 @@ int main(int argc, char **argv)
params.timeout = val; params.timeout = val;
break; break;
case 'D':;
end = optarg;
while (end && !invalid) {
switch (*end) {
case 'r':
dp->detect |= DETECT_HTTP_LOCAT;
break;
case 'c':
dp->detect |= DETECT_HTTP_CLERR;
break;
case 's':
dp->detect |= DETECT_TLS_INVSID;
break;
case 'a':
dp->detect |= DETECT_TLS_ALERT;
break;
default:
invalid = 1;
continue;
}
end = strchr(end, ',');
if (end) end++;
}
break;
case 's': case 's':
case 'd': case 'd':
case 'o': case 'o':

View File

@ -19,6 +19,7 @@
#define DETECT_HTTP_CLERR 2 #define DETECT_HTTP_CLERR 2
#define DETECT_TLS_INVSID 4 #define DETECT_TLS_INVSID 4
#define DETECT_TLS_ALERT 8 #define DETECT_TLS_ALERT 8
#define DETECT_TORST 16
enum demode { enum demode {
DESYNC_NONE, DESYNC_NONE,

68
proxy.c
View File

@ -594,20 +594,9 @@ static inline int on_request(struct poolhd *pool, struct eval *val,
} }
int try_again(struct poolhd *pool, struct eval *val, char data) int reconnect(struct poolhd *pool, struct eval *val, int m)
{ {
struct eval *client = val->pair; struct eval *client = val->pair;
int m = client->attempt + 1;
if (!data) for (; m < params.dp_count; m++) {
struct desync_params dp = params.dp[m];
if (dp.detect == 0) break;
}
if (m >= params.dp_count) {
mode_add_get(
(struct sockaddr_ina *)&val->in6, 0);
return -1;
}
if (create_conn(pool, client, if (create_conn(pool, client,
(struct sockaddr_ina *)&val->in6, EV_DESYNC)) { (struct sockaddr_ina *)&val->in6, EV_DESYNC)) {
@ -617,37 +606,64 @@ int try_again(struct poolhd *pool, struct eval *val, char data)
del_event(pool, val); del_event(pool, val);
client->type = EV_IGNORE; client->type = EV_IGNORE;
client->attempt++; client->attempt = m;
return 0; return 0;
} }
int find_bad_data(char *req, ssize_t qn, int on_torst(struct poolhd *pool, struct eval *val)
char *resp, ssize_t sn, int m)
{ {
int m = val->pair->attempt + 1;
for (; m < params.dp_count; m++) {
struct desync_params dp = params.dp[m];
if (dp.detect == 0
|| (dp.detect & DETECT_TORST))
break;
}
if (m >= params.dp_count) {
mode_add_get(
(struct sockaddr_ina *)&val->in6, 0);
return -1;
}
return reconnect(pool, val, m);
}
int on_response(struct poolhd *pool, struct eval *val,
char *resp, ssize_t sn)
{
int m = val->pair->attempt + 1;
char *req = val->pair->buff.data;
ssize_t qn = val->pair->buff.size;
for (; m < params.dp_count; m++) { for (; m < params.dp_count; m++) {
struct desync_params dp = params.dp[m]; struct desync_params dp = params.dp[m];
if ((dp.detect & DETECT_HTTP_LOCAT) if ((dp.detect & DETECT_HTTP_LOCAT)
&& is_http_redirect(req, qn, resp, sn)) { && is_http_redirect(req, qn, resp, sn)) {
return m; break;
} }
if ((dp.detect & DETECT_TLS_INVSID) if ((dp.detect & DETECT_TLS_INVSID)
&& neq_tls_sid(req, qn, resp, sn)) { && neq_tls_sid(req, qn, resp, sn)) {
return m; break;
} }
if ((dp.detect & DETECT_TLS_ALERT) if ((dp.detect & DETECT_TLS_ALERT)
&& is_tls_alert(resp, sn)) { && is_tls_alert(resp, sn)) {
return m; break;
} }
if (dp.detect & DETECT_HTTP_CLERR) { if (dp.detect & DETECT_HTTP_CLERR) {
int code = get_http_code(resp, sn); int code = get_http_code(resp, sn);
if (code > 400 && code < 451 && code != 429) { if (code > 400 && code < 451 && code != 429) {
return m; break;
} }
} }
} }
return 0; if (m < params.dp_count) {
return reconnect(pool, val, m);
}
return -1;
} }
@ -666,17 +682,13 @@ int on_tunnel_check(struct poolhd *pool, struct eval *val,
break; break;
default: return -1; default: return -1;
} }
return try_again(pool, val, 0); return on_torst(pool, val);
} }
// //
struct eval *pair = val->pair; if (on_response(pool, val, buffer, n) == 0) {
return 0;
int d = find_bad_data(pair->buff.data, pair->buff.size,
buffer, n, pair->attempt + 1);
if (d) {
val->pair->attempt = d - 1;
return try_again(pool, val, 1);
} }
struct eval *pair = val->pair;
ssize_t sn = send(pair->fd, buffer, n, 0); ssize_t sn = send(pair->fd, buffer, n, 0);
if (n != sn) { if (n != sn) {

View File

@ -40,14 +40,23 @@ $ ./ciadpi --disorder 3 -A --tlsrec 1+s
Если сервер его поддерживает, то первый пакет будет отправлен сразу вместе с SYN Если сервер его поддерживает, то первый пакет будет отправлен сразу вместе с SYN
Поддерживается только в Linux (4.11+) Поддерживается только в Linux (4.11+)
-A, --auto -A, --auto[=t,r,c,s,a]
Автоматический режим Автоматический режим
Если сервер сбросил подключение, превышено время ожидания, сработал --tr, Если произошло событие, похожее на блокировку или поломку,
то будут применены параметры обхода, следующие за данной опцией то будут применены параметры обхода, следующие за данной опцией
Можно указывать несколько групп параметров, раделяя их данным флагом Возможные события:
torst : Вышло время ожидания или сервер сбросил подключение после первого запроса
redirect: HTTP Redirect с Location, домен которого не совпадает с исходящим
cl_err : HTTP ответ, код которого равен 40x, но не 429
sid_inv : session_id в TLS ServerHello и ClientHello не совпадают
alert : TLS Error Alert в ответе
По умолчанию обрабатывается только torst
Можно указывать несколько групп опций, раделяя их данным параметром
Если соединение успешно прошло, то параметры для данного IP будут закешированны Если соединение успешно прошло, то параметры для данного IP будут закешированны
Параметры, которые можно вынести в отдельную группу: Параметры, которые можно вынести в отдельную группу:
detect, split, disorder, oob, fake, ttl, ip-opt, md5sig, mod-http, tlsrec detect, split, disorder, oob, fake, ttl, ip-opt, md5sig, mod-http, tlsrec
Пример:
--auto=redirect --split=1+h --auto=torst --fake -1 --auto=sid_inv,alert --tlsrec 1+s
-u, --cache-ttl <sec> -u, --cache-ttl <sec>
Время жизни значения в кеше, по умолчанию 100800 (28 часов) Время жизни значения в кеше, по умолчанию 100800 (28 часов)