From 6cd6ee27e7dcd80b033186f3b18cd593b75d7403 Mon Sep 17 00:00:00 2001 From: Test_User Date: Sun, 9 Jun 2024 23:03:09 -0400 Subject: In-progress mesh haxserv; still has a lot to write up before it's usable --- server_network.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 server_network.c (limited to 'server_network.c') diff --git a/server_network.c b/server_network.c new file mode 100644 index 0000000..aed6a41 --- /dev/null +++ b/server_network.c @@ -0,0 +1,162 @@ +// One of the code files for HaxServ +// +// Written by: Test_User +// +// This is free and unencumbered software released into the public +// domain. +// +// Anyone is free to copy, modify, publish, use, compile, sell, or +// distribute this software, either in source code form or as a compiled +// binary, for any purpose, commercial or non-commercial, and by any +// means. +// +// In jurisdictions that recognize copyright laws, the author or authors +// of this software dedicate any and all copyright interest in the +// software to the public domain. We make this dedication for the benefit +// of the public at large and to the detriment of our heirs and +// successors. We intend this dedication to be an overt act of +// relinquishment in perpetuity of all present and future rights to this +// software under copyright law. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +#include +#include +#include +#include + +#include "config.h" +#include "main.h" +#include "protocols.h" +#include "server_network.h" + +#ifdef USE_PLAINTEXT_SERVER +#include "plaintext_network.h" +#endif +#ifdef USE_GNUTLS_SERVER +#include "gnutls_network.h" +#endif + +int init_server_network(void) { + return 0; +} + +int start_server_network(void) { +#ifdef USE_PLAINTEXT_SERVER + if (start_server_network_threads(NET_TYPE_PLAINTEXT) != 0) + return 1; +#endif +#ifdef USE_GNUTLS_SERVER + if (start_server_network_threads(NET_TYPE_GNUTLS) != 0) + return 1; +#endif +#ifdef USE_OPENSSL_SERVER + if (start_server_network_threads(NET_TYPE_OPENSSL) != 0) + return 1; +#endif + + pthread_t trash; + for (size_t i = 0; i < server_config_len; i++) { + if (server_config[i].autoconnect) { + if (pthread_create(&trash, &pthread_attr, protocols[server_config[i].protocol].autoconnect, &(server_config[i])) != 0) { + return 1; + } + } + } + + return 0; +} + +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 + 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; + } +#endif + return 0; +} + +void * server_accept_thread(void *type) { + size_t net; + size_t protocol; + { + struct server_network_info *t = type; + net = t->net_type; + protocol = t->protocol; + } + + // Check if there is actually an incoming server connection configured using this net+protocol, and if not just return from this thread; some excess may have been spawned + { + char found = 0; + for (size_t i = 0; i < server_config_len; i++) { + if (server_config[i].protocol == protocol && !(server_config[i].autoconnect)) { // TODO: Don't make autoconnect conflict with incoming connections + found = 1; + break; + } + } + if (!found) + return 0; + } + + int listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (listen_fd < 0) + return 0; + + { + int one = 1; + setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + } + + { + struct sockaddr_in sockaddr = { + .sin_family = AF_INET, + }; + + sockaddr.sin_port = htons(SERVER_PORTS[net][protocol]); + size_t listen_number = SERVER_LISTEN[net][protocol]; + + if (bind(listen_fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr)) != 0) + return 0; + + listen(listen_fd, listen_number); + } + + while (1) { + struct string address; + void *con_handle; + int con_fd = networks[net].accept(listen_fd, &con_handle, &address); + if (con_fd == -1) + continue; // TODO: Handle error + + pthread_t trash; + struct server_connection_info *info; + info = malloc(sizeof(*info)); + if (!info) { + networks[net].close(con_fd, con_handle); + continue; + } + info->address = address; + info->type = type; + info->fd = con_fd; + info->handle = con_handle; + if (pthread_create(&trash, &pthread_attr, protocols[protocol].handle_connection, info) != 0) { + free(info); + networks[net].close(con_fd, con_handle); + } + } +} -- cgit v1.2.3