mirror of
https://github.com/hufrea/byedpi.git
synced 2025-02-03 18:11:10 +03:00
avl, --hosts, --dst
This commit is contained in:
parent
38d44ec1ca
commit
3b65b275b1
7 changed files with 296 additions and 163 deletions
1
conev.h
1
conev.h
|
@ -73,6 +73,7 @@ struct eval {
|
|||
};
|
||||
ssize_t recv_count;
|
||||
int attempt;
|
||||
char cache;
|
||||
#ifndef NOEPOLL
|
||||
uint32_t events;
|
||||
#endif
|
||||
|
|
109
main.c
109
main.c
|
@ -17,12 +17,13 @@
|
|||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <sys/mman.h>
|
||||
#else
|
||||
#include <ws2tcpip.h>
|
||||
#define close(fd) closesocket(fd)
|
||||
#endif
|
||||
|
||||
#define VERSION "8.1"
|
||||
#define VERSION "10"
|
||||
|
||||
#define MPOOL_INC 16
|
||||
|
||||
|
@ -71,12 +72,15 @@ const char help_text[] = {
|
|||
#ifdef TCP_FASTOPEN_CONNECT
|
||||
" -F, --tfo Enable TCP Fast Open\n"
|
||||
#endif
|
||||
" -A, --auto[=t,r,c,s,a] Try desync params after this option\n"
|
||||
" Detect: torst,redirect,cl_err,sid_inv,alert\n"
|
||||
" -L, --late-conn Waiting for request before connecting\n"
|
||||
" -A, --auto[=t,r,c,s,a,n] Try desync params after this option\n"
|
||||
" Detect: torst,redirect,cl_err,sid_inv,alert,nop\n"
|
||||
" -u, --cache-ttl <sec> Lifetime of cached desync params for IP\n"
|
||||
#ifdef TIMEOUT_SUPPORT
|
||||
" -T, --timeout <sec> Timeout waiting for response, after which trigger auto\n"
|
||||
#endif
|
||||
" -H, --hosts <file|:str> Hosts whitelist\n"
|
||||
" -D, --dst <addr> Custom destination IP\n"
|
||||
" -s, --split <n[+s]> Split packet at n\n"
|
||||
" +s - add SNI offset\n"
|
||||
" +h - add HTTP Host offset\n"
|
||||
|
@ -115,11 +119,14 @@ const struct option options[] = {
|
|||
#ifdef TCP_FASTOPEN_CONNECT
|
||||
{"tfo ", 0, 0, 'F'},
|
||||
#endif
|
||||
{"late-conn", 0, 0, 'L'},
|
||||
{"auto", 2, 0, 'A'},
|
||||
{"cache-ttl", 1, 0, 'u'},
|
||||
#ifdef TIMEOUT_SUPPORT
|
||||
{"timeout", 1, 0, 'T'},
|
||||
#endif
|
||||
{"hosts", 1, 0, 'H'},
|
||||
{"dst", 1, 0, 'D'},
|
||||
{"split", 1, 0, 's'},
|
||||
{"disorder", 1, 0, 'd'},
|
||||
{"oob", 1, 0, 'o'},
|
||||
|
@ -195,16 +202,27 @@ char *ftob(const char *str, ssize_t *sl)
|
|||
long size;
|
||||
|
||||
FILE *file = fopen(str, "rb");
|
||||
if (!file)
|
||||
if (!file) {
|
||||
return 0;
|
||||
}
|
||||
do {
|
||||
if (fseek(file, 0, SEEK_END)) {
|
||||
break;
|
||||
}
|
||||
size = ftell(file);
|
||||
if (!size || fseek(file, 0, SEEK_SET)) {
|
||||
if (size <= 0) {
|
||||
break;
|
||||
}
|
||||
if (fseek(file, 0, SEEK_SET)) {
|
||||
break;
|
||||
}
|
||||
#ifndef _WIN32
|
||||
buffer = mmap(0, size, PROT_READ, MAP_PRIVATE, fileno(file), 0);
|
||||
if (buffer == MAP_FAILED) {
|
||||
buffer = 0;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (!(buffer = malloc(size))) {
|
||||
break;
|
||||
}
|
||||
|
@ -212,6 +230,7 @@ char *ftob(const char *str, ssize_t *sl)
|
|||
free(buffer);
|
||||
buffer = 0;
|
||||
}
|
||||
#endif
|
||||
} while (0);
|
||||
if (buffer) {
|
||||
*sl = size;
|
||||
|
@ -221,6 +240,33 @@ char *ftob(const char *str, ssize_t *sl)
|
|||
}
|
||||
|
||||
|
||||
struct mphdr *parse_hosts(char *buffer, size_t size)
|
||||
{
|
||||
struct mphdr *hdr = mem_pool(1);
|
||||
if (!hdr) {
|
||||
return 0;
|
||||
}
|
||||
char *end = buffer + size;
|
||||
char *e = buffer, *s = buffer;
|
||||
|
||||
for (; e <= end; e++) {
|
||||
if (*e != ' ' && *e != '\n' && e != end) {
|
||||
continue;
|
||||
}
|
||||
if (s == e) {
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
if (mem_add(hdr, s, e - s) == 0) {
|
||||
free(hdr);
|
||||
return 0;
|
||||
}
|
||||
s = e + 1;
|
||||
}
|
||||
return hdr;
|
||||
}
|
||||
|
||||
|
||||
int get_addr(const char *str, struct sockaddr_ina *addr)
|
||||
{
|
||||
struct addrinfo hints = {0}, *res = 0;
|
||||
|
@ -284,18 +330,23 @@ int parse_offset(struct part *part, const char *str)
|
|||
|
||||
void *add(void **root, int *n, size_t ss)
|
||||
{
|
||||
void *p = realloc(*root, ss * (*n + 1));
|
||||
char *p = realloc(*root, ss * (*n + 1));
|
||||
if (!p) {
|
||||
uniperror("realloc");
|
||||
return 0;
|
||||
}
|
||||
*root = p;
|
||||
p = ((*root) + ((*n) * ss));
|
||||
p = (p + ((*n) * ss));
|
||||
memset(p, 0, ss);
|
||||
*n = *n + 1;
|
||||
return p;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
#define FREE(p, s) munmap(p, s)
|
||||
#else
|
||||
#define FREE(p, s) free(p)
|
||||
#endif
|
||||
|
||||
void clear_params(void)
|
||||
{
|
||||
|
@ -322,15 +373,15 @@ void clear_params(void)
|
|||
params.dp = 0;
|
||||
}
|
||||
if (fake_tls.data != tls_data) {
|
||||
free(fake_tls.data);
|
||||
FREE(fake_tls.data, fake_tls.size);
|
||||
fake_tls.data = tls_data;
|
||||
}
|
||||
if (fake_http.data != http_data) {
|
||||
free(fake_http.data);
|
||||
FREE(fake_http.data, fake_http.size);
|
||||
fake_http.data = http_data;
|
||||
}
|
||||
if (oob_data.data != oob_char) {
|
||||
free(oob_data.data);
|
||||
FREE(oob_data.data, oob_data.size);
|
||||
oob_data.data = oob_char;
|
||||
}
|
||||
}
|
||||
|
@ -382,6 +433,7 @@ int main(int argc, char **argv)
|
|||
clear_params();
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (!invalid && (rez = getopt_long_only(
|
||||
argc, argv, opt, options, 0)) != -1) {
|
||||
switch (rez) {
|
||||
|
@ -445,6 +497,10 @@ int main(int argc, char **argv)
|
|||
|
||||
// desync options
|
||||
|
||||
case 'L':
|
||||
params.late_conn = 1;
|
||||
break;
|
||||
|
||||
case 'K':
|
||||
params.de_known = 1;
|
||||
break;
|
||||
|
@ -482,6 +538,8 @@ int main(int argc, char **argv)
|
|||
case 'a':
|
||||
dp->detect |= DETECT_TLS_ALERT;
|
||||
break;
|
||||
case 'n':
|
||||
break;
|
||||
default:
|
||||
invalid = 1;
|
||||
continue;
|
||||
|
@ -512,6 +570,27 @@ int main(int argc, char **argv)
|
|||
params.timeout = val;
|
||||
break;
|
||||
|
||||
case 'H':;
|
||||
char *data = ftob(optarg, &val);
|
||||
if (!data) {
|
||||
uniperror("read/parse");
|
||||
invalid = 1;
|
||||
}
|
||||
dp->hosts = parse_hosts(data, val);
|
||||
if (!dp->hosts) {
|
||||
perror("parse_hosts");
|
||||
clear_params();
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
if (get_addr(optarg, (struct sockaddr_ina *)&dp->addr) < 0)
|
||||
invalid = 1;
|
||||
else
|
||||
dp->to_ip = 2;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
case 'd':
|
||||
case 'o':
|
||||
|
@ -671,6 +750,14 @@ int main(int argc, char **argv)
|
|||
clear_params();
|
||||
return -1;
|
||||
}
|
||||
if (dp->hosts) {
|
||||
dp = add((void *)¶ms.dp,
|
||||
¶ms.dp_count, sizeof(struct desync_params));
|
||||
if (!dp) {
|
||||
clear_params();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
s.in.sin_port = port;
|
||||
b.in.sin_port = 0;
|
||||
|
||||
|
@ -683,7 +770,7 @@ int main(int argc, char **argv)
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
params.mempool = mem_pool(MPOOL_INC);
|
||||
params.mempool = mem_pool(0);
|
||||
if (!params.mempool) {
|
||||
uniperror("mem_pool");
|
||||
clear_params();
|
||||
|
|
151
mpool.c
151
mpool.c
|
@ -3,129 +3,98 @@
|
|||
#include <mpool.h>
|
||||
|
||||
|
||||
struct mphdr *mem_pool(int count)
|
||||
static inline int scmp(const struct elem *p, const struct elem *q)
|
||||
{
|
||||
struct mphdr *hdr = malloc(sizeof(struct mphdr));
|
||||
if (!hdr) {
|
||||
return 0;
|
||||
if (p->len != q ->len) {
|
||||
return p->len < q->len ? -1 : 1;
|
||||
}
|
||||
hdr->inc = count;
|
||||
hdr->max = count;
|
||||
hdr->count = 0;
|
||||
return memcmp(p->data, q->data, p->len);
|
||||
}
|
||||
|
||||
hdr->values = malloc(sizeof(*hdr->values) * count);
|
||||
if (!hdr->values) {
|
||||
free(hdr);
|
||||
hdr = 0;
|
||||
KAVL_INIT(my, struct elem, head, scmp)
|
||||
|
||||
|
||||
struct mphdr *mem_pool(bool cst)
|
||||
{
|
||||
struct mphdr *hdr = calloc(sizeof(struct mphdr), 1);
|
||||
if (hdr) {
|
||||
hdr->stat = cst;
|
||||
}
|
||||
return hdr;
|
||||
}
|
||||
|
||||
|
||||
int mem_index(struct mphdr *hdr, char *str, int len)
|
||||
struct elem *mem_get(struct mphdr *hdr, char *str, int len)
|
||||
{
|
||||
if (!hdr->count) {
|
||||
return -2;
|
||||
}
|
||||
int s = 0, m, i;
|
||||
int e = hdr->count - 1;
|
||||
struct {
|
||||
int len;
|
||||
char *data;
|
||||
} temp = { .len = len, .data = str };
|
||||
|
||||
while (s <= e) {
|
||||
m = s + (e - s) / 2;
|
||||
|
||||
struct elem *val = hdr->values[m];
|
||||
if (val->len != len)
|
||||
i = len < val->len ? -1 : 1;
|
||||
else
|
||||
i = memcmp(str, val->data, len);
|
||||
|
||||
if (i > 0)
|
||||
s = m + 1;
|
||||
else if (i < 0)
|
||||
e = m - 1;
|
||||
else
|
||||
return m;
|
||||
}
|
||||
return -(m + 2 + (i > 0 ? 1 : 0));
|
||||
return kavl_find(my, hdr->root, (struct elem *)&temp, 0);
|
||||
}
|
||||
|
||||
|
||||
struct elem *mem_add(struct mphdr *hdr, char *str, int len, int pos)
|
||||
struct elem *mem_add(struct mphdr *hdr, char *str, int len)
|
||||
{
|
||||
int max = hdr->max;
|
||||
|
||||
if (hdr->count >= max) {
|
||||
max += hdr->inc;
|
||||
struct elem **new = realloc(hdr->values, sizeof(*hdr->values) * max);
|
||||
if (!new) {
|
||||
return 0;
|
||||
}
|
||||
hdr->max = max;
|
||||
hdr->values = new;
|
||||
}
|
||||
if (pos >= 0) {
|
||||
return hdr->values[pos];
|
||||
}
|
||||
pos = -pos - 2;
|
||||
|
||||
struct elem *val = malloc(sizeof(struct elem) + len);
|
||||
if (!val) {
|
||||
struct elem *v, *e = malloc(sizeof(struct elem));
|
||||
if (!e) {
|
||||
return 0;
|
||||
}
|
||||
memset(val, 0, sizeof(*val));
|
||||
memcpy(val->data, str, len);
|
||||
val->len = len;
|
||||
|
||||
if (pos < hdr->count) {
|
||||
void *p = &hdr->values[pos];
|
||||
void *n = &hdr->values[pos + 1];
|
||||
void *e = &hdr->values[hdr->count];
|
||||
memmove(n, p, e - p);
|
||||
e->len = len;
|
||||
if (!hdr->stat) {
|
||||
e->data = malloc(len);
|
||||
if (!e->data) {
|
||||
free(e);
|
||||
return 0;
|
||||
}
|
||||
memcpy(e->data, str, len);
|
||||
}
|
||||
hdr->values[pos] = val;
|
||||
hdr->count++;
|
||||
return val;
|
||||
else {
|
||||
e->data = str;
|
||||
}
|
||||
v = kavl_insert(my, &hdr->root, e, 0);
|
||||
if (e != v) {
|
||||
if (!hdr->stat) {
|
||||
free(e->data);
|
||||
}
|
||||
free(e);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
void mem_delete(struct mphdr *hdr, int pos)
|
||||
void mem_delete(struct mphdr *hdr, char *str, int len)
|
||||
{
|
||||
int max = hdr->max;
|
||||
if (!hdr->count) {
|
||||
struct {
|
||||
int len;
|
||||
char *data;
|
||||
} temp = { .len = len, .data = str };
|
||||
|
||||
struct elem *e = kavl_erase(my, &hdr->root, (struct elem *)&temp, 0);
|
||||
if (!e) {
|
||||
return;
|
||||
}
|
||||
if (max > hdr->inc &&
|
||||
(max - hdr->count) > hdr->inc * 2) {
|
||||
max -= hdr->inc;
|
||||
struct elem **new = realloc(hdr->values, sizeof(*hdr->values) * max);
|
||||
if (new) {
|
||||
hdr->max = max;
|
||||
hdr->values = new;
|
||||
}
|
||||
if (!hdr->stat) {
|
||||
free(e->data);
|
||||
e->data = 0;
|
||||
}
|
||||
free(hdr->values[pos]);
|
||||
|
||||
if (pos < hdr->count) {
|
||||
void *p = &hdr->values[pos];
|
||||
void *n = &hdr->values[pos + 1];
|
||||
void *e = &hdr->values[hdr->count];
|
||||
memmove(p, n, e - n);
|
||||
}
|
||||
hdr->count--;
|
||||
free(e);
|
||||
}
|
||||
|
||||
|
||||
void mem_destroy(struct mphdr *hdr)
|
||||
{
|
||||
for (int i = 0; i < hdr->count && hdr->values; i++) {
|
||||
struct elem *e = hdr->values[i];
|
||||
while (hdr->root) {
|
||||
struct elem *e = kavl_erase_first(my, &hdr->root);
|
||||
if (!e) {
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (!hdr->stat && e->data) {
|
||||
free(e->data);
|
||||
}
|
||||
e->data = 0;
|
||||
free(e);
|
||||
hdr->values[i] = 0;
|
||||
}
|
||||
free(hdr->values);
|
||||
memset(hdr, 0, sizeof(*hdr));
|
||||
free(hdr);
|
||||
}
|
29
mpool.h
29
mpool.h
|
@ -1,19 +1,26 @@
|
|||
#include <stdbool.h>
|
||||
#include <time.h>
|
||||
#include "kavl.h"
|
||||
|
||||
struct elem {
|
||||
int len;
|
||||
char *data;
|
||||
int m;
|
||||
time_t time;
|
||||
int len;
|
||||
char data[];
|
||||
KAVL_HEAD(struct elem) head;
|
||||
};
|
||||
|
||||
struct mphdr {
|
||||
int max;
|
||||
int inc;
|
||||
int count;
|
||||
struct elem **values;
|
||||
bool stat;
|
||||
struct elem *root;
|
||||
};
|
||||
struct mphdr *mem_pool(int count);
|
||||
int mem_index(struct mphdr *hdr, char *str, int len);
|
||||
struct elem *mem_add(struct mphdr *hdr, char *str, int len, int pos);
|
||||
void mem_delete(struct mphdr *hdr, int pos);
|
||||
void mem_destroy(struct mphdr *hdr);
|
||||
|
||||
struct mphdr *mem_pool(bool cst);
|
||||
|
||||
struct elem *mem_get(struct mphdr *hdr, char *str, int len);
|
||||
|
||||
struct elem *mem_add(struct mphdr *hdr, char *str, int len);
|
||||
|
||||
void mem_delete(struct mphdr *hdr, char *str, int len);
|
||||
|
||||
void mem_destroy(struct mphdr *hdr);
|
||||
|
|
5
params.h
5
params.h
|
@ -56,6 +56,10 @@ struct desync_params {
|
|||
int tlsrec_n;
|
||||
struct part *tlsrec;
|
||||
int detect;
|
||||
struct mphdr *hosts;
|
||||
|
||||
char to_ip;
|
||||
struct sockaddr_in6 addr;
|
||||
};
|
||||
|
||||
struct params {
|
||||
|
@ -67,6 +71,7 @@ struct params {
|
|||
int def_ttl;
|
||||
char custom_ttl;
|
||||
|
||||
char late_conn;
|
||||
char tfo;
|
||||
unsigned int timeout;
|
||||
long cache_ttl;
|
||||
|
|
147
proxy.c
147
proxy.c
|
@ -497,34 +497,26 @@ static inline int on_tunnel(struct poolhd *pool, struct eval *val,
|
|||
int mode_add_get(struct sockaddr_ina *dst, int m)
|
||||
{
|
||||
// m < 0: get, m > 0: set, m == 0: delete
|
||||
int len;
|
||||
time_t t;
|
||||
struct elem *val;
|
||||
|
||||
struct {
|
||||
uint16_t port;
|
||||
union {
|
||||
struct in_addr ip4;
|
||||
struct in6_addr ip6;
|
||||
};
|
||||
} str = { .port = dst->in.sin_port };
|
||||
char *str = (char *)&dst->in;
|
||||
int len = sizeof(dst->sa.sa_family);
|
||||
|
||||
if (dst->sa.sa_family == AF_INET) {
|
||||
str.ip4 = dst->in.sin_addr;
|
||||
len = sizeof(str.port) + sizeof(str.ip4);
|
||||
len = sizeof(dst->in);
|
||||
}
|
||||
else {
|
||||
str.ip6 = dst->in6.sin6_addr;
|
||||
len = sizeof(str);
|
||||
len = sizeof(dst->in6) - sizeof(dst->in6.sin6_scope_id);
|
||||
}
|
||||
int i = mem_index(params.mempool, (char *)&str, len);
|
||||
if (m == 0 && i >= 0) {
|
||||
mem_delete(params.mempool, i);
|
||||
len -= sizeof(dst->sa.sa_family);
|
||||
|
||||
if (m == 0) {
|
||||
mem_delete(params.mempool, str, len);
|
||||
return 0;
|
||||
}
|
||||
else if (m > 0) {
|
||||
time(&t);
|
||||
val = mem_add(params.mempool, (char *)&str, len, i);
|
||||
val = mem_add(params.mempool, str, len);
|
||||
if (!val) {
|
||||
uniperror("mem_add");
|
||||
return -1;
|
||||
|
@ -533,10 +525,10 @@ int mode_add_get(struct sockaddr_ina *dst, int m)
|
|||
val->time = t;
|
||||
return 0;
|
||||
}
|
||||
if (i < 0) {
|
||||
val = mem_get(params.mempool, str, len);
|
||||
if (!val) {
|
||||
return -1;
|
||||
}
|
||||
val = params.mempool->values[i];
|
||||
time(&t);
|
||||
if (t > val->time + params.cache_ttl) {
|
||||
LOG(LOG_S, "time=%ld, now=%ld, ignore\n", val->time, t);
|
||||
|
@ -546,6 +538,19 @@ int mode_add_get(struct sockaddr_ina *dst, int m)
|
|||
}
|
||||
|
||||
|
||||
int ext_connect(struct poolhd *pool, struct eval *val,
|
||||
struct sockaddr_ina *dst, int next, int m)
|
||||
{
|
||||
struct desync_params *dp = ¶ms.dp[m];
|
||||
if (dp->to_ip == 2) {
|
||||
struct sockaddr_ina addr = { .in6 = dp->addr };
|
||||
addr.in.sin_port = dst->in.sin_port;
|
||||
return create_conn(pool, val, &addr, next);
|
||||
}
|
||||
return create_conn(pool, val, dst, next);
|
||||
}
|
||||
|
||||
|
||||
static inline int on_request(struct poolhd *pool, struct eval *val,
|
||||
char *buffer, size_t bfsize)
|
||||
{
|
||||
|
@ -584,18 +589,26 @@ static inline int on_request(struct poolhd *pool, struct eval *val,
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
error = create_conn(pool, val, &dst, EV_CONNECT);
|
||||
if (params.late_conn) {
|
||||
val->type = EV_DESYNC;
|
||||
if (resp_error(val->fd, 0, val->flag) < 0) {
|
||||
perror("send");
|
||||
return -1;
|
||||
}
|
||||
val->in6 = dst.in6;
|
||||
return 0;
|
||||
}
|
||||
int m = mode_add_get(&dst, -1);
|
||||
val->cache = (m == 0);
|
||||
val->attempt = m < 0 ? 0 : m;
|
||||
|
||||
error = ext_connect(pool, val, &dst, EV_CONNECT, m);
|
||||
if (error) {
|
||||
int en = get_e();
|
||||
if (resp_error(val->fd, en ? en : error, val->flag) < 0)
|
||||
uniperror("send");
|
||||
return -1;
|
||||
}
|
||||
int m = mode_add_get(&dst, -1);
|
||||
if (m >= 0) {
|
||||
val->attempt = m;
|
||||
}
|
||||
val->pair->attempt = m;
|
||||
val->type = EV_IGNORE;
|
||||
return 0;
|
||||
}
|
||||
|
@ -605,8 +618,8 @@ int reconnect(struct poolhd *pool, struct eval *val, int m)
|
|||
{
|
||||
struct eval *client = val->pair;
|
||||
|
||||
if (create_conn(pool, client,
|
||||
(struct sockaddr_ina *)&val->in6, EV_DESYNC)) {
|
||||
if (ext_connect(pool, client,
|
||||
(struct sockaddr_ina *)&val->in6, EV_DESYNC, m)) {
|
||||
return -1;
|
||||
}
|
||||
val->pair = 0;
|
||||
|
@ -614,19 +627,34 @@ int reconnect(struct poolhd *pool, struct eval *val, int m)
|
|||
|
||||
client->type = EV_IGNORE;
|
||||
client->attempt = m;
|
||||
client->cache = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool check_host(struct mphdr *hosts, struct eval *val)
|
||||
{
|
||||
char *host;
|
||||
int len;
|
||||
if (!(len = parse_tls(val->buff.data, val->buff.size, &host))) {
|
||||
len = parse_http(val->buff.data, val->buff.size, &host, 0);
|
||||
}
|
||||
return mem_get(hosts, host, len) != 0;
|
||||
}
|
||||
|
||||
|
||||
int on_torst(struct poolhd *pool, struct eval *val)
|
||||
{
|
||||
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))
|
||||
struct desync_params *dp = ¶ms.dp[m];
|
||||
if (!(dp->detect & DETECT_TORST)) {
|
||||
continue;
|
||||
}
|
||||
if (!dp->hosts || check_host(dp->hosts, val->pair)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m >= params.dp_count) {
|
||||
mode_add_get(
|
||||
|
@ -646,25 +674,34 @@ int on_response(struct poolhd *pool, struct eval *val,
|
|||
ssize_t qn = val->pair->buff.size;
|
||||
|
||||
for (; m < params.dp_count; m++) {
|
||||
struct desync_params dp = params.dp[m];
|
||||
struct desync_params *dp = ¶ms.dp[m];
|
||||
|
||||
if ((dp.detect & DETECT_HTTP_LOCAT)
|
||||
&& is_http_redirect(req, qn, resp, sn)) {
|
||||
break;
|
||||
}
|
||||
if ((dp.detect & DETECT_TLS_INVSID)
|
||||
&& neq_tls_sid(req, qn, resp, sn)) {
|
||||
break;
|
||||
}
|
||||
if ((dp.detect & DETECT_TLS_ALERT)
|
||||
&& is_tls_alert(resp, sn)) {
|
||||
break;
|
||||
}
|
||||
if (dp.detect & DETECT_HTTP_CLERR) {
|
||||
int code = get_http_code(resp, sn);
|
||||
if (code > 400 && code < 451 && code != 429) {
|
||||
switch (0) {
|
||||
default:
|
||||
if ((dp->detect & DETECT_HTTP_LOCAT)
|
||||
&& is_http_redirect(req, qn, resp, sn)) {
|
||||
break;
|
||||
}
|
||||
else if ((dp->detect & DETECT_TLS_INVSID)
|
||||
&& neq_tls_sid(req, qn, resp, sn)
|
||||
&& !neq_tls_sid(
|
||||
fake_tls.data, fake_tls.size, resp, sn)) {
|
||||
break;
|
||||
}
|
||||
else if ((dp->detect & DETECT_TLS_ALERT)
|
||||
&& is_tls_alert(resp, sn)) {
|
||||
break;
|
||||
}
|
||||
else if (dp->detect & DETECT_HTTP_CLERR) {
|
||||
int code = get_http_code(resp, sn);
|
||||
if (code > 400 && code < 451 && code != 429) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!dp->hosts || check_host(dp->hosts, val->pair)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m < params.dp_count) {
|
||||
|
@ -715,8 +752,7 @@ int on_tunnel_check(struct poolhd *pool, struct eval *val,
|
|||
}
|
||||
int m = pair->attempt;
|
||||
|
||||
if ((m == 0 && val->attempt < 0)
|
||||
|| (m && m == val->attempt)) {
|
||||
if (!pair->cache) {
|
||||
return 0;
|
||||
}
|
||||
if (m == 0) {
|
||||
|
@ -757,6 +793,21 @@ int on_desync(struct poolhd *pool, struct eval *val,
|
|||
return -1;
|
||||
}
|
||||
memcpy(val->buff.data, buffer, n);
|
||||
|
||||
if (!m) for (; m < params.dp_count; m++) {
|
||||
struct desync_params *dp = ¶ms.dp[m];
|
||||
if (!dp->detect &&
|
||||
(!dp->hosts || check_host(dp->hosts, val))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m >= params.dp_count) return -1;
|
||||
val->attempt = m;
|
||||
|
||||
if (params.late_conn) {
|
||||
return ext_connect(pool, val,
|
||||
(struct sockaddr_ina *)&val->in6, EV_DESYNC, m);
|
||||
}
|
||||
}
|
||||
else {
|
||||
n = val->buff.size;
|
||||
|
|
17
readme.txt
17
readme.txt
|
@ -40,7 +40,11 @@ $ ./ciadpi --disorder 3 -A --tlsrec 1+s
|
|||
Если сервер его поддерживает, то первый пакет будет отправлен сразу вместе с SYN
|
||||
Поддерживается только в Linux (4.11+)
|
||||
|
||||
-A, --auto[=t,r,c,s,a]
|
||||
-L, --late-conn
|
||||
Выполнять настоящее подключение только после получения первого пакета от клиента
|
||||
Полезно при сочетании --hosts с --dst
|
||||
|
||||
-A, --auto[=t,r,c,s,a,n]
|
||||
Автоматический режим
|
||||
Если произошло событие, похожее на блокировку или поломку,
|
||||
то будут применены параметры обхода, следующие за данной опцией
|
||||
|
@ -50,11 +54,12 @@ $ ./ciadpi --disorder 3 -A --tlsrec 1+s
|
|||
cl_err : HTTP ответ, код которого равен 40x, но не 429
|
||||
sid_inv : session_id в TLS ServerHello и ClientHello не совпадают
|
||||
alert : TLS Error Alert в ответе
|
||||
nop : Предыдущая группа пропущена, например из-за ограничения по hosts
|
||||
По умолчанию обрабатывается только torst
|
||||
Можно указывать несколько групп опций, раделяя их данным параметром
|
||||
Если соединение успешно прошло, то параметры для данного IP будут закешированны
|
||||
Параметры, которые можно вынести в отдельную группу:
|
||||
split, disorder, oob, fake, ttl, ip-opt, md5sig, mod-http, tlsrec
|
||||
hosts, dst, 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
|
||||
|
||||
|
@ -66,6 +71,14 @@ $ ./ciadpi --disorder 3 -A --tlsrec 1+s
|
|||
В Linux переводится в миллисекунды, поэтому можно указать дробное число
|
||||
Истечение таймаута будет обработано --auto
|
||||
|
||||
-H, --hosts <file|:string>
|
||||
Ограничить область действия параметров списком доменов
|
||||
Домены должны быть разделены новой строкой или пробелом
|
||||
|
||||
-D, --dst <ip>
|
||||
Заменить адрес назначения из запроса на указанный
|
||||
Полезно совмещать с --auto и --hosts
|
||||
|
||||
-s, --split <n[+s]>
|
||||
Разбить запрос по указанному смещению
|
||||
После числа можно добавить флаг:
|
||||
|
|
Loading…
Add table
Reference in a new issue