From: HimbeerserverDE Date: Sun, 3 Oct 2021 13:43:00 +0000 (+0200) Subject: Refactor address conversions X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=7639851f75c977923e636044af1c44508424b75e;p=dragonnet.git Refactor address conversions --- diff --git a/addr.c b/addr.c index 226e0fd..a257a5d 100644 --- a/addr.c +++ b/addr.c @@ -1,22 +1,70 @@ -#include +#include +#include +#include #include #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 437e245..11fd281 100644 --- a/addr.h +++ b/addr.h @@ -1,11 +1,17 @@ #ifndef _DRAGONNET_ADDR_H_ #define _DRAGONNET_ADDR_H_ +#include + 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 diff --git a/listen.c b/listen.c index 9f25eed..440f889 100644 --- a/listen.c +++ b/listen.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -6,7 +5,6 @@ #include #include -#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); } diff --git a/listen.h b/listen.h index 249119c..6e322ea 100644 --- 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 2f4ec6a..4053bee 100644 --- a/peer.h +++ b/peer.h @@ -3,6 +3,8 @@ #include +#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;