return addresses;
}
+void Server_runLoop(struct pollfd* pollfds)
+ {
+ int timeout = 1000, rc, clientcount;
+ etimer_t janitorTimer;
+
+ Timer_init(&janitorTimer);
+
+ 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();
+ Timer_restart(&janitorTimer);
+ timeout = (int)(1000000LL - (int64_t)Timer_elapsed(&janitorTimer)) / 1000LL;
+ }
+ rc = poll(pollfds, clientcount + 2, timeout);
+ if (rc == 0) { /* Timeout */
+ /* Do maintenance */
+ Timer_restart(&janitorTimer);
+ Client_janitor();
+ continue;
+ }
+ if (rc < 0) {
+ if (errno == EINTR) /* signal */
+ continue;
+ else
+ Log_fatal("poll: error %d", errno);
+ }
+ if (pollfds[LISTEN_SOCK].revents) { /* New tcp connection */
+ int tcpfd, flag = 1;
+ uint32_t addrlen;
+ addrlen = sizeof(struct sockaddr_in);
+ tcpfd = accept(pollfds[LISTEN_SOCK].fd, (struct sockaddr*)&remote, &addrlen);
+ fcntl(tcpfd, F_SETFL, O_NONBLOCK);
+ 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));
+ if (Client_add(tcpfd, &remote) < 0)
+ close(tcpfd);
+ }
+
+ if (pollfds[UDP_SOCK].revents) {
+ Client_read_udp();
+ }
+ for (i = 0; i < clientcount; i++) {
+ if (pollfds[i + 2].revents & POLLIN) {
+ Client_read_fd(pollfds[i + 2].fd);
+ }
+ if (pollfds[i + 2].revents & POLLOUT) {
+ Client_write_fd(pollfds[i + 2].fd);
+ }
+ }
+ }
+ }
+
void Server_run()
{
- int timeout = 1000, rc;
+ int rc;
struct pollfd *pollfds;
int tcpsock, sockopt = 1;
struct sockaddr_in sin;
- int val, clientcount;
- etimer_t janitorTimer;
+ int val;
unsigned short port;
in_addr_t inet_address;
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));
+ struct sockaddr_storage** addresses = Server_setupAddressesAndPorts();
/* Prepare TCP socket */
memset(&sin, 0, sizeof(sin));
pollfds[UDP_SOCK].fd = udpsock;
pollfds[UDP_SOCK].events = POLLIN | POLLHUP | POLLERR;
- Timer_init(&janitorTimer);
-
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();
- Timer_restart(&janitorTimer);
- timeout = (int)(1000000LL - (int64_t)Timer_elapsed(&janitorTimer)) / 1000LL;
- }
- rc = poll(pollfds, clientcount + 2, timeout);
- if (rc == 0) { /* Timeout */
- /* Do maintenance */
- Timer_restart(&janitorTimer);
- Client_janitor();
- continue;
- }
- if (rc < 0) {
- if (errno == EINTR) /* signal */
- continue;
- else
- Log_fatal("poll: error %d", errno);
- }
- if (pollfds[LISTEN_SOCK].revents) { /* New tcp connection */
- int tcpfd, flag = 1;
- uint32_t addrlen;
- addrlen = sizeof(struct sockaddr_in);
- tcpfd = accept(pollfds[LISTEN_SOCK].fd, (struct sockaddr*)&remote, &addrlen);
- fcntl(tcpfd, F_SETFL, O_NONBLOCK);
- 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));
- if (Client_add(tcpfd, &remote) < 0)
- close(tcpfd);
- }
-
- if (pollfds[UDP_SOCK].revents) {
- Client_read_udp();
- }
- for (i = 0; i < clientcount; i++) {
- if (pollfds[i + 2].revents & POLLIN) {
- Client_read_fd(pollfds[i + 2].fd);
- }
- if (pollfds[i + 2].revents & POLLOUT) {
- Client_write_fd(pollfds[i + 2].fd);
- }
- }
- }
+ Server_runLoop(pollfds);
/* Disconnect clients */
Client_disconnect_all();