X-Git-Url: http://git.code-monkey.de/?a=blobdiff_plain;f=src%2Fserver.c;h=05f5213abc058575cd22b1591ecb68553188cf3d;hb=ce0029a0c689d9b96d6a797a2e46aa0bee712e36;hp=05bcba572667643a1aa9124bdfe3d573b9a946a4;hpb=46d18f60766f997d0ca37c5937f58c0c06477932;p=umurmur.git diff --git a/src/server.c b/src/server.c index 05bcba5..05f5213 100644 --- a/src/server.c +++ b/src/server.c @@ -1,5 +1,5 @@ -/* Copyright (C) 2009-2010, Martin Johansson - Copyright (C) 2005-2010, Thorvald Natvig +/* Copyright (C) 2009-2014, Martin Johansson + Copyright (C) 2005-2014, Thorvald Natvig All rights reserved. @@ -39,6 +39,7 @@ #include #include #include +#include #include "client.h" #include "conf.h" @@ -51,8 +52,10 @@ #define UDP_SOCK 1 /* globals */ -int udpsock; +int udpsock; bool_t shutdown_server; +extern char *bindaddr; +extern int bindport; void Server_run() { @@ -62,12 +65,28 @@ void Server_run() struct sockaddr_in sin; int val, clientcount; etimer_t janitorTimer; + unsigned short port; + in_addr_t inet_address; /* max clients + listen sock + udp sock + client connecting that will be disconnected */ pollfds = malloc((getIntConf(MAX_CLIENTS) + 3) * sizeof(struct pollfd)); if (pollfds == NULL) Log_fatal("out of memory"); - + + /* Figure out bind address and port */ + if (bindport != 0) + port = htons(bindport); + else + port = htons(getIntConf(BINDPORT)); + + if (bindaddr != NULL && inet_addr(bindaddr) != -1) + inet_address = inet_addr(bindaddr); + else if (inet_addr(getStrConf(BINDADDR)) != -1) + inet_address = inet_addr(getStrConf(BINDADDR)); + else + inet_address = inet_addr("0.0.0.0"); + Log_info("Bind to %s:%hu", inet_address == 0 ? "*" : inet_ntoa(*((struct in_addr *)&inet_address)), ntohs(port)); + /* Prepare TCP socket */ memset(&sin, 0, sizeof(sin)); tcpsock = socket(PF_INET, SOCK_STREAM, 0); @@ -76,14 +95,15 @@ void Server_run() if (setsockopt(tcpsock, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(int)) != 0) Log_fatal("setsockopt: %s", strerror(errno)); sin.sin_family = AF_INET; - sin.sin_port = htons(getIntConf(BINDPORT)); - sin.sin_addr.s_addr = inet_addr(getStrConf(BINDADDR)) == -1 ? inet_addr("0.0.0.0") : inet_addr(getStrConf(BINDADDR)); + sin.sin_port = port; + sin.sin_addr.s_addr = inet_address; + rc = bind(tcpsock, (struct sockaddr *) &sin, sizeof (struct sockaddr_in)); if (rc < 0) Log_fatal("bind: %s", strerror(errno)); rc = listen(tcpsock, 3); if (rc < 0) Log_fatal("listen"); fcntl(tcpsock, F_SETFL, O_NONBLOCK); - + pollfds[LISTEN_SOCK].fd = tcpsock; pollfds[LISTEN_SOCK].events = POLLIN; @@ -91,38 +111,40 @@ void Server_run() memset(&sin, 0, sizeof(sin)); udpsock = socket(PF_INET, SOCK_DGRAM, 0); sin.sin_family = AF_INET; - sin.sin_port = htons(getIntConf(BINDPORT)); - sin.sin_addr.s_addr = inet_addr(getStrConf(BINDADDR)) == -1 ? inet_addr("0.0.0.0") : inet_addr(getStrConf(BINDADDR)); + sin.sin_port = port; + sin.sin_addr.s_addr = inet_address; + rc = bind(udpsock, (struct sockaddr *) &sin, sizeof (struct sockaddr_in)); if (rc < 0) Log_fatal("bind %d %s: %s", getIntConf(BINDPORT), getStrConf(BINDADDR), strerror(errno)); val = 0xe0; rc = setsockopt(udpsock, IPPROTO_IP, IP_TOS, &val, sizeof(val)); if (rc < 0) - Log_fatal("Server: Failed to set TOS for UDP Socket"); + Log_warn("Server: Failed to set TOS for UDP Socket"); val = 0x80; rc = setsockopt(udpsock, IPPROTO_IP, IP_TOS, &val, sizeof(val)); if (rc < 0) - Log_fatal("Server: Failed to set TOS for UDP Socket"); - + Log_warn("Server: Failed to set TOS for UDP Socket"); + fcntl(udpsock, F_SETFL, O_NONBLOCK); pollfds[UDP_SOCK].fd = udpsock; pollfds[UDP_SOCK].events = POLLIN | POLLHUP | POLLERR; - + Timer_init(&janitorTimer); - - Log_info("uMurmur version %s protocol version %d.%d.%d -- http://code.google.com/p/umurmur/", - UMURMUR_VERSION, PROTVER_MAJOR, PROTVER_MINOR, PROTVER_PATCH); + + Log_info("uMurmur version %s ('%s') protocol version %d.%d.%d", + UMURMUR_VERSION, UMURMUR_CODENAME, PROTVER_MAJOR, PROTVER_MINOR, PROTVER_PATCH); + Log_info("Visit http://code.google.com/p/umurmur/"); /* Main server loop */ while (!shutdown_server) { struct sockaddr_in remote; int i; - + pollfds[UDP_SOCK].revents = 0; pollfds[TCP_SOCK].revents = 0; clientcount = Client_getfds(&pollfds[2]); - + timeout = (int)(1000000LL - (int64_t)Timer_elapsed(&janitorTimer)) / 1000LL; if (timeout <= 0) { Client_janitor(); @@ -151,7 +173,8 @@ void Server_run() setsockopt(tcpfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)); Log_debug("Connection from %s port %d\n", inet_ntoa(remote.sin_addr), ntohs(remote.sin_port)); - Client_add(tcpfd, &remote); + if (Client_add(tcpfd, &remote) < 0) + close(tcpfd); } if (pollfds[UDP_SOCK].revents) { @@ -165,7 +188,7 @@ void Server_run() Client_write_fd(pollfds[i + 2].fd); } } - } + } /* Disconnect clients */ Client_disconnect_all();