0
0
mirror of https://github.com/hufrea/byedpi.git synced 2025-06-29 18:21:14 +00:00

Use linked list for groups, fix cache

This commit is contained in:
ruti 2025-06-06 14:03:14 +03:00
parent 624248789c
commit 676817c068
7 changed files with 162 additions and 149 deletions

10
conev.h
View File

@ -4,6 +4,7 @@
#include <stdint.h>
#include <stdbool.h>
#include "params.h"
#ifndef __linux__
#define NOEPOLL
@ -48,12 +49,6 @@ struct poolhd;
struct eval;
typedef int (*evcb_t)(struct poolhd *, struct eval *, int);
union sockaddr_u {
struct sockaddr sa;
struct sockaddr_in in;
struct sockaddr_in6 in6;
};
#define FLAG_S4 1
#define FLAG_S5 2
#define FLAG_CONN 4
@ -85,8 +80,7 @@ struct eval {
ssize_t round_sent;
unsigned int round_count;
int attempt;
bool cache;
struct desync_params *dp;
bool mark; //
bool restore_ttl;

View File

@ -25,9 +25,7 @@
#include <ws2tcpip.h>
#include <mswsock.h>
#endif
#define STR_MODE
#include "params.h"
#include "packets.h"
#include "error.h"
@ -512,7 +510,7 @@ static void tamp(char *buffer, size_t bfsize, ssize_t *n,
ssize_t desync(struct poolhd *pool,
struct eval *val, struct buffer *buff, ssize_t *np, bool *wait)
{
struct desync_params dp = params.dp[val->pair->attempt];
struct desync_params dp = *val->pair->dp;
struct proto_info info = { 0 };
int sfd = val->fd;
@ -665,10 +663,8 @@ ssize_t desync(struct poolhd *pool,
}
int pre_desync(int sfd, int dp_c)
int pre_desync(int sfd, struct desync_params *dp)
{
struct desync_params *dp = &params.dp[dp_c];
#ifdef __linux__
if (dp->drop_sack && drop_sack(sfd)) {
return -1;
@ -677,14 +673,13 @@ int pre_desync(int sfd, int dp_c)
return 0;
}
int post_desync(int sfd, int dp_c)
int post_desync(int sfd, struct desync_params *dp)
{
struct desync_params *dp = &params.dp[dp_c];
#ifdef __linux__
int nop = 0;
if (dp->drop_sack) {
if (setsockopt(sfd, SOL_SOCKET,
SO_DETACH_FILTER, &dp_c, sizeof(dp_c)) == -1) {
SO_DETACH_FILTER, &nop, sizeof(nop)) == -1) {
uniperror("setsockopt SO_DETACH_FILTER");
return -1;
}
@ -695,10 +690,8 @@ int post_desync(int sfd, int dp_c)
ssize_t desync_udp(int sfd, char *buffer,
ssize_t n, const struct sockaddr *dst, int dp_c)
ssize_t n, const struct sockaddr *dst, struct desync_params *dp)
{
struct desync_params *dp = &params.dp[dp_c];
if (LOG_ENABLED) {
INIT_HEX_STR(buffer, (n > 16 ? 16 : n));
LOG(LOG_S, "bytes: %s (%zd)\n", HEX_STR, n);

View File

@ -1,10 +1,13 @@
#ifndef DESYNC_H
#define DESYNC_H
#define STR_MODE
#include <stdint.h>
#include <stddef.h>
#include "conev.h"
#include "params.h"
#ifdef _WIN32
#include <winsock2.h>
@ -14,13 +17,13 @@
ssize_t desync(struct poolhd *pool, struct eval *val, struct buffer *buff, ssize_t *n, bool *wait);
ssize_t desync_udp(int sfd, char *buffer, ssize_t n, const struct sockaddr *dst, int dp_c);
ssize_t desync_udp(int sfd, char *buffer, ssize_t n, const struct sockaddr *dst, struct desync_params *dp);
int setttl(int fd, int ttl);
int pre_desync(int sfd, int dp_c);
int pre_desync(int sfd, struct desync_params *dp);
int post_desync(int sfd, int dp_c);
int post_desync(int sfd, struct desync_params *dp);
struct proto_info {
char init, type;

151
extend.c
View File

@ -72,43 +72,48 @@ static ssize_t serialize_addr(const union sockaddr_u *dst,
}
static int cache_get(const union sockaddr_u *dst)
static void cache_del(const union sockaddr_u *dst)
{
uint8_t key[KEY_SIZE] = { 0 };
int len = serialize_addr(dst, key, sizeof(key));
INIT_ADDR_STR((*dst));
LOG(LOG_S, "delete ip: %s\n", ADDR_STR);
mem_delete(params.mempool, (char *)key, len);
}
static struct elem_i *cache_get(const union sockaddr_u *dst)
{
uint8_t key[KEY_SIZE] = { 0 };
int len = serialize_addr(dst, key, sizeof(key));
struct elem_i *val = (struct elem_i *)mem_get(params.mempool, (char *)key, len);
if (!val) {
return -1;
return 0;
}
time_t t = time(0);
if (t > val->time + params.cache_ttl) {
LOG(LOG_S, "time=%jd, now=%jd, ignore\n", (intmax_t)val->time, (intmax_t)t);
mem_delete(params.mempool, (char *)key, len);
return 0;
}
return val->m;
return val;
}
static int cache_add(const union sockaddr_u *dst, int m)
static struct elem_i *cache_add(const union sockaddr_u *dst)
{
assert(m >= 0 && m < params.dp_count);
uint8_t key[KEY_SIZE] = { 0 };
int len = serialize_addr(dst, key, sizeof(key));
INIT_ADDR_STR((*dst));
if (m == 0) {
LOG(LOG_S, "delete ip: %s\n", ADDR_STR);
mem_delete(params.mempool, (char *)key, len);
return 0;
}
LOG(LOG_S, "save ip: %s, m=%d\n", ADDR_STR, m);
LOG(LOG_S, "save ip: %s\n", ADDR_STR);
time_t t = time(0);
char *key_d = malloc(len);
if (!key_d) {
return -1;
return 0;
}
memcpy(key_d, key, len);
@ -116,38 +121,33 @@ static int cache_add(const union sockaddr_u *dst, int m)
if (!val) {
uniperror("mem_add");
free(key_d);
return -1;
}
val->m = m;
val->time = t;
return 0;
}
val->time = t;
return val;
}
int connect_hook(struct poolhd *pool, struct eval *val,
const union sockaddr_u *dst, evcb_t next)
{
int m = val->attempt;
if (!m) {
m = cache_get(dst);
val->cache = (m == 0);
struct desync_params *dp = val->dp, *init_dp;
if (!dp) {
struct elem_i *e = cache_get(dst);
dp = e ? e->dp : params.dp;
}
int init_m = m;
init_dp = dp;
m = m < 0 ? 0 : m;
struct desync_params *dp;
for (; ; m++) {
if (m == params.dp_count) {
for (; ; dp = dp->next) {
if (!dp) {
return -1;
}
dp = &params.dp[m];
if ((!dp->detect || m == init_m)
if ((!dp->detect || dp == init_dp)
&& check_l34(dp, SOCK_STREAM, dst)) {
break;
}
}
val->attempt = m;
val->dp = dp;
if (dp->custom_dst) {
union sockaddr_u addr = dp->custom_dst_addr;
@ -173,12 +173,12 @@ int socket_mod(int fd)
}
static int reconnect(struct poolhd *pool, struct eval *val, int m)
static int reconnect(struct poolhd *pool, struct eval *val, struct desync_params *dp)
{
assert(val->flag == FLAG_CONN);
struct eval *client = val->pair;
client->attempt = m;
client->dp = dp;
if (connect_hook(pool, client, &val->addr, &on_tunnel)) {
return -1;
@ -187,7 +187,6 @@ static int reconnect(struct poolhd *pool, struct eval *val, int m)
del_event(pool, val);
client->cb = &on_tunnel;
client->cache = 1;
if (!client->buff) {
client->buff = buff_pop(pool, client->sq_buff->size);
@ -288,33 +287,34 @@ static bool check_round(const int *nr, int r)
static int on_trigger(int type, struct poolhd *pool, struct eval *val)
{
int m = val->pair->attempt + 1;
struct desync_params *dp = val->pair->dp->next;
struct buffer *pair_buff = val->pair->sq_buff;
bool can_reconn = (
pair_buff && pair_buff->lock && !val->recv_count
pair_buff && pair_buff->lock
&& !val->recv_count
&& params.auto_level > AUTO_NOBUFF
);
if (!can_reconn && params.auto_level <= AUTO_NOSAVE) {
return -1;
}
for (; m < params.dp_count; m++) {
struct desync_params *dp = &params.dp[m];
for (; dp; dp = dp->next) {
if (!dp->detect) {
break;
}
if (!(dp->detect & type)) {
continue;
}
struct elem_i *e = cache_add(&val->addr);
if (e) {
e->dp = dp;
}
if (can_reconn) {
return reconnect(pool, val, m);
return reconnect(pool, val, dp);
}
cache_add(&val->addr, m);
break;
}
if (m >= params.dp_count && m > 1) {
cache_add(&val->addr, 0);
return -1;
}
cache_del(&val->addr);
return -1;
}
@ -348,13 +348,12 @@ static int on_fin(struct poolhd *pool, struct eval *val)
static int on_response(struct poolhd *pool, struct eval *val,
const char *resp, ssize_t sn)
{
int m = val->pair->attempt + 1;
struct desync_params *dp = val->pair->dp->next;
char *req = val->pair->sq_buff->data;
ssize_t qn = val->pair->sq_buff->size;
for (; m < params.dp_count; m++) {
struct desync_params *dp = &params.dp[m];
for (; dp; dp = dp->next) {
if (!dp->detect) {
return -1;
}
@ -368,8 +367,8 @@ static int on_response(struct poolhd *pool, struct eval *val,
break;
}
}
if (m < params.dp_count) {
return reconnect(pool, val, m);
if (dp) {
return reconnect(pool, val, dp);
}
return -1;
}
@ -384,31 +383,30 @@ static inline void free_first_req(struct poolhd *pool, struct eval *client)
static int setup_conn(struct eval *client, const char *buffer, ssize_t n)
{
int m = client->attempt, init_m = m;
struct desync_params *dp = client->dp, *init_dp = dp;
for (; m < params.dp_count; m++) {
struct desync_params *dp = &params.dp[m];
if ((!dp->detect || m == init_m)
&& (m == init_m || check_l34(dp, SOCK_STREAM, &client->pair->addr))
for (; dp; dp = dp->next) {
if ((!dp->detect || dp == init_dp)
&& (dp == init_dp || check_l34(dp, SOCK_STREAM, &client->pair->addr))
&& check_proto_tcp(dp->proto, buffer, n)
&& (!dp->hosts || check_host(dp->hosts, buffer, n))) {
break;
}
}
if (m >= params.dp_count) {
LOG(LOG_E, "drop connection (m=%d)\n", m);
if (!dp) {
LOG(LOG_E, "drop connection\n");
return -1;
}
if (params.auto_level > AUTO_NOBUFF && params.dp_count > 1) {
if (params.auto_level > AUTO_NOBUFF && params.dp->next) {
client->mark = is_tls_chello(buffer, n);
}
client->attempt = m;
client->dp = dp;
if (params.timeout
&& set_timeout(client->pair->fd, params.timeout)) {
return -1;
}
if (pre_desync(client->pair->fd, client->attempt)) {
if (pre_desync(client->pair->fd, client->dp)) {
return -1;
}
return 0;
@ -421,7 +419,7 @@ static int cancel_setup(struct eval *remote)
set_timeout(remote->fd, 0)) {
return -1;
}
if (post_desync(remote->fd, remote->pair->attempt)) {
if (post_desync(remote->fd, remote->pair->dp)) {
return -1;
}
return 0;
@ -442,12 +440,12 @@ ssize_t tcp_send_hook(struct poolhd *pool,
&& setup_conn(client, buff->data, *n) < 0) {
return -1;
}
int m = client->attempt, r = client->round_count;
if (!check_round(params.dp[m].rounds, r)) {
int r = client->round_count;
if (!check_round(client->dp->rounds, r)) {
skip = 1;
}
else {
LOG(LOG_S, "desync TCP: group=%d, round=%d, fd=%d\n", m, r, remote->fd);
LOG(LOG_S, "desync TCP: group=%d, round=%d, fd=%d\n", client->dp->id, r, remote->fd);
sn = desync(pool, remote, buff, n, wait);
}
}
@ -496,7 +494,7 @@ ssize_t tcp_recv_hook(struct poolhd *pool,
val->pair->part_sent = 0;
}
if (val->flag == FLAG_CONN && !val->round_sent) {
int *nr = params.dp[val->pair->attempt].rounds;
int *nr = val->pair->dp->rounds;
if (check_round(nr, val->round_count)
&& !check_round(nr, val->round_count + 1)
@ -529,11 +527,6 @@ ssize_t tcp_recv_hook(struct poolhd *pool,
return 0;
}
free_first_req(pool, val->pair);
int m = val->pair->attempt;
if (val->pair->cache && cache_add(&val->addr, m) < 0) {
return -1;
}
}
return n;
}
@ -543,26 +536,26 @@ ssize_t udp_hook(struct eval *val,
char *buffer, ssize_t n, const union sockaddr_u *dst)
{
struct eval *pair = val->pair->pair;
int r = pair->round_count;
int m = pair->attempt, r = pair->round_count;
if (!m) {
for (; m < params.dp_count; m++) {
struct desync_params *dp = &params.dp[m];
struct desync_params *dp = pair->dp;
if (!dp) {
for (dp = params.dp; ; dp = dp->next) {
if (!dp) {
return -1;
}
if (!dp->detect
&& check_l34(dp, SOCK_DGRAM, dst)) {
break;
}
}
if (m >= params.dp_count) {
return -1;
pair->dp = dp;
}
pair->attempt = m;
}
if (!check_round(params.dp[m].rounds, r)) {
if (!check_round(dp->rounds, r)) {
return send(val->fd, buffer, n, 0);
}
LOG(LOG_S, "desync UDP: group=%d, round=%d, fd=%d\n", m, r, val->fd);
return desync_udp(val->fd, buffer, n, &dst->sa, m);
LOG(LOG_S, "desync UDP: group=%d, round=%d, fd=%d\n", dp->id, r, val->fd);
return desync_udp(val->fd, buffer, n, &dst->sa, dp);
}

88
main.c
View File

@ -8,6 +8,7 @@
#include "proxy.h"
#include "packets.h"
#include "error.h"
#include "conev.h"
#ifndef _WIN32
#include <arpa/inet.h>
@ -538,6 +539,21 @@ void *add(void **root, int *n, size_t ss)
}
static struct desync_params *add_group(struct desync_params *prev)
{
struct desync_params *dp = calloc(1, sizeof(*prev));
if (!dp) {
return 0;
}
if (prev) {
dp->prev = prev;
prev->next = dp;
}
params.dp_n++;
return dp;
}
#ifdef DAEMON
int init_pid_file(const char *fname)
{
@ -579,41 +595,41 @@ void clear_params(void)
mem_destroy(params.mempool);
params.mempool = 0;
}
if (params.dp) {
for (int i = 0; i < params.dp_count; i++) {
struct desync_params s = params.dp[i];
if (s.parts != 0) {
free(s.parts);
s.parts = 0;
struct desync_params *dp = params.dp;
while (dp) {
if (dp->parts != 0) {
free(dp->parts);
dp->parts = 0;
}
if (s.tlsrec != 0) {
free(s.tlsrec);
s.tlsrec = 0;
if (dp->tlsrec != 0) {
free(dp->tlsrec);
dp->tlsrec = 0;
}
if (s.fake_data.data != 0) {
free(s.fake_data.data);
s.fake_data.data = 0;
if (dp->fake_data.data != 0) {
free(dp->fake_data.data);
dp->fake_data.data = 0;
}
if (s.file_ptr != 0) {
free(s.file_ptr);
s.file_ptr = 0;
if (dp->file_ptr != 0) {
free(dp->file_ptr);
dp->file_ptr = 0;
}
if (s.hosts != 0) {
mem_destroy(s.hosts);
s.hosts = 0;
if (dp->hosts != 0) {
mem_destroy(dp->hosts);
dp->hosts = 0;
}
if (s.ipset != 0) {
mem_destroy(s.ipset);
s.hosts = 0;
if (dp->ipset != 0) {
mem_destroy(dp->ipset);
dp->hosts = 0;
}
if (s.fake_sni_list != 0) {
free(s.fake_sni_list);
s.fake_sni_list = 0;
if (dp->fake_sni_list != 0) {
free(dp->fake_sni_list);
dp->fake_sni_list = 0;
}
struct desync_params *t = dp;
dp = dp->next;
free(t);
}
free(params.dp);
params.dp = 0;
}
}
@ -662,12 +678,12 @@ int main(int argc, char **argv)
int curr_optind = 1;
struct desync_params *dp = add((void *)&params.dp,
&params.dp_count, sizeof(struct desync_params));
struct desync_params *dp = add_group(0);
if (!dp) {
clear_params();
return -1;
}
params.dp = dp;
while (!invalid && (rez = getopt_long(
argc, argv, opt, options, 0)) != -1) {
@ -771,8 +787,7 @@ int main(int argc, char **argv)
if (!(dp->hosts || dp->proto || dp->pf[0] || dp->detect || dp->ipset)) {
all_limited = 0;
}
dp = add((void *)&params.dp, &params.dp_count,
sizeof(struct desync_params));
dp = add_group(dp);
if (!dp) {
clear_params();
return -1;
@ -803,6 +818,7 @@ int main(int argc, char **argv)
params.auto_level = AUTO_NOSAVE;
}
dp->_optind = optind;
dp->id = params.dp_n - 1;
break;
case 'B':
@ -814,11 +830,16 @@ int main(int argc, char **argv)
continue;
}
val = strtol(optarg, &end, 0);
if (val < 1 || val >= params.dp_count || *end)
struct desync_params *itdp = params.dp;
while (itdp && itdp->id != val - 1) {
itdp = itdp->next;
}
if (!itdp)
invalid = 1;
else {
curr_optind = optind;
optind = params.dp[val - 1]._optind;
optind = itdp->_optind;
}
break;
@ -1134,8 +1155,7 @@ int main(int argc, char **argv)
return -1;
}
if (all_limited) {
dp = add((void *)&params.dp,
&params.dp_count, sizeof(struct desync_params));
dp = add_group(dp);
if (!dp) {
clear_params();
return -1;

View File

@ -18,7 +18,7 @@ struct elem {
struct elem_i {
struct elem i;
int m;
void *dp;
time_t time;
};

View File

@ -7,7 +7,6 @@
#include <assert.h>
#include "mpool.h"
#include "conev.h"
#ifdef _WIN32
#include <ws2tcpip.h>
@ -60,6 +59,12 @@ static const char *demode_str[] = {
};
#endif
union sockaddr_u {
struct sockaddr sa;
struct sockaddr_in in;
struct sockaddr_in6 in6;
};
struct part {
int m;
int flag;
@ -106,10 +111,15 @@ struct desync_params {
ssize_t file_size;
int _optind;
int id;
int fail_count;
struct desync_params *prev;
struct desync_params *next;
};
struct params {
int dp_count;
int dp_n;
struct desync_params *dp;
int await_int;
bool wait_send;