From 391dd8e758fb40475631ae05684848d35d367328 Mon Sep 17 00:00:00 2001 From: ruti <> Date: Tue, 10 Oct 2023 20:24:46 +0200 Subject: [PATCH] Delete UDP support --- conev.h | 8 +- desync.c | 29 ------- desync.h | 1 - main.c | 31 +------ packets.c | 4 +- packets.h | 3 +- params.h | 5 -- proxy.c | 246 +++++------------------------------------------------- 8 files changed, 29 insertions(+), 298 deletions(-) diff --git a/conev.h b/conev.h index 300e8e9..90e99f4 100644 --- a/conev.h +++ b/conev.h @@ -24,8 +24,7 @@ enum eid { EV_REQUEST, EV_CONNECT, EV_IGNORE, - EV_TUNNEL, - EV_UDP_TUNNEL + EV_TUNNEL }; #define FLAG_S4 1 @@ -38,8 +37,7 @@ char *eid_name[] = { "EV_REQUEST", "EV_CONNECT", "EV_IGNORE", - "EV_TUNNEL", - "EV_UDP_TUNNEL" + "EV_TUNNEL" }; #endif @@ -86,4 +84,4 @@ void destroy_pool(struct poolhd *pool); struct eval *next_event(struct poolhd *pool, int *offs, int *type); -int mod_etype(struct poolhd *pool, struct eval *val, int type, char rm); \ No newline at end of file +int mod_etype(struct poolhd *pool, struct eval *val, int type, char rm); diff --git a/desync.c b/desync.c index f631b30..e62c47b 100644 --- a/desync.c +++ b/desync.c @@ -197,32 +197,3 @@ int desync(int sfd, char *buffer, } return 0; } - - -int desync_udp(int fd, char *buffer, - ssize_t n, struct sockaddr *dst) -{ - int fa = get_family(dst); - socklen_t s = dst->sa_family == AF_INET6 ? - sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); - - if (params.desync_udp & DESYNC_UDP_FAKE) { - if (setttl(fd, params.ttl, fa) < 0) { - return -1; - } - if (sendto(fd, fake_udp.data, - fake_udp.size, 0, dst, s) < 0) { - perror("sendto"); - return -1; - } - if (setttl(fd, params.def_ttl, fa) < 0) { - return -1; - } - } - ssize_t ns = sendto(fd, buffer, n, 0, dst, s); - if (ns < 0) { - perror("sendto"); - return -1; - } - return 0; -} \ No newline at end of file diff --git a/desync.h b/desync.h index 39e99f6..520259e 100644 --- a/desync.h +++ b/desync.h @@ -1,2 +1 @@ int desync(int sfd, char *buffer, ssize_t n, struct sockaddr *dst); -int desync_udp(int fd, char *buffer, ssize_t n, struct sockaddr *dst); \ No newline at end of file diff --git a/main.c b/main.c index f0bcaad..da741e6 100644 --- a/main.c +++ b/main.c @@ -26,9 +26,6 @@ struct packet fake_tls = { }, fake_http = { sizeof(http_data), http_data -}, -fake_udp = { - sizeof(udp_data), udp_data }; @@ -37,7 +34,6 @@ struct params params = { .split = 3, .sfdelay = 3000, .attack = DESYNC_NONE, - .desync_udp = 0, .split_host = 0, .def_ttl = 0, .mod_http = 0, @@ -45,7 +41,6 @@ struct params params = { .ipv6 = 1, .resolve = 1, - .udp = 1, .max_open = 512, .bfsize = 16384, .nodelay = 1, @@ -65,7 +60,6 @@ const char help_text[] = { " -f, --pidfile Write pid to file\n" " -c, --max-conn Connection count limit, default 512\n" " -N, --no-domain Deny domain resolving\n" - " -U, --no-udp Deny UDP associate\n" " -I --conn-ip Connection binded IP, default ::\n" " -b, --bfs Buffer size, default 16384\n" //" -L, --nodelay <0 or 1> Set TCP_NODELAY option\n" @@ -84,12 +78,10 @@ const char help_text[] = { #ifdef FAKE_SUPPORT " -t, --ttl TTL of fake packets, default 8\n" " -l, --fake-tls \n" - " -o, --fake-http \n" - " -e, --fake-udp Set custom fake packet\n" + " -o, --fake-http Set custom fake packet\n" " -n, --tls-sni Change SNI in fake CH\n" #endif " -M, --mod-http Modify http: hcsmix,dcsmix,rmspace\n" - " -u, --desync-udp UDP desync method: fake\n" }; @@ -97,7 +89,6 @@ const struct option options[] = { {"daemon", 0, 0, 'D'}, {"no-domain", 0, 0, 'N'}, {"no-ipv6", 0, 0, 'X'}, - {"no-udp", 0, 0, 'U'}, {"help", 0, 0, 'h'}, {"version", 0, 0, 'v'}, {"pidfile", 1, 0, 'f'}, @@ -119,11 +110,9 @@ const struct option options[] = { #ifdef FAKE_SUPPORT {"fake-tls", 1, 0, 'l'}, {"fake-http", 1, 0, 'o'}, - {"fake-udp", 1, 0, 'e'}, {"tls-sni", 1, 0, 'n'}, #endif {"mod-http", 1, 0, 'M'}, - {"desync-udp", 1, 0, 'u'}, {"global-ttl", 1, 0, 'g'}, // {"delay", 1, 0, 'w'}, // @@ -251,9 +240,6 @@ int main(int argc, char **argv) case 'X': params.ipv6 = 0; break; - case 'U': - params.udp = 0; - break; case 'h': printf(help_text); return 0; @@ -400,14 +386,6 @@ int main(int argc, char **argv) } break; - case 'e': - fake_udp.data = ftob(optarg, &fake_udp.size); - if (!fake_udp.data) { - perror("read file"); - return -1; - } - break; - case 'M': end = optarg; while (end && !invalid) { @@ -430,13 +408,6 @@ int main(int argc, char **argv) } break; - case 'u': - if (*optarg != 'f') - invalid = 1; - else - params.desync_udp = DESYNC_UDP_FAKE; - break; - case 'g': // val = strtol(optarg, &end, 0); if (val <= 0 || val > 255 || *end) diff --git a/packets.c b/packets.c index 6a7ac30..e3cb10d 100644 --- a/packets.c +++ b/packets.c @@ -47,8 +47,6 @@ char http_data[43] = { "Host: www.wikipedia.org\r\n\r\n" }; -char udp_data[64] = {0}; - int find_tls_ext_offset(uint16_t type, char *data, size_t size) { @@ -213,4 +211,4 @@ int mod_http(char *buffer, size_t bsize, int m) memset(par + 5 + hlen, '\t', sc); } return 0; -} \ No newline at end of file +} diff --git a/packets.h b/packets.h index 9370cac..a664102 100644 --- a/packets.h +++ b/packets.h @@ -11,7 +11,6 @@ extern char tls_data[517]; extern char http_data[43]; -extern char udp_data[64]; int change_tls_sni(char *host, char *buffer, size_t bsize); @@ -19,4 +18,4 @@ int parse_tls(char *buffer, size_t bsize, char **hs); int parse_http(char *buffer, size_t bsize, char **hs, uint16_t *port); -int mod_http(char *buffer, size_t bsize, int m); \ No newline at end of file +int mod_http(char *buffer, size_t bsize, int m); diff --git a/params.h b/params.h index fa317ad..8e10b5e 100644 --- a/params.h +++ b/params.h @@ -8,22 +8,18 @@ enum demode { DESYNC_FAKE }; -#define DESYNC_UDP_FAKE 1 - struct params { char de_known; int ttl; int split; size_t sfdelay; enum demode attack; - int desync_udp; char split_host; int def_ttl; int mod_http; char ipv6; char resolve; - char udp; int max_open; int debug; size_t bfsize; @@ -41,7 +37,6 @@ struct packet { }; extern struct packet fake_tls; extern struct packet fake_http; -extern struct packet fake_udp; #define LOG_S 1 #define LOG_L 2 diff --git a/proxy.c b/proxy.c index 1773027..8ea7c62 100644 --- a/proxy.c +++ b/proxy.c @@ -28,22 +28,6 @@ static void on_cancel(int sig) { } -static inline int ip_equ( - struct sockaddr_ina *a, struct sockaddr_ina *b) -{ - if (a->sa.sa_family == AF_INET) { - return - *((uint32_t *)(&a->in.sin_addr)) == - *((uint32_t *)(&b->in.sin_addr)); - } - return - *((uint64_t *)(&a->in6.sin6_addr)) == - *((uint64_t *)(&b->in6.sin6_addr)) && - *((uint64_t *)(&a->in6.sin6_addr) + 1) == - *((uint64_t *)(&b->in6.sin6_addr) + 1); -} - - void map_fix(struct sockaddr_ina *addr, char f6) { struct { @@ -115,11 +99,11 @@ int setopts(int fd) int resolve(char *host, int len, - struct sockaddr_ina *addr, int type) + struct sockaddr_ina *addr) { struct addrinfo hints = {0}, *res = 0; - hints.ai_socktype = type; + hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_ADDRCONFIG; hints.ai_family = params.ipv6 ? AF_UNSPEC : AF_INET; @@ -219,7 +203,7 @@ int handle_socks4(int fd, char *bf, int len = (bf + n - ie) - 2; if (len < 3) break; - if (resolve(ie + 1, len, dst, SOCK_STREAM)) { + if (resolve(ie + 1, len, dst)) { fprintf(stderr, "not resolved: %.*s\n", len, ie + 1); break; } @@ -240,7 +224,7 @@ int handle_socks4(int fd, char *bf, int s_get_addr(char *buffer, ssize_t n, - struct sockaddr_ina *addr, int type) + struct sockaddr_ina *addr) { struct s5_req *r = (struct s5_req *)buffer; @@ -249,7 +233,7 @@ int s_get_addr(char *buffer, ssize_t n, (r->atp == S_ATP_I6 ? S_SIZE_I6 : 0))); if (n < o) { fprintf(stderr, "ss: bad request\n"); - return -S_ER_GEN; + return S_ER_GEN; } switch (r->atp) { case S_ATP_I4: @@ -259,58 +243,25 @@ int s_get_addr(char *buffer, ssize_t n, case S_ATP_ID: if (!params.resolve) { - return -S_ER_ATP; + return S_ER_ATP; } - if (r->id.len == 1 && type == SOCK_DGRAM) { - addr->in.sin_family = AF_INET; - LOG(LOG_S, "domain len=1\n"); - } - else if (resolve(r->id.domain, r->id.len, addr, type)) { + if (r->id.len < 3 || + resolve(r->id.domain, r->id.len, addr)) { fprintf(stderr, "not resolved: %.*s\n", r->id.len, r->id.domain); - return -S_ER_HOST; + return S_ER_HOST; } break; case S_ATP_I6: if (!params.ipv6) - return -S_ER_ATP; + return S_ER_ATP; else { addr->in6.sin6_family = AF_INET6; addr->in6.sin6_addr = r->i6; } } addr->in.sin_port = *(uint16_t *)&buffer[o - 2]; - return o; -} - - -int s_set_addr(char *buffer, ssize_t n, - struct sockaddr_ina *addr, char end) -{ - struct s5_req *r = (struct s5_req *)buffer; - if (n < S_SIZE_I4) { - return -1; - } - if (addr->sa.sa_family == AF_INET) { - if (end) { - r = (struct s5_req *)(buffer - S_SIZE_I4); - } - r->atp = S_ATP_I4; - r->i4 = addr->in.sin_addr; - r->p4 = addr->in.sin_port; - return S_SIZE_I4; - } else { - if (n < S_SIZE_I6) { - return -1; - } - if (end) { - r = (struct s5_req *)(buffer - S_SIZE_I6); - } - r->atp = S_ATP_I6; - r->i6 = addr->in6.sin6_addr; - r->p6 = addr->in6.sin6_port; - return S_SIZE_I6; - } + return 0; } @@ -374,83 +325,11 @@ int create_conn(struct poolhd *pool, } -int udp_asc(struct poolhd *pool, - struct eval *val, struct sockaddr_ina *dst) -{ - struct sockaddr_ina bnda = { - .sa = {.sa_family = dst->sa.sa_family}}, dsta = {0}; - socklen_t asz = sizeof(bnda); - - int ip_not_set = ip_equ(&bnda, dst); - bnda.in6 = params.baddr; - - if (ip_not_set) { - dsta.in6 = val->in6; - dsta.in.sin_port = dst->in.sin_port; - } else { - dsta.in6 = dst->in6; - } - - if (bnda.sa.sa_family == AF_INET6) { - map_fix(&dsta, 6); - } - if (dsta.sa.sa_family == AF_INET6) { - map_fix(&bnda, 6); - } - - int ufd = nb_socket(bnda.sa.sa_family, SOCK_DGRAM); - if (ufd < 0) { - perror("socket"); - return -1; - } - if (bnda.sa.sa_family == AF_INET6) { - int no = 0; - if (setsockopt(ufd, IPPROTO_IPV6, - IPV6_V6ONLY, (char *)&no, sizeof(no))) { - perror("setsockopt IPV6_V6ONLY"); - close(ufd); - return -1; - } - } - if (bind(ufd, &bnda.sa, sizeof(bnda)) < 0) { - perror("bind"); - close(ufd); - return -1; - } - if (getsockname(ufd, &bnda.sa, &asz)) { - perror("getsockname"); - close(ufd); - return -1; - } - struct eval *upair = add_event(pool, EV_UDP_TUNNEL, ufd, POLLIN); - if (!upair) { - close(ufd); - return -1; - } - val->pair = upair; - upair->pair = val; - upair->in6 = dsta.in6; - - struct s5_req s5r = { - .ver = 0x05 - }; - int offs = s_set_addr((char *)&s5r, sizeof(s5r), &bnda, 0); - if (offs < 0) { - return -1; - } - if (send(val->fd, (char *)&s5r, offs, 0) < 0) { - perror("send"); - return -1; - } - return 0; -} - - static inline int on_request(struct poolhd *pool, struct eval *val, char *buffer, size_t bfsize) { struct sockaddr_ina dst = {0}; - int error = 0, offs_e = 0; + int error = 0, s5e = 0; ssize_t n = recv(val->fd, buffer, bfsize, 0); if (n < 1) { @@ -471,25 +350,15 @@ static inline int on_request(struct poolhd *pool, struct eval *val, } struct s5_req *r = (struct s5_req *)buffer; - switch (r->cmd) { - case S_CMD_CONN: - offs_e = s_get_addr(buffer, n, &dst, SOCK_STREAM); - if (offs_e > 0) { - error = create_conn(pool, val, &dst); - } - break; - case S_CMD_AUDP: - offs_e = s_get_addr(buffer, n, &dst, SOCK_DGRAM); - if (offs_e <= 0) { - break; - } - if (params.udp) { - error = udp_asc(pool, val, &dst); - break; - } - default: - fprintf(stderr, "ss: unsupported cmd: 0x%x\n", r->cmd); - offs_e = -S_ER_CMD; + if (r->cmd != S_CMD_CONN) { + fprintf(stderr, "ss: unsupported cmd: 0x%x\n", r->cmd); + s5e = S_ER_CMD; + } + else { + s5e = s_get_addr(buffer, n, &dst); + if (!s5e) { + error = create_conn(pool, val, &dst); + } } } else if (*buffer == S_VER4) { @@ -503,8 +372,8 @@ static inline int on_request(struct poolhd *pool, struct eval *val, fprintf(stderr, "ss: invalid version: 0x%x (%lu)\n", *buffer, n); return -1; } - if (error || offs_e < 0) { - if (resp_error(val->fd, errno, val->flag, -offs_e) < 0) + if (error || s5e) { + if (resp_error(val->fd, error ? errno : 0, val->flag, s5e) < 0) perror("send"); return -1; } @@ -658,70 +527,6 @@ static inline int on_tunnel(struct poolhd *pool, struct eval *val, } -int on_udp_tunnel(struct eval *val, char *buffer, size_t bfsize) -{ - int skip = S_SIZE_I6, offs; - do { - struct sockaddr_ina addr = {0}; - struct sockaddr_ina *dst = (struct sockaddr_ina *)&val->in6; - socklen_t asz = sizeof(addr); - - ssize_t n = recvfrom(val->fd, buffer + skip, - bfsize - skip, 0, &addr.sa, &asz), ns; - - if (n < 0 && errno == EAGAIN) - break; - if (n < 1) { - perror("recv udp"); - return -1; - } - - if (!dst->in.sin_port) { - dst->in.sin_port = addr.in.sin_port; - } - - if (ip_equ(dst, &addr) && dst->in.sin_port == addr.in.sin_port) { - if (buffer[skip + 2]) { // frag - continue; - } - offs = s_get_addr(buffer + skip, n, &addr, SOCK_DGRAM); - if (offs < 0) { - return -1; - } - if (dst->in.sin_family == AF_INET6) { - map_fix(&addr, 6); - } - if (dst->in.sin_family != addr.sa.sa_family) { - return -1; - } - if (val->flag == FLAG_CONN) - ns = sendto(val->fd, - buffer + skip + offs, n - offs, 0, &addr.sa, asz); - else { - ns = desync_udp(val->fd, - buffer + skip + offs, n - offs, &addr.sa); - val->flag = FLAG_CONN; - } - } else { - map_fix(&addr, 0); - - offs = s_set_addr(buffer + skip, skip, &addr, 1); - if (offs < 0 || offs > skip) { - return -1; - } - memset(buffer + skip - offs, 0, 3); - ns = sendto(val->fd, buffer + skip - offs, - n + offs, 0, (struct sockaddr *)&val->in6, sizeof(val->in6)); - } - if (ns < 0) { - perror("sendto"); - return -1; - } - } while(1); - return 0; -} - - int big_loop(int srvfd) { size_t bfsize = params.bfsize; @@ -776,11 +581,6 @@ int big_loop(int srvfd) del_event(pool, val); continue; - case EV_UDP_TUNNEL: - if (on_udp_tunnel(val, buffer, bfsize)) - del_event(pool, val); - continue; - case EV_IGNORE: if (etype & (POLLHUP | POLLERR | POLLRDHUP)) del_event(pool, val);