X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=src%2Fserver.c;h=8aa356c58c2f0df6e69f580f947e8137dd4183c7;hb=71893121fbce7762f5cd9e6a98c4ead7e5cd6211;hp=4dee126dcf40f5b9cb68b195c5100a037f2f02bb;hpb=e3d75b4d7bddb8db5e1a4fb218cc5f3b236de0cc;p=umurmur.git diff --git a/src/server.c b/src/server.c index 4dee126..8aa356c 100644 --- a/src/server.c +++ b/src/server.c @@ -47,6 +47,7 @@ #include "timer.h" #include "version.h" #include "util.h" +#include "sharedmemory.h" /* globals */ bool_t shutdown_server; @@ -60,14 +61,51 @@ bool_t hasv4 = true, hasv6 = true; const int on = 1; int nofServerSocks = 4; +/* Check which IP versions are supported by the system. */ +void checkIPversions() +{ + int testsocket = -1; + + testsocket = socket(PF_INET, SOCK_STREAM, 0); + hasv4 = (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) ? false : true; + if (!(testsocket < 0)) close(testsocket); + + testsocket = socket(PF_INET6, SOCK_STREAM, 0); + hasv6 = (errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) ? false : true; + if (!(testsocket < 0)) close(testsocket); + + if(!hasv4) + { + Log_info("IPv4 is not supported by this system"); + nofServerSocks -= 2; + } + + if(!hasv6) + { + Log_info("IPv6 is not supported by this system"); + nofServerSocks -= 2; + } + if(nofServerSocks == 0) + { + Log_fatal("Neither IPv4 nor IPv6 are supported by this system"); + } +} + /* Initialize the address structures for IPv4 and IPv6 */ struct sockaddr_storage** Server_setupAddressesAndPorts() { struct sockaddr_storage** addresses = calloc(2, sizeof(void*)); + if(!addresses) + Log_fatal("Not enough memory to allocate addresses"); struct sockaddr_storage* v4address = calloc(1, sizeof(struct sockaddr_storage)); + if(!v4address) + Log_fatal("Not enough memory to allocate IPv4 address"); v4address->ss_family = AF_INET; + struct sockaddr_storage* v6address = calloc(1, sizeof(struct sockaddr_storage)); + if(!v6address) + Log_fatal("Not enough memory to allocate IPv6 address"); v6address->ss_family = AF_INET6; #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__APPLE__) @@ -81,24 +119,15 @@ struct sockaddr_storage** Server_setupAddressesAndPorts() : bindaddr, &(((struct sockaddr_in*)v4address)->sin_addr)); if (error == 0) Log_fatal("Invalid IPv4 address supplied!"); - else if (error == -1) { + else if (error == -1) Log_warn("Could not allocate IPv4 address"); - hasv4 = false; - nofServerSocks -= 2; - } error = inet_pton(AF_INET6, (!bindaddr6) ? ((getStrConf(BINDADDR6)) ? getStrConf(BINDADDR6) : "::") : bindaddr6, &(((struct sockaddr_in6*)v6address)->sin6_addr)); if (error == 0) Log_fatal("Invalid IPv6 address supplied!"); - else if (error == -1) { + else if (error == -1) Log_warn("Could not allocate IPv6 address"); - hasv6 = false; - nofServerSocks -= 2; - } - - if (!hasv4 && !hasv6) - Log_fatal("Could not allocate IPv4 nor IPv6 address!"); ((struct sockaddr_in*)v4address)->sin_port = htons((bindport) ? bindport : getIntConf(BINDPORT)); ((struct sockaddr_in6*)v6address)->sin6_port = htons((bindport6) ? bindport6 : getIntConf(BINDPORT6)); @@ -120,14 +149,12 @@ void Server_runLoop(struct pollfd* pollfds) struct sockaddr_storage remote; int i; - if (nofServerSocks == 4) { - pollfds[0].revents = 0; - pollfds[1].revents = 0; - pollfds[2].revents = 0; - pollfds[3].revents = 0; - } else { - pollfds[0].revents = 0; - pollfds[1].revents = 0; +#ifdef USE_SHAREDMEMORY_API + Sharedmemory_alivetick(); +#endif + + for(i = 0; i < nofServerSocks; i++) { + pollfds[i].revents = 0; } clientcount = Client_getfds(&pollfds[nofServerSocks]); @@ -155,12 +182,14 @@ void Server_runLoop(struct pollfd* pollfds) /* Check for new connection */ for (i = 0; i < nofServerSocks / 2; i++) { if (pollfds[i].revents) { - static int tcpfd; - static uint32_t addrlen = sizeof(struct sockaddr_storage); + int tcpfd; + uint32_t addrlen = sizeof(struct sockaddr_storage); tcpfd = accept(pollfds[i].fd, (struct sockaddr *)&remote, &addrlen); fcntl(tcpfd, F_SETFL, O_NONBLOCK); setsockopt(tcpfd, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(int)); - Log_debug("Connection from %s port %d\n", Util_addressToString(&remote), Util_addressToPort(&remote)); + char *addressString = Util_addressToString(&remote); + Log_debug("Connection from %s port %d\n", addressString, Util_addressToPort(&remote)); + free(addressString); if (Client_add(tcpfd, &remote) < 0) close(tcpfd); } @@ -178,6 +207,9 @@ void Server_runLoop(struct pollfd* pollfds) if (pollfds[nofServerSocks + i].revents & POLLOUT) Client_write_fd(pollfds[nofServerSocks + i].fd); } +#ifdef USE_SHAREDMEMORY_API + Sharedmemory_update(); +#endif } } @@ -193,8 +225,11 @@ void Server_setupTCPSockets(struct sockaddr_storage* addresses[2], struct pollfd Log_fatal("socket IPv4"); if (setsockopt(sockets[0], SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) != 0) Log_fatal("setsockopt IPv4: %s", strerror(errno)); - if (bind(sockets[0], (struct sockaddr *)addresses[0], sizeof (struct sockaddr_in)) < 0) - Log_fatal("bind %s %d: %s", Util_addressToString(addresses[0]), Util_addressToPort(addresses[0]), strerror(errno)); + if (bind(sockets[0], (struct sockaddr *)addresses[0], sizeof (struct sockaddr_in)) < 0) { + char *addressString = Util_addressToString(addresses[0]); + Log_fatal("bind %s %d: %s", addressString, Util_addressToPort(addresses[0]), strerror(errno)); + free(addressString); + } if (listen(sockets[0], 3) < 0) Log_fatal("listen IPv4"); fcntl(sockets[0], F_SETFL, O_NONBLOCK); @@ -207,13 +242,16 @@ void Server_setupTCPSockets(struct sockaddr_storage* addresses[2], struct pollfd /* IPv6 socket setup */ sockets[1] = socket(PF_INET6, SOCK_STREAM, 0); if (sockets[1] < 0) - Log_fatal("socket IPv6"); + Log_fatal("socket IPv6: %s", strerror(errno)); if (setsockopt(sockets[1], SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) != 0) Log_fatal("setsockopt IPv6: %s", strerror(errno)); if (setsockopt(sockets[1], IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(int)) != 0) Log_fatal("setsockopt IPv6: %s", strerror(errno)); - if (bind(sockets[1], (struct sockaddr *)addresses[1], sizeof (struct sockaddr_in6)) < 0) - Log_fatal("bind %s %d: %s", Util_addressToString(addresses[1]), Util_addressToPort(addresses[1]), strerror(errno)); + if (bind(sockets[1], (struct sockaddr *)addresses[1], sizeof (struct sockaddr_in6)) < 0) { + char *addressString = Util_addressToString(addresses[1]); + Log_fatal("bind %s %d: %s", addressString, Util_addressToPort(addresses[1]), strerror(errno)); + free(addressString); + } if (listen(sockets[1], 3) < 0) Log_fatal("listen IPv6"); fcntl(sockets[1], F_SETFL, O_NONBLOCK); @@ -235,8 +273,11 @@ void Server_setupUDPSockets(struct sockaddr_storage* addresses[2], struct pollfd if (hasv4) { sockets[0] = socket(PF_INET, SOCK_DGRAM, 0); - if (bind(sockets[0], (struct sockaddr *) addresses[0], sizeof (struct sockaddr_in)) < 0) - Log_fatal("bind %s %d: %s", Util_addressToString(addresses[0]), Util_addressToPort(addresses[0]), strerror(errno)); + if (bind(sockets[0], (struct sockaddr *) addresses[0], sizeof (struct sockaddr_in)) < 0) { + char *addressString = Util_addressToString(addresses[0]); + Log_fatal("bind %s %d: %s", addressString, Util_addressToPort(addresses[0]), strerror(errno)); + free(addressString); + } val = 0xe0; if (setsockopt(sockets[0], IPPROTO_IP, IP_TOS, &val, sizeof(val)) < 0) Log_warn("Server: Failed to set TOS for UDP Socket"); @@ -254,8 +295,11 @@ void Server_setupUDPSockets(struct sockaddr_storage* addresses[2], struct pollfd sockets[1] = socket(PF_INET6, SOCK_DGRAM, 0); if (setsockopt(sockets[1], IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(int)) != 0) Log_fatal("setsockopt IPv6: %s", strerror(errno)); - if (bind(sockets[1], (struct sockaddr *) addresses[1], sizeof (struct sockaddr_in6)) < 0) - Log_fatal("bind %s %d: %s", Util_addressToString(addresses[1]), Util_addressToPort(addresses[1]), strerror(errno)); + if (bind(sockets[1], (struct sockaddr *) addresses[1], sizeof (struct sockaddr_in6)) < 0) { + char *addressString = Util_addressToString(addresses[1]); + Log_fatal("bind %s %d: %s", addressString, Util_addressToPort(addresses[1]), strerror(errno)); + free(addressString); + } val = 0xe0; if (setsockopt(sockets[1], IPPROTO_IPV6, IPV6_TCLASS, &val, sizeof(val)) < 0) Log_warn("Server: Failed to set TOS for UDP Socket"); @@ -275,8 +319,10 @@ void Server_run() { struct pollfd *pollfds; - /* max clients + listen sock + udp sock + client connecting that will be disconnected */ - if ((pollfds = calloc((getIntConf(MAX_CLIENTS) + 5) , sizeof(struct pollfd))) == NULL) + checkIPversions(); + + /* max clients + server sokets + client connecting that will be disconnected */ + if ((pollfds = calloc((getIntConf(MAX_CLIENTS) + nofServerSocks + 1) , sizeof(struct pollfd))) == NULL) Log_fatal("out of memory"); /* Figure out bind address and port */