#define _POSIX_SOURCE #include #include #include #include #include #include #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); }