mirror of
https://github.com/hufrea/byedpi.git
synced 2025-01-03 04:49:47 +00:00
Add --tr
This commit is contained in:
parent
0c6f95070c
commit
6b39efdd7a
126
main.c
126
main.c
@ -75,8 +75,9 @@ const char help_text[] = {
|
|||||||
" -A, --auto Try desync params after this option\n"
|
" -A, --auto Try desync params after this option\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\n"
|
" -T, --timeout <sec> Timeout waiting for response, after which trigger auto\n"
|
||||||
#endif
|
#endif
|
||||||
|
" -P, --tr <s:e:f|:str> Auto trigger data in first response\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"
|
||||||
@ -85,13 +86,13 @@ const char help_text[] = {
|
|||||||
#ifdef FAKE_SUPPORT
|
#ifdef FAKE_SUPPORT
|
||||||
" -f, --fake <n[+s]> Split and send fake packet\n"
|
" -f, --fake <n[+s]> Split and send fake packet\n"
|
||||||
" -t, --ttl <num> TTL of fake packets, default 8\n"
|
" -t, --ttl <num> TTL of fake packets, default 8\n"
|
||||||
" -l, --fake-tls <file>\n"
|
" -l, --fake-tls <f|:str>\n"
|
||||||
" -j, --fake-http <file> Set custom fake packet\n"
|
" -j, --fake-http <f|:str> Set custom fake packet\n"
|
||||||
" -n, --tls-sni <str> Change SNI in fake ClientHello\n"
|
" -n, --tls-sni <str> Change SNI in fake ClientHello\n"
|
||||||
#endif
|
#endif
|
||||||
" -e, --oob-data <file> Set custom OOB data\n"
|
" -e, --oob-data <f|:str> Set custom OOB data, filename or :string\n"
|
||||||
" -M, --mod-http <h,d,r> Modify HTTP: hcsmix,dcsmix,rmspace\n"
|
" -M, --mod-http <h,d,r> Modify HTTP: hcsmix,dcsmix,rmspace\n"
|
||||||
" -r, --tlsrec <n[+s]> Make TLS record at offset\n"
|
" -r, --tlsrec <n[+s]> Make TLS record at position\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -113,6 +114,7 @@ const struct option options[] = {
|
|||||||
#ifdef TIMEOUT_SUPPORT
|
#ifdef TIMEOUT_SUPPORT
|
||||||
{"timeout", 1, 0, 'T'},
|
{"timeout", 1, 0, 'T'},
|
||||||
#endif
|
#endif
|
||||||
|
{"tr", 1, 0, 'P'},
|
||||||
{"split", 1, 0, 's'},
|
{"split", 1, 0, 's'},
|
||||||
{"disorder", 1, 0, 'd'},
|
{"disorder", 1, 0, 'd'},
|
||||||
{"oob", 1, 0, 'o'},
|
{"oob", 1, 0, 'o'},
|
||||||
@ -132,12 +134,57 @@ const struct option options[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
char *ftob(char *name, ssize_t *sl)
|
char *parse_cform(const char *str, ssize_t *size)
|
||||||
{
|
{
|
||||||
|
ssize_t len = strlen(str);
|
||||||
|
char *d = malloc(len);
|
||||||
|
if (!d) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static char esca[] = {
|
||||||
|
'r','\r','n','\n','t','\t','\\','\\',
|
||||||
|
'f','\f','b','\b','v','\v','a','\a', 0
|
||||||
|
};
|
||||||
|
ssize_t i = 0, p = 0;
|
||||||
|
for (; p < len; ++p && ++i) {
|
||||||
|
if (str[p] != '\\') {
|
||||||
|
d[i] = str[p];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
char *e = esca;
|
||||||
|
for (; *e; e += 2) {
|
||||||
|
if (*e == str[p]) {
|
||||||
|
d[i] = *(e + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int n = 0;
|
||||||
|
if (sscanf(&str[p], "x%2hhx%n", &d[i], &n) == 1
|
||||||
|
|| sscanf(&str[p], "%3hho%n", &d[i], &n) == 1) {
|
||||||
|
p += (n - 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
i--; p--;
|
||||||
|
}
|
||||||
|
*size = i;
|
||||||
|
char *m = realloc(d, i);
|
||||||
|
return m ? m : d;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *ftob(const char *str, ssize_t *sl)
|
||||||
|
{
|
||||||
|
if (*str == ':') {
|
||||||
|
return parse_cform(str + 1, sl);
|
||||||
|
}
|
||||||
char *buffer = 0;
|
char *buffer = 0;
|
||||||
long size;
|
long size;
|
||||||
|
|
||||||
FILE *file = fopen(name, "rb");
|
FILE *file = fopen(str, "rb");
|
||||||
if (!file)
|
if (!file)
|
||||||
return 0;
|
return 0;
|
||||||
do {
|
do {
|
||||||
@ -164,7 +211,7 @@ char *ftob(char *name, ssize_t *sl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int get_addr(char *str, struct sockaddr_ina *addr)
|
int get_addr(const char *str, struct sockaddr_ina *addr)
|
||||||
{
|
{
|
||||||
struct addrinfo hints = {0}, *res = 0;
|
struct addrinfo hints = {0}, *res = 0;
|
||||||
|
|
||||||
@ -203,20 +250,6 @@ int get_default_ttl()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct part *add_part(struct part **root, int *n)
|
|
||||||
{
|
|
||||||
struct part *p = realloc(
|
|
||||||
*root, sizeof(struct part) * (*n + 1));
|
|
||||||
if (!p) {
|
|
||||||
uniperror("realloc");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*root = p;
|
|
||||||
*n = *n + 1;
|
|
||||||
return &((*root)[(*n) - 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int parse_offset(struct part *part, const char *str)
|
int parse_offset(struct part *part, const char *str)
|
||||||
{
|
{
|
||||||
char *end = 0;
|
char *end = 0;
|
||||||
@ -239,19 +272,17 @@ int parse_offset(struct part *part, const char *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct desync_params *add_dparams(
|
void *add(void **root, int *n, size_t ss)
|
||||||
struct desync_params **root, int *n)
|
|
||||||
{
|
{
|
||||||
struct desync_params *p = realloc(
|
void *p = realloc(*root, ss * (*n + 1));
|
||||||
*root, sizeof(struct desync_params) * (*n + 1));
|
|
||||||
if (!p) {
|
if (!p) {
|
||||||
uniperror("realloc");
|
uniperror("realloc");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*root = p;
|
*root = p;
|
||||||
|
p = ((*root) + ((*n) * ss));
|
||||||
|
memset(p, 0, ss);
|
||||||
*n = *n + 1;
|
*n = *n + 1;
|
||||||
p = &((*root)[(*n) - 1]);
|
|
||||||
memset(p, 0, sizeof(*p));
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -296,8 +327,8 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
uint16_t port = htons(1080);
|
uint16_t port = htons(1080);
|
||||||
|
|
||||||
struct desync_params *dp = add_dparams(
|
struct desync_params *dp = add((void *)¶ms.dp,
|
||||||
¶ms.dp, ¶ms.dp_count);
|
¶ms.dp_count, sizeof(struct desync_params));
|
||||||
if (!dp) {
|
if (!dp) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -367,7 +398,8 @@ int main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'A':
|
case 'A':
|
||||||
dp = add_dparams(¶ms.dp, ¶ms.dp_count);
|
dp = add((void *)¶ms.dp, ¶ms.dp_count,
|
||||||
|
sizeof(struct desync_params));
|
||||||
if (!dp) {
|
if (!dp) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -394,13 +426,32 @@ int main(int argc, char **argv)
|
|||||||
params.timeout = val;
|
params.timeout = val;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'P':;
|
||||||
|
struct spos *spos = add((void *)¶ms.spos,
|
||||||
|
¶ms.spos_n, sizeof(struct spos));
|
||||||
|
if (!spos) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
sscanf(optarg, "%zi:%zi:%zn", &spos->start, &spos->end, &val);
|
||||||
|
if (val == 0 || !optarg[val]) {
|
||||||
|
invalid = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
spos->data = ftob(&optarg[val], &spos->size);
|
||||||
|
if (!spos->data) {
|
||||||
|
uniperror("read/parse");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'o':
|
case 'o':
|
||||||
case 'f':
|
case 'f':
|
||||||
;
|
;
|
||||||
struct part *part = add_part(
|
struct part *part = add((void *)&dp->parts,
|
||||||
&dp->parts, &dp->parts_n);
|
&dp->parts_n, sizeof(struct part));
|
||||||
if (!part) {
|
if (!part) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -438,7 +489,7 @@ int main(int argc, char **argv)
|
|||||||
case 'l':
|
case 'l':
|
||||||
fake_tls.data = ftob(optarg, &fake_tls.size);
|
fake_tls.data = ftob(optarg, &fake_tls.size);
|
||||||
if (!fake_tls.data) {
|
if (!fake_tls.data) {
|
||||||
uniperror("read file");
|
uniperror("read/parse");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -446,7 +497,7 @@ int main(int argc, char **argv)
|
|||||||
case 'j':
|
case 'j':
|
||||||
fake_http.data = ftob(optarg, &fake_http.size);
|
fake_http.data = ftob(optarg, &fake_http.size);
|
||||||
if (!fake_http.data) {
|
if (!fake_http.data) {
|
||||||
uniperror("read file");
|
uniperror("read/parse");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -454,7 +505,7 @@ int main(int argc, char **argv)
|
|||||||
case 'e':
|
case 'e':
|
||||||
oob_data.data = ftob(optarg, &oob_data.size);
|
oob_data.data = ftob(optarg, &oob_data.size);
|
||||||
if (!oob_data.data) {
|
if (!oob_data.data) {
|
||||||
uniperror("read file");
|
uniperror("read/parse");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -482,7 +533,8 @@ int main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
part = add_part(&dp->tlsrec, &dp->tlsrec_n);
|
part = add((void *)&dp->tlsrec,
|
||||||
|
&dp->tlsrec_n, sizeof(struct part));
|
||||||
if (!part) {
|
if (!part) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
7
params.h
7
params.h
@ -43,6 +43,8 @@ struct params {
|
|||||||
|
|
||||||
unsigned int timeout;
|
unsigned int timeout;
|
||||||
long cache_ttl;
|
long cache_ttl;
|
||||||
|
int spos_n;
|
||||||
|
struct spos *spos;
|
||||||
char ipv6;
|
char ipv6;
|
||||||
char resolve;
|
char resolve;
|
||||||
int max_open;
|
int max_open;
|
||||||
@ -61,3 +63,8 @@ struct packet {
|
|||||||
extern struct packet fake_tls;
|
extern struct packet fake_tls;
|
||||||
extern struct packet fake_http;
|
extern struct packet fake_http;
|
||||||
extern struct packet oob_data;
|
extern struct packet oob_data;
|
||||||
|
|
||||||
|
struct spos {
|
||||||
|
ssize_t start, end, size;
|
||||||
|
char *data;
|
||||||
|
};
|
53
proxy.c
53
proxy.c
@ -447,7 +447,7 @@ static inline int on_tunnel(struct poolhd *pool, struct eval *val,
|
|||||||
break;
|
break;
|
||||||
if (n < 1) {
|
if (n < 1) {
|
||||||
if (n) uniperror("recv");
|
if (n) uniperror("recv");
|
||||||
return get_e();
|
return -1;
|
||||||
}
|
}
|
||||||
val->recv_count += n;
|
val->recv_count += n;
|
||||||
|
|
||||||
@ -603,17 +603,37 @@ int try_again(struct poolhd *pool, struct eval *val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char find_bad_data(char *buffer, ssize_t n)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < params.spos_n; i++) {
|
||||||
|
struct spos bad_data = params.spos[i];
|
||||||
|
if (bad_data.start >= n) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ssize_t end = n;
|
||||||
|
if (bad_data.end && bad_data.end < n) {
|
||||||
|
end = bad_data.end;
|
||||||
|
}
|
||||||
|
char *found = memmem(buffer + bad_data.start,
|
||||||
|
end - bad_data.start, bad_data.data, bad_data.size);
|
||||||
|
if (found) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int on_tunnel_check(struct poolhd *pool, struct eval *val,
|
int on_tunnel_check(struct poolhd *pool, struct eval *val,
|
||||||
char *buffer, size_t bfsize, int out)
|
char *buffer, size_t bfsize, int out)
|
||||||
{
|
{
|
||||||
int e = on_tunnel(pool, val, buffer, bfsize, out);
|
|
||||||
|
|
||||||
if (val->flag == FLAG_CONN) {
|
|
||||||
if (out) {
|
if (out) {
|
||||||
return e;
|
return on_tunnel(pool, val, buffer, bfsize, out);
|
||||||
}
|
}
|
||||||
if (e) {
|
ssize_t n = recv(val->fd, buffer, bfsize, 0);
|
||||||
switch (unie(e)) {
|
if (n < 1) {
|
||||||
|
uniperror("recv");
|
||||||
|
switch (unie(get_e())) {
|
||||||
case ECONNRESET:
|
case ECONNRESET:
|
||||||
case ETIMEDOUT:
|
case ETIMEDOUT:
|
||||||
break;
|
break;
|
||||||
@ -621,7 +641,19 @@ int on_tunnel_check(struct poolhd *pool, struct eval *val,
|
|||||||
}
|
}
|
||||||
return try_again(pool, val);
|
return try_again(pool, val);
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
char found_bd = find_bad_data(buffer, n);
|
||||||
|
if (found_bd &&
|
||||||
|
!try_again(pool, val)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
struct eval *pair = val->pair;
|
struct eval *pair = val->pair;
|
||||||
|
|
||||||
|
ssize_t sn = send(pair->fd, buffer, n, 0);
|
||||||
|
if (n != sn) {
|
||||||
|
uniperror("send");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
val->type = EV_TUNNEL;
|
val->type = EV_TUNNEL;
|
||||||
pair->type = EV_TUNNEL;
|
pair->type = EV_TUNNEL;
|
||||||
|
|
||||||
@ -636,7 +668,8 @@ int on_tunnel_check(struct poolhd *pool, struct eval *val,
|
|||||||
int m = pair->attempt;
|
int m = pair->attempt;
|
||||||
|
|
||||||
if ((m == 0 && val->attempt < 0)
|
if ((m == 0 && val->attempt < 0)
|
||||||
|| (m && m == val->attempt)) {
|
|| (m && m == val->attempt)
|
||||||
|
|| found_bd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (m == 0) {
|
if (m == 0) {
|
||||||
@ -646,8 +679,6 @@ int on_tunnel_check(struct poolhd *pool, struct eval *val,
|
|||||||
}
|
}
|
||||||
return mode_add_get(
|
return mode_add_get(
|
||||||
(struct sockaddr_ina *)&val->in6, m);
|
(struct sockaddr_ina *)&val->in6, m);
|
||||||
}
|
|
||||||
return e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -692,7 +723,7 @@ int on_desync(struct poolhd *pool, struct eval *val,
|
|||||||
(struct sockaddr *)&val->pair->in6, m)) {
|
(struct sockaddr *)&val->pair->in6, m)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
val->type = EV_PRE_TUNNEL;
|
val->type = EV_TUNNEL;
|
||||||
val->pair->type = EV_PRE_TUNNEL;
|
val->pair->type = EV_PRE_TUNNEL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
19
proxy.h
19
proxy.h
@ -94,6 +94,25 @@ enum s4_rep {
|
|||||||
#define S_SIZE_I6 22
|
#define S_SIZE_I6 22
|
||||||
#define S_SIZE_ID 7
|
#define S_SIZE_ID 7
|
||||||
|
|
||||||
|
#ifndef __linux__
|
||||||
|
inline char *memmem(char *a, ssize_t as, char *b, ssize_t bs)
|
||||||
|
{
|
||||||
|
for (char *p = a; ; p++) {
|
||||||
|
p = memchr(p, *b, as - (p - a));
|
||||||
|
if (!p) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if ((p + bs) > (a + as)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!memcmp(p, b, bs)) {
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int listen_socket(struct sockaddr_ina *srv);
|
int listen_socket(struct sockaddr_ina *srv);
|
||||||
int event_loop(int srvfd);
|
int event_loop(int srvfd);
|
||||||
int run(struct sockaddr_ina *srv);
|
int run(struct sockaddr_ina *srv);
|
||||||
|
15
readme.txt
15
readme.txt
@ -37,10 +37,12 @@ $ ./ciadpi --disorder 3 -A --tlsrec 1+s
|
|||||||
|
|
||||||
-A, --auto
|
-A, --auto
|
||||||
Автоматический режим
|
Автоматический режим
|
||||||
Если сервер сбросил подключение после первого запроса,
|
Если сервер сбросил подключение, превышено время ожидания, сработал --tr,
|
||||||
то будут применены параметры обхода, следующие за данной опцией
|
то будут применены параметры обхода, следующие за данной опцией
|
||||||
Можно указывать несколько групп параметров, раделяя их данным флагом
|
Можно указывать несколько групп параметров, раделяя их данным флагом
|
||||||
Если соединение успешно прошло, то параметры для данного IP будут закешированны
|
Если соединение успешно прошло, то параметры для данного IP будут закешированны
|
||||||
|
Параметры, которые можно вынести в отдельную группу:
|
||||||
|
split, disorder, oob, fake, ttl, mod-http, tlsrec
|
||||||
|
|
||||||
-u, --cache-ttl <sec>
|
-u, --cache-ttl <sec>
|
||||||
Время жизни значения в кеше, по умолчанию 100800 (28 часов)
|
Время жизни значения в кеше, по умолчанию 100800 (28 часов)
|
||||||
@ -48,6 +50,11 @@ $ ./ciadpi --disorder 3 -A --tlsrec 1+s
|
|||||||
-T, --timeout <sec>
|
-T, --timeout <sec>
|
||||||
Таймаут ожидания первого ответа от сервера в секундах
|
Таймаут ожидания первого ответа от сервера в секундах
|
||||||
В Linux переводится в миллисекунды, поэтому можно указать дробное число
|
В Linux переводится в миллисекунды, поэтому можно указать дробное число
|
||||||
|
Истечение таймаута будет обработано --auto
|
||||||
|
|
||||||
|
-P, --tr <s:e:file|:str>
|
||||||
|
Поиск строки в первом ответе от сервера, начиная с s и заканчивая e
|
||||||
|
Является триггером для --auto
|
||||||
|
|
||||||
-s, --split <n[+s]>
|
-s, --split <n[+s]>
|
||||||
Разбить запрос по указанному смещению
|
Разбить запрос по указанному смещению
|
||||||
@ -72,11 +79,11 @@ $ ./ciadpi --disorder 3 -A --tlsrec 1+s
|
|||||||
TTL для поддельного пакета, по умолчанию 8
|
TTL для поддельного пакета, по умолчанию 8
|
||||||
Необходимо подобрать такое значение, чтобы пакет не дошел до сервера, но был обработан DPI
|
Необходимо подобрать такое значение, чтобы пакет не дошел до сервера, но был обработан DPI
|
||||||
|
|
||||||
-l, --fake-tls <file>
|
-l, --fake-tls <file|:str>
|
||||||
-j, --fake-http <file>
|
-j, --fake-http <file|:str>
|
||||||
Указать свои поддельные пакеты, вместо дефолтных
|
Указать свои поддельные пакеты, вместо дефолтных
|
||||||
|
|
||||||
-e, --oob-data <file>
|
-e, --oob-data <file|:str>
|
||||||
Данные, отсылаемые вне основного потока, по умолчанию один байт 'a'
|
Данные, отсылаемые вне основного потока, по умолчанию один байт 'a'
|
||||||
! При размере более одного байта может работать нестабильно
|
! При размере более одного байта может работать нестабильно
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user