/*************************************************************************** * Copyright (C) 03/2005 by Olaf Rempel * * razzor@kopf-tisch.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include "hlswmaster.h" #include "plugin.h" #include "list.h" #define DEBUG 1 LIST_HEAD(server_list); /* sichert die server liste */ static pthread_mutex_t server_list_lock = PTHREAD_MUTEX_INITIALIZER; /** * server_cmp() * LIST_FIND helper * * @param struct game_server *a * @param struct game_server *b * @return true wenn es sich um den selben server handelt */ static inline int server_cmp(const struct game_server *a, struct game_server *b) { return (a->gameid == b->gameid && a->ip == b->ip && a->port1 == b->port1 && a->port2 == b->port2); } /** * server_add() * fuegt der internen serverliste einen server hinzu * wenn dieser server schon in der liste vorhanden ist, wird nur * die modtime angepasst * * @param unsigned int gameid * @param struct in_addr ip * @param u_int16_t port1 * @param u_int16_t port2 * @return false bei fehler */ int server_add(u_int16_t gameid, u_int32_t ip, u_int16_t port1, u_int16_t port2) { struct game_server server, *nserver; server.gameid = gameid; server.ip = ip; server.port1 = port1; server.port2 = port2; pthread_mutex_lock(&server_list_lock); /* diesen server in der liste suchen */ nserver = LIST_FIND(&server_list, server_cmp, struct game_server *, &server); if (!nserver) { /* neuen eintrag anlegen */ if (!(nserver = malloc(sizeof(struct game_server)))) { pthread_mutex_unlock(&server_list_lock); return 0; } #ifdef DEBUG { struct in_addr tmp; tmp.s_addr = server.ip; printf("server_add_new: gameid=%2d ip=%15s port1=%5d port2=%5d\n", server.gameid, inet_ntoa(tmp), server.port1, server.port2); } #endif memcpy(nserver, &server, sizeof(struct game_server)); list_add_tail(&nserver->list, &server_list); } /* modtime anpassen */ nserver->modtime = time(NULL); pthread_mutex_unlock(&server_list_lock); return 1; } /** * server_collector() * loescht alte server aus der liste * baut aus den verbleibenden die client_liste auf * * TODO: timeout und intervall als config parameter (config file?) */ void server_collector(void) { struct game_server *server, *tmp; unsigned long now, timeout = 60; while (1) { sleep(5); now = time(NULL); pthread_mutex_lock(&server_list_lock); list_for_each_entry_safe(server, tmp, &server_list, list) { if ((server->modtime + timeout) < now) { #ifdef DEBUG { struct in_addr tmp2; tmp2.s_addr = server->ip; printf("server timeout: gameid=%2d ip=%15s port1=%5d port2=%5d\n", server->gameid, inet_ntoa(tmp2), server->port1, server->port2); } #endif list_del(&server->list); free(server); continue; } client_pkt_add(server); } pthread_mutex_unlock(&server_list_lock); client_pkt_commit(); } }