]> git.lizzy.rs Git - dragonnet.git/commitdiff
Handle WSA errors properly
authorElias Fleckenstein <eliasfleckenstein@web.de>
Tue, 26 Apr 2022 10:02:26 +0000 (12:02 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Tue, 26 Apr 2022 10:02:26 +0000 (12:02 +0200)
CMakeLists.txt
dragonnet/error.c [new file with mode: 0644]
dragonnet/error.h [new file with mode: 0644]
dragonnet/listen.c
dragonnet/peer.c
dragonnet/recv.c
dragonnet/recv_thread.c
dragonnet/send.c

index 22bd2adc52e914721f7600707daaf8bf0732d0cb..d65b49bfd86734feda69c30cfbb4f2e0a8e1996c 100644 (file)
@@ -9,6 +9,7 @@ add_compile_options(
 
 add_library(dragonnet
        dragonnet/addr.c
+       dragonnet/error.c
        dragonnet/init.c
        dragonnet/listen.c
        dragonnet/peer.c
diff --git a/dragonnet/error.c b/dragonnet/error.c
new file mode 100644 (file)
index 0000000..150a67b
--- /dev/null
@@ -0,0 +1,37 @@
+#include <errno.h>
+#include <stdio.h>
+#include "error.h"
+#include "sock.h"
+
+void dragonnet_perror(const char *str)
+{
+#ifdef _WIN32
+       wchar_t *msg = NULL;
+       FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+               NULL, WSAGetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR) &msg, 0, NULL);
+       fprintf(stderr, "%s: %S\n", str, msg);
+       LocalFree(msg);
+#else // _WIN32
+       perror(str);
+#endif // _WIN32
+}
+
+bool dragonnet_isconnerr()
+{
+#ifdef _WIN32
+       int err = WSAGetLastError();
+       return err == WSAECONNRESET || err == WSAETIMEDOUT || err == WSAEDISCON;
+#else // _WIN32
+       return errno == ECONNRESET || errno == EPIPE || errno == ETIMEDOUT;
+#endif // _WIN32
+}
+
+
+bool dragonnet_isintrerr()
+{
+#ifdef _WIN32
+       return WSAGetLastError() == WSAEINTR; 
+#else // _WIN32
+       return errno == EINTR;
+#endif // _WIN32
+}
diff --git a/dragonnet/error.h b/dragonnet/error.h
new file mode 100644 (file)
index 0000000..6a44130
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef _DRAGONNET_ERROR_H_
+#define _DRAGONNET_ERROR_H_
+
+#include <stdbool.h>
+
+void dragonnet_perror(const char *str);
+bool dragonnet_isconnerr();
+bool dragonnet_isintrerr();
+
+#endif
index 303ccaddebc72457ac0492fd4df860682f1ecb32..24ba59d54c0611c359d56e7bea6065c81cdbc875 100644 (file)
@@ -1,10 +1,10 @@
 #define _GNU_SOURCE
 #include <assert.h>
-#include <errno.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include "addr.h"
+#include "error.h"
 #include "listen.h"
 #include "recv.h"
 #include "sock.h"
@@ -54,7 +54,7 @@ DragonnetListener *dragonnet_listener_new(char *addr)
        DragonnetListener *l = malloc(sizeof *l);
 
        if ((l->sock = socket(info->ai_family, info->ai_socktype, info->ai_protocol)) < 0) {
-               perror("socket");
+               dragonnet_perror("socket");
                freeaddrinfo(info);
                free(l);
                return NULL;
@@ -70,14 +70,14 @@ DragonnetListener *dragonnet_listener_new(char *addr)
        int so_reuseaddr = 1;
        if (setsockopt(l->sock, SOL_SOCKET, SO_REUSEADDR, (void *) &so_reuseaddr,
                        sizeof so_reuseaddr) < 0) {
-               perror("setsockopt");
+               dragonnet_perror("setsockopt");
                freeaddrinfo(info);
                dragonnet_listener_delete(l);
                return NULL;
        }
 
        if (bind(l->sock, info->ai_addr, info->ai_addrlen) < 0) {
-               perror("bind");
+               dragonnet_perror("bind");
                freeaddrinfo(info);
                dragonnet_listener_delete(l);
                return NULL;
@@ -86,7 +86,7 @@ DragonnetListener *dragonnet_listener_new(char *addr)
        freeaddrinfo(info);
 
        if (listen(l->sock, 10) < 0) {
-               perror("listen");
+               dragonnet_perror("listen");
                dragonnet_listener_delete(l);
                return NULL;
        }
@@ -108,8 +108,8 @@ static void *listener_main(void *g_listener)
 
                int clt_sock = accept(l->sock, (struct sockaddr *) &clt_addr, &clt_addrlen);
                if (clt_sock < 0) {
-                       if (errno != EINTR)
-                               perror("accept");
+                       if (!dragonnet_isintrerr())
+                               dragonnet_perror("accept");
                        continue;
                }
 
index 95877bfed9de6752accd02ea96543fa3edb4eea1..cdbea44e31e7a151cdb620d301b2266b7f269857 100644 (file)
@@ -3,6 +3,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include "addr.h"
+#include "error.h"
 #include "peer.h"
 #include "recv.h"
 #include "recv_thread.h"
@@ -17,14 +18,14 @@ static bool dragonnet_peer_init(DragonnetPeer *p, char *addr)
                return false;
 
        if ((p->sock = socket(info->ai_family, info->ai_socktype, info->ai_protocol)) < 0) {
-               perror("socket");
+               dragonnet_perror("socket");
                freeaddrinfo(info);
                return false;
        }
        p->address = dragonnet_addr2str(info->ai_addr, info->ai_addrlen);
 
        if (connect(p->sock, info->ai_addr, info->ai_addrlen) < 0) {
-               perror("connect");
+               dragonnet_perror("connect");
                freeaddrinfo(info);
                return false;
        }
index 089aa3544aa53dfb4a2dda2aa0cc6e52dac4d424..36026604e6e566a3fe34b4b8197606356cd36f48 100644 (file)
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include "error.h"
 #include "recv.h"
 #include "sock.h"
 
@@ -12,7 +13,7 @@ bool dragonnet_recv_raw(DragonnetPeer *p, void *buf, size_t n)
 
        ssize_t len = recv(p->sock, buf, n, MSG_WAITALL);
        if (len < 0) {
-               perror("recv");
+               dragonnet_perror("recv");
                abort();
        }
 
index 348c3361e191219f19a7794c35b3f75a2f556daa..459e3466d20df54b49d8a305ac10a01bb2b16165 100644 (file)
@@ -1,13 +1,13 @@
 #define _GNU_SOURCE
 #include <assert.h>
 #include <endian.h>
-#include <errno.h>
 #include <pthread.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include "error.h"
 #include "peer.h"
 #include "recv.h"
 #include "recv_thread.h"
@@ -28,10 +28,10 @@ void *dragonnet_peer_recv_thread(void *g_peer)
 
                ssize_t len = recv(p->sock, (void *) &type_id, sizeof type_id, MSG_WAITALL);
                if (len < 0) {
-                       if (errno == ECONNRESET || errno == EPIPE || errno == ETIMEDOUT) {
+                       if (dragonnet_isconnerr()) {
                                reset = true;
                        } else {
-                               perror("recv");
+                               dragonnet_perror("recv");
                                abort();
                        }
                }
index 2305ff12519875b6396826f33401e52b71fecdc8..b0e5b7bfbcf27af1b30f8930c1b3573ab84fa46e 100644 (file)
@@ -1,7 +1,7 @@
-#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include "error.h"
 #include "send.h"
 #include "sock.h"
 
@@ -10,13 +10,13 @@ bool dragonnet_send_raw(DragonnetPeer *p, bool submit, const void *buf, size_t n
        ssize_t len = send(p->sock, buf, n, MSG_NOSIGNAL | (submit ? 0 : MSG_MORE));
 
        if (len < 0) {
-               if (errno == ECONNRESET || errno == EPIPE || errno == ETIMEDOUT) {
+               if (dragonnet_isconnerr()) {
                        shutdown(p->sock, SHUT_RDWR);
                        pthread_mutex_unlock(&p->mtx);
                        return false;
                }
 
-               perror("send");
+               dragonnet_perror("send");
                abort();
        }