#include #include #include #include #include #include #include "config.h" #include "logging.h" #include "hlswserver.h" #define HLSW_MASTER_PORT 7140 static const char hlsw_header[] = "\xFF\xFF\xFF\xFFHLSWLANSEARCH"; 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; } bool HlswServer::HlswPacket::addGame(GameEntry* ge) { if (count < 140) { count++; return true; } else { return false; } } 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()"); } } HlswServer::HlswServer(Config& conf) { struct sockaddr_in dst; const char *ip; if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { LogSystem::log(LOG_CRIT, "HlswServer(): socket()"); return; } ip = conf.getString("global", "master_ip", "0.0.0.0"); LogSystem::log(LOG_NOTICE, "HlswServer listen on %s:%d", ip, HLSW_MASTER_PORT); 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) { LogSystem::log(LOG_ERROR, "HlswServer(): bind()"); return; } pktlist = new HlswPacket(NULL); } HlswServer::~HlswServer() { close(sock); delete pktlist; } 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); if (ret != sizeof(hlsw_header)) { LogSystem::log(LOG_NOTICE, "HlswServer: invalid packet"); continue; } /* testen ob es sich um ein HLSW anforderung handelt */ if (memcmp(buf, hlsw_header, sizeof(hlsw_header))) { LogSystem::log(LOG_NOTICE, "HlswServer: not a hlsw packet"); continue; } mutex.lock(); pktlist->send(sock, &src); mutex.unlock(); } return 0; } void HlswServer::rebuild(GameList& glist) { Iterator* it = glist.createIterator(); HlswPacket* newlist = NULL; while (it->hasNext()) { GameEntry* d = it->next(); if (!newlist || !newlist->addGame(d)) { newlist = new HlswPacket(newlist); newlist->addGame(d); } } mutex.lock(); HlswPacket* oldlist = pktlist; pktlist = newlist; mutex.unlock(); delete oldlist; delete it; }