Cache ttl, handle client rst

This commit is contained in:
ruti 2024-03-08 21:33:25 +03:00
parent 0b4d6d72cc
commit 69286c71db
8 changed files with 142 additions and 38 deletions

View File

@ -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

View File

@ -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
View File

@ -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
View File

@ -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--;
}

View File

@ -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);

View File

@ -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
View File

@ -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:

View File

@ -40,7 +40,10 @@ $ ./ciadpi --disorder 3 -A --tlsrec 1+s
Если обнаружены признаки блокировки (соединение разорвано сразу после первого пакета),
то будут применены параметры обхода, следующие за данной опцией
Можно указывать несколько групп параметров, раделяя их данным флагом
Если соединение успешно прошло, то параметры будут сохранены для данного IP до следующего перезапуска
Если соединение успешно прошло, то параметры для данного IP будут закешированны
-u, --cache-ttl <sec>
Время жизни значения в кеше, указывается в секундах
-s, --split <n[+s]>
Разбить запрос по указанному смещению