hlswmaster-ng/hlswserver.cpp

145 lines
3.1 KiB
C++
Raw Normal View History

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 "config.h"
#include "logging.h"
#include "hlswserver.h"
#define HLSW_MASTER_PORT 7140
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
#define DEFAULT_REBUILD_INTERVAL 5
struct hlsw_entry {
uint16_t gameid;
uint32_t ip;
uint16_t port1;
uint16_t port2;
} __attribute__ ((packed));
2006-02-06 20:58:32 +01:00
HlswServer::HlswPacket::HlswPacket(HlswPacket* next)
: next(next), count(0)
{
memcpy(data, hlsw_header, sizeof(hlsw_header));
memset(data + sizeof(hlsw_header), 0, sizeof(data) - sizeof(hlsw_header));
}
HlswServer::HlswPacket::~HlswPacket()
{
if (next)
delete next;
}
2006-02-19 18:45:56 +01:00
bool HlswServer::HlswPacket::addGame(GameEntry* ge)
2006-02-06 20:58:32 +01:00
{
2006-02-20 21:58:59 +01:00
if (count >= 140)
2006-02-06 20:58:32 +01:00
return false;
2006-02-20 21:58:59 +01:00
struct hlsw_entry tmp;
tmp.gameid = ge->gameid;
tmp.ip = ge->addr.s_addr;
tmp.port1 = ge->port1;
tmp.port2 = ge->port2;
memcpy(data + sizeof(hlsw_header) + count * 10, &tmp, sizeof(tmp));
count++;
return true;
2006-02-06 20:58:32 +01:00
}
void HlswServer::HlswPacket::send(int socket, struct sockaddr_in* dst)
{
if (next)
next->send(socket, dst);
if (sendto(socket, data, sizeof(hlsw_header) + count * 10, 0,
(struct sockaddr *)dst, sizeof(*dst)) < 0) {
LogSystem::log(LOG_WARN, "HlswPacket::send()");
}
}
2006-02-02 16:55:44 +01:00
2006-02-20 21:58:59 +01:00
HlswServer::HlswServer(Config& conf, GameList& glist)
: lastUpdate(0)
2006-02-02 16:55:44 +01:00
{
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
LogSystem::log(LOG_CRIT, "HlswServer(): socket()");
return;
}
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);
if (bind(sock, (struct sockaddr *)&dst, sizeof(dst)) < 0) {
2006-02-05 12:00:47 +01:00
LogSystem::log(LOG_ERROR, "HlswServer(): bind()");
2006-02-02 16:55:44 +01:00
return;
}
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-02-06 20:58:32 +01:00
pktlist = new HlswPacket(NULL);
2006-02-02 16:55:44 +01:00
}
HlswServer::~HlswServer()
{
close(sock);
2006-02-06 20:58:32 +01:00
delete pktlist;
2006-02-02 16:55:44 +01:00
}
int HlswServer::execute(void* arg)
{
struct sockaddr_in src;
unsigned char buf[32];
socklen_t len;
int ret;
while (1) {
/* auf clientanfrage warten */
len = sizeof(src);
ret = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&src, &len);
2006-02-06 20:58:32 +01:00
if (memcmp(buf, hlsw_header, sizeof(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();
pktlist->send(sock, &src);
mutex.unlock();
2006-02-02 16:55:44 +01:00
}
return 0;
}
2006-02-06 20:58:32 +01:00
2006-02-20 21:58:59 +01:00
2006-02-19 18:45:56 +01:00
void HlswServer::rebuild(GameList& glist) {
2006-02-20 21:58:59 +01:00
if (glist.getLastUpdate() > lastUpdate) {
HlswPacket* newlist = new HlswPacket(NULL);
Iterator<GameEntry>* it = glist.createIterator();
while (it->hasNext()) {
GameEntry* d = it->next();
if (!newlist->addGame(d)) {
newlist = new HlswPacket(newlist);
newlist->addGame(d);
}
2006-02-06 20:58:32 +01:00
}
2006-02-20 21:58:59 +01:00
lastUpdate = glist.getLastUpdate();
delete it;
mutex.lock();
HlswPacket* oldlist = pktlist;
pktlist = newlist;
mutex.unlock();
2006-02-06 20:58:32 +01:00
2006-02-20 21:58:59 +01:00
delete oldlist;
}
2006-02-19 18:45:56 +01:00
}