1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
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);
}
|