#include #include #include #include #include #include #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(); } 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* it = pktlist->createIterator(); while (it->hasNext()) socket->sendto(it->next(), pkt->getAddress()); delete it; mutex.unlock(); } return 0; } void HlswServer::rebuild(GameList& glist) { List* newlist = new List(); // header NetPkt* pkt = new NetPkt(HLSW_MAX_PACKET_SIZE); pkt->append(hlsw_header, sizeof(hlsw_header)); newlist->add(pkt); Iterator* 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* 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)); }