From f711eebb694c7fd23a5e70f76647534a930d2426 Mon Sep 17 00:00:00 2001 From: ruti <> Date: Wed, 11 Jun 2025 21:00:42 +0300 Subject: [PATCH] Dump cache, save hostname --- conev.c | 4 ++ conev.h | 2 + extend.c | 115 +++++++++++++++++++++++++++++++------------------------ main.c | 23 ++++++++++- mpool.c | 23 +++++++++++ mpool.h | 25 +++++++++++- params.h | 5 ++- 7 files changed, 143 insertions(+), 54 deletions(-) diff --git a/conev.c b/conev.c index 7769fca..f9218cb 100644 --- a/conev.c +++ b/conev.c @@ -106,6 +106,10 @@ void del_event(struct poolhd *pool, struct eval *val) val->restore_fake = 0; } #endif + if (val->host) { + free(val->host); + val->host = 0; + } close(val->fd); val->fd = -1; val->mod_iter = pool->iters; diff --git a/conev.h b/conev.h index 2c8bfeb..78de30a 100644 --- a/conev.h +++ b/conev.h @@ -75,6 +75,8 @@ struct eval { struct buffer *buff, *sq_buff; int flag; union sockaddr_u addr; + char *host; + int host_len; ssize_t recv_count; ssize_t round_sent; diff --git a/extend.c b/extend.c index 33cfae3..97adf54 100644 --- a/extend.c +++ b/extend.c @@ -23,8 +23,6 @@ #include "desync.h" #include "packets.h" -#define KEY_SIZE sizeof(union sockaddr_u) - static int set_timeout(int fd, unsigned int s) { @@ -48,79 +46,63 @@ static int set_timeout(int fd, unsigned int s) static ssize_t serialize_addr(const union sockaddr_u *dst, - uint8_t *const out, const size_t out_len) + struct cache_key *out) { - #define serialize(raw, field, len, counter){ \ - const size_t size = sizeof(field); \ - if ((counter + size) <= len) { \ - memcpy(raw + counter, &(field), size); \ - counter += size; \ - } else return 0; \ - } - size_t c = 0; - serialize(out, dst->in.sin_port, out_len, c); - serialize(out, dst->sa.sa_family, out_len, c); + out->port = dst->in.sin_port; + out->family = dst->sa.sa_family; + static const ssize_t c = offsetof(struct cache_key, ip.v4); if (dst->sa.sa_family == AF_INET) { - serialize(out, dst->in.sin_addr, out_len, c); - } else { - serialize(out, dst->in6.sin6_addr, out_len, c); + out->ip.v4 = dst->in.sin_addr; + return c + sizeof(out->ip.v4); + } + else { + out->ip.v6 = dst->in6.sin6_addr; + return c + sizeof(out->ip.v6); } - #undef serialize - - return c; -} - - -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 cache_key key = { 0 }; + int len = serialize_addr(dst, &key); - struct elem_i *val = (struct elem_i *)mem_get(params.mempool, (char *)key, len); + struct elem_i *val = (struct elem_i *)mem_get(params.mempool, (char *)&key, len); if (!val) { return 0; } time_t t = time(0); - if (t > val->time + params.cache_ttl) { + if (t > val->time + params.cache_ttl || val->dp == params.dp) { LOG(LOG_S, "time=%jd, now=%jd, ignore\n", (intmax_t)val->time, (intmax_t)t); - mem_delete(params.mempool, (char *)key, len); + mem_delete(params.mempool, (char *)&key, len); return 0; } return val; } -static struct elem_i *cache_add(const union sockaddr_u *dst) +static struct elem_i *cache_add( + const union sockaddr_u *dst, const char *host, int host_len) { - uint8_t key[KEY_SIZE] = { 0 }; - int len = serialize_addr(dst, key, sizeof(key)); - - INIT_ADDR_STR((*dst)); - LOG(LOG_S, "save ip: %s\n", ADDR_STR); + struct cache_key key = { 0 }; + int cmp_len = serialize_addr(dst, &key); time_t t = time(0); - char *key_d = malloc(len); - if (!key_d) { + size_t total = sizeof(struct cache_data) + host_len; + struct cache_data *data = malloc(total); + if (!data) { return 0; } - memcpy(key_d, key, len); + memcpy(data, &key, cmp_len); - struct elem_i *val = (struct elem_i *)mem_add(params.mempool, key_d, len, sizeof(struct elem_i)); + data->host_len = host_len; + memcpy(data->host, host, host_len); + + struct elem_i *val = (struct elem_i *)mem_add(params.mempool, (char *)data, cmp_len, sizeof(struct elem_i)); if (!val) { uniperror("mem_add"); - free(key_d); + free(data); return 0; } val->time = t; @@ -287,7 +269,8 @@ static bool check_round(const int *nr, int r) static int on_trigger(int type, struct poolhd *pool, struct eval *val) { - struct desync_params *dp = val->pair->dp->next; + struct desync_params *dp = val->pair->dp; + dp->fail_count++; struct buffer *pair_buff = val->pair->sq_buff; bool can_reconn = ( @@ -298,14 +281,18 @@ static int on_trigger(int type, struct poolhd *pool, struct eval *val) if (!can_reconn && params.auto_level <= AUTO_NOSAVE) { return -1; } - for (; dp; dp = dp->next) { + INIT_ADDR_STR((val->addr)); + + for (dp = dp->next; dp; dp = dp->next) { if (!dp->detect) { break; } if (!(dp->detect & type)) { continue; } - struct elem_i *e = cache_add(&val->addr); + LOG(LOG_S, "save: ip=%s, id=%d\n", ADDR_STR, dp->id); + + struct elem_i *e = cache_add(&val->addr, val->pair->host, val->pair->host_len); if (e) { e->dp = dp; } @@ -314,7 +301,12 @@ static int on_trigger(int type, struct poolhd *pool, struct eval *val) } return -1; } - cache_del(&val->addr); + LOG(LOG_S, "unreach ip: %s\n", ADDR_STR); + + struct elem_i *e = cache_add(&val->addr, val->pair->host, val->pair->host_len); + if (e) { + e->dp = params.dp; + } return -1; } @@ -381,8 +373,31 @@ static inline void free_first_req(struct poolhd *pool, struct eval *client) } +static void save_hostname(struct eval *client, const char *buffer, ssize_t n) +{ + if (client->host) { + return; + } + char *host = 0; + int len = parse_tls(buffer, n, &host); + if (!len) { + if (!(len = parse_http(buffer, n, &host, 0))) { + return; + } + } + if (!(client->host = malloc(len))) { + return; + } + memcpy(client->host, host, len); + client->host_len = len; +} + + static int setup_conn(struct eval *client, const char *buffer, ssize_t n) { + if (params.cache_file) { + save_hostname(client, buffer, n); + } struct desync_params *dp = client->dp, *init_dp = dp; for (; dp; dp = dp->next) { diff --git a/main.c b/main.c index 2bcf29a..fe3cba9 100644 --- a/main.c +++ b/main.c @@ -88,6 +88,7 @@ static const char help_text[] = { " Detect: torst,redirect,ssl_err,none\n" " -L, --auto-mode <0|1> 1 - handle trigger after several packets\n" " -u, --cache-ttl Lifetime of cached desync params for IP\n" + " -y, --cache-dump Dump cache to file or stdout\n" #ifdef TIMEOUT_SUPPORT " -T, --timeout Timeout waiting for response, after which trigger auto\n" #endif @@ -155,6 +156,7 @@ const struct option options[] = { {"timeout", 1, 0, 'T'}, #endif {"copy", 1, 0, 'B'}, + {"cache-dump", 1, 0, 'y'}, {"proto", 1, 0, 'K'}, {"hosts", 1, 0, 'H'}, {"pf", 1, 0, 'V'}, @@ -666,7 +668,7 @@ int main(int argc, char **argv) params.baddr.sa.sa_family = AF_INET; } - char *pid_file = 0; + const char *pid_file = 0; bool daemonize = 0; int rez; @@ -765,6 +767,10 @@ int main(int argc, char **argv) invalid = 1; break; + case 'y': // + params.cache_file = optarg; + break; + // desync options case 'F': @@ -1190,6 +1196,21 @@ int main(int argc, char **argv) } #endif int status = run(¶ms.laddr); + + for (dp = params.dp; dp; dp = dp->next) { + LOG(LOG_S, "group: %d, triggered: %d\n", dp->id, dp->fail_count); + } + if (params.cache_file) { + FILE *f; + if (!strcmp(params.cache_file, "-")) + f = stdout; + else + f = fopen(params.cache_file, "w"); + if (!f) + perror("fopen"); + else + dump_cache(params.mempool, f); + } clear_params(); return status; } diff --git a/mpool.c b/mpool.c index 5a8b0b6..3dd4005 100644 --- a/mpool.c +++ b/mpool.c @@ -147,3 +147,26 @@ void mem_destroy(struct mphdr *hdr) } free(hdr); } + + +void dump_cache(struct mphdr *hdr, FILE *out) +{ + if (!hdr->root) { + return; + } + kavl_itr_t(my) itr; + kavl_itr_first(my, hdr->root, &itr); + do { + const struct elem_i *p = (const struct elem_i *)kavl_at(&itr); + struct cache_data *value = (struct cache_data *)p->i.data; + + char ADDR_STR[INET6_ADDRSTRLEN]; + if (value->key.family == AF_INET) + inet_ntop(AF_INET, &value->key.ip.v4, ADDR_STR, sizeof(ADDR_STR)); + else + inet_ntop(AF_INET6, &value->key.ip.v6, ADDR_STR, sizeof(ADDR_STR)); + + fprintf(out, "%s %d %d %jd %.*s\n", + ADDR_STR, ntohs(value->key.port), p->dp->id, (intmax_t)p->time, value->host_len, value->host); + } while (kavl_itr_next(my, &itr)); +} diff --git a/mpool.h b/mpool.h index 28d36f0..911a8d3 100644 --- a/mpool.h +++ b/mpool.h @@ -3,12 +3,33 @@ #include #include + #include "kavl.h" +#include "params.h" #define CMP_BYTES 0 #define CMP_BITS 1 #define CMP_HOST 2 +#pragma pack(push, 1) + +struct cache_key { + uint16_t family; + uint16_t port; + union { + struct in_addr v4; + struct in6_addr v6; + } ip; +}; + +struct cache_data { + struct cache_key key; + int host_len; + char host[]; +}; + +#pragma pack(pop) + struct elem { int len; char *data; @@ -18,7 +39,7 @@ struct elem { struct elem_i { struct elem i; - void *dp; + struct desync_params *dp; time_t time; }; @@ -39,4 +60,6 @@ void mem_delete(struct mphdr *hdr, const char *str, int len); void mem_destroy(struct mphdr *hdr); +void dump_cache(struct mphdr *hdr, FILE *out); + #endif diff --git a/params.h b/params.h index eaaa2c7..e501000 100644 --- a/params.h +++ b/params.h @@ -6,8 +6,6 @@ #include #include -#include "mpool.h" - #ifdef _WIN32 #include #else @@ -17,6 +15,8 @@ #include #endif +#include "mpool.h" + #if defined(__linux__) || defined(_WIN32) #define FAKE_SUPPORT 1 #define TIMEOUT_SUPPORT 1 @@ -145,6 +145,7 @@ struct params { const char *protect_path; const char *pid_file; int pid_fd; + const char *cache_file; }; extern struct params params;