diff --git a/Makefile b/Makefile index d227fc8..0d1e44f 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,7 @@ - TARGET = ciadpi CPPFLAGS = -D_DEFAULT_SOURCE -CFLAGS += -I. -std=c99 -Wall -Wno-unused -O2 +CFLAGS += -I. -std=c99 -O2 -Wall -Wno-unused -Wextra -pedantic WIN_LDFLAGS = -lws2_32 -lmswsock HEADERS = conev.h desync.h error.h extend.h kavl.h mpool.h packets.h params.h proxy.h win_service.h diff --git a/conev.c b/conev.c index 41fa47a..713a69a 100644 --- a/conev.c +++ b/conev.c @@ -9,7 +9,7 @@ struct poolhd *init_pool(int count) { - struct poolhd *pool = calloc(sizeof(struct poolhd), 1); + struct poolhd *pool = calloc(1, sizeof(struct poolhd)); if (!pool) { uniperror("init pool"); return 0; diff --git a/conev.h b/conev.h index 9673bf0..57d515b 100644 --- a/conev.h +++ b/conev.h @@ -32,6 +32,12 @@ #define POLLRDHUP 0 #endif +union sockaddr_u { + struct sockaddr sa; + struct sockaddr_in in; + struct sockaddr_in6 in6; +}; + enum eid { EV_ACCEPT, EV_REQUEST, @@ -72,10 +78,7 @@ struct eval { struct eval *pair; struct buffer buff; int flag; - union { - struct sockaddr_in in; - struct sockaddr_in6 in6; - }; + union sockaddr_u addr; ssize_t recv_count; ssize_t round_sent; unsigned int round_count; diff --git a/desync.c b/desync.c index a44a0de..407fefe 100644 --- a/desync.c +++ b/desync.c @@ -124,7 +124,7 @@ static void wait_send_if_support(int sfd) if (i) LOG(LOG_S, "waiting for send: %d ms\n", i); } #else -#define wait_send_if_support(sfd) +#define wait_send_if_support(sfd) {} #endif @@ -157,7 +157,7 @@ static struct packet get_tcp_fake(const char *buffer, size_t n, static ssize_t send_fake(int sfd, const char *buffer, long pos, const struct desync_params *opt, struct packet pkt) { - struct sockaddr_in6 addr = {}; + struct sockaddr_in6 addr; socklen_t addr_size = sizeof(addr); if (opt->md5sig || opt->ip_options) { @@ -251,7 +251,7 @@ static ssize_t send_fake(int sfd, const char *buffer, #endif #ifdef _WIN32 -OVERLAPPED ov = {}; +OVERLAPPED ov = { 0 }; static ssize_t send_fake(int sfd, const char *buffer, long pos, const struct desync_params *opt, struct packet pkt) @@ -341,6 +341,9 @@ static ssize_t send_fake(int sfd, const char *buffer, static ssize_t send_oob(int sfd, char *buffer, ssize_t n, long pos, const char *c) { + if (n <= pos) { + return -1; + } char rchar = buffer[pos]; buffer[pos] = c[1] ? c[0] : 'a'; @@ -497,7 +500,7 @@ static ssize_t tamp(char *buffer, size_t bfsize, ssize_t n, ssize_t desync(int sfd, char *buffer, size_t bfsize, - ssize_t n, ssize_t offset, const struct sockaddr *dst, int dp_c) + ssize_t n, ssize_t offset, int dp_c) { struct desync_params dp = params.dp[dp_c]; struct proto_info info = { 0 }; @@ -555,12 +558,12 @@ ssize_t desync(int sfd, char *buffer, size_t bfsize, case DESYNC_OOB: s = send_oob(sfd, - buffer + lp, n - lp, pos - lp, dp.oob_char); + buffer + lp, bfsize - lp, pos - lp, dp.oob_char); break; case DESYNC_DISOOB: s = send_late_oob(sfd, - buffer + lp, n - lp, pos - lp, dp.oob_char); + buffer + lp, bfsize - lp, pos - lp, dp.oob_char); break; case DESYNC_SPLIT: @@ -618,7 +621,7 @@ int post_desync(int sfd, int dp_c) } -ssize_t desync_udp(int sfd, char *buffer, size_t bfsize, +ssize_t desync_udp(int sfd, char *buffer, ssize_t n, const struct sockaddr *dst, int dp_c) { struct desync_params *dp = ¶ms.dp[dp_c]; diff --git a/desync.h b/desync.h index fede53d..9b47925 100644 --- a/desync.h +++ b/desync.h @@ -10,9 +10,9 @@ #include #endif -ssize_t desync(int sfd, char *buffer, size_t bfsize, ssize_t n, ssize_t offset, const struct sockaddr *dst, int dp_c); +ssize_t desync(int sfd, char *buffer, size_t bfsize, ssize_t n, ssize_t offset, int dp_c); -ssize_t desync_udp(int sfd, char *buffer, size_t bfsize, 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, int dp_c); int setttl(int fd, int ttl); diff --git a/error.h b/error.h index d65d9ee..342a0d6 100644 --- a/error.h +++ b/error.h @@ -2,6 +2,7 @@ #define CIADPI_ERROR_H #include +#include #include #ifdef _WIN32 @@ -35,7 +36,7 @@ #endif #endif -static inline const int unie(int e) +static int unie(int e) { #ifdef _WIN32 switch (e) { @@ -66,9 +67,13 @@ static inline const int unie(int e) #define LOG_E -1 #define LOG_S 1 #define LOG_L 2 - #define LOG(s, str, ...) \ - if (params.debug >= s) \ - fprintf(stderr, str, ##__VA_ARGS__) + static void LOG(int s, char *str, ...) { + if (params.debug >= s) { + va_list args; + va_start(args, str); + vfprintf(stderr, str, args); + } + } #endif #define INIT_ADDR_STR(dst) \ @@ -86,7 +91,7 @@ static inline const int unie(int e) char HEX_STR[s * 2 + 1]; \ HEX_STR[sizeof(HEX_STR) - 1] = 0; \ do { \ - size_t i; \ + ssize_t i; \ for (i = 0; i + 4 <= s; i += 4) \ snprintf(HEX_STR + i * 2, sizeof(HEX_STR) - i * 2, \ "%02x%02x%02x%02x", b[i],b[i+1],b[i+2],b[i+3]); \ diff --git a/extend.c b/extend.c index e8de005..42ccaa3 100644 --- a/extend.c +++ b/extend.c @@ -23,7 +23,7 @@ #include "desync.h" #include "packets.h" -#define KEY_SIZE sizeof(struct sockaddr_ina) +#define KEY_SIZE sizeof(union sockaddr_u) static int set_timeout(int fd, unsigned int s) @@ -47,7 +47,7 @@ static int set_timeout(int fd, unsigned int s) } -static ssize_t serialize_addr(const struct sockaddr_ina *dst, +static ssize_t serialize_addr(const union sockaddr_u *dst, uint8_t *const out, const size_t out_len) { #define serialize(raw, field, len, counter){ \ @@ -72,7 +72,7 @@ static ssize_t serialize_addr(const struct sockaddr_ina *dst, } -static int cache_get(const struct sockaddr_ina *dst) +static int cache_get(const union sockaddr_u *dst) { uint8_t key[KEY_SIZE] = { 0 }; int len = serialize_addr(dst, key, sizeof(key)); @@ -90,7 +90,7 @@ static int cache_get(const struct sockaddr_ina *dst) } -static int cache_add(const struct sockaddr_ina *dst, int m) +static int cache_add(const union sockaddr_u *dst, int m) { assert(m >= 0 && m < params.dp_count); @@ -123,10 +123,9 @@ static int cache_add(const struct sockaddr_ina *dst, int m) return 0; } -static bool check_l34(struct desync_params *dp, int st, const struct sockaddr_in6 *dst); int connect_hook(struct poolhd *pool, struct eval *val, - const struct sockaddr_ina *dst, int next) + const union sockaddr_u *dst, int next) { int m = cache_get(dst); val->cache = (m == 0); @@ -156,8 +155,7 @@ static int reconnect(struct poolhd *pool, struct eval *val, int m) struct eval *client = val->pair; - if (create_conn(pool, client, - (struct sockaddr_ina *)&val->in6, EV_FIRST_TUNNEL)) { + if (create_conn(pool, client, &val->addr, EV_FIRST_TUNNEL)) { return -1; } val->pair = 0; @@ -190,10 +188,8 @@ static bool check_host( static bool check_ip( - struct mphdr *ipset, const struct sockaddr_in6 *addr) + struct mphdr *ipset, const union sockaddr_u *dst) { - const struct sockaddr_ina *dst = (const struct sockaddr_ina *)addr; - int len = sizeof(dst->in.sin_addr); char *data = (char *)&dst->in.sin_addr; @@ -225,7 +221,7 @@ static bool check_proto_tcp(int proto, const char *buffer, ssize_t n) } -static bool check_l34(struct desync_params *dp, int st, const struct sockaddr_in6 *dst) +static bool check_l34(struct desync_params *dp, int st, const union sockaddr_u *dst) { if ((dp->proto & IS_UDP) && (st != SOCK_DGRAM)) { return 0; @@ -233,13 +229,13 @@ static bool check_l34(struct desync_params *dp, int st, const struct sockaddr_in if (dp->proto & IS_IPV4) { static const char *pat = "\0\0\0\0\0\0\0\0\0\0\xff\xff"; - if (dst->sin6_family != AF_INET - && memcmp(&dst->sin6_addr, pat, 12)) { + if (dst->sa.sa_family != AF_INET + && memcmp(&dst->in6.sin6_addr, pat, 12)) { return 0; } } if (dp->pf[0] && - (dst->sin6_port < dp->pf[0] || dst->sin6_port > dp->pf[1])) { + (dst->in.sin_port < dp->pf[0] || dst->in.sin_port > dp->pf[1])) { return 0; } if (dp->ipset && !check_ip(dp->ipset, dst)) { @@ -277,13 +273,11 @@ static int on_trigger(int type, struct poolhd *pool, struct eval *val) if (can_reconn) { return reconnect(pool, val, m); } - cache_add( - (struct sockaddr_ina *)&val->in6, m); + cache_add(&val->addr, m); break; } if (m >= params.dp_count && m > 1) { - cache_add( - (struct sockaddr_ina *)&val->in6, 0); + cache_add(&val->addr, 0); } return -1; } @@ -362,7 +356,7 @@ static int setup_conn(struct eval *client, const char *buffer, ssize_t n) if (!m) for (; m < params.dp_count; m++) { struct desync_params *dp = ¶ms.dp[m]; if (!dp->detect - && check_l34(dp, SOCK_STREAM, &client->pair->in6) + && check_l34(dp, SOCK_STREAM, &client->pair->addr) && check_proto_tcp(dp->proto, buffer, n) && (!dp->hosts || check_host(dp->hosts, buffer, n))) { break; @@ -423,7 +417,7 @@ static int send_saved_req(struct poolhd *pool, int on_first_tunnel(struct poolhd *pool, - struct eval *val, char *buffer, ssize_t bfsize, int etype) + struct eval *val, char *buffer, size_t bfsize, int etype) { if ((etype & POLLOUT) && val->flag == FLAG_CONN) { if (mod_etype(pool, val, POLLIN) || @@ -462,8 +456,7 @@ int on_first_tunnel(struct poolhd *pool, free_first_req(val->pair); int m = val->pair->attempt; - if (val->pair->cache && - cache_add((struct sockaddr_ina *)&val->in6, m) < 0) { + if (val->pair->cache && cache_add(&val->addr, m) < 0) { return -1; } } @@ -497,8 +490,8 @@ ssize_t tcp_send_hook(struct eval *remote, ssize_t offset = remote->pair->round_sent; if (!offset && remote->round_count) offset = -1; - sn = desync(remote->fd, buffer, bfsize, n, - offset, (struct sockaddr *)&remote->in6, m); + sn = desync(remote->fd, + buffer, bfsize, n, offset, m); } } if (skip) { @@ -512,8 +505,8 @@ ssize_t tcp_send_hook(struct eval *remote, } -ssize_t tcp_recv_hook(struct poolhd *pool, struct eval *val, - char *buffer, size_t bfsize) +ssize_t tcp_recv_hook(struct poolhd *pool, + struct eval *val, char *buffer, size_t bfsize) { ssize_t n = recv(val->fd, buffer, bfsize, 0); if (n < 1) { @@ -557,7 +550,7 @@ ssize_t tcp_recv_hook(struct poolhd *pool, struct eval *val, ssize_t udp_hook(struct eval *val, - char *buffer, size_t bfsize, ssize_t n, struct sockaddr_ina *dst) + char *buffer, ssize_t n, const union sockaddr_u *dst) { struct eval *pair = val->pair->pair; @@ -566,7 +559,7 @@ ssize_t udp_hook(struct eval *val, for (; m < params.dp_count; m++) { struct desync_params *dp = ¶ms.dp[m]; if (!dp->detect - && check_l34(dp, SOCK_DGRAM, &dst->in6)) { + && check_l34(dp, SOCK_DGRAM, dst)) { break; } } @@ -579,7 +572,7 @@ ssize_t udp_hook(struct eval *val, 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, bfsize, n, &dst->sa, m); + return desync_udp(val->fd, buffer, n, &dst->sa, m); } @@ -605,7 +598,7 @@ static int protect(int conn_fd, const char *path) close(fd); return -1; } - char buf[CMSG_SPACE(sizeof(fd))] = {}; + char buf[CMSG_SPACE(sizeof(fd))] = { 0 }; struct iovec io = { .iov_base = "1", .iov_len = 1 }; struct msghdr msg = { .msg_iov = &io }; diff --git a/extend.h b/extend.h index edae150..b653e9d 100644 --- a/extend.h +++ b/extend.h @@ -8,7 +8,7 @@ int socket_mod(int fd); int connect_hook(struct poolhd *pool, struct eval *val, - const struct sockaddr_ina *dst, int next); + const union sockaddr_u *dst, int next); ssize_t tcp_send_hook(struct eval *val, char *buffer, size_t bfsize, ssize_t n); @@ -17,10 +17,10 @@ ssize_t tcp_recv_hook(struct poolhd *pool, struct eval *val, char *buffer, size_t bfsize); ssize_t udp_hook(struct eval *val, - char *buffer, size_t bfsize, ssize_t n, struct sockaddr_ina *dst); + char *buffer, ssize_t n, const union sockaddr_u *dst); int on_first_tunnel(struct poolhd *pool, - struct eval *val, char *buffer, ssize_t bfsize, int etype); + struct eval *val, char *buffer, size_t bfsize, int etype); #ifdef __linux__ static int protect(int conn_fd, const char *path); diff --git a/main.c b/main.c index 2e3794e..56a2155 100644 --- a/main.c +++ b/main.c @@ -54,17 +54,17 @@ struct params params = { .max_open = 512, .bfsize = 16384, .baddr = { - .sin6_family = AF_INET6 + .in6 = { .sin6_family = AF_INET6 } }, .laddr = { - .sin6_family = AF_INET + .in = { .sin_family = AF_INET } }, .debug = 0, .auto_level = AUTO_NOBUFF }; -const static char help_text[] = { +static const char help_text[] = { " -i, --ip, Listening IP, default 0.0.0.0\n" " -p, --port Listening port, default 1080\n" #ifdef DAEMON @@ -187,15 +187,15 @@ const struct option options[] = { }; -size_t parse_cform(char *buffer, size_t blen, +ssize_t parse_cform(char *buffer, size_t blen, const char *str, size_t slen) { static char esca[] = { 'r','\r','n','\n','t','\t','\\','\\', 'f','\f','b','\b','v','\v','a','\a', 0 }; - ssize_t i = 0, p = 0; - for (; p < slen && i < blen; ++p && ++i) { + size_t i = 0, p = 0; + for (; p < slen && i < blen; ++p, ++i) { if (str[p] != '\\') { buffer[i] = str[p]; continue; @@ -212,8 +212,8 @@ size_t parse_cform(char *buffer, size_t blen, continue; } int n = 0; - if (sscanf(&str[p], "x%2hhx%n", &buffer[i], &n) == 1 - || sscanf(&str[p], "%3hho%n", &buffer[i], &n) == 1) { + if (sscanf(&str[p], "x%2hhx%n", (uint8_t *)&buffer[i], &n) == 1 + || sscanf(&str[p], "%3hho%n", (uint8_t *)&buffer[i], &n) == 1) { p += (n - 1); continue; } @@ -233,7 +233,7 @@ char *data_from_str(const char *str, ssize_t *size) if (!d) { return 0; } - size_t i = parse_cform(d, len, str, len); + ssize_t i = parse_cform(d, len, str, len); char *m = len != i ? realloc(d, i) : 0; if (i == 0) { @@ -270,7 +270,8 @@ char *ftob(const char *str, ssize_t *sl) if (!(buffer = malloc(size))) { break; } - if (fread(buffer, 1, size, file) != size) { + size_t rs = fread(buffer, 1, size, file); + if (rs != (size_t )size) { free(buffer); buffer = 0; } @@ -330,7 +331,7 @@ struct mphdr *parse_hosts(char *buffer, size_t size) } } else { - LOG(LOG_E, "invalid host: num: %zd \"%.*s\"\n", num + 1, (int )(e - s), s); + LOG(LOG_E, "invalid host: num: %zd \"%.*s\"\n", num + 1, ((int )(e - s)), s); drop = 0; } num++; @@ -412,7 +413,7 @@ struct mphdr *parse_ipset(char *buffer, size_t size) } -int get_addr(const char *str, struct sockaddr_ina *addr) +int get_addr(const char *str, union sockaddr_u *addr) { struct addrinfo hints = {0}, *res = 0; @@ -438,7 +439,7 @@ int get_addr(const char *str, struct sockaddr_ina *addr) } -int get_default_ttl() +int get_default_ttl(void) { int orig_ttl = -1, fd; socklen_t tsize = sizeof(orig_ttl); @@ -456,7 +457,7 @@ int get_default_ttl() } -bool ipv6_support() +bool ipv6_support(void) { int fd = socket(AF_INET6, SOCK_STREAM, 0); if (fd < 0) { @@ -637,10 +638,10 @@ int main(int argc, char **argv) opt[o] = ':'; } } - - params.laddr.sin6_port = htons(1080); + // + params.laddr.in.sin_port = htons(1080); if (!ipv6_support()) { - params.baddr.sin6_family = AF_INET; + params.baddr.sa.sa_family = AF_INET; } char *pid_file = 0; @@ -699,8 +700,7 @@ int main(int argc, char **argv) return 0; case 'i': - if (get_addr(optarg, - (struct sockaddr_ina *)¶ms.laddr) < 0) + if (get_addr(optarg, ¶ms.laddr) < 0) invalid = 1; break; @@ -709,12 +709,11 @@ int main(int argc, char **argv) if (val <= 0 || val > 0xffff || *end) invalid = 1; else - params.laddr.sin6_port = htons(val); + params.laddr.in.sin_port = htons(val); break; case 'I': - if (get_addr(optarg, - (struct sockaddr_ina *)¶ms.baddr) < 0) + if (get_addr(optarg, ¶ms.baddr) < 0) invalid = 1; break; @@ -1096,7 +1095,7 @@ int main(int argc, char **argv) } } - if (params.baddr.sin6_family != AF_INET6) { + if (params.baddr.sa.sa_family != AF_INET6) { params.ipv6 = 0; } if (!params.def_ttl) { @@ -1123,7 +1122,7 @@ int main(int argc, char **argv) return -1; } #endif - int status = run((struct sockaddr_ina *)¶ms.laddr); + int status = run(¶ms.laddr); clear_params(); return status; } diff --git a/mpool.c b/mpool.c index 01e1af4..5a8b0b6 100644 --- a/mpool.c +++ b/mpool.c @@ -5,6 +5,7 @@ #include #include + static int bit_cmp(const struct elem *p, const struct elem *q) { int len = q->len < p->len ? q->len : p->len; @@ -23,6 +24,7 @@ static int bit_cmp(const struct elem *p, const struct elem *q) return 0; } + static int byte_cmp(const struct elem *p, const struct elem *q) { if (p->len != q->len) { @@ -31,6 +33,7 @@ static int byte_cmp(const struct elem *p, const struct elem *q) return memcmp(p->data, q->data, p->len); } + static int host_cmp(const struct elem *p, const struct elem *q) { int len = q->len < p->len ? q->len : p->len; @@ -48,6 +51,7 @@ static int host_cmp(const struct elem *p, const struct elem *q) return p->len > q->len ? 1 : -1; } + static int scmp(const struct elem *p, const struct elem *q) { switch (p->cmp_type) { @@ -65,7 +69,7 @@ KAVL_INIT(my, struct elem, head, scmp) struct mphdr *mem_pool(bool is_static, unsigned char cmp_type) { - struct mphdr *hdr = calloc(sizeof(struct mphdr), 1); + struct mphdr *hdr = calloc(1, sizeof(struct mphdr)); if (hdr) { hdr->static_data = is_static; hdr->cmp_type = cmp_type; @@ -86,7 +90,7 @@ struct elem *mem_get(const struct mphdr *hdr, const char *str, int len) struct elem *mem_add(struct mphdr *hdr, char *str, int len, size_t struct_size) { - struct elem *v, *e = calloc(struct_size, 1); + struct elem *v, *e = calloc(1, struct_size); if (!e) { return 0; } diff --git a/packets.c b/packets.c index 8f6fb30..5c10600 100644 --- a/packets.c +++ b/packets.c @@ -108,7 +108,7 @@ static size_t chello_ext_offset(uint16_t type, const char *data, size_t size) return 0; } uint8_t sid_len = data[43]; - if (size < 44 + sid_len + 2) { + if (size < (44lu + sid_len + 2)) { return 0; } uint16_t cip_len = ANTOHS(data, 44 + sid_len); diff --git a/params.h b/params.h index 706be71..526b915 100644 --- a/params.h +++ b/params.h @@ -7,6 +7,7 @@ #include #include "mpool.h" +#include "conev.h" #ifdef _WIN32 #include @@ -114,8 +115,8 @@ struct params { int max_open; int debug; size_t bfsize; - struct sockaddr_in6 baddr; - struct sockaddr_in6 laddr; + union sockaddr_u baddr; + union sockaddr_u laddr; bool transparent; struct mphdr *mempool; diff --git a/proxy.c b/proxy.c index 3f88324..e3239a6 100644 --- a/proxy.c +++ b/proxy.c @@ -45,11 +45,11 @@ int NOT_EXIT = 1; static void on_cancel(int sig) { - NOT_EXIT = 0; + if (sig) NOT_EXIT = 0; } -void map_fix(struct sockaddr_ina *addr, char f6) +void map_fix(union sockaddr_u *addr, char f6) { struct { uint64_t o64; @@ -75,18 +75,15 @@ void map_fix(struct sockaddr_ina *addr, char f6) static inline char addr_equ( - const struct sockaddr_ina *a, const struct sockaddr_ina *b) + const union sockaddr_u *a, const union sockaddr_u *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); + return memcmp(&a->in6.sin6_addr, + &b->in6.sin6_addr, sizeof(b->in6.sin6_addr)) == 0; } @@ -122,7 +119,7 @@ static inline int nb_socket(int domain, int type) static int resolve(char *host, int len, - struct sockaddr_ina *addr, int type) + union sockaddr_u *addr, int type) { struct addrinfo hints = {0}, *res = 0; @@ -161,7 +158,7 @@ static int auth_socks5(int fd, const char *buffer, ssize_t n) break; } uint8_t a[2] = { S_VER5, c }; - if (send(fd, a, sizeof(a), 0) < 0) { + if (send(fd, (char *)a, sizeof(a), 0) < 0) { uniperror("send"); return -1; } @@ -221,7 +218,7 @@ static int resp_error(int fd, int e, int flag) static int s4_get_addr(const char *buff, - size_t n, struct sockaddr_ina *dst) + size_t n, union sockaddr_u *dst) { if (n < sizeof(struct s4_req) + 1) { return -1; @@ -258,7 +255,7 @@ static int s4_get_addr(const char *buff, static int s5_get_addr(const char *buffer, - size_t n, struct sockaddr_ina *addr, int type) + size_t n, union sockaddr_u *addr, int type) { if (n < S_SIZE_MIN) { LOG(LOG_E, "ss: request too small\n"); @@ -267,7 +264,7 @@ static int s5_get_addr(const char *buffer, struct s5_req *r = (struct s5_req *)buffer; size_t o = (r->atp == S_ATP_I4 ? S_SIZE_I4 : - (r->atp == S_ATP_ID ? r->id.len + S_SIZE_ID : + (r->atp == S_ATP_ID ? r->dst.id.len + S_SIZE_ID : (r->atp == S_ATP_I6 ? S_SIZE_I6 : 0))); if (n < o) { LOG(LOG_E, "ss: bad request\n"); @@ -276,16 +273,16 @@ static int s5_get_addr(const char *buffer, switch (r->atp) { case S_ATP_I4: addr->in.sin_family = AF_INET; - addr->in.sin_addr = r->i4; + addr->in.sin_addr = r->dst.i4.ip; break; case S_ATP_ID: if (!params.resolve) { return -S_ER_ATP; } - if (r->id.len < 3 || - resolve(r->id.domain, r->id.len, addr, type)) { - LOG(LOG_E, "not resolved: %.*s\n", r->id.len, r->id.domain); + if (r->dst.id.len < 3 || + resolve(r->dst.id.domain, r->dst.id.len, addr, type)) { + LOG(LOG_E, "not resolved: %.*s\n", r->dst.id.len, r->dst.id.domain); return -S_ER_HOST; } break; @@ -295,7 +292,7 @@ static int s5_get_addr(const char *buffer, return -S_ER_ATP; else { addr->in6.sin6_family = AF_INET6; - addr->in6.sin6_addr = r->i6; + addr->in6.sin6_addr = r->dst.i6.ip; } } memcpy(&addr->in.sin_port, &buffer[o - 2], sizeof(uint16_t)); @@ -304,7 +301,7 @@ static int s5_get_addr(const char *buffer, static int s5_set_addr(char *buffer, size_t n, - const struct sockaddr_ina *addr, char end) + const union sockaddr_u *addr, char end) { struct s5_req *r = (struct s5_req *)buffer; if (n < S_SIZE_I4) { @@ -315,8 +312,8 @@ static int s5_set_addr(char *buffer, size_t n, 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; + r->dst.i4.ip = addr->in.sin_addr; + r->dst.i4.port = addr->in.sin_port; return S_SIZE_I4; } else { if (n < S_SIZE_I6) { @@ -326,22 +323,22 @@ static int s5_set_addr(char *buffer, size_t n, 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; + r->dst.i6.ip = addr->in6.sin6_addr; + r->dst.i6.port = addr->in6.sin6_port; return S_SIZE_I6; } return 0; } -static int remote_sock(struct sockaddr_ina *dst, int type) +static int remote_sock(union sockaddr_u *dst, int type) { - if (params.baddr.sin6_family == AF_INET6) { + if (params.baddr.sa.sa_family == AF_INET6) { map_fix(dst, 6); } else { map_fix(dst, 0); } - if (dst->sa.sa_family != params.baddr.sin6_family) { + if (dst->sa.sa_family != params.baddr.sa.sa_family) { LOG(LOG_E, "different addresses family\n"); return -1; } @@ -374,9 +371,9 @@ static int remote_sock(struct sockaddr_ina *dst, int type) int create_conn(struct poolhd *pool, - struct eval *val, const struct sockaddr_ina *dst, int next) + struct eval *val, const union sockaddr_u *dst, int next) { - struct sockaddr_ina addr = *dst; + union sockaddr_u addr = *dst; int sfd = remote_sock(&addr, SOCK_STREAM); if (sfd < 0) { @@ -434,9 +431,9 @@ int create_conn(struct poolhd *pool, val->pair = pair; pair->pair = val; #ifdef __NetBSD__ - pair->in6 = addr.in6; + pair->addr = addr; #else - pair->in6 = dst->in6; + pair->addr = *dst; #endif pair->flag = FLAG_CONN; val->type = EV_IGNORE; @@ -445,9 +442,9 @@ int create_conn(struct poolhd *pool, static int udp_associate(struct poolhd *pool, - struct eval *val, const struct sockaddr_ina *dst) + struct eval *val, const union sockaddr_u *dst) { - struct sockaddr_ina addr = *dst; + union sockaddr_u addr = *dst; int ufd = remote_sock(&addr, SOCK_DGRAM); if (ufd < 0) { @@ -464,7 +461,7 @@ static int udp_associate(struct poolhd *pool, del_event(pool, pair); return -1; } - pair->in6 = addr.in6; + pair->addr = addr; } // socklen_t sz = sizeof(addr); @@ -504,8 +501,8 @@ static int udp_associate(struct poolhd *pool, pair->pair = val; client->flag = FLAG_CONN; - client->in6 = val->in6; - client->in6.sin6_port = 0; + client->addr = val->addr; + client->addr.in.sin_port = 0; sz = sizeof(addr); if (getsockname(cfd, &addr.sa, &sz)) { @@ -533,7 +530,7 @@ static int udp_associate(struct poolhd *pool, #ifdef __linux__ static inline int transp_conn(struct poolhd *pool, struct eval *val) { - struct sockaddr_ina remote, self; + union sockaddr_u remote, self; socklen_t rlen = sizeof(remote), slen = sizeof(self); if (getsockopt(val->fd, IPPROTO_IP, SO_ORIGINAL_DST, &remote, &rlen) != 0) @@ -565,7 +562,7 @@ static inline int transp_conn(struct poolhd *pool, struct eval *val) static int on_accept(struct poolhd *pool, const struct eval *val) { - struct sockaddr_ina client; + union sockaddr_u client; struct eval *rval; while (1) { @@ -607,7 +604,7 @@ static int on_accept(struct poolhd *pool, const struct eval *val) close(c); continue; } - rval->in6 = client.in6; + rval->addr = client; #ifdef __linux__ if (params.transparent && transp_conn(pool, rval) < 0) { del_event(pool, rval); @@ -689,7 +686,7 @@ static int on_tunnel(struct poolhd *pool, struct eval *val, } break; } - } while (n == bfsize); + } while (n == (ssize_t )bfsize); return 0; } @@ -703,7 +700,7 @@ static int on_udp_tunnel(struct eval *val, char *buffer, size_t bfsize) data += S_SIZE_I6; data_len -= S_SIZE_I6; } - struct sockaddr_ina addr = {0}; + union sockaddr_u addr = {0}; struct eval *pair = val->flag == FLAG_CONN ? val->pair : val->pair->pair; @@ -726,15 +723,15 @@ static int on_udp_tunnel(struct eval *val, char *buffer, size_t bfsize) ssize_t ns; if (val->flag == FLAG_CONN) { - if (!val->in6.sin6_port) { - if (!addr_equ(&addr, (struct sockaddr_ina *)&val->in6)) { + if (!val->addr.in.sin_port) { + if (!addr_equ(&addr, &val->addr)) { return 0; } if (connect(val->fd, &addr.sa, SA_SIZE(&addr)) < 0) { uniperror("connect"); return -1; } - val->in6 = addr.in6; + val->addr = addr; } if (*(data + 2) != 0) { // frag continue; @@ -744,21 +741,20 @@ static int on_udp_tunnel(struct eval *val, char *buffer, size_t bfsize) LOG(LOG_E, "udp parse error\n"); return -1; } - if (!pair->in6.sin6_port) { - if (params.baddr.sin6_family == AF_INET6) { + if (!pair->addr.in.sin_port) { + if (params.baddr.sa.sa_family == AF_INET6) { map_fix(&addr, 6); } - if (params.baddr.sin6_family != addr.sa.sa_family) { + if (params.baddr.sa.sa_family != addr.sa.sa_family) { return -1; } if (connect(pair->fd, &addr.sa, SA_SIZE(&addr)) < 0) { uniperror("connect"); return -1; } - pair->in6 = addr.in6; + pair->addr = addr; } - ns = udp_hook(pair, data + offs, bfsize - offs, n - offs, - (struct sockaddr_ina *)&pair->in6); + ns = udp_hook(pair, data + offs, n - offs, &pair->addr); } else { map_fix(&addr, 0); @@ -782,7 +778,7 @@ static int on_udp_tunnel(struct eval *val, char *buffer, size_t bfsize) static inline int on_request(struct poolhd *pool, struct eval *val, char *buffer, size_t bfsize) { - struct sockaddr_ina dst = {0}; + union sockaddr_u dst = {0}; ssize_t n = recv(val->fd, buffer, bfsize, 0); if (n < 1) { @@ -820,6 +816,7 @@ static inline int on_request(struct poolhd *pool, struct eval *val, } break; } + __attribute__((fallthrough)); default: LOG(LOG_E, "ss: unsupported cmd: 0x%x\n", r->cmd); s5e = -S_ER_CMD; @@ -986,7 +983,7 @@ int event_loop(int srvfd) } -int listen_socket(const struct sockaddr_ina *srv) +int listen_socket(const union sockaddr_u *srv) { int srvfd = nb_socket(srv->sa.sa_family, SOCK_STREAM); if (srvfd < 0) { @@ -1014,7 +1011,7 @@ int listen_socket(const struct sockaddr_ina *srv) } -int run(const struct sockaddr_ina *srv) +int run(const union sockaddr_u *srv) { #ifdef SIGPIPE if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) diff --git a/proxy.h b/proxy.h index fb28035..6b54ca0 100644 --- a/proxy.h +++ b/proxy.h @@ -16,14 +16,6 @@ (((struct sockaddr *)s)->sa_family == AF_INET6) ? \ sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in) -struct sockaddr_ina { - union { - struct sockaddr sa; - struct sockaddr_in in; - struct sockaddr_in6 in6; - }; -}; - #pragma pack(push, 1) struct s4_req { @@ -36,18 +28,18 @@ struct s5_req { uint8_t ver, cmd, zero, atp; union { struct { - struct in_addr i4; - uint16_t p4; - }; + struct in_addr ip; + uint16_t port; + } i4; struct { - struct in6_addr i6; - uint16_t p6; - }; + struct in6_addr ip; + uint16_t port; + } i6; struct { uint8_t len; - char domain[]; + char domain[257]; } id; - }; + } dst; }; struct s5_rep { @@ -55,46 +47,34 @@ struct s5_rep { struct { struct in_addr i4; uint16_t port; - }; + } addr; }; #pragma pack(pop) -enum s_auth { - S_AUTH_NONE = 0x00, - S_AUTH_GSSAPI = 0x01, - S_AUTH_USPA = 0x02, - S_AUTH_BAD = 0xff -}; +#define S_AUTH_NONE 0x00 +#define S_AUTH_BAD 0xff -enum s_atp { - S_ATP_I4 = 0x01, - S_ATP_ID = 0x03, - S_ATP_I6 = 0x04 -}; +#define S_ATP_I4 0x01 +#define S_ATP_ID 0x03 +#define S_ATP_I6 0x04 -enum s_cmd { - S_CMD_CONN = 0x01, - S_CMD_BIND = 0x02, - S_CMD_AUDP = 0x03 -}; +#define S_CMD_CONN 0x01 +#define S_CMD_BIND 0x02 +#define S_CMD_AUDP 0x03 -enum s_err { - S_ER_OK = 0x00, - S_ER_GEN = 0x01, - S_ER_DENY = 0x02, - S_ER_NET = 0x03, - S_ER_HOST = 0x04, - S_ER_CONN = 0x05, - S_ER_TTL = 0x06, - S_ER_CMD = 0x07, - S_ER_ATP = 0x08 -}; +#define S_ER_OK 0x00 +#define S_ER_GEN 0x01 +#define S_ER_DENY 0x02 +#define S_ER_NET 0x03 +#define S_ER_HOST 0x04 +#define S_ER_CONN 0x05 +#define S_ER_TTL 0x06 +#define S_ER_CMD 0x07 +#define S_ER_ATP 0x08 -enum s4_rep { - S4_OK = 0x5a, - S4_ER = 0x5b -}; +#define S4_OK 0x5a +#define S4_ER 0x5b #define S_VER5 0x05 #define S_VER4 0x04 @@ -104,15 +84,15 @@ enum s4_rep { #define S_SIZE_I6 22 #define S_SIZE_ID 7 -void map_fix(struct sockaddr_ina *addr, char f6); +void map_fix(union sockaddr_u *addr, char f6); int create_conn(struct poolhd *pool, - struct eval *val, const struct sockaddr_ina *dst, int next); + struct eval *val, const union sockaddr_u *dst, int next); -int listen_socket(const struct sockaddr_ina *srv); +int listen_socket(const union sockaddr_u *srv); int event_loop(int srvfd); -int run(const struct sockaddr_ina *srv); +int run(const union sockaddr_u *srv); #endif