mirror of
https://github.com/hufrea/byedpi.git
synced 2024-12-22 14:25:44 +00:00
Cache ttl, handle client rst
This commit is contained in:
parent
0b4d6d72cc
commit
69286c71db
3
conev.h
3
conev.h
@ -34,6 +34,7 @@ enum eid {
|
||||
EV_CONNECT,
|
||||
EV_IGNORE,
|
||||
EV_TUNNEL,
|
||||
EV_PRE_TUNNEL,
|
||||
EV_DESYNC
|
||||
};
|
||||
|
||||
@ -48,6 +49,7 @@ char *eid_name[] = {
|
||||
"EV_CONNECT",
|
||||
"EV_IGNORE",
|
||||
"EV_TUNNEL",
|
||||
"EV_PRE_TUNNEL",
|
||||
"EV_DESYNC"
|
||||
};
|
||||
#endif
|
||||
@ -71,6 +73,7 @@ struct eval {
|
||||
};
|
||||
ssize_t recv_count;
|
||||
int try_count;
|
||||
int saved_m;
|
||||
#ifndef NOEPOLL
|
||||
uint32_t events;
|
||||
#endif
|
||||
|
2
desync.c
2
desync.c
@ -270,7 +270,7 @@ int desync(int sfd, char *buffer, size_t bfsize,
|
||||
#ifndef _WIN32
|
||||
case DESYNC_FAKE:
|
||||
s = send_fake(sfd,
|
||||
buffer + lp, type, pos - lp, fa, dp.ttl);
|
||||
buffer + lp, type, pos - lp, fa, dp.ttl ? dp.ttl : 8);
|
||||
break;
|
||||
#endif
|
||||
case DESYNC_DISORDER:
|
||||
|
11
main.c
11
main.c
@ -46,6 +46,7 @@ struct params params = {
|
||||
.custom_ttl = 0,
|
||||
.de_known = 0,
|
||||
|
||||
.cache_ttl = 3600,
|
||||
.ipv6 = 1,
|
||||
.resolve = 1,
|
||||
.max_open = 512,
|
||||
@ -69,6 +70,7 @@ const char help_text[] = {
|
||||
// desync options
|
||||
" -K, --desync-known Desync only HTTP and TLS with SNI\n"
|
||||
" -A, --auto Try desync params after this option\n"
|
||||
" -u, --cache-ttl <sec> Lifetime of cached desync params for IP\n"
|
||||
" -s, --split <n[+s]> Split packet at n\n"
|
||||
" +s - add SNI offset\n"
|
||||
" +h - add HTTP Host offset\n"
|
||||
@ -101,6 +103,7 @@ const struct option options[] = {
|
||||
|
||||
{"desync-known ", 0, 0, 'K'},
|
||||
{"auto", 0, 0, 'A'},
|
||||
{"cache-ttl", 1, 0, 'u'},
|
||||
{"split", 1, 0, 's'},
|
||||
{"disorder", 1, 0, 'd'},
|
||||
{"oob", 1, 0, 'o'},
|
||||
@ -360,6 +363,14 @@ int main(int argc, char **argv)
|
||||
}
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
val = strtol(optarg, &end, 0);
|
||||
if (val <= 0 || *end)
|
||||
invalid = 1;
|
||||
else
|
||||
params.cache_ttl = val;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
case 'd':
|
||||
case 'o':
|
||||
|
30
mpool.c
30
mpool.c
@ -50,7 +50,7 @@ int mem_index(struct mphdr *hdr, char *str, int len)
|
||||
}
|
||||
|
||||
|
||||
struct elem *mem_add(struct mphdr *hdr, char *str, int len)
|
||||
struct elem *mem_add(struct mphdr *hdr, char *str, int len, int pos)
|
||||
{
|
||||
int max = hdr->max;
|
||||
|
||||
@ -63,7 +63,6 @@ struct elem *mem_add(struct mphdr *hdr, char *str, int len)
|
||||
hdr->max = max;
|
||||
hdr->values = new;
|
||||
}
|
||||
int pos = mem_index(hdr, str, len);
|
||||
if (pos >= 0) {
|
||||
return hdr->values[pos];
|
||||
}
|
||||
@ -87,3 +86,30 @@ struct elem *mem_add(struct mphdr *hdr, char *str, int len)
|
||||
hdr->count++;
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
void mem_delete(struct mphdr *hdr, int pos)
|
||||
{
|
||||
int max = hdr->max;
|
||||
if (!hdr->count) {
|
||||
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;
|
||||
}
|
||||
hdr->max = max;
|
||||
hdr->values = new;
|
||||
}
|
||||
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--;
|
||||
}
|
||||
|
6
mpool.h
6
mpool.h
@ -1,5 +1,8 @@
|
||||
#include <time.h>
|
||||
|
||||
struct elem {
|
||||
int m;
|
||||
time_t time;
|
||||
int len;
|
||||
char data[];
|
||||
};
|
||||
@ -11,4 +14,5 @@ struct mphdr {
|
||||
};
|
||||
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);
|
||||
struct elem *mem_add(struct mphdr *hdr, char *str, int len, int pos);
|
||||
void mem_delete(struct mphdr *hdr, int pos);
|
1
params.h
1
params.h
@ -41,6 +41,7 @@ struct params {
|
||||
int def_ttl;
|
||||
char custom_ttl;
|
||||
|
||||
long cache_ttl;
|
||||
char ipv6;
|
||||
char resolve;
|
||||
int max_open;
|
||||
|
120
proxy.c
120
proxy.c
@ -5,6 +5,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <proxy.h>
|
||||
#include <params.h>
|
||||
@ -509,10 +510,6 @@ static inline int on_tunnel(struct poolhd *pool, struct eval *val,
|
||||
int try_again(struct poolhd *pool, struct eval *val)
|
||||
{
|
||||
struct eval *client = val->pair;
|
||||
if (client->try_count + 1 >= params.dp_count) {
|
||||
return -1;
|
||||
}
|
||||
LOG(LOG_S, "try next params: %d\n", client->try_count + 1);
|
||||
|
||||
int e = create_conn(pool, client,
|
||||
(struct sockaddr_ina *)&val->in6);
|
||||
@ -532,6 +529,9 @@ int mode_add_get(struct sockaddr_ina *dst, int m)
|
||||
{
|
||||
char *data;
|
||||
int len;
|
||||
time_t t;
|
||||
struct elem *val;
|
||||
|
||||
if (dst->sa.sa_family == AF_INET) {
|
||||
data = (char *)(&dst->in.sin_addr);
|
||||
len = sizeof(dst->in.sin_addr);
|
||||
@ -539,68 +539,118 @@ int mode_add_get(struct sockaddr_ina *dst, int m)
|
||||
data = (char *)(&dst->in6.sin6_addr);
|
||||
len = sizeof(dst->in6.sin6_addr);
|
||||
}
|
||||
struct elem *val;
|
||||
if (m >= 0) {
|
||||
val = mem_add(params.mempool, data, len);
|
||||
int i = mem_index(params.mempool, data, len);
|
||||
if (m == 0 && i >= 0) {
|
||||
mem_delete(params.mempool, i);
|
||||
return 0;
|
||||
}
|
||||
else if (m > 0) {
|
||||
time(&t);
|
||||
val = mem_add(params.mempool, data, len, i);
|
||||
if (!val) {
|
||||
uniperror("mem_add");
|
||||
return -1;
|
||||
}
|
||||
val->m = m;
|
||||
val->time = t;
|
||||
return 0;
|
||||
}
|
||||
int i = mem_index(params.mempool, data, len);
|
||||
if (i < 0) {
|
||||
return -1;
|
||||
}
|
||||
val = params.mempool->values[i];
|
||||
time(&t);
|
||||
if (t > val->time + params.cache_ttl) {
|
||||
LOG(LOG_S, "cache value is too old, ignore\n");
|
||||
return -1;
|
||||
}
|
||||
return val->m;
|
||||
}
|
||||
|
||||
|
||||
int on_tunnel_check(struct poolhd *pool, struct eval *val,
|
||||
char *buffer, size_t bfsize, int out)
|
||||
{
|
||||
if (!out && val->flag == FLAG_CONN) {
|
||||
int e = on_tunnel(pool, val, buffer, bfsize, out);
|
||||
if (e) {
|
||||
if (unie(e) != ECONNRESET) {
|
||||
return -1;
|
||||
}
|
||||
if (val->pair->try_count + 1 >= params.dp_count) {
|
||||
mode_add_get(
|
||||
(struct sockaddr_ina *)&val->in6, 0);
|
||||
return -1;
|
||||
}
|
||||
return try_again(pool, val);;
|
||||
}
|
||||
struct eval *pair = val->pair;
|
||||
val->type = EV_TUNNEL;
|
||||
pair->type = EV_TUNNEL;
|
||||
|
||||
free(pair->buff.data);
|
||||
pair->buff.data = 0;
|
||||
pair->buff.size = 0;
|
||||
|
||||
int m = pair->try_count;
|
||||
if (m == 0 && !val->saved_m) {
|
||||
return 0;
|
||||
}
|
||||
return mode_add_get(
|
||||
(struct sockaddr_ina *)&val->in6, m);
|
||||
}
|
||||
else {
|
||||
int e = on_tunnel(pool, val, buffer, bfsize, out);
|
||||
if (e) {
|
||||
if (val->flag == FLAG_CONN) {
|
||||
val = val->pair;
|
||||
}
|
||||
int m = val->try_count + 1;
|
||||
if (m >= params.dp_count) {
|
||||
m = 0;
|
||||
}
|
||||
mode_add_get(
|
||||
(struct sockaddr_ina *)&val->pair->in6, m);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int on_desync(struct poolhd *pool, struct eval *val,
|
||||
char *buffer, size_t bfsize)
|
||||
{
|
||||
ssize_t n;
|
||||
int m;
|
||||
|
||||
if (val->flag == FLAG_CONN) {
|
||||
int e = on_tunnel(pool, val, buffer, bfsize, 0);
|
||||
if (e) {
|
||||
if (unie(e) == ECONNRESET) {
|
||||
return try_again(pool, val);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
free(val->pair->buff.data);
|
||||
val->pair->buff.data = 0;
|
||||
val->pair->buff.size = 0;
|
||||
val->type = EV_TUNNEL;
|
||||
|
||||
m = val->pair->try_count;
|
||||
return mode_add_get(
|
||||
(struct sockaddr_ina *)&val->in6, m);
|
||||
}
|
||||
if (!val->try_count) {
|
||||
m = mode_add_get(
|
||||
(struct sockaddr_ina *)&val->pair->in6, -1);
|
||||
if (m < 0) {
|
||||
m = val->try_count;
|
||||
if (m >= 0) {
|
||||
val->saved_m = m + 1;
|
||||
val->try_count = m;
|
||||
}
|
||||
}
|
||||
m = val->try_count;
|
||||
LOG(LOG_S, "desync params index: %d\n", m);
|
||||
|
||||
if (!val->buff.data) {
|
||||
n = recv(val->fd, buffer, bfsize, 0);
|
||||
if (n <= 0) {
|
||||
if (n) uniperror("recv data");
|
||||
return -1;
|
||||
}
|
||||
val->recv_count += n;
|
||||
val->buff.size = n;
|
||||
val->recv_count += n;
|
||||
|
||||
if (!(val->buff.data = malloc(n))) {
|
||||
uniperror("malloc");
|
||||
return -1;
|
||||
}
|
||||
memcpy(val->buff.data, buffer, n);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
n = val->buff.size;
|
||||
memcpy(buffer, val->buff.data, n);
|
||||
}
|
||||
@ -608,7 +658,8 @@ int on_desync(struct poolhd *pool, struct eval *val,
|
||||
(struct sockaddr *)&val->pair->in6, m)) {
|
||||
return -1;
|
||||
}
|
||||
val->type = EV_TUNNEL;
|
||||
val->type = EV_PRE_TUNNEL;
|
||||
val->pair->type = EV_PRE_TUNNEL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -701,11 +752,16 @@ int event_loop(int srvfd)
|
||||
del_event(pool, val);
|
||||
continue;
|
||||
|
||||
case EV_PRE_TUNNEL:
|
||||
if (on_tunnel_check(pool, val,
|
||||
buffer, bfsize, etype & POLLOUT))
|
||||
del_event(pool, val);
|
||||
continue;
|
||||
|
||||
case EV_TUNNEL:
|
||||
if (on_tunnel(pool, val,
|
||||
buffer, bfsize, etype & POLLOUT)) {
|
||||
buffer, bfsize, etype & POLLOUT))
|
||||
del_event(pool, val);
|
||||
}
|
||||
continue;
|
||||
|
||||
case EV_CONNECT:
|
||||
|
@ -40,7 +40,10 @@ $ ./ciadpi --disorder 3 -A --tlsrec 1+s
|
||||
Если обнаружены признаки блокировки (соединение разорвано сразу после первого пакета),
|
||||
то будут применены параметры обхода, следующие за данной опцией
|
||||
Можно указывать несколько групп параметров, раделяя их данным флагом
|
||||
Если соединение успешно прошло, то параметры будут сохранены для данного IP до следующего перезапуска
|
||||
Если соединение успешно прошло, то параметры для данного IP будут закешированны
|
||||
|
||||
-u, --cache-ttl <sec>
|
||||
Время жизни значения в кеше, указывается в секундах
|
||||
|
||||
-s, --split <n[+s]>
|
||||
Разбить запрос по указанному смещению
|
||||
|
Loading…
Reference in New Issue
Block a user