From 09c0ec3bdf113dd507135237603bf0096e642172 Mon Sep 17 00:00:00 2001 From: Test_User Date: Wed, 24 Jul 2024 02:48:49 -0400 Subject: Probable outgoing IPv6 support --- Makefile | 15 +++++++++++++++ general_network.c | 23 ++++++++++++++++++++--- general_network.h | 2 +- networks/gnutls.c | 14 ++++++++------ networks/gnutls_buffered.c | 14 ++++++++------ networks/openssl.c | 14 ++++++++------ networks/openssl_buffered.c | 14 ++++++++------ networks/plaintext.c | 14 ++++++++------ networks/plaintext_buffered.c | 14 ++++++++------ 9 files changed, 84 insertions(+), 40 deletions(-) diff --git a/Makefile b/Makefile index fe1f263..dd49dbe 100644 --- a/Makefile +++ b/Makefile @@ -53,6 +53,7 @@ LDFLAGS = -lpthread printf '%s\n' 'LAST_FUTEX = $(FUTEX)' >> .makeopts printf '%s\n' 'LAST_MISERABLE_SPINLOCKS = $(MISERABLE_SPINLOCKS)' >> .makeopts printf '%s\n' 'LAST_ATOMICS = $(ATOMICS)' >> .makeopts + printf '%s\n' 'LAST_IPv6 = $(IPv6)' >> .makeopts printf '%s\n' 'LAST_CFLAGS = $(ORIGINAL_CFLAGS)' >> .makeopts printf '%s\n' 'LAST_CC = $(CC)' >> .makeopts @@ -240,6 +241,14 @@ else ATOMICS := $(LAST_ATOMICS) endif +ifneq ($(IPv6),) +ifneq ($(IPv6),$(LAST_IPv6)) +rebuild = 1 +endif +else +IPv6 := $(LAST_IPv6) +endif + ifeq ($(rebuild),1) .PHONY: .makeopts endif @@ -437,6 +446,12 @@ endif +ifeq ($(IPv6),1) +CFLAGS += -DUSE_IPv6 +endif + + + ifeq ($(SAFE_STACK),1) CFLAGS += -fstack-check endif diff --git a/general_network.c b/general_network.c index afc11fb..452b950 100644 --- a/general_network.c +++ b/general_network.c @@ -169,7 +169,7 @@ struct table channel_list = {0}; struct server_info *self; -int resolve(struct string address, struct string port, struct sockaddr *sockaddr) { +int resolve(struct string address, struct string port, struct sockaddr *sockaddr, socklen_t *len, int *family) { // NULL isn't really valid in this anyways so... just checking it and replacing with null-terminated for now for (size_t i = 0; i < address.len; i++) if (address.data[i] == 0) @@ -194,7 +194,7 @@ int resolve(struct string address, struct string port, struct sockaddr *sockaddr int success; struct addrinfo hints = { - .ai_family = AF_INET, + .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM, .ai_protocol = IPPROTO_TCP, .ai_flags = AI_NUMERICSERV | AI_ADDRCONFIG, @@ -204,7 +204,24 @@ int resolve(struct string address, struct string port, struct sockaddr *sockaddr success = getaddrinfo(addr_null, port_null, &hints, &info); if (success == 0) { - *sockaddr = *(info->ai_addr); + struct addrinfo *this = info; + while (1) { + if (this->ai_family == AF_INET +#ifdef USE_IPv6 + || this->ai_family == AF_INET6 +#endif + ) { + memcpy(sockaddr, this->ai_addr, this->ai_addrlen); + *len = this->ai_addrlen; + *family = this->ai_family; + break; + } else if (this->ai_next) { + this = this->ai_next; + } else { + success = 1; + break; + } + } freeaddrinfo(info); } diff --git a/general_network.h b/general_network.h index 2705cec..8d563db 100644 --- a/general_network.h +++ b/general_network.h @@ -127,7 +127,7 @@ struct channel_info { void *protocol_specific[NUM_PROTOCOLS]; }; -int resolve(struct string address, struct string port, struct sockaddr *sockaddr); +int resolve(struct string address, struct string port, struct sockaddr *sockaddr, socklen_t *len, int *family); int init_general_network(void); diff --git a/networks/gnutls.c b/networks/gnutls.c index dfa9e88..d84ae05 100644 --- a/networks/gnutls.c +++ b/networks/gnutls.c @@ -210,10 +210,12 @@ int gnutls_connect(void **handle, struct string address, struct string port, str mutex_init(&(gnutls_handle->mutex)); struct sockaddr sockaddr; - if (resolve(address, port, &sockaddr) != 0) + socklen_t sockaddr_len; + int family; + if (resolve(address, port, &sockaddr, &sockaddr_len, &family) != 0) goto gnutls_connect_destroy_mutex; - int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + int fd = socket(family, SOCK_STREAM, IPPROTO_TCP); if (fd == -1) goto gnutls_connect_destroy_mutex; @@ -222,7 +224,7 @@ int gnutls_connect(void **handle, struct string address, struct string port, str int res; do { - res = connect(fd, &sockaddr, sizeof(sockaddr)); + res = connect(fd, &sockaddr, sockaddr_len); } while (res < 0 && errno == EINTR); if (res < 0) goto gnutls_connect_close; @@ -287,12 +289,12 @@ int gnutls_connect(void **handle, struct string address, struct string port, str goto gnutls_connect_deinit_session; } while (1); - addr_out->data = malloc(sizeof(sockaddr)); + addr_out->data = malloc(sockaddr_len); if (!addr_out->data) goto gnutls_connect_deinit_session; - memcpy(addr_out->data, &sockaddr, sizeof(sockaddr)); - addr_out->len = sizeof(sockaddr); + memcpy(addr_out->data, &sockaddr, sockaddr_len); + addr_out->len = sockaddr_len; return fd; diff --git a/networks/gnutls_buffered.c b/networks/gnutls_buffered.c index 0c113fa..2c23801 100644 --- a/networks/gnutls_buffered.c +++ b/networks/gnutls_buffered.c @@ -210,10 +210,12 @@ int gnutls_buffered_connect(void **handle, struct string address, struct string mutex_init(&(gnutls_handle->mutex)); struct sockaddr sockaddr; - if (resolve(address, port, &sockaddr) != 0) + socklen_t sockaddr_len; + int family; + if (resolve(address, port, &sockaddr, &sockaddr_len, &family) != 0) goto gnutls_connect_destroy_mutex; - int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + int fd = socket(family, SOCK_STREAM, IPPROTO_TCP); if (fd == -1) goto gnutls_connect_destroy_mutex; @@ -222,7 +224,7 @@ int gnutls_buffered_connect(void **handle, struct string address, struct string int res; do { - res = connect(fd, &sockaddr, sizeof(sockaddr)); + res = connect(fd, &sockaddr, sockaddr_len); } while (res < 0 && errno == EINTR); if (res < 0) goto gnutls_connect_close; @@ -287,12 +289,12 @@ int gnutls_buffered_connect(void **handle, struct string address, struct string goto gnutls_connect_deinit_session; } while (1); - addr_out->data = malloc(sizeof(sockaddr)); + addr_out->data = malloc(sockaddr_len); if (!addr_out->data) goto gnutls_connect_deinit_session; - memcpy(addr_out->data, &sockaddr, sizeof(sockaddr)); - addr_out->len = sizeof(sockaddr); + memcpy(addr_out->data, &sockaddr, sockaddr_len); + addr_out->len = sockaddr_len; return fd; diff --git a/networks/openssl.c b/networks/openssl.c index d2b84b1..570d3e5 100644 --- a/networks/openssl.c +++ b/networks/openssl.c @@ -203,10 +203,12 @@ size_t openssl_recv(void *handle, char *data, size_t len, char *err) { int openssl_connect(void **handle, struct string address, struct string port, struct string *addr_out) { struct sockaddr sockaddr; - if (resolve(address, port, &sockaddr) != 0) + socklen_t sockaddr_len; + int family; + if (resolve(address, port, &sockaddr, &sockaddr_len, &family) != 0) return -1; - int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + int fd = socket(family, SOCK_STREAM, IPPROTO_TCP); if (fd == -1) return -1; @@ -221,7 +223,7 @@ int openssl_connect(void **handle, struct string address, struct string port, st int res; do { - res = connect(fd, &sockaddr, sizeof(sockaddr)); + res = connect(fd, &sockaddr, sockaddr_len); } while (res < 0 && errno == EINTR); if (res < 0) goto openssl_connect_close; @@ -232,11 +234,11 @@ int openssl_connect(void **handle, struct string address, struct string port, st if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) goto openssl_connect_close; - addr_out->data = malloc(sizeof(sockaddr)); + addr_out->data = malloc(sockaddr_len); if (!addr_out->data) goto openssl_connect_close; - memcpy(addr_out->data, &sockaddr, sizeof(sockaddr)); - addr_out->len = sizeof(sockaddr); + memcpy(addr_out->data, &sockaddr, sockaddr_len); + addr_out->len = sockaddr_len; struct openssl_handle *openssl_handle; openssl_handle = malloc(sizeof(*openssl_handle)); diff --git a/networks/openssl_buffered.c b/networks/openssl_buffered.c index 47057aa..5c1d0c9 100644 --- a/networks/openssl_buffered.c +++ b/networks/openssl_buffered.c @@ -320,10 +320,12 @@ size_t openssl_buffered_recv(void *handle, char *data, size_t len, char *err) { int openssl_buffered_connect(void **handle, struct string address, struct string port, struct string *addr_out) { struct sockaddr sockaddr; - if (resolve(address, port, &sockaddr) != 0) + socklen_t sockaddr_len; + int family; + if (resolve(address, port, &sockaddr, &sockaddr_len, &family) != 0) return -1; - int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + int fd = socket(family, SOCK_STREAM, IPPROTO_TCP); if (fd == -1) return -1; @@ -338,7 +340,7 @@ int openssl_buffered_connect(void **handle, struct string address, struct string int res; do { - res = connect(fd, &sockaddr, sizeof(sockaddr)); + res = connect(fd, &sockaddr, sockaddr_len); } while (res < 0 && errno == EINTR); if (res < 0) goto openssl_connect_close; @@ -349,11 +351,11 @@ int openssl_buffered_connect(void **handle, struct string address, struct string if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) goto openssl_connect_close; - addr_out->data = malloc(sizeof(sockaddr)); + addr_out->data = malloc(sockaddr_len); if (!addr_out->data) goto openssl_connect_close; - memcpy(addr_out->data, &sockaddr, sizeof(sockaddr)); - addr_out->len = sizeof(sockaddr); + memcpy(addr_out->data, &sockaddr, sockaddr_len); + addr_out->len = sockaddr_len; struct openssl_buffered_handle *openssl_handle; openssl_handle = malloc(sizeof(*openssl_handle)); diff --git a/networks/plaintext.c b/networks/plaintext.c index 0bc17a6..b3554ab 100644 --- a/networks/plaintext.c +++ b/networks/plaintext.c @@ -89,10 +89,12 @@ size_t plaintext_recv(void *fd, char *data, size_t len, char *err) { int plaintext_connect(void **handle, struct string address, struct string port, struct string *addr_out) { struct sockaddr sockaddr; - if (resolve(address, port, &sockaddr) != 0) + socklen_t sockaddr_len; + int family; + if (resolve(address, port, &sockaddr, &sockaddr_len, &family) != 0) return -1; - int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + int fd = socket(family, SOCK_STREAM, IPPROTO_TCP); if (fd == -1) return -1; @@ -107,7 +109,7 @@ int plaintext_connect(void **handle, struct string address, struct string port, int res; do { - res = connect(fd, &sockaddr, sizeof(sockaddr)); + res = connect(fd, &sockaddr, sockaddr_len); } while (res < 0 && errno == EINTR); if (res < 0) { close(fd); @@ -121,14 +123,14 @@ int plaintext_connect(void **handle, struct string address, struct string port, } *((int*)*handle) = fd; - addr_out->data = malloc(sizeof(sockaddr)); + addr_out->data = malloc(sockaddr_len); if (!addr_out->data) { free(handle); close(fd); return -1; } - memcpy(addr_out->data, &sockaddr, sizeof(sockaddr)); - addr_out->len = sizeof(sockaddr); + memcpy(addr_out->data, &sockaddr, sockaddr_len); + addr_out->len = sockaddr_len; return fd; } diff --git a/networks/plaintext_buffered.c b/networks/plaintext_buffered.c index 5fea3bd..d56ff27 100644 --- a/networks/plaintext_buffered.c +++ b/networks/plaintext_buffered.c @@ -222,10 +222,12 @@ size_t plaintext_buffered_recv(void *handle, char *data, size_t len, char *err) int plaintext_buffered_connect(void **handle, struct string address, struct string port, struct string *addr_out) { struct sockaddr sockaddr; - if (resolve(address, port, &sockaddr) != 0) + socklen_t sockaddr_len; + int family; + if (resolve(address, port, &sockaddr, &sockaddr_len, &family) != 0) return -1; - int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + int fd = socket(family, SOCK_STREAM, IPPROTO_TCP); if (fd == -1) return -1; @@ -240,7 +242,7 @@ int plaintext_buffered_connect(void **handle, struct string address, struct stri int res; do { - res = connect(fd, &sockaddr, sizeof(sockaddr)); + res = connect(fd, &sockaddr, sockaddr_len); } while (res < 0 && errno == EINTR); if (res < 0) goto plaintext_buffered_connect_close; @@ -254,11 +256,11 @@ int plaintext_buffered_connect(void **handle, struct string address, struct stri plaintext_handle->close = 0; plaintext_handle->fd = fd; - addr_out->data = malloc(sizeof(sockaddr)); + addr_out->data = malloc(sockaddr_len); if (!addr_out->data) goto plaintext_buffered_connect_free_handle; - memcpy(addr_out->data, &sockaddr, sizeof(sockaddr)); - addr_out->len = sizeof(sockaddr); + memcpy(addr_out->data, &sockaddr, sockaddr_len); + addr_out->len = sockaddr_len; plaintext_handle->buffer = malloc(PLAINTEXT_BUFFERED_LEN); if (!plaintext_handle->buffer) -- cgit v1.2.3