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__);
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 *
**********/
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;
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) {
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) {
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);
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;
*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);
}
*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);
}
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);
}
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);
}
}
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);
}
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);
}