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_CONNECT,
EV_IGNORE, EV_IGNORE,
EV_TUNNEL, EV_TUNNEL,
EV_PRE_TUNNEL,
EV_DESYNC EV_DESYNC
}; };
@ -48,6 +49,7 @@ char *eid_name[] = {
"EV_CONNECT", "EV_CONNECT",
"EV_IGNORE", "EV_IGNORE",
"EV_TUNNEL", "EV_TUNNEL",
"EV_PRE_TUNNEL",
"EV_DESYNC" "EV_DESYNC"
}; };
#endif #endif
@ -71,6 +73,7 @@ struct eval {
}; };
ssize_t recv_count; ssize_t recv_count;
int try_count; int try_count;
int saved_m;
#ifndef NOEPOLL #ifndef NOEPOLL
uint32_t events; uint32_t events;
#endif #endif

View File

@ -270,7 +270,7 @@ int desync(int sfd, char *buffer, size_t bfsize,
#ifndef _WIN32 #ifndef _WIN32
case DESYNC_FAKE: case DESYNC_FAKE:
s = send_fake(sfd, s = send_fake(sfd,
buffer + lp, type, pos - lp, fa, dp.ttl); buffer + lp, type, pos - lp, fa, dp.ttl ? dp.ttl : 8);
break; break;
#endif #endif
case DESYNC_DISORDER: case DESYNC_DISORDER:

11
main.c
View File

@ -46,6 +46,7 @@ struct params params = {
.custom_ttl = 0, .custom_ttl = 0,
.de_known = 0, .de_known = 0,
.cache_ttl = 3600,
.ipv6 = 1, .ipv6 = 1,
.resolve = 1, .resolve = 1,
.max_open = 512, .max_open = 512,
@ -69,6 +70,7 @@ const char help_text[] = {
// desync options // desync options
" -K, --desync-known Desync only HTTP and TLS with SNI\n" " -K, --desync-known Desync only HTTP and TLS with SNI\n"
" -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"
" -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"
@ -101,6 +103,7 @@ const struct option options[] = {
{"desync-known ", 0, 0, 'K'}, {"desync-known ", 0, 0, 'K'},
{"auto", 0, 0, 'A'}, {"auto", 0, 0, 'A'},
{"cache-ttl", 1, 0, 'u'},
{"split", 1, 0, 's'}, {"split", 1, 0, 's'},
{"disorder", 1, 0, 'd'}, {"disorder", 1, 0, 'd'},
{"oob", 1, 0, 'o'}, {"oob", 1, 0, 'o'},
@ -360,6 +363,14 @@ int main(int argc, char **argv)
} }
break; break;
case 'u':
val = strtol(optarg, &end, 0);
if (val <= 0 || *end)
invalid = 1;
else
params.cache_ttl = val;
break;
case 's': case 's':
case 'd': case 'd':
case 'o': 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; int max = hdr->max;
@ -63,7 +63,6 @@ struct elem *mem_add(struct mphdr *hdr, char *str, int len)
hdr->max = max; hdr->max = max;
hdr->values = new; hdr->values = new;
} }
int pos = mem_index(hdr, str, len);
if (pos >= 0) { if (pos >= 0) {
return hdr->values[pos]; return hdr->values[pos];
} }
@ -87,3 +86,30 @@ struct elem *mem_add(struct mphdr *hdr, char *str, int len)
hdr->count++; hdr->count++;
return val; 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 { struct elem {
int m; int m;
time_t time;
int len; int len;
char data[]; char data[];
}; };
@ -11,4 +14,5 @@ struct mphdr {
}; };
struct mphdr *mem_pool(int count); struct mphdr *mem_pool(int count);
int mem_index(struct mphdr *hdr, char *str, int len); 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; int def_ttl;
char custom_ttl; char custom_ttl;
long cache_ttl;
char ipv6; char ipv6;
char resolve; char resolve;
int max_open; int max_open;

122
proxy.c
View File

