diff --git a/extend.c b/extend.c index e47b637..54e2a87 100644 --- a/extend.c +++ b/extend.c @@ -162,20 +162,6 @@ bool check_proto_tcp(int proto, struct eval *val) } -bool check_proto_udp(int proto, char *buffer, size_t n) -{ - if ((proto & IS_QUIC) && - is_quic_inital(buffer, n)) { - return 1; - } - if ((proto & IS_DNS) && - is_dns_req(buffer, n)) { - return 1; - } - return 0; -} - - int on_torst(struct poolhd *pool, struct eval *val) { int m = val->pair->attempt + 1; @@ -371,41 +357,3 @@ int on_desync(struct poolhd *pool, struct eval *val, val->pair->type = EV_PRE_TUNNEL; return 0; } - - -ssize_t udp_hook(struct eval *val, - char *buffer, size_t n, struct sockaddr_ina *dst) -{ - int m = val->attempt; - struct desync_params *dp = ¶ms.dp[m]; - - if (val->flag != FLAG_CONN) { - if (!m) for (; m < params.dp_count; m++) { - dp = ¶ms.dp[m]; - if ((!dp->proto || check_proto_udp(dp->proto, buffer, n))) { - break; - } - } - if (m >= params.dp_count) { - return -1; - } - val->attempt = m; - val->flag = FLAG_CONN; - } - - struct sockaddr_ina addr; - if (dp->to_ip) { - addr.in6 = dp->addr; - if (dst->sa.sa_family == AF_INET6) { - map_fix(&addr, 6); - } - else { - map_fix(&addr, 0); - } - if (!addr.in.sin_port) { - addr.in.sin_port = dst->in.sin_port; - } - dst = &addr; - } - return sendto(val->fd, buffer, n, 0, &dst->sa, sizeof(*dst)); -} diff --git a/extend.h b/extend.h index df7c866..bbedb5e 100644 --- a/extend.h +++ b/extend.h @@ -6,6 +6,3 @@ int on_tunnel_check(struct poolhd *pool, struct eval *val, int on_desync(struct poolhd *pool, struct eval *val, char *buffer, size_t bfsize); - -ssize_t udp_hook(struct eval *val, - char *buffer, size_t n, struct sockaddr_ina *dst); \ No newline at end of file diff --git a/main.c b/main.c index bfc8523..7eaa1c7 100644 --- a/main.c +++ b/main.c @@ -56,6 +56,9 @@ struct params params = { .baddr = { .sin6_family = AF_INET6 }, + .laddr = { + .sin6_family = AF_INET + }, .debug = 0 }; @@ -81,7 +84,7 @@ const char help_text[] = { #ifdef TIMEOUT_SUPPORT " -T, --timeout Timeout waiting for response, after which trigger auto\n" #endif - " -K, --proto[=t,h,d,q] Protocol whitelist: tls,http,dns,quic\n" + " -K, --proto[=t,h] Protocol whitelist: tls,http\n" " -H, --hosts Hosts whitelist\n" " -D, --dst Custom destination IP\n" " -s, --split Split packet at n\n" @@ -280,10 +283,13 @@ int get_addr(const char *str, struct sockaddr_ina *addr) if (getaddrinfo(str, 0, &hints, &res) || !res) { return -1; } + if (res->ai_addr->sa_family == AF_INET6) - addr->in6 = *(struct sockaddr_in6 *)res->ai_addr; + addr->in6.sin6_addr = ( + (struct sockaddr_in6 *)res->ai_addr)->sin6_addr; else - addr->in = *(struct sockaddr_in *)res->ai_addr; + addr->in.sin_addr = ( + (struct sockaddr_in *)res->ai_addr)->sin_addr; freeaddrinfo(res); return 0; @@ -438,13 +444,6 @@ int main(int argc, char **argv) return 0; } #endif - struct sockaddr_ina s = { - .in = { - .sin_family = AF_INET, - .sin_port = htons(1080) - }}, - b = { .in6 = params.baddr }; - int optc = sizeof(options)/sizeof(*options); for (int i = 0, e = optc; i < e; i++) optc += options[i].has_arg; @@ -459,6 +458,8 @@ int main(int argc, char **argv) opt[o] = ':'; } } + + params.laddr.sin6_port = htons(1080); int rez; int invalid = 0; @@ -466,8 +467,6 @@ int main(int argc, char **argv) long val = 0; char *end = 0; - uint16_t port = htons(1080); - struct desync_params *dp = add((void *)¶ms.dp, ¶ms.dp_count, sizeof(struct desync_params)); if (!dp) { @@ -499,7 +498,8 @@ int main(int argc, char **argv) return 0; case 'i': - if (get_addr(optarg, &s) < 0) + if (get_addr(optarg, + (struct sockaddr_ina *)¶ms.laddr) < 0) invalid = 1; break; @@ -508,14 +508,13 @@ int main(int argc, char **argv) if (val <= 0 || val > 0xffff || *end) invalid = 1; else - port = htons(val); + params.laddr.sin6_port = htons(val); break; case 'I': - if (get_addr(optarg, &b) < 0) + if (get_addr(optarg, + (struct sockaddr_ina *)¶ms.baddr) < 0) invalid = 1; - else - params.baddr = b.in6; break; case 'b': @@ -625,12 +624,6 @@ int main(int argc, char **argv) case 'h': dp->proto |= IS_HTTP; break; - case 'd': - dp->proto |= IS_DNS; - break; - case 'q': - dp->proto |= IS_QUIC; - break; default: invalid = 1; continue; @@ -821,10 +814,8 @@ int main(int argc, char **argv) return -1; } } - s.in.sin_port = port; - b.in.sin_port = 0; - if (b.sa.sa_family != AF_INET6) { + if (params.laddr.sin6_family != AF_INET6) { params.ipv6 = 0; } if (!params.def_ttl) { @@ -839,7 +830,7 @@ int main(int argc, char **argv) clear_params(); return -1; } - int status = run(&s); + int status = run((struct sockaddr_ina *)¶ms.laddr); clear_params(); return status; } diff --git a/packets.c b/packets.c index b0b9b95..188fbdf 100644 --- a/packets.c +++ b/packets.c @@ -350,7 +350,7 @@ bool is_tls_alert(char *resp, size_t sn) { && !memcmp(resp, "\x15\x03\x01\x00\x02\x02", 6)); } - +/* bool is_dns_req(char *buffer, size_t n) { if (n < 12) { @@ -364,7 +364,7 @@ bool is_quic_inital(char *buffer, size_t bsize) { return (bsize > 64 && (buffer[0] & 0xc0) == 0xc0); } - +*/ int mod_http(char *buffer, size_t bsize, int m) { diff --git a/packets.h b/packets.h index 2a5dcd9..46fd482 100644 --- a/packets.h +++ b/packets.h @@ -6,8 +6,8 @@ #define IS_UNKNOWN 0 #define IS_HTTP 1 #define IS_HTTPS 2 -#define IS_QUIC 4 -#define IS_DNS 8 +//#define IS_QUIC 4 +//#define IS_DNS 8 #define MH_HMIX 1 #define MH_SPACE 2 @@ -38,6 +38,6 @@ bool is_tls_alert(char *resp, size_t sn); int part_tls(char *buffer, size_t bsize, ssize_t n, long pos); -bool is_dns_req(char *buffer, size_t n); +//bool is_dns_req(char *buffer, size_t n); -bool is_quic_inital(char *buffer, size_t bsize); +//bool is_quic_inital(char *buffer, size_t bsize); diff --git a/params.h b/params.h index 7083116..9eef291 100644 --- a/params.h +++ b/params.h @@ -91,6 +91,7 @@ struct params { int debug; size_t bfsize; struct sockaddr_in6 baddr; + struct sockaddr_in6 laddr; struct mphdr *mempool; }; diff --git a/proxy.c b/proxy.c index f065532..7a260b0 100644 --- a/proxy.c +++ b/proxy.c @@ -64,9 +64,6 @@ void map_fix(struct sockaddr_ina *addr, char f6) static inline char addr_equ( struct sockaddr_ina *a, struct sockaddr_ina *b) { - if (a->in.sin_port != b->in.sin_port) { - return 0; - } if (a->sa.sa_family == AF_INET) { return *((uint32_t *)(&a->in.sin_addr)) == @@ -398,7 +395,8 @@ int create_conn(struct poolhd *pool, int udp_associate(struct poolhd *pool, struct eval *val, struct sockaddr_ina *dst) { - struct sockaddr_ina addr = {}; + struct sockaddr_ina addr = { .in6 = params.laddr }; + addr.in.sin_port = 0; int ufd = nb_socket(params.baddr.sin6_family, SOCK_DGRAM); if (ufd < 0) { @@ -420,21 +418,44 @@ int udp_associate(struct poolhd *pool, close(ufd); return -1; } - socklen_t sz = sizeof(addr); - if (getsockname(ufd, &addr.sa, &sz)) { - perror("getsockname"); - close(ufd); - return -1; - } struct eval *pair = add_event(pool, EV_UDP_TUNNEL, ufd, POLLIN); if (!pair) { close(ufd); return -1; } - val->pair = pair; - pair->pair = val; - pair->in6.sin6_port = 0; + int cfd = nb_socket(addr.sa.sa_family, SOCK_DGRAM); + if (cfd < 0) { + perror("socket"); + del_event(pool, pair); + return -1; + } + if (bind(cfd, &addr.sa, sizeof(addr)) < 0) { + uniperror("bind"); + del_event(pool, pair); + close(cfd); + return -1; + } + struct eval *client = add_event(pool, EV_UDP_TUNNEL, cfd, POLLIN); + if (!pair) { + del_event(pool, pair); + close(cfd); + return -1; + } + val->type = EV_IGNORE; + val->pair = client; + client->pair = pair; + pair->pair = val; + + client->flag = FLAG_CONN; + client->in6 = val->in6; + client->in6.sin6_port = 0; + + socklen_t sz = sizeof(addr); + if (getsockname(cfd, &addr.sa, &sz)) { + perror("getsockname"); + return -1; + } struct s5_req s5r = { .ver = 0x05 }; @@ -573,55 +594,61 @@ int on_tunnel(struct poolhd *pool, struct eval *val, int on_udp_tunnel(struct eval *val, char *buffer, size_t bfsize) { - char *data = buffer + S_SIZE_I6; - size_t data_len = bfsize - S_SIZE_I6; + char *data = buffer; + size_t data_len = bfsize; + + if (val->flag != FLAG_CONN) { + data += S_SIZE_I6; + data_len -= S_SIZE_I6; + } + struct sockaddr_ina addr = {0}; + do { - struct sockaddr_ina addr = {0}; - struct sockaddr_ina *src = (struct sockaddr_ina *)&val->in6; socklen_t asz = sizeof(addr); - ssize_t n = recvfrom(val->fd, data, data_len, 0, &addr.sa, &asz); + ssize_t n = recvfrom(val->fd, data, data_len, 0, &addr.sa, &asz); if (n < 1) { if (n && errno == EAGAIN) break; perror("recv udp"); return -1; } - if (!src->in.sin_port) { - src->in6 = addr.in6; - } - ssize_t ns = 0; + ssize_t ns; - if (addr_equ(src, &addr)) { + if (val->flag == FLAG_CONN) { + if (!val->in6.sin6_port) { + if (connect(val->fd, &addr.sa, sizeof(addr)) < 0) { + uniperror("connect"); + return -1; + } + val->in6 = addr.in6; + } if (*(data + 2) != 0) { // frag continue; } int offs = s5_get_addr(data, n, &addr, SOCK_DGRAM); if (offs < 0) { + LOG(LOG_E, "udp parse error\n"); return -1; } - val->pair->in6 = addr.in6; - - if (src->sa.sa_family == AF_INET6) { + if (params.baddr.sin6_family == AF_INET6) { map_fix(&addr, 6); } - if (src->sa.sa_family != addr.sa.sa_family) { + if (params.baddr.sin6_family != addr.sa.sa_family) { return -1; } - ns = udp_hook(val, - data + offs, n - offs, &addr); + ns = sendto(val->pair->fd, + data + offs, n - offs, 0, &addr.sa, sizeof(addr)); } else { - //map_fix(&addr, 0); + map_fix(&addr, 0); memset(buffer, 0, S_SIZE_I6); - int offs = s5_set_addr(data, S_SIZE_I6, - (struct sockaddr_ina *)&val->pair->in6, 1); + int offs = s5_set_addr(data, S_SIZE_I6, &addr, 1); if (offs < 0 || offs > S_SIZE_I6) { return -1; } - ns = sendto(val->fd, data - offs, offs + n, 0, - (struct sockaddr *)&val->in6, sizeof(val->in6)); + ns = send(val->pair->pair->fd, data - offs, offs + n, 0); } if (ns < 0) { perror("sendto"); diff --git a/readme.txt b/readme.txt index dfd9a7d..fa7d180 100644 --- a/readme.txt +++ b/readme.txt @@ -74,8 +74,8 @@ $ ./ciadpi --disorder 3 -A --tlsrec 1+s В Linux переводится в миллисекунды, поэтому можно указать дробное число Истечение таймаута будет обработано --auto --K, --proto[=t,h,d,q] - Белый список протоколов: tls,http,dns,quic +-K, --proto[=t,h] + Белый список протоколов: tls,http -H, --hosts Ограничить область действия параметров списком доменов