Use thread safe strerror and change many errors to warnings
authorJames Bunton <jamesbunton@delx.net.au>
Tue, 22 Sep 2015 22:25:58 +0000 (08:25 +1000)
committerJames Bunton <jamesbunton@delx.net.au>
Tue, 22 Sep 2015 22:25:58 +0000 (08:25 +1000)
Makefile
socks5server.c

index 5732821..caad0ba 100644 (file)
--- 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
index 592bef0..972687d 100644 (file)
@@ -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);
     }