diff options
Diffstat (limited to 'src/server/server.c')
-rw-r--r-- | src/server/server.c | 100 |
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); +} |