-#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;
}
#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
-#include <arpa/inet.h>
#include <assert.h>
#include <netdb.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
-#include "addr.h"
#include "listen.h"
// ----
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);
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;
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);
}