From 2efa84c34e12ad0670c22484a5fa198304b803e0 Mon Sep 17 00:00:00 2001 From: James Bunton Date: Wed, 23 Sep 2015 08:25:58 +1000 Subject: [PATCH] Use thread safe strerror and change many errors to warnings --- Makefile | 2 +- socks5server.c | 52 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 5732821..caad0ba 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION := 0.1 +VERSION := 0.2 PREFIX := /usr/local CFLAGS += -Wall -Wextra -Werror -std=c99 -DVERSION='"$(VERSION)"' LDFLAGS += -lpthread -lbsd diff --git a/socks5server.c b/socks5server.c index 592bef0..972687d 100644 --- a/socks5server.c +++ b/socks5server.c @@ -24,9 +24,6 @@ static __thread char* log_context = ""; -#define log_errno(fmt, ...) \ - fprintf(stderr, "ERROR [%s] " fmt ": %s\n", log_context , ##__VA_ARGS__ , strerror(errno)); - #define log_error(fmt, ...) \ fprintf(stderr, "ERROR [%s] " fmt "\n", log_context , ##__VA_ARGS__); @@ -80,17 +77,36 @@ char* sockaddr_tostring(struct sockaddr_storage* addr) { return buf; } +static __thread char* errno_string = NULL; +static __thread size_t errno_string_len = 0; + +void realloc_errno_string() { + if (errno_string_len == 0) { + errno_string_len = 1; + } else { + errno_string_len *= 2; + } + errno_string = realloc(errno_string, errno_string_len); +} + +char* sstrerrno() { + int original_errno = errno; + while (strerror_r(original_errno, errno_string, errno_string_len) != 0) { + realloc_errno_string(); + } + return errno_string; +} + void* smalloc(size_t sz) { void* ptr = calloc(1, sz); if (ptr == NULL) { - log_errno("Memory allocation failed"); + log_error("Memory allocation failed: %s", sstrerrno()); exit(1); } return ptr; } - /********** * Config * **********/ @@ -146,7 +162,7 @@ bool ssend(int fd, void* buf, size_t len) { while (len > 0) { ssize_t sz = send(fd, buf, len, MSG_NOSIGNAL); if (sz < 0) { - log_errno("Failed to write, closing connection"); + log_warn("Failed to write, closing connection: %s", sstrerrno()); return false; } buf += sz; @@ -161,7 +177,7 @@ ssize_t srecv(int fd, void* buf, size_t len) { bool read_bytes(int fd, uint8_t* value, ssize_t sz) { if (srecv(fd, value, sz) != sz) { - log_errno("Failed to read from client socket"); + log_warn("Failed to read from client socket: %s", sstrerrno()); return false; } for (ssize_t i = 0; i < sz; ++i) { @@ -198,7 +214,7 @@ void proxy_copy_fd(int wfd, int rfd) { int bufsz = srecv(rfd, buf, sizeof(buf)); log_debug("proxy_copy_fd unblocked from read %d", rfd); if (bufsz < 0) { - log_errno("Failed to read, closing connection"); + log_warn("Failed to read, closing connection: %s", sstrerrno()); break; } if (bufsz == 0) { @@ -208,7 +224,7 @@ void proxy_copy_fd(int wfd, int rfd) { log_debug("proxy_copy_fd blocking on write %d", wfd); if (!ssend(wfd, buf, bufsz)) { - log_errno("Failed to write, closing connection"); + log_warn("Failed to write, closing connection: %s", sstrerrno()); break; } log_debug("proxy_copy_fd unblocked from write %d", wfd); @@ -247,7 +263,7 @@ bool proxy_create_copy_from_dest_thread( data->src_fd = src_fd; strlcpy(data->log_context, log_context, sizeof(data->log_context)); if (pthread_create(&data->tid, NULL, &proxy_copy_from_dest, data) != 0) { - log_errno("Failed to spawn thread"); + log_error("Failed to spawn thread: %s", sstrerrno()); exit(1); } return true; @@ -381,7 +397,7 @@ bool proxy_ipv6_handle_request(int* dst_fd, int fd) { *dst_fd = socket(AF_INET6, SOCK_STREAM, 0); if (*dst_fd < 0) { - log_errno("Failed to create socket"); + log_error("Failed to create socket: %s", sstrerrno()); exit(1); } @@ -411,7 +427,7 @@ bool proxy_ipv4_handle_request(int* dst_fd, int fd) { *dst_fd = socket(AF_INET, SOCK_STREAM, 0); if (*dst_fd < 0) { - log_errno("Failed to create socket"); + log_error("Failed to create socket: %s", sstrerrno()); exit(1); } @@ -596,7 +612,7 @@ void server_accept_connection(int listen_fd) { int fd = accept(listen_fd, (struct sockaddr*)&client_addr, &client_addr_length); if (fd < 0) { - log_errno("Failed to accept connection"); + log_error("Failed to accept connection: %s", sstrerrno()); exit(1); } @@ -613,7 +629,7 @@ void server_accept_connection(int listen_fd) { data->fd = fd; sockaddr_stringify(data->log_context, sizeof(data->log_context), &client_addr); if (pthread_create(&data->tid, NULL, &proxy_handle_accept, data) != 0) { - log_errno("Failed to spawn thread"); + log_error("Failed to spawn thread: %s", sstrerrno()); exit(1); } } @@ -621,13 +637,13 @@ void server_accept_connection(int listen_fd) { int server_create_socket(int listen_port) { int listen_fd = socket(AF_INET6, SOCK_STREAM, 0); if (listen_fd < 0) { - log_errno("Failed to create socket"); + log_error("Failed to create socket: %s", sstrerrno()); exit(1); } int yes = 1; if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) != 0) { - log_errno("Failed to set SO_REUSEADDR"); + log_error("Failed to set SO_REUSEADDR: %s", sstrerrno()); exit(1); } @@ -639,12 +655,12 @@ int server_create_socket(int listen_port) { server_addr.sin6_port = htons(listen_port); if (bind(listen_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { - log_errno("Failed to bind to port"); + log_error("Failed to bind to port: %s", sstrerrno()); exit(1); } if (listen(listen_fd, 5) < 0) { - log_errno("Failed to listen on socket"); + log_error("Failed to listen on socket: %s", sstrerrno()); exit(1); } -- 2.39.2