summaryrefslogtreecommitdiff
path: root/src/server/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/server.c')
-rw-r--r--src/server/server.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/server/server.c b/src/server/server.c
new file mode 100644
index 0000000..c8975ee
--- /dev/null
+++ b/src/server/server.c
@@ -0,0 +1,100 @@
+#define _POSIX_SOURCE
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <signal.h>
+
+#include "addr.h"
+#include "server.h"
+#include "resolver.h"
+#include "../io/log.h"
+
+static pid_t udp, tcp;
+
+void server_init(uint16_t port, Server* server) {
+ INFO("Server port set to %hu", port);
+ create_binding(UDP, port, &server->udp);
+ create_binding(TCP, port, &server->tcp);
+}
+
+static void server_listen(Binding* binding) {
+ while(1) {
+
+ Connection connection;
+ if (!accept_connection(binding, &connection)) {
+ ERROR("Failed to accept connection");
+ continue;
+ }
+
+ Packet request;
+ if (!read_connection(&connection, &request)) {
+ ERROR("Failed to read connection");
+ free_connection(&connection);
+ continue;
+ }
+
+ if(fork() != 0) {
+ free_packet(&request);
+ free_connection(&connection);
+ continue;
+ }
+
+ INFO("Recieved packet request ID %hu", request.header.id);
+
+ Packet response;
+ handle_query(&request, &response, connection.type);
+
+ if (!write_connection(&connection, &response)) {
+ ERROR("Failed to respond to connection ID %hu: %s", request.header.id, strerror(errno));
+ }
+
+ free_packet(&request);
+ free_packet(&response);
+ free_connection(&connection);
+ exit(EXIT_SUCCESS);
+ }
+}
+
+static void signal_handler() {
+ printf("\n");
+ kill(udp, SIGTERM);
+ kill(tcp, SIGTERM);
+}
+
+void server_run(Server* server) {
+ if ((udp = fork()) == 0) {
+ INFO("Listening for connections on UDP");
+ server_listen(&server->udp);
+ exit(EXIT_SUCCESS);
+ }
+
+ if ((tcp = fork()) == 0) {
+ INFO("Listening for connections on TCP");
+ server_listen(&server->tcp);
+ exit(EXIT_SUCCESS);
+ }
+
+ signal(SIGINT, signal_handler);
+
+ int status;
+ waitpid(udp, &status, 0);
+ if (status == 0) {
+ INFO("UDP process closed successfully");
+ } else {
+ ERROR("UDP process failed with error code %d", status);
+ }
+
+ waitpid(tcp, &status, 0);
+ if (status == 0) {
+ INFO("TCP process closed successfully");
+ } else {
+ ERROR("TCP process failed with error code %d", status);
+ }
+}
+
+void server_free(Server* server) {
+ free_binding(&server->udp);
+ free_binding(&server->tcp);
+}