]> git.lizzy.rs Git - dragonnet.git/commitdiff
Add CMake config
authorElias Fleckenstein <eliasfleckenstein@web.de>
Mon, 25 Apr 2022 10:12:32 +0000 (12:12 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Mon, 25 Apr 2022 10:12:32 +0000 (12:12 +0200)
30 files changed:
.gitignore
.gitmodules [new file with mode: 0644]
CMakeLists.txt [new file with mode: 0644]
addr.c [deleted file]
addr.h [deleted file]
dragonnet/addr.c [new file with mode: 0644]
dragonnet/addr.h [new file with mode: 0644]
dragonnet/listen.c [new file with mode: 0644]
dragonnet/listen.h [new file with mode: 0644]
dragonnet/peer.c [new file with mode: 0644]
dragonnet/peer.h [new file with mode: 0644]
dragonnet/recv.c [new file with mode: 0644]
dragonnet/recv.h [new file with mode: 0644]
dragonnet/recv_thread.c [new file with mode: 0644]
dragonnet/recv_thread.h [new file with mode: 0644]
dragonnet/send.c [new file with mode: 0644]
dragonnet/send.h [new file with mode: 0644]
dragonnet/sock.h [new file with mode: 0644]
endian.h [new submodule]
listen.c [deleted file]
listen.h [deleted file]
peer.c [deleted file]
peer.h [deleted file]
recv.c [deleted file]
recv.h [deleted file]
recv_thread.c [deleted file]
recv_thread.h [deleted file]
send.c [deleted file]
send.h [deleted file]
sock.h [deleted file]

index c6127b38c1aa25968a88db3940604d41529e4cf5..5a5f2d0a2d37e280c27c0e9c381b48a65bbd9fa5 100644 (file)
@@ -1,52 +1,12 @@
-# Prerequisites
-*.d
-
-# Object files
-*.o
-*.ko
-*.obj
-*.elf
-
-# Linker output
-*.ilk
-*.map
-*.exp
-
-# Precompiled Headers
-*.gch
-*.pch
-
-# Libraries
-*.lib
+CMakeLists.txt.user
+CMakeCache.txt
+CMakeFiles
+CMakeScripts
+Testing
+Makefile
+cmake_install.cmake
+install_manifest.txt
+compile_commands.json
+CTestTestfile.cmake
+_deps
 *.a
-*.la
-*.lo
-
-# Shared objects (inc. Windows DLLs)
-*.dll
-*.so
-*.so.*
-*.dylib
-
-# Executables
-*.exe
-*.out
-*.app
-*.i*86
-*.x86_64
-*.hex
-
-# Debug files
-*.dSYM/
-*.su
-*.idb
-*.pdb
-
-# Kernel Module Compile Results
-*.mod*
-*.cmd
-.tmp_versions/
-modules.order
-Module.symvers
-Mkfile.old
-dkms.conf
diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..e626dc6
--- /dev/null
@@ -0,0 +1,3 @@
+[submodule "endian.h"]
+       path = endian.h
+       url = https://github.com/dragonblocks/endian.h
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..9690a50
--- /dev/null
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 3.14)
+project(Dragonnet)
+
+add_compile_options(
+       -Wall
+       -Wextra
+       -Werror
+)
+
+add_library(dragonnet
+       dragonnet/addr.c
+       dragonnet/listen.c
+       dragonnet/peer.c
+       dragonnet/recv.c
+       dragonnet/recv_thread.c
+       dragonnet/send.c
+)
+
+target_link_libraries(dragonnet
+       pthread
+)
+
+target_include_directories(dragonnet
+       PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}"
+       PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/endian.h"
+)
+
+if("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
+       target_link_libraries(dragonnet
+               ws2_32
+       )
+endif()
diff --git a/addr.c b/addr.c
deleted file mode 100644 (file)
index 04c4537..0000000
--- a/addr.c
+++ /dev/null
@@ -1,56 +0,0 @@
-#include <dragonnet/addr.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-struct addrinfo *dragonnet_str2addr(const char *str)
-{
-       const char *port = str + strlen(str) - 1;
-       while (port >= str && *port != ':')
-               port--;
-       port++;
-
-       const char *host_begin = str;
-       if (*host_begin == '[')
-               host_begin++;
-
-       const char *host_end = port - 2;
-       if (host_end >= str && *host_end == ']')
-               host_end--;
-
-       ssize_t host_len = host_end - host_begin + 1;
-       if (host_len < 0)
-               host_len = 0;
-
-       char host[host_len + 1];
-       host[host_len] = '\0';
-       memcpy(host, host_begin, host_len);
-
-       struct addrinfo *result, hints = {0};
-       hints.ai_family = AF_UNSPEC;
-       hints.ai_socktype = SOCK_STREAM;
-
-       int err;
-       if ((err = getaddrinfo(host, port, &hints, &result))) {
-               fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err));
-               return NULL;
-       }
-
-       return result;
-}
-
-char *dragonnet_addr2str(struct sockaddr *addr, socklen_t addr_len)
-{
-       char host[NI_MAXHOST], port[NI_MAXSERV];
-
-       int err;
-       if ((err = getnameinfo(addr, addr_len, host, NI_MAXHOST, port, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV))) {
-               fprintf(stderr, "getnameinfo: %s\n", gai_strerror(err));
-               return NULL;
-       }
-
-       char str[1 + strlen(host) + 1 + 1 + strlen(port) + 1];
-       sprintf(str, "[%s]:%s", host, port);
-       return strdup(str);
-}
diff --git a/addr.h b/addr.h
deleted file mode 100644 (file)
index 2bc21cc..0000000
--- a/addr.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _DRAGONNET_ADDR_H_
-#define _DRAGONNET_ADDR_H_
-
-#include "sock.h"
-
-struct addrinfo *dragonnet_str2addr(const char *str);
-char *dragonnet_addr2str(struct sockaddr *addr, socklen_t addr_len);
-
-#endif
diff --git a/dragonnet/addr.c b/dragonnet/addr.c
new file mode 100644 (file)
index 0000000..e555f1b
--- /dev/null
@@ -0,0 +1,56 @@
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "addr.h"
+
+struct addrinfo *dragonnet_str2addr(const char *str)
+{
+       const char *port = str + strlen(str) - 1;
+       while (port >= str && *port != ':')
+               port--;
+       port++;
+
+       const char *host_begin = str;
+       if (*host_begin == '[')
+               host_begin++;
+
+       const char *host_end = port - 2;
+       if (host_end >= str && *host_end == ']')
+               host_end--;
+
+       ssize_t host_len = host_end - host_begin + 1;
+       if (host_len < 0)
+               host_len = 0;
+
+       char host[host_len + 1];
+       host[host_len] = '\0';
+       memcpy(host, host_begin, host_len);
+
+       struct addrinfo *result, hints = {0};
+       hints.ai_family = AF_UNSPEC;
+       hints.ai_socktype = SOCK_STREAM;
+
+       int err;
+       if ((err = getaddrinfo(host, port, &hints, &result))) {
+               fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err));
+               return NULL;
+       }
+
+       return result;
+}
+
+char *dragonnet_addr2str(struct sockaddr *addr, socklen_t addr_len)
+{
+       char host[NI_MAXHOST], port[NI_MAXSERV];
+
+       int err;
+       if ((err = getnameinfo(addr, addr_len, host, NI_MAXHOST, port, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV))) {
+               fprintf(stderr, "getnameinfo: %s\n", gai_strerror(err));
+               return NULL;
+       }
+
+       char str[1 + strlen(host) + 1 + 1 + strlen(port) + 1];
+       sprintf(str, "[%s]:%s", host, port);
+       return strdup(str);
+}
diff --git a/dragonnet/addr.h b/dragonnet/addr.h
new file mode 100644 (file)
index 0000000..2bc21cc
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _DRAGONNET_ADDR_H_
+#define _DRAGONNET_ADDR_H_
+
+#include "sock.h"
+
+struct addrinfo *dragonnet_str2addr(const char *str);
+char *dragonnet_addr2str(struct sockaddr *addr, socklen_t addr_len);
+
+#endif
diff --git a/dragonnet/listen.c b/dragonnet/listen.c
new file mode 100644 (file)
index 0000000..a42066f
--- /dev/null
@@ -0,0 +1,144 @@
+#define _GNU_SOURCE
+#include <assert.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "addr.h"
+#include "listen.h"
+#include "recv.h"
+#include "sock.h"
+
+// ----
+// Peer
+// ----
+
+static bool dragonnet_peer_init_accepted(DragonnetPeer *p, int sock,
+               char *addr, DragonnetListener *l)
+{
+       pthread_mutex_init(&p->mtx, NULL);
+
+       p->sock = sock;
+       p->address = addr;
+       p->on_disconnect = l->on_disconnect;
+       p->on_recv = l->on_recv;
+       p->on_recv_type = l->on_recv_type;
+
+       return true;
+}
+
+static DragonnetPeer *dragonnet_peer_accept(int sock, char *addr,
+               DragonnetListener *l)
+{
+       DragonnetPeer *p = malloc(sizeof *p);
+       if (!dragonnet_peer_init_accepted(p, sock, addr, l)) {
+               pthread_mutex_destroy(&p->mtx);
+               free(p);
+               free(addr);
+               return NULL;
+       }
+
+       return p;
+}
+
+// --------
+// Listener
+// --------
+
+DragonnetListener *dragonnet_listener_new(char *addr)
+{
+       struct addrinfo *info = dragonnet_str2addr(addr);
+       if (!info)
+               return NULL;
+
+       DragonnetListener *l = malloc(sizeof *l);
+
+       l->active = true;
+       l->sock = socket(info->ai_family, info->ai_socktype, info->ai_protocol);
+       l->address = dragonnet_addr2str(info->ai_addr, info->ai_addrlen);
+       l->on_connect = NULL;
+       l->on_disconnect = NULL;
+       l->on_recv = NULL;
+       l->on_recv_type = calloc(sizeof *l->on_recv_type, dragonnet_num_types);
+
+       int so_reuseaddr = 1;
+       if (setsockopt(l->sock, SOL_SOCKET, SO_REUSEADDR, (void *) &so_reuseaddr,
+                       sizeof so_reuseaddr) < 0) {
+               perror("setsockopt");
+               freeaddrinfo(info);
+               dragonnet_listener_delete(l);
+               return NULL;
+       }
+
+       if (bind(l->sock, info->ai_addr, info->ai_addrlen) < 0) {
+               perror("bind");
+               freeaddrinfo(info);
+               dragonnet_listener_delete(l);
+               return NULL;
+       }
+
+       freeaddrinfo(info);
+
+       if (listen(l->sock, 10) < 0) {
+               perror("listen");
+               dragonnet_listener_delete(l);
+               return NULL;
+       }
+
+       return l;
+}
+
+static void *listener_main(void *g_listener)
+{
+#ifdef __GLIBC__
+       pthread_setname_np(pthread_self(), "listen");
+#endif
+
+       DragonnetListener *l = (DragonnetListener *) g_listener;
+
+       while (l->active) {
+               struct sockaddr_storage clt_addr;
+               socklen_t clt_addrlen = sizeof clt_addr;
+
+               int clt_sock = accept(l->sock, (struct sockaddr *) &clt_addr, &clt_addrlen);
+               if (clt_sock < 0) {
+                       if (errno != EINTR)
+                               perror("accept");
+                       continue;
+               }
+
+               char *clt_addstr =  dragonnet_addr2str((struct sockaddr *) &clt_addr, clt_addrlen);
+               DragonnetPeer *p = dragonnet_peer_accept(clt_sock, clt_addstr, l);
+               if (p == NULL)
+                       continue;
+
+               void (*on_connect)(DragonnetPeer *) = l->on_connect;
+
+               if (on_connect != NULL)
+                       on_connect(p);
+
+               dragonnet_peer_run(p);
+       }
+
+       return NULL;
+}
+
+void dragonnet_listener_run(DragonnetListener *l)
+{
+       pthread_create(&l->accept_thread, NULL, &listener_main, l);
+}
+
+void dragonnet_listener_close(DragonnetListener *l)
+{
+       l->active = false;
+
+       pthread_kill(l->accept_thread, SIGINT);
+       pthread_join(l->accept_thread, NULL);
+}
+
+void dragonnet_listener_delete(DragonnetListener *l)
+{
+       free(l->on_recv_type);
+       free(l->address);
+       free(l);
+}
diff --git a/dragonnet/listen.h b/dragonnet/listen.h
new file mode 100644 (file)
index 0000000..03a2305
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef _DRAGONNET_LISTEN_H_
+#define _DRAGONNET_LISTEN_H_
+
+#include <stdbool.h>
+#include "peer.h"
+
+typedef struct {
+       int sock;
+       char *address;
+
+       pthread_t accept_thread;
+       bool active;
+
+       void (*on_connect)(DragonnetPeer *);
+       void (*on_disconnect)(DragonnetPeer *);
+       bool (*on_recv)(DragonnetPeer *, DragonnetTypeId, void *);
+       void (**on_recv_type)(DragonnetPeer *, void *);
+} DragonnetListener;
+
+DragonnetListener *dragonnet_listener_new(char *addr);
+void dragonnet_listener_run(DragonnetListener *l);
+void dragonnet_listener_close(DragonnetListener *l);
+void dragonnet_listener_delete(DragonnetListener *l);
+
+#endif
diff --git a/dragonnet/peer.c b/dragonnet/peer.c
new file mode 100644 (file)
index 0000000..f4c5685
--- /dev/null
@@ -0,0 +1,57 @@
+#include <assert.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "addr.h"
+#include "peer.h"
+#include "recv.h"
+#include "recv_thread.h"
+#include "sock.h"
+
+static bool dragonnet_peer_init(DragonnetPeer *p, char *addr)
+{
+       pthread_mutex_init(&p->mtx, NULL);
+
+       struct addrinfo *info = dragonnet_str2addr(addr);
+       if (!info)
+               return false;
+
+       p->sock = socket(info->ai_family, info->ai_socktype, info->ai_protocol);
+       p->address = dragonnet_addr2str(info->ai_addr, info->ai_addrlen);
+
+       if (connect(p->sock, info->ai_addr, info->ai_addrlen) < 0) {
+               freeaddrinfo(info);
+               perror("connect");
+               return false;
+       }
+
+       freeaddrinfo(info);
+
+       p->on_disconnect = NULL;
+       p->on_recv = NULL;
+       p->on_recv_type = calloc(sizeof *p->on_recv_type, dragonnet_num_types); // fixme: memory leak
+
+       return true;
+}
+
+DragonnetPeer *dragonnet_connect(char *addr)
+{
+       DragonnetPeer *p = malloc(sizeof *p);
+       if (!dragonnet_peer_init(p, addr)) {
+               pthread_mutex_destroy(&p->mtx);
+               free(p);
+               return NULL;
+       }
+
+       return p;
+}
+
+void dragonnet_peer_run(DragonnetPeer *p)
+{
+       pthread_create(&p->recv_thread, NULL, &dragonnet_peer_recv_thread, p);
+}
+
+void dragonnet_peer_shutdown(DragonnetPeer *p)
+{
+       shutdown(p->sock, SHUT_RDWR);
+}
diff --git a/dragonnet/peer.h b/dragonnet/peer.h
new file mode 100644 (file)
index 0000000..ce6100b
--- /dev/null
@@ -0,0 +1,28 @@
+#ifndef _DRAGONNET_PEER_H_
+#define _DRAGONNET_PEER_H_
+
+#include <pthread.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+typedef uint16_t DragonnetTypeId;
+
+typedef struct dragonnet_peer {
+       int sock;
+       char *address;
+
+       pthread_t recv_thread;
+       pthread_mutex_t mtx;
+
+       void (*on_disconnect)(struct dragonnet_peer *);
+       bool (*on_recv)(struct dragonnet_peer *, DragonnetTypeId, void *);
+       void (**on_recv_type)(struct dragonnet_peer *, void *);
+
+       void *extra;
+} DragonnetPeer;
+
+DragonnetPeer *dragonnet_connect(char *addr);
+void dragonnet_peer_run(DragonnetPeer *p);
+void dragonnet_peer_shutdown(DragonnetPeer *p);
+
+#endif
diff --git a/dragonnet/recv.c b/dragonnet/recv.c
new file mode 100644 (file)
index 0000000..ffad396
--- /dev/null
@@ -0,0 +1,20 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "recv.h"
+#include "sock.h"
+
+bool dragonnet_recv_raw(DragonnetPeer *p, void *buf, size_t n)
+{
+       if (n == 0)
+               return true;
+
+       ssize_t len = recv(p->sock, buf, n, MSG_WAITALL);
+       if (len < 0) {
+               perror("recv");
+               abort();
+       }
+
+       return len != 0;
+}
diff --git a/dragonnet/recv.h b/dragonnet/recv.h
new file mode 100644 (file)
index 0000000..eae26d3
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _DRAGONNET_RECV_H_
+#define _DRAGONNET_RECV_H_
+
+#include "peer.h"
+
+typedef struct {
+       size_t siz;
+       bool (*deserialize)(DragonnetPeer *, void *);
+       void (*free)(void *);
+} DragonnetType;
+
+extern DragonnetTypeId dragonnet_num_types;
+extern DragonnetType dragonnet_types[];
+
+bool dragonnet_recv_raw(DragonnetPeer *p, void *buf, size_t n);
+
+#endif
diff --git a/dragonnet/recv_thread.c b/dragonnet/recv_thread.c
new file mode 100644 (file)
index 0000000..48f02ef
--- /dev/null
@@ -0,0 +1,85 @@
+#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 "peer.h"
+#include "recv.h"
+#include "recv_thread.h"
+#include "sock.h"
+
+void *dragonnet_peer_recv_thread(void *g_peer)
+{
+#ifdef __GLIBC__
+       pthread_setname_np(pthread_self(), "recv");
+#endif
+
+       DragonnetPeer *p = (DragonnetPeer *) g_peer;
+
+       while (true) {
+               DragonnetTypeId type_id;
+
+               bool reset = false;
+
+               ssize_t len = recv(p->sock, (void *) &type_id, sizeof type_id, MSG_WAITALL);
+               if (len < 0) {
+                       if (errno == ECONNRESET || errno == EPIPE || errno == ETIMEDOUT) {
+                               reset = true;
+                       } else {
+                               perror("recv");
+                               abort();
+                       }
+               }
+
+               // Connection closed
+               if (len == 0 || reset) {
+                       if (p->on_disconnect)
+                               p->on_disconnect(p);
+
+                       close(p->sock);
+                       free(p->address);
+
+                       pthread_mutex_destroy(&p->mtx);
+                       free(p);
+                       return NULL;
+               }
+
+               type_id = be16toh(type_id);
+
+               if (type_id >= dragonnet_num_types) {
+                       fprintf(stderr, "[warning] received invalid type id %d\n", type_id);
+                       continue;
+               }
+
+               DragonnetType type = dragonnet_types[type_id];
+
+               unsigned char buf[type.siz];
+               memset(buf, 0, type.siz);
+
+               if (!type.deserialize(p, buf)) {
+                       if (type.free != NULL)
+                               type.free(buf);
+
+                       fprintf(stderr, "[warning] failed to deserialize package of type %d\n", type_id);
+
+                       continue;
+               }
+
+               bool (*on_recv)(struct dragonnet_peer *, DragonnetTypeId, void *) = p->on_recv;
+               void (*on_recv_type)(DragonnetPeer *, void *) = p->on_recv_type[type_id];
+
+               if (on_recv != NULL && !on_recv(p, type_id, buf))
+                       on_recv_type = NULL;
+
+               if (on_recv_type != NULL)
+                       on_recv_type(p, buf);
+
+               if (type.free != NULL)
+                       type.free(buf);
+       }
+}
diff --git a/dragonnet/recv_thread.h b/dragonnet/recv_thread.h
new file mode 100644 (file)
index 0000000..ea847ba
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _DRAGONNET_RECV_THREAD_H_
+#define _DRAGONNET_RECV_THREAD_H
+
+void *dragonnet_peer_recv_thread(void *g_peer);
+
+#endif
diff --git a/dragonnet/send.c b/dragonnet/send.c
new file mode 100644 (file)
index 0000000..2305ff1
--- /dev/null
@@ -0,0 +1,27 @@
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "send.h"
+#include "sock.h"
+
+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) {
+                       shutdown(p->sock, SHUT_RDWR);
+                       pthread_mutex_unlock(&p->mtx);
+                       return false;
+               }
+
+               perror("send");
+               abort();
+       }
+
+       if (submit)
+               pthread_mutex_unlock(&p->mtx);
+
+       return true;
+}
diff --git a/dragonnet/send.h b/dragonnet/send.h
new file mode 100644 (file)
index 0000000..c07f4b4
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _DRAGONNET_SEND_H_
+#define _DRAGONNET_SEND_H_
+
+#include <stdbool.h>
+#include "peer.h"
+
+bool dragonnet_send_raw(DragonnetPeer *p, bool submit, const void *buf, size_t n);
+
+#endif
diff --git a/dragonnet/sock.h b/dragonnet/sock.h
new file mode 100644 (file)
index 0000000..de1eb91
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef _WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <iphlpapi.h>
+#include <ws2def.h>
+#include <windows.h>
+#include <io.h>
+#define SHUT_RDWR SD_BOTH
+#define MSG_NOSIGNAL 0
+#define MSG_MORE 0
+#else
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#endif
diff --git a/endian.h b/endian.h
new file mode 160000 (submodule)
index 0000000..f24960e
--- /dev/null
+++ b/endian.h
@@ -0,0 +1 @@
+Subproject commit f24960eca3bb806fa72d8de2b9a761a889fdeee3
diff --git a/listen.c b/listen.c
deleted file mode 100644 (file)
index f8f212b..0000000
--- a/listen.c
+++ /dev/null
@@ -1,144 +0,0 @@
-#define _GNU_SOURCE
-#include <assert.h>
-#include <dragonnet/addr.h>
-#include <dragonnet/listen.h>
-#include <dragonnet/recv.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "sock.h"
-
-// ----
-// Peer
-// ----
-
-static bool dragonnet_peer_init_accepted(DragonnetPeer *p, int sock,
-               char *addr, DragonnetListener *l)
-{
-       pthread_mutex_init(&p->mtx, NULL);
-
-       p->sock = sock;
-       p->address = addr;
-       p->on_disconnect = l->on_disconnect;
-       p->on_recv = l->on_recv;
-       p->on_recv_type = l->on_recv_type;
-
-       return true;
-}
-
-static DragonnetPeer *dragonnet_peer_accept(int sock, char *addr,
-               DragonnetListener *l)
-{
-       DragonnetPeer *p = malloc(sizeof *p);
-       if (!dragonnet_peer_init_accepted(p, sock, addr, l)) {
-               pthread_mutex_destroy(&p->mtx);
-               free(p);
-               free(addr);
-               return NULL;
-       }
-
-       return p;
-}
-
-// --------
-// Listener
-// --------
-
-DragonnetListener *dragonnet_listener_new(char *addr)
-{
-       struct addrinfo *info = dragonnet_str2addr(addr);
-       if (!info)
-               return NULL;
-
-       DragonnetListener *l = malloc(sizeof *l);
-
-       l->active = true;
-       l->sock = socket(info->ai_family, info->ai_socktype, info->ai_protocol);
-       l->address = dragonnet_addr2str(info->ai_addr, info->ai_addrlen);
-       l->on_connect = NULL;
-       l->on_disconnect = NULL;
-       l->on_recv = NULL;
-       l->on_recv_type = calloc(sizeof *l->on_recv_type, dragonnet_num_types);
-
-       int so_reuseaddr = 1;
-       if (setsockopt(l->sock, SOL_SOCKET, SO_REUSEADDR, (void *) &so_reuseaddr,
-                       sizeof so_reuseaddr) < 0) {
-               perror("setsockopt");
-               freeaddrinfo(info);
-               dragonnet_listener_delete(l);
-               return NULL;
-       }
-
-       if (bind(l->sock, info->ai_addr, info->ai_addrlen) < 0) {
-               perror("bind");
-               freeaddrinfo(info);
-               dragonnet_listener_delete(l);
-               return NULL;
-       }
-
-       freeaddrinfo(info);
-
-       if (listen(l->sock, 10) < 0) {
-               perror("listen");
-               dragonnet_listener_delete(l);
-               return NULL;
-       }
-
-       return l;
-}
-
-static void *listener_main(void *g_listener)
-{
-#ifdef __GLIBC__
-       pthread_setname_np(pthread_self(), "listen");
-#endif
-
-       DragonnetListener *l = (DragonnetListener *) g_listener;
-
-       while (l->active) {
-               struct sockaddr_storage clt_addr;
-               socklen_t clt_addrlen = sizeof clt_addr;
-
-               int clt_sock = accept(l->sock, (struct sockaddr *) &clt_addr, &clt_addrlen);
-               if (clt_sock < 0) {
-                       if (errno != EINTR)
-                               perror("accept");
-                       continue;
-               }
-
-               char *clt_addstr =  dragonnet_addr2str((struct sockaddr *) &clt_addr, clt_addrlen);
-               DragonnetPeer *p = dragonnet_peer_accept(clt_sock, clt_addstr, l);
-               if (p == NULL)
-                       continue;
-
-               void (*on_connect)(DragonnetPeer *) = l->on_connect;
-
-               if (on_connect != NULL)
-                       on_connect(p);
-
-               dragonnet_peer_run(p);
-       }
-
-       return NULL;
-}
-
-void dragonnet_listener_run(DragonnetListener *l)
-{
-       pthread_create(&l->accept_thread, NULL, &listener_main, l);
-}
-
-void dragonnet_listener_close(DragonnetListener *l)
-{
-       l->active = false;
-
-       pthread_kill(l->accept_thread, SIGINT);
-       pthread_join(l->accept_thread, NULL);
-}
-
-void dragonnet_listener_delete(DragonnetListener *l)
-{
-       free(l->on_recv_type);
-       free(l->address);
-       free(l);
-}
diff --git a/listen.h b/listen.h
deleted file mode 100644 (file)
index 6d31eaa..0000000
--- a/listen.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef _DRAGONNET_LISTEN_H_
-#define _DRAGONNET_LISTEN_H_
-
-#include <dragonnet/peer.h>
-#include <stdbool.h>
-
-typedef struct {
-       int sock;
-       char *address;
-
-       pthread_t accept_thread;
-       bool active;
-
-       void (*on_connect)(DragonnetPeer *);
-       void (*on_disconnect)(DragonnetPeer *);
-       bool (*on_recv)(DragonnetPeer *, DragonnetTypeId, void *);
-       void (**on_recv_type)(DragonnetPeer *, void *);
-} DragonnetListener;
-
-DragonnetListener *dragonnet_listener_new(char *addr);
-void dragonnet_listener_run(DragonnetListener *l);
-void dragonnet_listener_close(DragonnetListener *l);
-void dragonnet_listener_delete(DragonnetListener *l);
-
-#endif
diff --git a/peer.c b/peer.c
deleted file mode 100644 (file)
index 7c5ce29..0000000
--- a/peer.c
+++ /dev/null
@@ -1,57 +0,0 @@
-#include <assert.h>
-#include <dragonnet/addr.h>
-#include <dragonnet/peer.h>
-#include <dragonnet/recv.h>
-#include <dragonnet/recv_thread.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "sock.h"
-
-static bool dragonnet_peer_init(DragonnetPeer *p, char *addr)
-{
-       pthread_mutex_init(&p->mtx, NULL);
-
-       struct addrinfo *info = dragonnet_str2addr(addr);
-       if (!info)
-               return false;
-
-       p->sock = socket(info->ai_family, info->ai_socktype, info->ai_protocol);
-       p->address = dragonnet_addr2str(info->ai_addr, info->ai_addrlen);
-
-       if (connect(p->sock, info->ai_addr, info->ai_addrlen) < 0) {
-               freeaddrinfo(info);
-               perror("connect");
-               return false;
-       }
-
-       freeaddrinfo(info);
-
-       p->on_disconnect = NULL;
-       p->on_recv = NULL;
-       p->on_recv_type = calloc(sizeof *p->on_recv_type, dragonnet_num_types); // fixme: memory leak
-
-       return true;
-}
-
-DragonnetPeer *dragonnet_connect(char *addr)
-{
-       DragonnetPeer *p = malloc(sizeof *p);
-       if (!dragonnet_peer_init(p, addr)) {
-               pthread_mutex_destroy(&p->mtx);
-               free(p);
-               return NULL;
-       }
-
-       return p;
-}
-
-void dragonnet_peer_run(DragonnetPeer *p)
-{
-       pthread_create(&p->recv_thread, NULL, &dragonnet_peer_recv_thread, p);
-}
-
-void dragonnet_peer_shutdown(DragonnetPeer *p)
-{
-       shutdown(p->sock, SHUT_RDWR);
-}
diff --git a/peer.h b/peer.h
deleted file mode 100644 (file)
index ce6100b..0000000
--- a/peer.h
+++ /dev/null
@@ -1,28 +0,0 @@
-#ifndef _DRAGONNET_PEER_H_
-#define _DRAGONNET_PEER_H_
-
-#include <pthread.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-typedef uint16_t DragonnetTypeId;
-
-typedef struct dragonnet_peer {
-       int sock;
-       char *address;
-
-       pthread_t recv_thread;
-       pthread_mutex_t mtx;
-
-       void (*on_disconnect)(struct dragonnet_peer *);
-       bool (*on_recv)(struct dragonnet_peer *, DragonnetTypeId, void *);
-       void (**on_recv_type)(struct dragonnet_peer *, void *);
-
-       void *extra;
-} DragonnetPeer;
-
-DragonnetPeer *dragonnet_connect(char *addr);
-void dragonnet_peer_run(DragonnetPeer *p);
-void dragonnet_peer_shutdown(DragonnetPeer *p);
-
-#endif
diff --git a/recv.c b/recv.c
deleted file mode 100644 (file)
index 7a2dfbe..0000000
--- a/recv.c
+++ /dev/null
@@ -1,20 +0,0 @@
-#include <dragonnet/recv.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include "sock.h"
-
-bool dragonnet_recv_raw(DragonnetPeer *p, void *buf, size_t n)
-{
-       if (n == 0)
-               return true;
-
-       ssize_t len = recv(p->sock, buf, n, MSG_WAITALL);
-       if (len < 0) {
-               perror("recv");
-               abort();
-       }
-
-       return len != 0;
-}
diff --git a/recv.h b/recv.h
deleted file mode 100644 (file)
index adb39aa..0000000
--- a/recv.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef _DRAGONNET_RECV_H_
-#define _DRAGONNET_RECV_H_
-
-#include <dragonnet/peer.h>
-
-typedef struct {
-       size_t siz;
-       bool (*deserialize)(DragonnetPeer *, void *);
-       void (*free)(void *);
-} DragonnetType;
-
-extern DragonnetTypeId dragonnet_num_types;
-extern DragonnetType dragonnet_types[];
-
-bool dragonnet_recv_raw(DragonnetPeer *p, void *buf, size_t n);
-
-#endif
diff --git a/recv_thread.c b/recv_thread.c
deleted file mode 100644 (file)
index 578c4e8..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-#define _GNU_SOURCE
-#include <assert.h>
-#include <dragonnet/peer.h>
-#include <dragonnet/recv.h>
-#include <dragonnet/recv_thread.h>
-#include <endian.h/endian.h>
-#include <errno.h>
-#include <pthread.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include "sock.h"
-
-void *dragonnet_peer_recv_thread(void *g_peer)
-{
-#ifdef __GLIBC__
-       pthread_setname_np(pthread_self(), "recv");
-#endif
-
-       DragonnetPeer *p = (DragonnetPeer *) g_peer;
-
-       while (true) {
-               DragonnetTypeId type_id;
-
-               bool reset = false;
-
-               ssize_t len = recv(p->sock, (void *) &type_id, sizeof type_id, MSG_WAITALL);
-               if (len < 0) {
-                       if (errno == ECONNRESET || errno == EPIPE || errno == ETIMEDOUT) {
-                               reset = true;
-                       } else {
-                               perror("recv");
-                               abort();
-                       }
-               }
-
-               // Connection closed
-               if (len == 0 || reset) {
-                       if (p->on_disconnect)
-                               p->on_disconnect(p);
-
-                       close(p->sock);
-                       free(p->address);
-
-                       pthread_mutex_destroy(&p->mtx);
-                       free(p);
-                       return NULL;
-               }
-
-               type_id = be16toh(type_id);
-
-               if (type_id >= dragonnet_num_types) {
-                       fprintf(stderr, "[warning] received invalid type id %d\n", type_id);
-                       continue;
-               }
-
-               DragonnetType type = dragonnet_types[type_id];
-
-               unsigned char buf[type.siz];
-               memset(buf, 0, type.siz);
-
-               if (!type.deserialize(p, buf)) {
-                       if (type.free != NULL)
-                               type.free(buf);
-
-                       fprintf(stderr, "[warning] failed to deserialize package of type %d\n", type_id);
-
-                       continue;
-               }
-
-               bool (*on_recv)(struct dragonnet_peer *, DragonnetTypeId, void *) = p->on_recv;
-               void (*on_recv_type)(DragonnetPeer *, void *) = p->on_recv_type[type_id];
-
-               if (on_recv != NULL && !on_recv(p, type_id, buf))
-                       on_recv_type = NULL;
-
-               if (on_recv_type != NULL)
-                       on_recv_type(p, buf);
-
-               if (type.free != NULL)
-                       type.free(buf);
-       }
-}
diff --git a/recv_thread.h b/recv_thread.h
deleted file mode 100644 (file)
index ea847ba..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _DRAGONNET_RECV_THREAD_H_
-#define _DRAGONNET_RECV_THREAD_H
-
-void *dragonnet_peer_recv_thread(void *g_peer);
-
-#endif
diff --git a/send.c b/send.c
deleted file mode 100644 (file)
index caeb7c8..0000000
--- a/send.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <dragonnet/send.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "sock.h"
-
-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) {
-                       shutdown(p->sock, SHUT_RDWR);
-                       pthread_mutex_unlock(&p->mtx);
-                       return false;
-               }
-
-               perror("send");
-               abort();
-       }
-
-       if (submit)
-               pthread_mutex_unlock(&p->mtx);
-
-       return true;
-}
diff --git a/send.h b/send.h
deleted file mode 100644 (file)
index 206a198..0000000
--- a/send.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _DRAGONNET_SEND_H_
-#define _DRAGONNET_SEND_H_
-
-#include <dragonnet/peer.h>
-#include <stdbool.h>
-
-bool dragonnet_send_raw(DragonnetPeer *p, bool submit, const void *buf, size_t n);
-
-#endif
diff --git a/sock.h b/sock.h
deleted file mode 100644 (file)
index de1eb91..0000000
--- a/sock.h
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <iphlpapi.h>
-#include <ws2def.h>
-#include <windows.h>
-#include <io.h>
-#define SHUT_RDWR SD_BOTH
-#define MSG_NOSIGNAL 0
-#define MSG_MORE 0
-#else
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#endif