From 6c636818b25c9ef6d12af669914c84c94de2fd88 Mon Sep 17 00:00:00 2001 From: Test_User Date: Wed, 24 Jul 2024 05:04:03 -0400 Subject: Possibly broken incoming IPv6 support --- protocols.h | 1 + server_network.c | 70 +++++++++++++++++++++++++++++++++----------------------- server_network.h | 1 + 3 files changed, 43 insertions(+), 29 deletions(-) diff --git a/protocols.h b/protocols.h index c72fb93..0b40752 100644 --- a/protocols.h +++ b/protocols.h @@ -157,3 +157,4 @@ void protocols_fail_set_channel(struct string from, struct channel_info *channel void protocols_fail_join_channel(struct string from, struct channel_info *channel, size_t user_count, struct user_info **users, char propagate); extern struct protocol protocols[NUM_PROTOCOLS]; +extern char active_protocols[NUM_PROTOCOLS]; diff --git a/server_network.c b/server_network.c index a5b78a1..845794a 100644 --- a/server_network.c +++ b/server_network.c @@ -118,47 +118,50 @@ int start_server_network(void) { int start_server_network_threads(size_t net) { pthread_t trash; // Not actually used, so discard struct server_network_info *type; -#ifdef USE_INSPIRCD2_PROTOCOL - if (SERVER_INCOMING[net][INSPIRCD2_PROTOCOL]) { - type = malloc(sizeof(*type)); - if (!type) - return 1; - type->net_type = net; - type->protocol = INSPIRCD2_PROTOCOL; - type->is_incoming = 1; - if (pthread_create(&trash, &pthread_attr, server_accept_thread, type) != 0) { - free(type); - return 1; - } - } + for (size_t i = 0; i < NUM_PROTOCOLS; i++) { + if (active_protocols[i] && SERVER_INCOMING[net][i]) { + type = malloc(sizeof(*type)); + if (!type) + return 1; + type->net_type = net; + type->protocol = INSPIRCD2_PROTOCOL; + type->family = AF_INET; + type->is_incoming = 1; + if (pthread_create(&trash, &pthread_attr, server_accept_thread, type) != 0) { + free(type); + return 1; + } + +#ifdef USE_IPv6 + type = malloc(sizeof(*type)); + if (!type) + return 1; + type->net_type = net; + type->protocol = INSPIRCD2_PROTOCOL; + type->family = AF_INET6; + type->is_incoming = 1; + if (pthread_create(&trash, &pthread_attr, server_accept_thread, type) != 0) { + free(type); + return 1; + } #endif -#ifdef USE_INSPIRCD3_PROTOCOL - if (SERVER_INCOMING[net][INSPIRCD3_PROTOCOL]) { - type = malloc(sizeof(*type)); - if (!type) - return 1; - type->net_type = net; - type->protocol = INSPIRCD3_PROTOCOL; - type->is_incoming = 1; - if (pthread_create(&trash, &pthread_attr, server_accept_thread, type) != 0) { - free(type); - return 1; } } -#endif return 0; } void * server_accept_thread(void *type) { size_t net; size_t protocol; + int family; { struct server_network_info *t = type; net = t->net_type; protocol = t->protocol; + family = t->family; } - int listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + int listen_fd = socket(family, SOCK_STREAM, IPPROTO_TCP); if (listen_fd < 0) return 0; @@ -168,11 +171,20 @@ void * server_accept_thread(void *type) { } { - struct sockaddr_in sockaddr = { - .sin_family = AF_INET, + struct sockaddr sockaddr = { + .sa_family = family, }; - sockaddr.sin_port = htons(SERVER_PORTS[net][protocol]); + if (family == AF_INET) { + ((struct sockaddr_in *)&sockaddr)->sin_port = htons(SERVER_PORTS[net][protocol]); +#ifdef IPv6 + } else if (family == AF_INET6) { + ((struct sockaddr_in6 *)&sockaddr)->sin_port = htons(SERVER_PORTS[net][protocol]); + int one = 1; + setsockopt(listen_fd, SOL_IPV6, IPV6_V6ONLY, &one, sizeof(one)); +#endif + } + size_t listen_number = SERVER_LISTEN[net][protocol]; if (bind(listen_fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) != 0) diff --git a/server_network.h b/server_network.h index b32f1b2..a4ca2df 100644 --- a/server_network.h +++ b/server_network.h @@ -37,6 +37,7 @@ struct server_network_info { size_t net_type; size_t protocol; + int family; char is_incoming; }; -- cgit v1.2.3