]> git.lizzy.rs Git - dragonnet.git/commitdiff
Refactor address conversions
authorHimbeerserverDE <himbeerserverde@gmail.com>
Sun, 3 Oct 2021 13:43:00 +0000 (15:43 +0200)
committerHimbeerserverDE <himbeerserverde@gmail.com>
Sun, 3 Oct 2021 13:43:00 +0000 (15:43 +0200)
addr.c
addr.h
listen.c
listen.h
peer.h

diff --git a/addr.c b/addr.c
index 226e0fde14a63280fb87a51f2fc6f3390ae8fef1..a257a5dd8e1c26acf7db7038feb0a363650761f7 100644 (file)
--- a/addr.c
+++ b/addr.c
@@ -1,22 +1,70 @@
-#include <arpa/inet.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 #include "addr.h"
 
-DragonnetAddr dragonnet_addr_parse(char *addr)
+DragonnetAddr dragonnet_addr_parse_str(char *str)
 {
-       DragonnetAddr net_addr;
-
-       size_t port_i = 0;
-       for (size_t i = 0; i < strlen(addr); ++i) {
-               if (!port_i) {
-                       if (addr[i] != ':')
-                               net_addr.ip[i] = addr[i];
-                       else
-                               port_i = i+1;
-               } else
-                       net_addr.port[i-port_i] = addr[i];
+       // Reverse string for easier splitting
+       char buf[1+strlen(str)];
+       memset(buf, 0, sizeof buf);
+
+       for (size_t i = 0; i < strlen(str); ++i)
+               buf[i] = str[strlen(str)-1-i];
+
+       char *r_port = strtok(buf, ":");
+       char r_ip_addr[2+INET6_ADDRSTRLEN];
+
+       char *tok = NULL;
+       while (tok != NULL) {
+               tok = strtok(NULL, ":");
+               strcat(r_ip_addr, tok);
        }
 
-       return net_addr;
+       // Reverse strings again
+       char ip_addr[1+strlen(r_ip_addr)];
+       memset(ip_addr, 0, sizeof ip_addr);
+
+       for (size_t i = 0; i < strlen(r_ip_addr); ++i)
+               ip_addr[i] = r_ip_addr[strlen(r_ip_addr)-1-i];
+
+       char port[1+strlen(r_port)];
+       memset(port, 0, sizeof port);
+
+       for (size_t i = 0; i < strlen(r_port); ++i)
+               port[i] = r_port[strlen(r_port)-1-i];
+
+       DragonnetAddr addr = {0};
+       strcpy(addr.ip, ip_addr);
+       strcpy(addr.port, port);
+
+       return addr;
+}
+
+void dragonnet_addr_str(char dst[7+INET6_ADDRSTRLEN], DragonnetAddr addr)
+{
+       memset(dst, 0, 7+INET6_ADDRSTRLEN);
+       sprintf(dst, "[%s]:%s", addr.ip, addr.port);
+}
+
+DragonnetAddr dragonnet_addr_parse_sock(struct sockaddr_in6 ai_addr)
+{
+       DragonnetAddr addr = {0};
+       sprintf(addr.port, "%d", ntohs(ai_addr.sin6_port));
+       inet_ntop(AF_INET6, &ai_addr.sin6_addr, addr.ip, INET6_ADDRSTRLEN);
+
+       return addr;
+}
+
+struct sockaddr_in6 dragonnet_addr_sock(DragonnetAddr addr)
+{
+       struct sockaddr_in6 ai_addr = {0};
+       ai_addr.sin6_family = AF_INET6;
+       ai_addr.sin6_flowinfo = 0;
+       ai_addr.sin6_port = htons(atoi(addr.port));
+       inet_pton(AF_INET6, addr.ip, &ai_addr.sin6_addr);
+
+       return ai_addr;
 }
diff --git a/addr.h b/addr.h
index 437e2452e8238f7621ddeff3a9c2e23ca6b182b1..11fd2818158243e4518a3139ab15576f667d64a3 100644 (file)
--- a/addr.h
+++ b/addr.h
@@ -1,11 +1,17 @@
 #ifndef _DRAGONNET_ADDR_H_
 #define _DRAGONNET_ADDR_H_
 
+#include <arpa/inet.h>
+
 typedef struct {
        char ip[INET6_ADDRSTRLEN];
        char port[5];
 } DragonnetAddr;
 
-DragonnetAddr dragonnet_addr_parse(char *addr);
+DragonnetAddr dragonnet_addr_parse_str(char *addr);
+void dragonnet_addr_str(char dst[7+INET6_ADDRSTRLEN], DragonnetAddr addr);
+
+DragonnetAddr dragonnet_addr_parse_sock(struct sockaddr_in6 ai_addr);
+struct sockaddr_in6 dragonnet_addr_sock(DragonnetAddr addr);
 
 #endif
index 9f25eedc732046ae99fe2564dbf3d1217116f94e..440f889f944f0aecd8f12ae15aeccf4b5ae843b2 100644 (file)
--- a/listen.c
+++ b/listen.c
@@ -1,4 +1,3 @@
-#include <arpa/inet.h>
 #include <assert.h>
 #include <netdb.h>
 #include <stdio.h>
@@ -6,7 +5,6 @@
 #include <sys/socket.h>
 #include <unistd.h>
 
-#include "addr.h"
 #include "listen.h"
 
 // ----
@@ -23,19 +21,7 @@ static DragonnetPeer *dragonnet_peer_accept(int sock, struct sockaddr_in6 addr,
 
        p->sock = sock;
        p->laddr = l->laddr;
-
-       char ip_addr[INET6_ADDRSTRLEN] = {0};
-       inet_ntop(AF_INET6, &addr.sin6_addr, ip_addr, INET6_ADDRSTRLEN);
-
-       char port[6] = {0};
-       sprintf(port, "%d", ntohs(addr.sin6_port));
-
-       int err = getaddrinfo(ip_addr, port, NULL, &p->raddr);
-       if (err != 0) {
-               fprintf(stderr, "invalid network address %s:%s\n", ip_addr, port);
-               dragonnet_peer_delete(p);
-               p = NULL;
-       }
+       p->raddr = dragonnet_addr_parse_sock(addr);
 
        if (p != NULL)
                pthread_rwlock_unlock(p->mu);
@@ -64,15 +50,10 @@ DragonnetListener *dragonnet_listener_new(char *addr, void (*on_connect)(Dragonn
                return NULL;
        }
 
-       DragonnetAddr net_addr = dragonnet_addr_parse(addr);
-       int err = getaddrinfo(net_addr.ip, net_addr.port, NULL, &l->laddr);
-       if (err != 0) {
-               fprintf(stderr, "invalid network address %s\n", addr);
-               dragonnet_listener_delete(l);
-               return NULL;
-       }
+       l->laddr = dragonnet_addr_parse_str(addr);
+       struct sockaddr_in6 ai_addr = dragonnet_addr_sock(l->laddr);
 
-       if (bind(l->sock, l->laddr->ai_addr, l->laddr->ai_addrlen) < 0) {
+       if (bind(l->sock, (const struct sockaddr *) &ai_addr, sizeof ai_addr) < 0) {
                perror("bind");
                dragonnet_listener_delete(l);
                return NULL;
@@ -129,12 +110,6 @@ void dragonnet_listener_close(DragonnetListener *l)
 
 void dragonnet_listener_delete(DragonnetListener *l)
 {
-       pthread_rwlock_wrlock(l->mu);
-
-       if (l->laddr != NULL)
-               freeaddrinfo(l->laddr);
-
-       pthread_rwlock_unlock(l->mu);
        pthread_rwlock_destroy(l->mu);
        free(l);
 }
index 249119c3cf64c124d66198190f9b00db6bb25187..6e322eafdeec68a770fa5f4eacc448a87b24748a 100644 (file)
--- a/listen.h
+++ b/listen.h
@@ -13,7 +13,7 @@ typedef enum {
 
 typedef struct {
        int sock;
-       struct addrinfo *laddr;
+       DragonnetAddr laddr;
        void (*on_connect)(DragonnetPeer *p);
        DragonnetListenerState state;
 
diff --git a/peer.h b/peer.h
index 2f4ec6a2fcebf9134efcfb25064ff8d7598fb66f..4053bee277fea7801a2de84d240c7eae7b03215b 100644 (file)
--- a/peer.h
+++ b/peer.h
@@ -3,6 +3,8 @@
 
 #include <pthread.h>
 
+#include "addr.h"
+
 typedef enum {
        DRAGONNET_PEER_CREATED,
        DRAGONNET_PEER_ACTIVE,
@@ -11,8 +13,7 @@ typedef enum {
 
 typedef struct {
        int sock;
-       struct addrinfo *laddr;
-       struct addrinfo *raddr;
+       DragonnetAddr laddr, raddr;
        DragonnetPeerState state;
 
        pthread_rwlock_t *mu;