Hotfix for banning issues
[umurmur.git] / src / server.c
1 /* Copyright (C) 2009-2014, Martin Johansson <martin@fatbob.nu>
2    Copyright (C) 2005-2014, Thorvald Natvig <thorvald@natvig.com>
3
4    All rights reserved.
5
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions
8    are met:
9
10    - Redistributions of source code must retain the above copyright notice,
11      this list of conditions and the following disclaimer.
12    - Redistributions in binary form must reproduce the above copyright notice,
13      this list of conditions and the following disclaimer in the documentation
14      and/or other materials provided with the distribution.
15    - Neither the name of the Developers nor the names of its contributors may
16      be used to endorse or promote products derived from this software without
17      specific prior written permission.
18
19    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31 #include <stdio.h>
32 #include <sys/time.h>
33 #include <sys/poll.h>
34 #include <netinet/tcp.h>
35 #include <sys/socket.h>
36 #include <errno.h>
37 #include <string.h>
38 #include <limits.h>
39 #include <unistd.h>
40 #include <fcntl.h>
41 #include <errno.h>
42 #include <stdlib.h>
43
44 #include "client.h"
45 #include "conf.h"
46 #include "log.h"
47 #include "timer.h"
48 #include "version.h"
49 #include "util.h"
50
51 /* globals */
52 bool_t shutdown_server;
53 extern char *bindaddr;
54 extern char *bindaddr6;
55 extern int bindport;
56 extern int bindport6;
57 int* udpsocks;
58 bool_t hasv4 = true, hasv6 = true;
59
60 const int on = 1;
61 int nofServerSocks = 4;
62
63 /* Check which IP versions are supported by the system. */
64 void checkIPversions()
65 {
66         int testsocket = -1;
67
68         testsocket = socket(PF_INET, SOCK_STREAM, 0);
69         hasv4 = (errno == EAFNOSUPPORT) ? false : true;
70         if (!(testsocket < 0)) close(testsocket);
71
72         testsocket = socket(PF_INET6, SOCK_STREAM, 0);
73         hasv6 = (errno == EAFNOSUPPORT) ? false : true;
74         if (!(testsocket < 0)) close(testsocket);
75
76         if(!hasv4)
77         {
78                 Log_info("IPv4 is not supported by this system");
79                 nofServerSocks -= 2;
80         }
81
82         if(!hasv6)
83         {
84                 Log_info("IPv6 is not supported by this system");
85                 nofServerSocks -= 2;
86         }
87
88         if(nofServerSocks == 0)
89         {
90                 Log_fatal("Neither IPv4 nor IPv6 are supported by this system");
91         }
92 }
93
94 /* Initialize the address structures for IPv4 and IPv6 */
95 struct sockaddr_storage** Server_setupAddressesAndPorts()
96 {
97         struct sockaddr_storage** addresses = calloc(2, sizeof(void*));
98
99         struct sockaddr_storage* v4address = calloc(1, sizeof(struct sockaddr_storage));
100         v4address->ss_family = AF_INET;
101         struct sockaddr_storage* v6address = calloc(1, sizeof(struct sockaddr_storage));
102         v6address->ss_family = AF_INET6;
103
104 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__)
105         v4address->ss_len = sizeof(struct sockaddr_storage);
106         v6address->ss_len = sizeof(struct sockaddr_storage);
107 #endif
108
109         int error = 0;
110
111         error = inet_pton(AF_INET, (!bindaddr) ? ((getStrConf(BINDADDR)) ? getStrConf(BINDADDR) : "0.0.0.0")
112                 : bindaddr, &(((struct sockaddr_in*)v4address)->sin_addr));
113         if (error == 0)
114                 Log_fatal("Invalid IPv4 address supplied!");
115         else if (error == -1)
116                 Log_warn("Could not allocate IPv4 address");
117
118         error = inet_pton(AF_INET6, (!bindaddr6) ? ((getStrConf(BINDADDR6)) ? getStrConf(BINDADDR6) : "::")
119                 : bindaddr6, &(((struct sockaddr_in6*)v6address)->sin6_addr));
120         if (error == 0)
121                 Log_fatal("Invalid IPv6 address supplied!");
122         else if (error == -1)
123                 Log_warn("Could not allocate IPv6 address");
124
125         ((struct sockaddr_in*)v4address)->sin_port = htons((bindport) ? bindport : getIntConf(BINDPORT));
126         ((struct sockaddr_in6*)v6address)->sin6_port = htons((bindport6) ? bindport6 : getIntConf(BINDPORT6));
127
128         addresses[0] = v4address;
129         addresses[1] = v6address;
130
131         return addresses;
132 }
133
134 void Server_runLoop(struct pollfd* pollfds)
135 {
136         int timeout, rc, clientcount;
137
138         etimer_t janitorTimer;
139         Timer_init(&janitorTimer);
140
141         while (!shutdown_server) {
142                 struct sockaddr_storage remote;
143                 int i;
144
145                 for(i = 0; i < nofServerSocks; i++) {
146                         pollfds[i].revents = 0;
147                 }
148
149                 clientcount = Client_getfds(&pollfds[nofServerSocks]);
150
151                 timeout = (int)(1000000LL - (int64_t)Timer_elapsed(&janitorTimer)) / 1000LL;
152                 if (timeout <= 0) {
153                         Client_janitor();
154                         Timer_restart(&janitorTimer);
155                         timeout = (int)(1000000LL - (int64_t)Timer_elapsed(&janitorTimer)) / 1000LL;
156                 }
157                 rc = poll(pollfds, clientcount + nofServerSocks, timeout);
158                 if (rc == 0) {
159                         /* Poll timed out, do maintenance */
160                         Timer_restart(&janitorTimer);
161                         Client_janitor();
162                         continue;
163                 }
164                 if (rc < 0) {
165                         if (errno == EINTR) /* signal */
166                                 continue;
167                         else
168                                 Log_fatal("poll: error %d (%s)", errno, strerror(errno));
169                 }
170
171                 /* Check for new connection */
172                 for (i = 0; i < nofServerSocks / 2; i++) {
173                         if (pollfds[i].revents) {
174                                 int tcpfd;
175                                 uint32_t addrlen = sizeof(struct sockaddr_storage);
176                                 tcpfd = accept(pollfds[i].fd, (struct sockaddr *)&remote, &addrlen);
177                                 fcntl(tcpfd, F_SETFL, O_NONBLOCK);
178                                 setsockopt(tcpfd, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(int));
179                                 Log_debug("Connection from %s port %d\n", Util_addressToString(&remote), Util_addressToPort(&remote));
180                                 if (Client_add(tcpfd, &remote) < 0)
181                                         close(tcpfd);
182                         }
183                 }
184
185                 for (i = nofServerSocks / 2; i < nofServerSocks; i++) {
186                         if (pollfds[i].revents)
187                                 Client_read_udp(udpsocks[i - nofServerSocks / 2]);
188                 }
189
190                 for (i = 0; i < clientcount; i++) {
191                         if (pollfds[nofServerSocks + i].revents & POLLIN)
192                                 Client_read_fd(pollfds[nofServerSocks + i].fd);
193
194                         if (pollfds[nofServerSocks + i].revents & POLLOUT)
195                                 Client_write_fd(pollfds[nofServerSocks + i].fd);
196                 }
197         }
198 }
199
200 void Server_setupTCPSockets(struct sockaddr_storage* addresses[2], struct pollfd* pollfds)
201 {
202         uint8_t yes = 1;
203         int sockets[2];
204
205         if (hasv4) {
206                 /* IPv4 socket setup */
207                 sockets[0] = socket(PF_INET, SOCK_STREAM, 0);
208                 if (sockets[0] < 0)
209                         Log_fatal("socket IPv4");
210                 if (setsockopt(sockets[0], SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) != 0)
211                         Log_fatal("setsockopt IPv4: %s", strerror(errno));
212                 if (bind(sockets[0], (struct sockaddr *)addresses[0], sizeof (struct sockaddr_in)) < 0)
213                         Log_fatal("bind %s %d: %s", Util_addressToString(addresses[0]), Util_addressToPort(addresses[0]), strerror(errno));
214                 if (listen(sockets[0], 3) < 0)
215                         Log_fatal("listen IPv4");
216                 fcntl(sockets[0], F_SETFL, O_NONBLOCK);
217
218                 pollfds[0].fd = sockets[0];
219                 pollfds[0].events = POLLIN;
220         }
221
222         if (hasv6) {
223                 /* IPv6 socket setup */
224                 sockets[1] = socket(PF_INET6, SOCK_STREAM, 0);
225                 if (sockets[1] < 0)
226                         Log_fatal("socket IPv6: %s", strerror(errno));
227                 if (setsockopt(sockets[1], SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) != 0)
228                         Log_fatal("setsockopt IPv6: %s", strerror(errno));
229                 if (setsockopt(sockets[1], IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(int)) != 0)
230                         Log_fatal("setsockopt IPv6: %s", strerror(errno));
231                 if (bind(sockets[1], (struct sockaddr *)addresses[1], sizeof (struct sockaddr_in6)) < 0)
232                         Log_fatal("bind %s %d: %s", Util_addressToString(addresses[1]), Util_addressToPort(addresses[1]), strerror(errno));
233                 if (listen(sockets[1], 3) < 0)
234                         Log_fatal("listen IPv6");
235                 fcntl(sockets[1], F_SETFL, O_NONBLOCK);
236
237
238                 /* If  there is an IPv4 address, then IPv6 will use the second socket, otherwise it uses the first */
239                 pollfds[(hasv4) ? 1 : 0].fd = sockets[1];
240                 pollfds[(hasv4) ? 1 : 0].events = POLLIN;
241         }
242 }
243
244 void Server_setupUDPSockets(struct sockaddr_storage* addresses[2], struct pollfd* pollfds)
245 {
246         int val = 0;
247         int sockets[2] = {-1, -1};
248
249         if((udpsocks = calloc(nofServerSocks / 2, sizeof(int))) == NULL)
250                 Log_fatal("Out of memory (%s:%s)", __FILE__, __LINE__);
251
252         if (hasv4) {
253                 sockets[0] = socket(PF_INET, SOCK_DGRAM, 0);
254                 if (bind(sockets[0], (struct sockaddr *) addresses[0], sizeof (struct sockaddr_in)) < 0)
255                         Log_fatal("bind %s %d: %s", Util_addressToString(addresses[0]), Util_addressToPort(addresses[0]), strerror(errno));
256                 val = 0xe0;
257                 if (setsockopt(sockets[0], IPPROTO_IP, IP_TOS, &val, sizeof(val)) < 0)
258                         Log_warn("Server: Failed to set TOS for UDP Socket");
259                 val = 0x80;
260                 if (setsockopt(sockets[0], IPPROTO_IP, IP_TOS, &val, sizeof(val)) < 0)
261                         Log_warn("Server: Failed to set TOS for UDP Socket");
262
263                 fcntl(sockets[0], F_SETFL, O_NONBLOCK);
264                 pollfds[(hasv6) ? 2 : 1].fd = sockets[0];
265                 pollfds[(hasv6) ? 2 : 1].events = POLLIN | POLLHUP | POLLERR;
266                 udpsocks[0] = sockets[0];
267         }
268
269         if (hasv6) {
270                 sockets[1] = socket(PF_INET6, SOCK_DGRAM, 0);
271                 if (setsockopt(sockets[1], IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(int)) != 0)
272                         Log_fatal("setsockopt IPv6: %s", strerror(errno));
273                 if (bind(sockets[1], (struct sockaddr *) addresses[1], sizeof (struct sockaddr_in6)) < 0)
274                         Log_fatal("bind %s %d: %s", Util_addressToString(addresses[1]), Util_addressToPort(addresses[1]), strerror(errno));
275                 val = 0xe0;
276                 if (setsockopt(sockets[1], IPPROTO_IPV6, IPV6_TCLASS, &val, sizeof(val)) < 0)
277                         Log_warn("Server: Failed to set TOS for UDP Socket");
278                 val = 0x80;
279                 if (setsockopt(sockets[1], IPPROTO_IPV6, IPV6_TCLASS, &val, sizeof(val)) < 0)
280                         Log_warn("Server: Failed to set TOS for UDP Socket");
281
282                 fcntl(sockets[1], F_SETFL, O_NONBLOCK);
283                 pollfds[(hasv4) ? 3 : 1].fd = sockets[1];
284                 pollfds[(hasv4) ? 3 : 1].events = POLLIN | POLLHUP | POLLERR;
285                 udpsocks[(hasv4) ? 1 : 0] = sockets[1];
286         }
287
288 }
289
290 void Server_run()
291 {
292         struct pollfd *pollfds;
293
294         checkIPversions();
295
296         /* max clients + server sokets + client connecting that will be disconnected */
297         if ((pollfds = calloc((getIntConf(MAX_CLIENTS) + nofServerSocks + 1) , sizeof(struct pollfd))) == NULL)
298                 Log_fatal("out of memory");
299
300         /* Figure out bind address and port */
301         struct sockaddr_storage** addresses = Server_setupAddressesAndPorts();
302
303         /* Prepare TCP sockets */
304         Server_setupTCPSockets(addresses, pollfds);
305
306         /* Prepare UDP sockets */
307         Server_setupUDPSockets(addresses, pollfds);
308
309         Log_info("uMurmur version %s ('%s') protocol version %d.%d.%d",
310                 UMURMUR_VERSION, UMURMUR_CODENAME, PROTVER_MAJOR, PROTVER_MINOR, PROTVER_PATCH);
311         Log_info("Visit http://code.google.com/p/umurmur/");
312
313         /* Main server loop */
314         Server_runLoop(pollfds);
315
316         /* Disconnect clients and cleanup memory */
317         Client_disconnect_all();
318         free(pollfds);
319         free(addresses[0]);
320         free(addresses[1]);
321         free(addresses);
322         free(udpsocks);
323 }
324
325 void Server_shutdown()
326 {
327         shutdown_server = true;
328 }