aboutsummaryrefslogtreecommitdiff
path: root/server_network.c
diff options
context:
space:
mode:
authorTest_User <hax@andrewyu.org>2024-06-09 23:03:09 -0400
committerTest_User <hax@andrewyu.org>2024-06-09 23:03:09 -0400
commit6cd6ee27e7dcd80b033186f3b18cd593b75d7403 (patch)
tree8f7639fbb51a08571738c7df340881a2b1fc8ce1 /server_network.c
downloadhaxircd-6cd6ee27e7dcd80b033186f3b18cd593b75d7403.tar.gz
haxircd-6cd6ee27e7dcd80b033186f3b18cd593b75d7403.zip
In-progress mesh haxserv; still has a lot to write up before it's usable
Diffstat (limited to 'server_network.c')
-rw-r--r--server_network.c162
1 files changed, 162 insertions, 0 deletions
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 <hax@andrewyu.org>
+//
+// 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 <arpa/inet.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#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);
+ }
+ }
+}