diff --git a/src/Makefile.am b/src/Makefile.am index b926e7d4..de93f53d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ VERSION_INFO = 2:0:0 -AM_CFLAGS = -g -O2 -Wall -Werror -Wno-deprecated-declarations -fno-strict-aliasing -std=gnu99 -D_GNU_SOURCE +AM_CFLAGS = -g -O2 -Wall -Werror -Wno-deprecated-declarations -Wcast-align -std=gnu99 -D_GNU_SOURCE AM_CFLAGS += $(PTHREAD_CFLAGS) if !USE_SYSTEM_SHARED_LIB AM_CFLAGS += -I$(top_srcdir)/libbloom diff --git a/src/aead.c b/src/aead.c index 1fe27131..10fcfe00 100644 --- a/src/aead.c +++ b/src/aead.c @@ -591,7 +591,7 @@ aead_chunk_decrypt(cipher_ctx_t *ctx, uint8_t *p, uint8_t *c, uint8_t *n, return CRYPTO_ERROR; assert(*plen == CHUNK_SIZE_LEN); - mlen = ntohs(*(uint16_t *)len_buf); + mlen = load16_be(len_buf); mlen = mlen & CHUNK_SIZE_MASK; if (mlen == 0) diff --git a/src/local.c b/src/local.c index e14d0b50..09de3c8c 100644 --- a/src/local.c +++ b/src/local.c @@ -381,7 +381,7 @@ server_handshake(EV_P_ ev_io *w, buffer_t *buf) abuf->len += in_addr_len + 2; if (acl || verbose) { - uint16_t p = ntohs(*(uint16_t *)(buf->data + request_len + in_addr_len)); + uint16_t p = load16_be(buf->data + request_len + in_addr_len); if (!inet_ntop(AF_INET, (const void *)(buf->data + request_len), ip, INET_ADDRSTRLEN)) { LOGI("inet_ntop(AF_INET): %s", strerror(errno)); @@ -399,8 +399,7 @@ server_handshake(EV_P_ ev_io *w, buffer_t *buf) abuf->len += name_len + 2; if (acl || verbose) { - uint16_t p = - ntohs(*(uint16_t *)(buf->data + request_len + 1 + name_len)); + uint16_t p = load16_be(buf->data + request_len + 1 + name_len); memcpy(host, buf->data + request_len + 1, name_len); host[name_len] = '\0'; sprintf(port, "%d", p); @@ -414,7 +413,7 @@ server_handshake(EV_P_ ev_io *w, buffer_t *buf) abuf->len += in6_addr_len + 2; if (acl || verbose) { - uint16_t p = ntohs(*(uint16_t *)(buf->data + request_len + in6_addr_len)); + uint16_t p = load16_be(buf->data + request_len + in6_addr_len); if (!inet_ntop(AF_INET6, (const void *)(buf->data + request_len), ip, INET6_ADDRSTRLEN)) { LOGI("inet_ntop(AF_INET6): %s", strerror(errno)); @@ -437,7 +436,7 @@ server_handshake(EV_P_ ev_io *w, buffer_t *buf) int hostname_len = 0; char *hostname; - uint16_t dst_port = ntohs(*(uint16_t *)(abuf->data + abuf->len - 2)); + uint16_t dst_port = load16_be(abuf->data + abuf->len - 2); if (atyp == SOCKS5_ATYP_IPV4 || atyp == SOCKS5_ATYP_IPV6) { if (dst_port == http_protocol->default_port) diff --git a/src/server.c b/src/server.c index b7d805b8..ae511732 100644 --- a/src/server.c +++ b/src/server.c @@ -439,11 +439,13 @@ connect_to_remote(EV_P_ struct addrinfo *res, memset(ipstr, 0, INET6_ADDRSTRLEN); if (res->ai_addr->sa_family == AF_INET) { - struct sockaddr_in *s = (struct sockaddr_in *)res->ai_addr; - inet_ntop(AF_INET, &s->sin_addr, ipstr, INET_ADDRSTRLEN); + struct sockaddr_in s; + memcpy(&s, res->ai_addr, sizeof(struct sockaddr_in)); + inet_ntop(AF_INET, &s.sin_addr, ipstr, INET_ADDRSTRLEN); } else if (res->ai_addr->sa_family == AF_INET6) { - struct sockaddr_in6 *s = (struct sockaddr_in6 *)res->ai_addr; - inet_ntop(AF_INET6, &s->sin6_addr, ipstr, INET6_ADDRSTRLEN); + struct sockaddr_in6 s; + memcpy(&s, res->ai_addr, sizeof(struct sockaddr_in6)); + inet_ntop(AF_INET6, &s.sin6_addr, ipstr, INET6_ADDRSTRLEN); } if (outbound_block_match_host(ipstr) == 1) { @@ -553,10 +555,12 @@ connect_to_remote(EV_P_ struct addrinfo *res, FATAL("failed to set TCP_FASTOPEN_CONNECT"); s = connect(sockfd, res->ai_addr, res->ai_addrlen); #elif defined(CONNECT_DATA_IDEMPOTENT) - ((struct sockaddr_in *)(res->ai_addr))->sin_len = sizeof(struct sockaddr_in); + struct sockaddr_in sa; + memcpy(&sa, res->ai_addr, sizeof(struct sockaddr_in)); + sa.sin_len = sizeof(struct sockaddr_in); sa_endpoints_t endpoints; memset((char *)&endpoints, 0, sizeof(endpoints)); - endpoints.sae_dstaddr = res->ai_addr; + endpoints.sae_dstaddr = (struct sockaddr *)&sa; endpoints.sae_dstaddrlen = res->ai_addrlen; s = connectx(sockfd, &endpoints, SAE_ASSOCID_ANY, CONNECT_DATA_IDEMPOTENT, @@ -803,7 +807,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) size_t in_addr_len = sizeof(struct in_addr); addr->sin_family = AF_INET; if (server->buf->len >= in_addr_len + 3) { - addr->sin_addr = *(struct in_addr *)(server->buf->data + offset); + memcpy(&addr->sin_addr, server->buf->data + offset, in_addr_len); inet_ntop(AF_INET, (const void *)(server->buf->data + offset), host, INET_ADDRSTRLEN); offset += in_addr_len; @@ -812,7 +816,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) stop_server(EV_A_ server); return; } - addr->sin_port = *(uint16_t *)(server->buf->data + offset); + memcpy(&addr->sin_port, server->buf->data + offset, sizeof(uint16_t)); info.ai_family = AF_INET; info.ai_socktype = SOCK_STREAM; info.ai_protocol = IPPROTO_TCP; @@ -842,7 +846,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) if (ip.version == 4) { struct sockaddr_in *addr = (struct sockaddr_in *)&storage; inet_pton(AF_INET, host, &(addr->sin_addr)); - addr->sin_port = *(uint16_t *)(server->buf->data + offset); + memcpy(&addr->sin_port, server->buf->data + offset, sizeof(uint16_t)); addr->sin_family = AF_INET; info.ai_family = AF_INET; info.ai_addrlen = sizeof(struct sockaddr_in); @@ -850,7 +854,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) } else if (ip.version == 6) { struct sockaddr_in6 *addr = (struct sockaddr_in6 *)&storage; inet_pton(AF_INET6, host, &(addr->sin6_addr)); - addr->sin6_port = *(uint16_t *)(server->buf->data + offset); + memcpy(&addr->sin6_port, server->buf->data + offset, sizeof(uint16_t)); addr->sin6_family = AF_INET6; info.ai_family = AF_INET6; info.ai_addrlen = sizeof(struct sockaddr_in6); @@ -870,7 +874,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) size_t in6_addr_len = sizeof(struct in6_addr); addr->sin6_family = AF_INET6; if (server->buf->len >= in6_addr_len + 3) { - addr->sin6_addr = *(struct in6_addr *)(server->buf->data + offset); + memcpy(&addr->sin6_addr, server->buf->data + offset, in6_addr_len); inet_ntop(AF_INET6, (const void *)(server->buf->data + offset), host, INET6_ADDRSTRLEN); offset += in6_addr_len; @@ -880,7 +884,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) stop_server(EV_A_ server); return; } - addr->sin6_port = *(uint16_t *)(server->buf->data + offset); + memcpy(&addr->sin6_port, server->buf->data + offset, sizeof(uint16_t)); info.ai_family = AF_INET6; info.ai_socktype = SOCK_STREAM; info.ai_protocol = IPPROTO_TCP; @@ -894,7 +898,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) return; } - port = (*(uint16_t *)(server->buf->data + offset)); + port = ntohs(load16_be(server->buf->data + offset)); offset += 2; diff --git a/src/udprelay.c b/src/udprelay.c index 91d6f330..3c3cb588 100644 --- a/src/udprelay.c +++ b/src/udprelay.c @@ -252,8 +252,8 @@ parse_udprelay_header(const char *buf, const size_t buf_len, if (storage != NULL) { struct sockaddr_in *addr = (struct sockaddr_in *)storage; addr->sin_family = AF_INET; - addr->sin_addr = *(struct in_addr *)(buf + offset); - addr->sin_port = *(uint16_t *)(buf + offset + in_addr_len); + memcpy(&addr->sin_addr, buf + offset, sizeof(struct in_addr)); + memcpy(&addr->sin_port, buf + offset + in_addr_len, sizeof(uint16_t)); } if (host != NULL) { inet_ntop(AF_INET, (const void *)(buf + offset), @@ -273,12 +273,12 @@ parse_udprelay_header(const char *buf, const size_t buf_len, if (ip.version == 4) { struct sockaddr_in *addr = (struct sockaddr_in *)storage; inet_pton(AF_INET, tmp, &(addr->sin_addr)); - addr->sin_port = *(uint16_t *)(buf + offset + 1 + name_len); + memcpy(&addr->sin_port, buf + offset + 1 + name_len, sizeof(uint16_t)); addr->sin_family = AF_INET; } else if (ip.version == 6) { struct sockaddr_in6 *addr = (struct sockaddr_in6 *)storage; inet_pton(AF_INET, tmp, &(addr->sin6_addr)); - addr->sin6_port = *(uint16_t *)(buf + offset + 1 + name_len); + memcpy(&addr->sin6_port, buf + offset + 1 + name_len, sizeof(uint16_t)); addr->sin6_family = AF_INET6; } } @@ -295,8 +295,8 @@ parse_udprelay_header(const char *buf, const size_t buf_len, if (storage != NULL) { struct sockaddr_in6 *addr = (struct sockaddr_in6 *)storage; addr->sin6_family = AF_INET6; - addr->sin6_addr = *(struct in6_addr *)(buf + offset); - addr->sin6_port = *(uint16_t *)(buf + offset + in6_addr_len); + memcpy(&addr->sin6_addr, buf + offset, sizeof(struct in6_addr)); + memcpy(&addr->sin6_port, buf + offset + in6_addr_len, sizeof(uint16_t)); } if (host != NULL) { inet_ntop(AF_INET6, (const void *)(buf + offset), @@ -312,7 +312,7 @@ parse_udprelay_header(const char *buf, const size_t buf_len, } if (port != NULL) { - sprintf(port, "%d", ntohs(*(uint16_t *)(buf + offset))); + sprintf(port, "%d", load16_be(buf + offset)); } offset += 2; @@ -327,19 +327,21 @@ get_addr_str(const struct sockaddr *sa) char addr[INET6_ADDRSTRLEN] = { 0 }; char port[PORTSTRLEN] = { 0 }; uint16_t p; + struct sockaddr_in sa_in; + struct sockaddr_in6 sa_in6; switch (sa->sa_family) { case AF_INET: - inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr), - addr, INET_ADDRSTRLEN); - p = ntohs(((struct sockaddr_in *)sa)->sin_port); + memcpy(&sa_in, sa, sizeof(struct sockaddr_in)); + inet_ntop(AF_INET, &sa_in.sin_addr, addr, INET_ADDRSTRLEN); + p = ntohs(sa_in.sin_port); sprintf(port, "%d", p); break; case AF_INET6: - inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr), - addr, INET6_ADDRSTRLEN); - p = ntohs(((struct sockaddr_in *)sa)->sin_port); + memcpy(&sa_in6, sa, sizeof(struct sockaddr_in6)); + inet_ntop(AF_INET6, &sa_in6.sin6_addr, addr, INET6_ADDRSTRLEN); + p = ntohs(sa_in6.sin6_port); sprintf(port, "%d", p); break; diff --git a/src/utils.h b/src/utils.h index a9b77699..acecf362 100644 --- a/src/utils.h +++ b/src/utils.h @@ -247,7 +247,13 @@ void *ss_realloc(void *ptr, size_t new_size); #endif int ss_is_ipv6addr(const char *addr); - char *get_default_conf(void); +inline uint16_t load16_be(const void *s) +{ + const uint8_t *in = (const uint8_t *)s; + return ((uint16_t)in[0] << 8) + | ((uint16_t)in[1]); +} + #endif // _UTILS_H