@ -5,6 +5,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
#include <time.h>
#include <proxy.h> #include <proxy.h>
#include <params.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) int try_again(struct poolhd *pool, struct eval *val)
{ {
struct eval *client = val->pair; 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, int e = create_conn(pool, client,
(struct sockaddr_ina *)&val->in6); (struct sockaddr_ina *)&val->in6);
@ -532,6 +529,9 @@ int mode_add_get(struct sockaddr_ina *dst, int m)
{ {
char *data; char *data;
int len; int len;
time_t t;
struct elem *val;
if (dst->sa.sa_family == AF_INET) { if (dst->sa.sa_family == AF_INET) {
data = (char *)(&dst->in.sin_addr); data = (char *)(&dst->in.sin_addr);
len = sizeof(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); data = (char *)(&dst->in6.sin6_addr);
len = sizeof(dst->in6.sin6_addr); len = sizeof(dst->in6.sin6_addr);
} }
struct elem *val; int i = mem_index(params.mempool, data, len);
if (m >= 0) { if (m == 0 && i >= 0) {
val = mem_add(params.mempool, data, len); mem_delete(params.mempool, i);
return 0;
}
else if (m > 0) {
time(&t);
val = mem_add(params.mempool, data, len, i);
if (!val) { if (!val) {
uniperror("mem_add"); uniperror("mem_add");
return -1; return -1;
} }
val->m = m; val->m = m;
val->time = t;
return 0; return 0;
} }
int i = mem_index(params.mempool, data, len);
if (i < 0) { if (i < 0) {
return -1; return -1;
} }
val = params.mempool->values[i]; 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; 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, int on_desync(struct poolhd *pool, struct eval *val,
char *buffer, size_t bfsize) char *buffer, size_t bfsize)
{ {
ssize_t n; ssize_t n;
int m; int m;
if (val->flag == FLAG_CONN) { if (!val->try_count) {
int e = on_tunnel(pool, val, buffer, bfsize, 0); m = mode_add_get(
if (e) { (struct sockaddr_ina *)&val->pair->in6, -1);
if (unie(e) == ECONNRESET) { if (m >= 0) {
return try_again(pool, val); val->saved_m = m + 1;
} val->try_count = m;
return -1;
} }
free(val->pair->buff.data); }
val->pair->buff.data = 0; m = val->try_count;
val->pair->buff.size = 0; LOG(LOG_S, "desync params index: %d\n", m);
val->type = EV_TUNNEL;
m = val->pair->try_count;
return mode_add_get(
(struct sockaddr_ina *)&val->in6, m);
}
m = mode_add_get(
(struct sockaddr_ina *)&val->pair->in6, -1);
if (m < 0) {
m = val->try_count;
}
if (!val->buff.data) { if (!val->buff.data) {
n = recv(val->fd, buffer, bfsize, 0); n = recv(val->fd, buffer, bfsize, 0);
if (n <= 0) { if (n <= 0) {
if (n) uniperror("recv data"); if (n) uniperror("recv data");
return -1; return -1;
} }
val->recv_count += n;
val->buff.size = n; val->buff.size = n;
val->recv_count += n;
if (!(val->buff.data = malloc(n))) { if (!(val->buff.data = malloc(n))) {
uniperror("malloc"); uniperror("malloc");
return -1; return -1;
} }
memcpy(val->buff.data, buffer, n); memcpy(val->buff.data, buffer, n);
} else { }
else {
n = val->buff.size; n = val->buff.size;
memcpy(buffer, val->buff.data, n); 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)) { (struct sockaddr *)&val->pair->in6, m)) {
return -1; return -1;
} }
val->type = EV_TUNNEL; val->type = EV_PRE_TUNNEL;
val->pair->type = EV_PRE_TUNNEL;
return 0; return 0;
} }
@ -701,11 +752,16 @@ int event_loop(int srvfd)
del_event(pool, val); del_event(pool, val);
continue; continue;
case EV_PRE_TUNNEL:
if (on_tunnel_check(pool, val,
buffer, bfsize, etype & POLLOUT))
del_event(pool, val);
continue;
case EV_TUNNEL: case EV_TUNNEL:
if (on_tunnel(pool, val, if (on_tunnel(pool, val,
buffer, bfsize, etype & POLLOUT)) { buffer, bfsize, etype & POLLOUT))
del_event(pool, val); del_event(pool, val);
}
continue; continue;
case EV_CONNECT: 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]> -s, --split <n[+s]>
Разбить запрос по указанному смещению Разбить запрос по указанному смещению