2006-04-16 21:37:00 +02:00
|
|
|
/***************************************************************************
|
|
|
|
* 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. *
|
|
|
|
***************************************************************************/
|
2006-02-02 16:55:44 +01:00
|
|
|
#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"
|
2006-04-16 21:02:41 +02:00
|
|
|
#include "logging.h"
|
2006-02-02 16:55:44 +01:00
|
|
|
|
2006-02-06 20:58:32 +01:00
|
|
|
static const char hlsw_header[] = "\xFF\xFF\xFF\xFFHLSWLANSEARCH";
|
|
|
|
|
2006-02-20 21:58:59 +01:00
|
|
|
struct hlsw_entry {
|
|
|
|
uint16_t gameid;
|
|
|
|
uint32_t ip;
|
|
|
|
uint16_t port1;
|
|
|
|
uint16_t port2;
|
|
|
|
} __attribute__ ((packed));
|
|
|
|
|
2006-03-06 20:13:26 +01:00
|
|
|
#define HLSW_MASTER_PORT 7140
|
|
|
|
#define HLSW_MAX_PACKET_SIZE (sizeof(hlsw_header) + 140 * sizeof(struct hlsw_entry))
|
|
|
|
#define DEFAULT_REBUILD_INTERVAL 5
|
|
|
|
|
2006-02-20 21:58:59 +01:00
|
|
|
HlswServer::HlswServer(Config& conf, GameList& glist)
|
2006-02-02 16:55:44 +01:00
|
|
|
{
|
2006-02-20 21:58:59 +01:00
|
|
|
const char *ip = conf.getString("global", "master_ip", "0.0.0.0");
|
2006-02-02 16:55:44 +01:00
|
|
|
LogSystem::log(LOG_NOTICE, "HlswServer listen on %s:%d", ip, HLSW_MASTER_PORT);
|
|
|
|
|
2006-02-20 21:58:59 +01:00
|
|
|
struct sockaddr_in dst;
|
2006-02-02 16:55:44 +01:00
|
|
|
dst.sin_family = AF_INET;
|
|
|
|
dst.sin_port = htons(HLSW_MASTER_PORT);
|
|
|
|
inet_aton(ip, &dst.sin_addr);
|
2006-03-05 02:28:19 +01:00
|
|
|
socket = Socket::createSocket(&dst);
|
2006-02-02 16:55:44 +01:00
|
|
|
|
2006-02-20 21:58:59 +01:00
|
|
|
int interval = conf.getInteger("global", "rebuild_interval", DEFAULT_REBUILD_INTERVAL);
|
|
|
|
TimerService::registerTimer(new Timer(new RebuildEvent(*this, glist), interval));
|
2006-03-05 02:28:19 +01:00
|
|
|
|
2006-04-15 19:55:07 +02:00
|
|
|
pktlist = new List<NetPkt>();
|
2006-02-02 16:55:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
HlswServer::~HlswServer()
|
|
|
|
{
|
2006-04-15 19:55:07 +02:00
|
|
|
while (!pktlist->isEmpty())
|
|
|
|
delete pktlist->get();
|
|
|
|
|
2006-02-06 20:58:32 +01:00
|
|
|
delete pktlist;
|
2006-03-05 02:28:19 +01:00
|
|
|
delete socket;
|
2006-02-02 16:55:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int HlswServer::execute(void* arg)
|
|
|
|
{
|
|
|
|
while (1) {
|
2006-03-05 02:28:19 +01:00
|
|
|
NetPkt* pkt = socket->recv();
|
2006-04-15 19:55:07 +02:00
|
|
|
if (!pkt->compare(0, hlsw_header, strlen(hlsw_header))) {
|
2006-02-05 12:00:47 +01:00
|
|
|
LogSystem::log(LOG_NOTICE, "HlswServer: not a hlsw packet");
|
2006-02-02 16:55:44 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2006-02-06 20:58:32 +01:00
|
|
|
mutex.lock();
|
2006-04-15 19:55:07 +02:00
|
|
|
Iterator<NetPkt>* it = pktlist->createIterator();
|
|
|
|
while (it->hasNext())
|
|
|
|
socket->sendto(it->next(), pkt->getAddress());
|
2006-03-05 02:28:19 +01:00
|
|
|
|
2006-04-15 19:55:07 +02:00
|
|
|
delete it;
|
|
|
|
mutex.unlock();
|
2006-02-02 16:55:44 +01:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2006-02-06 20:58:32 +01:00
|
|
|
|
2006-02-19 18:45:56 +01:00
|
|
|
void HlswServer::rebuild(GameList& glist) {
|
2006-04-15 19:55:07 +02:00
|
|
|
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);
|
2006-02-06 20:58:32 +01:00
|
|
|
}
|
2006-03-05 02:28:19 +01:00
|
|
|
|
2006-04-15 19:55:07 +02:00
|
|
|
addGame(last, it->next());
|
2006-02-20 21:58:59 +01:00
|
|
|
}
|
2006-04-15 19:55:07 +02:00
|
|
|
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));
|
2006-02-19 18:45:56 +01:00
|
|
|
}
|