You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
3.9 KiB
130 lines
3.9 KiB
/*************************************************************************** |
|
* Copyright (C) 04/2006 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 <unistd.h> |
|
#include <string.h> |
|
#include <sys/socket.h> |
|
#include <netinet/in.h> |
|
#include <netinet/ip.h> |
|
#include <arpa/inet.h> |
|
|
|
#include "hlswserver.h" |
|
#include "logging.h" |
|
|
|
static const char hlsw_header[] = "\xFF\xFF\xFF\xFFHLSWLANSEARCH"; |
|
|
|
struct hlsw_entry { |
|
uint16_t gameid; |
|
uint32_t ip; |
|
uint16_t port1; |
|
uint16_t port2; |
|
} __attribute__ ((packed)); |
|
|
|
#define HLSW_MASTER_PORT 7140 |
|
#define HLSW_MAX_PACKET_SIZE (sizeof(hlsw_header) + 140 * sizeof(struct hlsw_entry)) |
|
#define DEFAULT_REBUILD_INTERVAL 5 |
|
|
|
HlswServer::HlswServer(Config& conf, GameList& glist) |
|
{ |
|
const char *ip = conf.getString("global", "master_ip", "0.0.0.0"); |
|
LogSystem::log(LOG_NOTICE, "HlswServer listen on %s:%d", ip, HLSW_MASTER_PORT); |
|
|
|
struct sockaddr_in dst; |
|
dst.sin_family = AF_INET; |
|
dst.sin_port = htons(HLSW_MASTER_PORT); |
|
inet_aton(ip, &dst.sin_addr); |
|
socket = Socket::createSocket(&dst); |
|
|
|
int interval = conf.getInteger("global", "rebuild_interval", DEFAULT_REBUILD_INTERVAL); |
|
TimerService::registerTimer(new Timer(new RebuildEvent(*this, glist), interval)); |
|
|
|
pktlist = new List<NetPkt>(); |
|
} |
|
|
|
HlswServer::~HlswServer() |
|
{ |
|
while (!pktlist->isEmpty()) |
|
delete pktlist->get(); |
|
|
|
delete pktlist; |
|
delete socket; |
|
} |
|
|
|
int HlswServer::execute(void* arg) |
|
{ |
|
while (1) { |
|
NetPkt* pkt = socket->recv(); |
|
if (!pkt->compare(0, hlsw_header, strlen(hlsw_header))) { |
|
LogSystem::log(LOG_NOTICE, "HlswServer: not a hlsw packet"); |
|
continue; |
|
} |
|
|
|
mutex.lock(); |
|
Iterator<NetPkt>* it = pktlist->createIterator(); |
|
while (it->hasNext()) |
|
socket->sendto(it->next(), pkt->getAddress()); |
|
|
|
delete it; |
|
mutex.unlock(); |
|
} |
|
return 0; |
|
} |
|
|
|
void HlswServer::rebuild(GameList& glist) { |
|
List<NetPkt>* newlist = new List<NetPkt>(); |
|
|
|
// header |
|
NetPkt* pkt = new NetPkt(HLSW_MAX_PACKET_SIZE); |
|
pkt->append(hlsw_header, sizeof(hlsw_header)); |
|
newlist->add(pkt); |
|
|
|
Iterator<GameEntry>* it = glist.createIterator(); |
|
while (it->hasNext()) { |
|
NetPkt* last = newlist->peekTail(); |
|
if (last->getSize() == HLSW_MAX_PACKET_SIZE) { |
|
last = new NetPkt(HLSW_MAX_PACKET_SIZE); |
|
last->append(hlsw_header, sizeof(hlsw_header)); |
|
newlist->add(last); |
|
} |
|
|
|
addGame(last, it->next()); |
|
} |
|
delete it; |
|
|
|
mutex.lock(); |
|
List<NetPkt>* oldlist = pktlist; |
|
pktlist = newlist; |
|
mutex.unlock(); |
|
|
|
while (!oldlist->isEmpty()) |
|
delete oldlist->get(); |
|
|
|
delete oldlist; |
|
} |
|
|
|
void HlswServer::addGame(NetPkt* pkt, GameEntry* entry) |
|
{ |
|
struct hlsw_entry tmp; |
|
tmp.gameid = entry->gameid; |
|
tmp.ip = entry->addr.s_addr; |
|
tmp.port1 = entry->port1; |
|
tmp.port2 = entry->port2; |
|
|
|
pkt->append((char*)&tmp, sizeof(tmp)); |
|
}
|
|
|