diff --git a/extend.c b/extend.c index 8f3c58d..07a3a81 100644 --- a/extend.c +++ b/extend.c @@ -127,10 +127,29 @@ static int cache_add(const union sockaddr_u *dst, int m) int connect_hook(struct poolhd *pool, struct eval *val, const union sockaddr_u *dst, evcb_t next) { - int m = cache_get(dst); + int m = cache_get(dst), init_m = m; val->cache = (m == 0); - val->attempt = m < 0 ? 0 : m; + m = m < 0 ? 0 : m; + struct desync_params *dp; + for (; ; m++) { + dp = ¶ms.dp[m]; + if ((!dp->detect || m == init_m) + && check_l34(dp, SOCK_STREAM, dst)) { + break; + } + if (m == params.dp_count) { + return -1; + } + } + val->attempt = m; + + if (dp->custom_dst) { + union sockaddr_u addr = dp->custom_dst_addr; + addr.in6.sin6_port = dst->in6.sin6_port; + + return create_conn(pool, val, &addr, next); + } return create_conn(pool, val, dst, next); } @@ -360,12 +379,12 @@ 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; + int m = client->attempt, init_m = m; - if (!m) for (; m < params.dp_count; m++) { + for (; m < params.dp_count; m++) { struct desync_params *dp = ¶ms.dp[m]; - if (!dp->detect - && check_l34(dp, SOCK_STREAM, &client->pair->addr) + if ((!dp->detect || m == init_m) + && (m == init_m || check_l34(dp, SOCK_STREAM, &client->pair->addr)) && check_proto_tcp(dp->proto, buffer, n) && (!dp->hosts || check_host(dp->hosts, buffer, n))) { break; diff --git a/extend.h b/extend.h index 8e9fecb..62f0844 100644 --- a/extend.h +++ b/extend.h @@ -4,6 +4,7 @@ #include #include "proxy.h" +#include "params.h" int socket_mod(int fd); @@ -19,6 +20,8 @@ ssize_t tcp_recv_hook(struct poolhd *pool, ssize_t udp_hook(struct eval *val, char *buffer, ssize_t n, const union sockaddr_u *dst); +static bool check_l34(struct desync_params *dp, int st, const union sockaddr_u *dst); + #ifdef __linux__ static int protect(int conn_fd, const char *path); #else diff --git a/main.c b/main.c index bdc357a..ed8dd35 100644 --- a/main.c +++ b/main.c @@ -185,6 +185,7 @@ const struct option options[] = { {"protect-path", 1, 0, 'P'}, // #endif {"ipset", 1, 0, 'j'}, + {"connect-to", 1, 0, 'C'}, // {0} }; @@ -1076,6 +1077,13 @@ int main(int argc, char **argv) params.await_int = atoi(optarg); break; + case 'C': + if (get_addr(optarg, &dp->custom_dst_addr) < 0) + invalid = 1; + else + dp->custom_dst = 1; + break; + #ifdef __linux__ case 'P': params.protect_path = optarg; diff --git a/params.h b/params.h index 23fba1e..8e399e8 100644 --- a/params.h +++ b/params.h @@ -94,6 +94,9 @@ struct desync_params { uint16_t pf[2]; int rounds[2]; + union sockaddr_u custom_dst_addr; + bool custom_dst; + char *file_ptr; ssize_t file_size; };