daily work

This commit is contained in:
Olaf Rempel 2006-03-05 02:28:19 +01:00
parent 38542d7ddf
commit 2e728963c7
32 changed files with 186 additions and 382 deletions

View File

@ -16,6 +16,9 @@ hlswmaster: $(OBJS)
%.d: %.cpp %.d: %.cpp
$(CXX) $(CFLAGS) -MM -c $< -o $@ $(CXX) $(CFLAGS) -MM -c $< -o $@
dist:
git-tar-tree HEAD hlswmaster-ng | gzip -9 -c > hlswmaster-ng.tar.gz
clean: clean:
rm -f hlswmaster *.d *.o *.log rm -f hlswmaster *.d *.o *.log

View File

@ -43,7 +43,7 @@ bool Config::Section::addTupel(const char* name, const char* value)
Tupel* t = new Tupel(name, value); Tupel* t = new Tupel(name, value);
tupelList.addTail(t); tupelList.addTail(t);
return true; return true;
} }
@ -51,12 +51,12 @@ void Config::Section::show() const
{ {
Iterator<Tupel>* it = tupelList.createIterator(); Iterator<Tupel>* it = tupelList.createIterator();
LogSystem::log(LOG_INFO, "[%s]", name); LogSystem::log(LOG_INFO, "[%s]", name);
while (it->hasNext()) { while (it->hasNext()) {
Tupel* t = it->next(); Tupel* t = it->next();
LogSystem::log(LOG_INFO, " %s = %s", t->name, t->value); LogSystem::log(LOG_INFO, " %s = %s", t->name, t->value);
} }
delete it; delete it;
} }
@ -71,7 +71,7 @@ const char* Config::Section::getTupelValue(const char* name) const
break; break;
} }
} }
delete it; delete it;
return retval; return retval;
} }
@ -132,18 +132,18 @@ bool Config::parseFile(const char* name)
int i = 0; int i = 0;
char *row, *tok, *tok2; char *row, *tok, *tok2;
bool ret = true; bool ret = true;
row = new char[BUFSIZE]; row = new char[BUFSIZE];
if (!row) { if (!row) {
LogSystem::log(LOG_ERROR, "config_parse(): out of memory()"); LogSystem::log(LOG_ERROR, "config_parse(): out of memory()");
return false; return false;
} }
if (!(fz = fopen(name, "r"))) { if (!(fz = fopen(name, "r"))) {
LogSystem::log(LOG_ERROR, "config_parse(): can not open %s", name); LogSystem::log(LOG_ERROR, "config_parse(): can not open %s", name);
return false; return false;
} }
while (fgets(row, BUFSIZE, fz)) { while (fgets(row, BUFSIZE, fz)) {
i++; i++;
@ -168,7 +168,7 @@ bool Config::parseFile(const char* name)
ret = false; ret = false;
break; break;
} }
/* option */ /* option */
if ((tok = strtok(row, " \n"))) { if ((tok = strtok(row, " \n"))) {
while ((tok2 = strtok(NULL, " \n"))) { while ((tok2 = strtok(NULL, " \n"))) {
@ -177,10 +177,10 @@ bool Config::parseFile(const char* name)
} }
} }
} }
fclose(fz); fclose(fz);
delete row; delete row;
return ret; return ret;
} }
@ -206,7 +206,7 @@ Config::Section* Config::getSection(const char* name) const
break; break;
} }
} }
delete it; delete it;
return retval; return retval;
} }
@ -250,7 +250,7 @@ Iterator<char>* Config::createIterator(const char* section, const char* name)
return new NullIterator<char>(); return new NullIterator<char>();
} else { } else {
return new Config::Section::SectionIterator(s, name); return new Config::Section::SectionIterator(s, name);
} }
} }

View File

@ -18,14 +18,14 @@ public:
private: private:
class Tupel { class Tupel {
public: public:
Tupel(const char* name, const char* value); Tupel(const char* name, const char* value);
~Tupel(); ~Tupel();
const char* name; const char* name;
const char* value; const char* value;
}; };
class Section { class Section {
public: public:
class SectionIterator : public Iterator<char> { class SectionIterator : public Iterator<char> {
@ -35,20 +35,20 @@ private:
bool hasNext(); bool hasNext();
char* next(); char* next();
void reset(); void reset();
private: private:
Iterator<Tupel>* it; Iterator<Tupel>* it;
Tupel* nexttup; Tupel* nexttup;
const char* name; const char* name;
}; };
Section(const char* name); Section(const char* name);
~Section(); ~Section();
bool addTupel(const char* name, const char* option); bool addTupel(const char* name, const char* option);
const char* getTupelValue(const char* name) const; const char* getTupelValue(const char* name) const;
void show() const; void show() const;
const char* name; const char* name;
private: private:

View File

@ -3,6 +3,10 @@
#define DEFAULT_TIMEOUT 180 #define DEFAULT_TIMEOUT 180
/*
** TODO: replace list with sorted list, or even better with a hash
*/
GameList::GameList(Config& conf) GameList::GameList(Config& conf)
: lastUpdate(0) : lastUpdate(0)
{ {
@ -12,6 +16,8 @@ GameList::GameList(Config& conf)
GameList::~GameList() GameList::~GameList()
{ {
while (!glist.isEmpty())
delete glist.get();
} }
void GameList::cleanup() void GameList::cleanup()
@ -29,11 +35,11 @@ Iterator<GameEntry>* GameList::createIterator()
return glist.createIterator(); return glist.createIterator();
} }
void GameList::addGame(int gameid, NetPkt* pkt) void GameList::addGame(int gameid, NetPkt* pkt, int port2)
{ {
char buf[64]; char buf[64];
pkt->show(buf, sizeof(buf)); pkt->show(buf, sizeof(buf));
LogSystem::log(LOG_NOTICE, "Adding Game %d: %s", gameid, buf); LogSystem::log(LOG_NOTICE, "Adding Game %d: %s %d", gameid, buf, port2);
glist.add(new GameEntry()); glist.add(new GameEntry());
} }

View File

@ -2,25 +2,10 @@
#define _GAMELIST_H_ #define _GAMELIST_H_
#include "config.h" #include "config.h"
#include "list.h"
#include "netpkt.h" #include "netpkt.h"
#include "gameentry.h"
#include "timerservice.h" #include "timerservice.h"
#include "list.h"
class GameEntry {
public:
GameEntry() {};
~GameEntry() {};
struct in_addr addr;
int port1;
int port2;
int gameid;
protected:
GameEntry(const GameEntry& ge);
GameEntry& operator=(const GameEntry& ge);
};
class GameList { class GameList {
public: public:
@ -28,7 +13,7 @@ public:
~GameList(); ~GameList();
void cleanup(); void cleanup();
void addGame(int gameid, NetPkt* pkt); void addGame(int gameid, NetPkt* pkt, int port2 = 0);
long getLastUpdate(); long getLastUpdate();
Iterator<GameEntry>* createIterator(); Iterator<GameEntry>* createIterator();
@ -43,10 +28,10 @@ private:
CleanupEvent(GameList& gl) : gl(gl) {} CleanupEvent(GameList& gl) : gl(gl) {}
~CleanupEvent() {} ~CleanupEvent() {}
void execute() { gl.cleanup(); } void execute() { gl.cleanup(); }
private: private:
GameList& gl; GameList& gl;
}; };
List<GameEntry> glist; List<GameEntry> glist;
long lastUpdate; long lastUpdate;

View File

@ -7,10 +7,6 @@ GameParser::GameParser(RecvQueue& rxQueue, ModuleList& modList, GameList& gameLi
{ {
} }
GameParser::~GameParser()
{
}
int GameParser::execute(void* arg) int GameParser::execute(void* arg)
{ {
while (1) { while (1) {
@ -25,10 +21,10 @@ int GameParser::execute(void* arg)
case PARSE_ACCEPT: case PARSE_ACCEPT:
delete pkt; delete pkt;
case PARSE_ACCEPT_FREED: case PARSE_ACCEPT_FREED:
break; break;
} }
} }
return 0; return 0;
} }

View File

@ -10,10 +10,10 @@
class GameParser : public Thread { class GameParser : public Thread {
public: public:
GameParser(RecvQueue& rxQueue, ModuleList& modlist, GameList& gameList); GameParser(RecvQueue& rxQueue, ModuleList& modlist, GameList& gameList);
~GameParser(); ~GameParser() {};
int execute(void* arg); int execute(void* arg);
protected: protected:
GameParser(const GameParser& rp); GameParser(const GameParser& rp);
GameParser& operator=(const GameParser& rp); GameParser& operator=(const GameParser& rp);

View File

@ -9,7 +9,7 @@ GameScanner::GameScanner(Config& conf, ModuleList& modList, RecvQueue& rxQueue)
: modList(modList), rxQueue(rxQueue) : modList(modList), rxQueue(rxQueue)
{ {
msock = new MultiSock(conf); msock = new MultiSock(conf);
int interval = conf.getInteger("global", "scan_interval", DEFAULT_SCAN_INTERVAL); int interval = conf.getInteger("global", "scan_interval", DEFAULT_SCAN_INTERVAL);
TimerService::registerTimer(new Timer(new ScanEvent(*this), interval)); TimerService::registerTimer(new Timer(new ScanEvent(*this), interval));
} }
@ -22,9 +22,9 @@ GameScanner::~GameScanner()
int GameScanner::execute(void* arg) int GameScanner::execute(void* arg)
{ {
while (1) { while (1) {
int fd = msock->waitOnSocket(); NetPkt* pkt = msock->recv();
NetPkt* pkt = NetPkt::createFromSocket(fd); if (pkt)
rxQueue.addPkt(pkt); rxQueue.addPkt(pkt);
} }
return 0; return 0;
} }

View File

@ -13,7 +13,7 @@ class GameScanner : public Thread {
public: public:
GameScanner(Config& conf, ModuleList& modList, RecvQueue& rxQueue); GameScanner(Config& conf, ModuleList& modList, RecvQueue& rxQueue);
~GameScanner(); ~GameScanner();
int execute(void* arg); int execute(void* arg);
void scan(); void scan();
@ -27,10 +27,10 @@ private:
ScanEvent(GameScanner& gs) : gs(gs) {} ScanEvent(GameScanner& gs) : gs(gs) {}
~ScanEvent() {} ~ScanEvent() {}
void execute() { gs.scan(); } void execute() { gs.scan(); }
private: private:
GameScanner& gs; GameScanner& gs;
}; };
ModuleList& modList; ModuleList& modList;
RecvQueue& rxQueue; RecvQueue& rxQueue;

View File

@ -66,7 +66,7 @@ int main(int argc, char *argv[])
break; break;
} }
} }
Config conf; Config conf;
conf.parseFile(configfile); conf.parseFile(configfile);
@ -78,7 +78,7 @@ int main(int argc, char *argv[])
} else { } else {
LogSystem::init(logprio, new StdErrLog()); LogSystem::init(logprio, new StdErrLog());
} }
LogSystem::log(LOG_EVERYTIME, "hlswmaster-ng startup (pid:%d)", getpid()); LogSystem::log(LOG_EVERYTIME, "hlswmaster-ng startup (pid:%d)", getpid());
conf.show(); conf.show();
@ -91,11 +91,11 @@ int main(int argc, char *argv[])
HlswServer server(conf, gameList); HlswServer server(conf, gameList);
// modList.reg(new ModHalfLife()); // modList.reg(new ModHalfLife());
// modList.reg(new ModQ3Engine()); modList.reg(new ModQ3Engine());
// modList.reg(new ModD3Engine()); // modList.reg(new ModD3Engine());
// modList.reg(new ModGameSpy1()); // modList.reg(new ModGameSpy1());
// modList.reg(new ModGameSpy2()); // modList.reg(new ModGameSpy2());
server.start(); server.start();
parser.start(); parser.start();
scanner.start(); scanner.start();
@ -108,12 +108,12 @@ int main(int argc, char *argv[])
LogSystem::log(LOG_CRIT, "Scanner aborted!"); LogSystem::log(LOG_CRIT, "Scanner aborted!");
break; break;
} }
if (!parser.isRunning()) { if (!parser.isRunning()) {
LogSystem::log(LOG_CRIT, "RecvParser aborted!"); LogSystem::log(LOG_CRIT, "RecvParser aborted!");
break; break;
} }
if (!server.isRunning()) { if (!server.isRunning()) {
LogSystem::log(LOG_CRIT, "HlswServer aborted!"); LogSystem::log(LOG_CRIT, "HlswServer aborted!");
break; break;

View File

@ -22,10 +22,10 @@ struct hlsw_entry {
} __attribute__ ((packed)); } __attribute__ ((packed));
HlswServer::HlswPacket::HlswPacket(HlswPacket* next) HlswServer::HlswPacket::HlswPacket(HlswPacket* next)
: next(next), count(0) : NetPkt(1418), next(next)
{ {
memcpy(data, hlsw_header, sizeof(hlsw_header)); memcpy((void*)data, hlsw_header, sizeof(hlsw_header));
memset(data + sizeof(hlsw_header), 0, sizeof(data) - sizeof(hlsw_header)); used = sizeof(hlsw_header);
} }
HlswServer::HlswPacket::~HlswPacket() HlswServer::HlswPacket::~HlswPacket()
@ -36,39 +36,31 @@ HlswServer::HlswPacket::~HlswPacket()
bool HlswServer::HlswPacket::addGame(GameEntry* ge) bool HlswServer::HlswPacket::addGame(GameEntry* ge)
{ {
if (count >= 140) if (used >= 1418)
return false; return false;
struct hlsw_entry tmp; struct hlsw_entry tmp;
tmp.gameid = ge->gameid; tmp.gameid = ge->gameid;
tmp.ip = ge->addr.s_addr; tmp.ip = ge->addr.s_addr;
tmp.port1 = ge->port1; tmp.port1 = ge->port1;
tmp.port2 = ge->port2; tmp.port2 = ge->port2;
memcpy(data + sizeof(hlsw_header) + count * 10, &tmp, sizeof(tmp)); memcpy((void*)(data + used), &tmp, sizeof(tmp));
count++; used += sizeof(tmp);
return true; return true;
} }
void HlswServer::HlswPacket::send(int socket, struct sockaddr_in* dst) void HlswServer::HlswPacket::send(Socket* socket, struct sockaddr_in* dst)
{ {
if (next) if (next)
next->send(socket, dst); next->send(socket, dst);
if (sendto(socket, data, sizeof(hlsw_header) + count * 10, 0, socket->sendto(this, dst);
(struct sockaddr *)dst, sizeof(*dst)) < 0) {
LogSystem::log(LOG_WARN, "HlswPacket::send()");
}
} }
HlswServer::HlswServer(Config& conf, GameList& glist) HlswServer::HlswServer(Config& conf, GameList& glist)
: lastUpdate(0) : lastUpdate(0)
{ {
if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
LogSystem::log(LOG_CRIT, "HlswServer(): socket()");
return;
}
const char *ip = conf.getString("global", "master_ip", "0.0.0.0"); 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); LogSystem::log(LOG_NOTICE, "HlswServer listen on %s:%d", ip, HLSW_MASTER_PORT);
@ -76,44 +68,33 @@ HlswServer::HlswServer(Config& conf, GameList& glist)
dst.sin_family = AF_INET; dst.sin_family = AF_INET;
dst.sin_port = htons(HLSW_MASTER_PORT); dst.sin_port = htons(HLSW_MASTER_PORT);
inet_aton(ip, &dst.sin_addr); inet_aton(ip, &dst.sin_addr);
socket = Socket::createSocket(&dst);
if (bind(sock, (struct sockaddr *)&dst, sizeof(dst)) < 0) {
LogSystem::log(LOG_ERROR, "HlswServer(): bind()");
return;
}
int interval = conf.getInteger("global", "rebuild_interval", DEFAULT_REBUILD_INTERVAL); int interval = conf.getInteger("global", "rebuild_interval", DEFAULT_REBUILD_INTERVAL);
TimerService::registerTimer(new Timer(new RebuildEvent(*this, glist), interval)); TimerService::registerTimer(new Timer(new RebuildEvent(*this, glist), interval));
pktlist = new HlswPacket(NULL); pktlist = new HlswPacket(NULL);
} }
HlswServer::~HlswServer() HlswServer::~HlswServer()
{ {
close(sock);
delete pktlist; delete pktlist;
delete socket;
} }
int HlswServer::execute(void* arg) int HlswServer::execute(void* arg)
{ {
struct sockaddr_in src;
unsigned char buf[32];
socklen_t len;
int ret;
while (1) { while (1) {
/* auf clientanfrage warten */ NetPkt* pkt = socket->recv();
len = sizeof(src); if (!pkt->compare(0, hlsw_header, sizeof(hlsw_header))) {
ret = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&src, &len);
if (memcmp(buf, hlsw_header, sizeof(hlsw_header))) {
LogSystem::log(LOG_NOTICE, "HlswServer: not a hlsw packet"); LogSystem::log(LOG_NOTICE, "HlswServer: not a hlsw packet");
continue; continue;
} }
mutex.lock(); mutex.lock();
pktlist->send(sock, &src); pktlist->send(socket, pkt->getAddress());
mutex.unlock(); mutex.unlock();
} }
return 0; return 0;
} }
@ -122,7 +103,7 @@ int HlswServer::execute(void* arg)
void HlswServer::rebuild(GameList& glist) { void HlswServer::rebuild(GameList& glist) {
if (glist.getLastUpdate() > lastUpdate) { if (glist.getLastUpdate() > lastUpdate) {
HlswPacket* newlist = new HlswPacket(NULL); HlswPacket* newlist = new HlswPacket(NULL);
Iterator<GameEntry>* it = glist.createIterator(); Iterator<GameEntry>* it = glist.createIterator();
while (it->hasNext()) { while (it->hasNext()) {
GameEntry* d = it->next(); GameEntry* d = it->next();
@ -133,12 +114,12 @@ void HlswServer::rebuild(GameList& glist) {
} }
lastUpdate = glist.getLastUpdate(); lastUpdate = glist.getLastUpdate();
delete it; delete it;
mutex.lock(); mutex.lock();
HlswPacket* oldlist = pktlist; HlswPacket* oldlist = pktlist;
pktlist = newlist; pktlist = newlist;
mutex.unlock(); mutex.unlock();
delete oldlist; delete oldlist;
} }
} }

View File

@ -6,6 +6,8 @@
#include "thread.h" #include "thread.h"
#include "config.h" #include "config.h"
#include "gamelist.h" #include "gamelist.h"
#include "netpkt.h"
#include "socket.h"
#include "mutex.h" #include "mutex.h"
class HlswServer : public Thread { class HlswServer : public Thread {
@ -16,7 +18,7 @@ public:
int execute(void* arg); int execute(void* arg);
void rebuild(GameList& gl); void rebuild(GameList& gl);
protected: protected:
HlswServer(const HlswServer& hs); HlswServer(const HlswServer& hs);
HlswServer& operator=(const HlswServer& hs); HlswServer& operator=(const HlswServer& hs);
@ -27,29 +29,27 @@ private:
RebuildEvent(HlswServer& hs, GameList& gl) : hs(hs), gl(gl) {} RebuildEvent(HlswServer& hs, GameList& gl) : hs(hs), gl(gl) {}
~RebuildEvent() {} ~RebuildEvent() {}
void execute() { hs.rebuild(gl); } void execute() { hs.rebuild(gl); }
private: private:
HlswServer& hs; HlswServer& hs;
GameList& gl; GameList& gl;
}; };
class HlswPacket { class HlswPacket : private NetPkt {
public: public:
HlswPacket(HlswPacket* next); HlswPacket(HlswPacket* next);
~HlswPacket(); ~HlswPacket();
bool addGame(GameEntry* ge); bool addGame(GameEntry* ge);
void send(int socket, struct sockaddr_in* dst); void send(Socket* socket, struct sockaddr_in* dst);
private: private:
HlswPacket* next; HlswPacket* next;
int count;
char data[1418];
}; };
Socket* socket;
HlswPacket* pktlist; HlswPacket* pktlist;
Mutex mutex; Mutex mutex;
int sock;
long lastUpdate; long lastUpdate;
}; };

View File

@ -48,7 +48,7 @@ void LogSystem::init(const char* prio, LogOutput* out)
else if (!strcasecmp(prio, "INFO")) else if (!strcasecmp(prio, "INFO"))
init(LOG_INFO, out); init(LOG_INFO, out);
else if (!strcasecmp(prio, "NOTICE")) else if (!strcasecmp(prio, "NOTICE"))
init(LOG_NOTICE, out); init(LOG_NOTICE, out);
@ -57,7 +57,7 @@ void LogSystem::init(const char* prio, LogOutput* out)
else if (!strcasecmp(prio, "ERROR")) else if (!strcasecmp(prio, "ERROR"))
init(LOG_ERROR, out); init(LOG_ERROR, out);
else if (!strcasecmp(prio, "CRIT")) else if (!strcasecmp(prio, "CRIT"))
init(LOG_CRIT, out); init(LOG_CRIT, out);

View File

@ -1,5 +1,6 @@
#include <string.h> #include <string.h>
#include "netpkt.h" #include "netpkt.h"
#include "modhelper.h"
#include "mod_d3engine.h" #include "mod_d3engine.h"
static struct game_ports port_arr[] = { static struct game_ports port_arr[] = {
@ -13,16 +14,17 @@ static const char replyhead[] = "\xff\xffinfoResponse";
void ModD3Engine::scan(MultiSock* msock) void ModD3Engine::scan(MultiSock* msock)
{ {
msock->send(port_arr, scanmsg, strlen(scanmsg)); ModHelper::send(msock, port_arr, scanmsg, strlen(scanmsg));
} }
int ModD3Engine::parse(NetPkt* pkt, GameList* glist) int ModD3Engine::parse(NetPkt* pkt, GameList* glist)
{ {
int gameid; int gameid;
if (!(gameid = pkt->checkPortArray(port_arr))) gameid = ModHelper::checkPorts(pkt, port_arr);
if (!gameid)
return PARSE_REJECT; return PARSE_REJECT;
if (pkt->compare(0, replyhead, strlen(replyhead))) if (pkt->compare(0, replyhead, strlen(replyhead)))
return PARSE_REJECT; return PARSE_REJECT;

View File

@ -7,10 +7,10 @@ class ModD3Engine : public Module {
public: public:
ModD3Engine() {} ModD3Engine() {}
~ModD3Engine() {} ~ModD3Engine() {}
void scan(MultiSock* msock); void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* slist); int parse(NetPkt* pkt, GameList* slist);
const char* getName() { return "Doom3 engine"; } const char* getName() { return "Doom3 engine"; }
}; };

View File

@ -1,4 +1,5 @@
#include <string.h> #include <string.h>
#include "modhelper.h"
#include "mod_gamespy1.h" #include "mod_gamespy1.h"
static struct game_ports port_arr[] = { static struct game_ports port_arr[] = {
@ -14,7 +15,7 @@ static const char scanmsg[] = "\\status\\";
void ModGameSpy1::scan(MultiSock* msock) void ModGameSpy1::scan(MultiSock* msock)
{ {
msock->send(port_arr, scanmsg, strlen(scanmsg)); ModHelper::send(msock, port_arr, scanmsg, strlen(scanmsg));
} }
int ModGameSpy1::parse(NetPkt* pkt, GameList* slist) int ModGameSpy1::parse(NetPkt* pkt, GameList* slist)

View File

@ -7,10 +7,10 @@ class ModGameSpy1 : public Module {
public: public:
ModGameSpy1() {} ModGameSpy1() {}
~ModGameSpy1() {} ~ModGameSpy1() {}
void scan(MultiSock* msock); void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* glist); int parse(NetPkt* pkt, GameList* glist);
const char* getName() { return "GameSpy 1 Protocol"; } const char* getName() { return "GameSpy 1 Protocol"; }
}; };

View File

@ -1,4 +1,5 @@
#include <string.h> #include <string.h>
#include "modhelper.h"
#include "mod_gamespy2.h" #include "mod_gamespy2.h"
static struct game_ports port_arr[] = { static struct game_ports port_arr[] = {
@ -15,7 +16,7 @@ static const char replyhead[] = { 0x00, 0xDE, 0xAD, 0xBE, 0xEF };
void ModGameSpy2::scan(MultiSock* msock) void ModGameSpy2::scan(MultiSock* msock)
{ {
msock->send(port_arr, scanmsg, sizeof(scanmsg)); ModHelper::send(msock, port_arr, scanmsg, sizeof(scanmsg));
} }
int ModGameSpy2::parse(NetPkt* pkt, GameList* slist) int ModGameSpy2::parse(NetPkt* pkt, GameList* slist)

View File

@ -7,10 +7,10 @@ class ModGameSpy2 : public Module {
public: public:
ModGameSpy2() {} ModGameSpy2() {}
~ModGameSpy2() {} ~ModGameSpy2() {}
void scan(MultiSock* msock); void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* glist); int parse(NetPkt* pkt, GameList* glist);
const char* getName() { return "GameSpy 2 Protocol"; } const char* getName() { return "GameSpy 2 Protocol"; }
}; };

View File

@ -1,4 +1,5 @@
#include <string.h> #include <string.h>
#include "modhelper.h"
#include "mod_halflife.h" #include "mod_halflife.h"
static struct game_ports port_arr[] = { static struct game_ports port_arr[] = {
@ -12,9 +13,9 @@ static const char scanmsg3[] = "\xff\xff\xff\xff""TSource Engine Query";
void ModHalfLife::scan(MultiSock* msock) void ModHalfLife::scan(MultiSock* msock)
{ {
msock->send(port_arr, scanmsg1, strlen(scanmsg1)); ModHelper::send(msock, port_arr, scanmsg1, strlen(scanmsg1));
msock->send(port_arr, scanmsg2, strlen(scanmsg2)); ModHelper::send(msock, port_arr, scanmsg2, strlen(scanmsg2));
msock->send(port_arr, scanmsg3, strlen(scanmsg3)); ModHelper::send(msock, port_arr, scanmsg3, strlen(scanmsg3));
} }
int ModHalfLife::parse(NetPkt* pkt, GameList* slist) int ModHalfLife::parse(NetPkt* pkt, GameList* slist)

View File

@ -7,10 +7,10 @@ class ModHalfLife : public Module {
public: public:
ModHalfLife() {} ModHalfLife() {}
~ModHalfLife() {} ~ModHalfLife() {}
void scan(MultiSock* msock); void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* glist); int parse(NetPkt* pkt, GameList* glist);
const char* getName() { return "HalfLife engine"; } const char* getName() { return "HalfLife engine"; }
}; };

View File

@ -1,10 +1,9 @@
#include <string.h> #include <string.h>
#include "modhelper.h"
#include "logging.h"
#include "mod_q3engine.h" #include "mod_q3engine.h"
static struct game_ports port_arr[] = { static struct game_ports port_arr[] = {
{ 27960, 27969, ID_Q3A }, // q3(6), ef(7), et25), rtcw(8) { 27960, 27960, ID_Q3A }, // q3(6), ef(7), et25), rtcw(8)
// { 28070, 28070, ID_JK2 }, // jk2(12) // { 28070, 28070, ID_JK2 }, // jk2(12)
// { 28960, 28963, ID_COD }, // cod(31), cod:uo(42), cod2(48) // { 28960, 28963, ID_COD }, // cod(31), cod:uo(42), cod2(48)
// { 29070, 29070, ID_JK3 }, // jk3(27) // { 29070, 29070, ID_JK3 }, // jk3(27)
@ -30,14 +29,15 @@ static const char reply_cod2[] = "Call of Duty 2\\";
void ModQ3Engine::scan(MultiSock* msock) void ModQ3Engine::scan(MultiSock* msock)
{ {
msock->send(port_arr, scanmsg, strlen(scanmsg)); ModHelper::send(msock, port_arr, scanmsg, strlen(scanmsg));
} }
int ModQ3Engine::parse(NetPkt* pkt, GameList* glist) int ModQ3Engine::parse(NetPkt* pkt, GameList* glist)
{ {
int gameid = 0, pos1, pos2; int gameid = 0, pos1, pos2;
if (!pkt->checkPortArray(port_arr)) gameid = ModHelper::checkPorts(pkt, port_arr);
if (!gameid)
return PARSE_REJECT; return PARSE_REJECT;
if (!pkt->compare(0, replyhead, strlen(replyhead))) if (!pkt->compare(0, replyhead, strlen(replyhead)))
@ -48,36 +48,36 @@ int ModQ3Engine::parse(NetPkt* pkt, GameList* glist)
pos1 += strlen(search_version); pos1 += strlen(search_version);
if (pkt->compare(pos1, reply_q3, strlen(reply_q3))) if (pkt->compare(pos1, reply_q3, strlen(reply_q3)))
gameid = ID_Q3A; gameid = ID_Q3A;
else if (pkt->compare(pos1, reply_ef, strlen(reply_ef))) else if (pkt->compare(pos1, reply_ef, strlen(reply_ef)))
gameid = ID_EF; gameid = ID_EF;
else if (pkt->compare(pos1, reply_rtcw, strlen(reply_rtcw))) else if (pkt->compare(pos1, reply_rtcw, strlen(reply_rtcw)))
gameid = ID_RTCW; gameid = ID_RTCW;
else if (pkt->compare(pos1, reply_et, strlen(reply_et))) else if (pkt->compare(pos1, reply_et, strlen(reply_et)))
gameid = ID_ET; gameid = ID_ET;
else if (pkt->compare(pos1, reply_jk2, strlen(reply_jk2))) else if (pkt->compare(pos1, reply_jk2, strlen(reply_jk2)))
gameid = ID_JK2; gameid = ID_JK2;
else if (pkt->compare(pos1, reply_jk3, strlen(reply_jk3))) else if (pkt->compare(pos1, reply_jk3, strlen(reply_jk3)))
gameid = ID_JK3; gameid = ID_JK3;
} }
pos2 = pkt->find(0, search_gamename, strlen(search_gamename)); pos2 = pkt->find(0, search_gamename, strlen(search_gamename));
if (gameid == 0 && pos2 != -1) { if (gameid == 0 && pos2 != -1) {
pos2 += strlen(search_gamename); pos2 += strlen(search_gamename);
if (pkt->compare(pos2, reply_cod, strlen(reply_cod))) if (pkt->compare(pos2, reply_cod, strlen(reply_cod)))
gameid = ID_COD; gameid = ID_COD;
else if (pkt->compare(pos2, reply_coduo, strlen(reply_coduo))) else if (pkt->compare(pos2, reply_coduo, strlen(reply_coduo)))
gameid = ID_COD_UO; gameid = ID_COD_UO;
else if (pkt->compare(pos2, reply_cod2, strlen(reply_cod2))) else if (pkt->compare(pos2, reply_cod2, strlen(reply_cod2)))
gameid = ID_COD2; gameid = ID_COD2;
} }
if (gameid == 0) if (gameid == 0)
return PARSE_REJECT; return PARSE_REJECT;

View File

@ -7,10 +7,10 @@ class ModQ3Engine : public Module {
public: public:
ModQ3Engine() {} ModQ3Engine() {}
~ModQ3Engine() {} ~ModQ3Engine() {}
void scan(MultiSock* msock); void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* glist); int parse(NetPkt* pkt, GameList* glist);
const char* getName() { return "Quake3 engine"; } const char* getName() { return "Quake3 engine"; }
}; };

View File

@ -2,13 +2,10 @@
#define _MODULE_H_ #define _MODULE_H_
#include "config.h" #include "config.h"
#include "multisock.h"
#include "netpkt.h" #include "netpkt.h"
#include "gamelist.h" #include "gamelist.h"
/* avoid cyclic deps, include this later.. */
//#include "multisock.h"
class MultiSock;
enum { enum {
ID_UNKNOWN = 0, // "Unknown" ID_UNKNOWN = 0, // "Unknown"
ID_HL, // "Halflife" ID_HL, // "Halflife"
@ -81,6 +78,4 @@ protected:
Module& operator=(const Module& m); Module& operator=(const Module& m);
}; };
#include "multisock.h"
#endif // _MODULE_H_ #endif // _MODULE_H_

View File

@ -17,101 +17,6 @@
#define DEVFILE "/proc/net/dev" #define DEVFILE "/proc/net/dev"
#define BUFSIZE 1024 #define BUFSIZE 1024
MultiSock::Socket::Socket()
{
if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
LogSystem::log(LOG_CRIT, "Socket: socket()");
}
MultiSock::Socket::~Socket()
{
close(fd);
}
bool MultiSock::Socket::bindToDevice(const char* name)
{
strncpy(devname, name, sizeof(devname));
int ret = setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, devname, sizeof(devname));
if (ret < 0) {
LogSystem::log(LOG_NOTICE, "Socket: setsockopt(SO_BINDTODEVICE) %s", devname);
return false;
}
return true;
}
bool MultiSock::Socket::bindToPort(int port)
{
struct ifreq ifr;
strncpy(ifr.ifr_name, devname, sizeof(ifr.ifr_name));
if (ioctl(fd, SIOCGIFADDR, &ifr) != 0) {
LogSystem::log(LOG_WARN, "Socket: ioctl(SIOCGIFADDR) %s", devname);
return false;
}
memcpy(&addr, &ifr.ifr_addr, sizeof(addr));
addr.sin_port = htons(port);
if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
LogSystem::log(LOG_WARN, "Socket: bind() %s", devname);
return false;
}
int bcast = 1;
if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &bcast, sizeof(bcast))) {
LogSystem::log(LOG_WARN, "Socket: setsockopt(SO_BROADCAST) %s", devname);
return false;
}
return true;
}
int MultiSock::Socket::show(char* buf, int size)
{
return snprintf(buf, size, "%s (%s:%d) ", devname,
inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
}
MultiSock::Socket* MultiSock::Socket::createSocket(const char* name, int port)
{
Socket* sock = new Socket();
if (sock->fd < 0) {
delete sock;
return NULL;
}
struct ifreq ifr;
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
if (ioctl(sock->fd, SIOCGIFFLAGS, &ifr) != 0) {
LogSystem::log(LOG_WARN, "Socket: ioctl(SIOCGIFFLAGS) %s", name);
delete sock;
return NULL;
}
if (!(ifr.ifr_flags & IFF_UP) || (ifr.ifr_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) {
delete sock;
return NULL;
}
sock->bindToDevice(name);
if (!sock->bindToPort(port)) {
delete sock;
return NULL;
}
return sock;
}
MultiSock::MultiSock(Config& conf) MultiSock::MultiSock(Config& conf)
{ {
char* buf = new char [BUFSIZE]; char* buf = new char [BUFSIZE];
@ -126,17 +31,17 @@ MultiSock::MultiSock(Config& conf)
free(buf); free(buf);
return; return;
} }
fgets(buf, BUFSIZE, fp); fgets(buf, BUFSIZE, fp);
fgets(buf, BUFSIZE, fp); fgets(buf, BUFSIZE, fp);
int port = conf.getInteger("global", "scan_port", DEFAULT_PORT); int port = conf.getInteger("global", "scan_port", DEFAULT_PORT);
Iterator<char>* it = conf.createIterator("global", "scan_deny_iface"); Iterator<char>* it = conf.createIterator("global", "scan_deny_iface");
FD_ZERO(&fdsel); FD_ZERO(&fdsel);
while (fgets(buf, BUFSIZE, fp) != NULL) { while (fgets(buf, BUFSIZE, fp) != NULL) {
char* tok = strtok(buf, " :"); char* tok = strtok(buf, " :");
it->reset(); it->reset();
while (it->hasNext()) { while (it->hasNext()) {
if (!strcmp(it->next(), tok)) { if (!strcmp(it->next(), tok)) {
@ -145,21 +50,21 @@ MultiSock::MultiSock(Config& conf)
break; break;
} }
} }
if (tok) { if (tok) {
Socket* sock = Socket::createSocket(tok, port); Socket* sock = Socket::createSocket(tok, port);
if (sock) { if (sock) {
FD_SET(sock->getFD(), &fdsel); FD_SET(sock->getFD(), &fdsel);
sock->show(buf, BUFSIZE); sock->show(buf, BUFSIZE);
LogSystem::log(LOG_NOTICE, "adding Interface %s", buf); LogSystem::log(LOG_NOTICE, "adding Interface %s", buf);
ifaceList.add(sock); ifaceList.add(sock);
} }
} }
} }
delete it; delete it;
fclose(fp); fclose(fp);
delete buf; delete buf;
@ -173,62 +78,36 @@ MultiSock::~MultiSock()
delete ifaceList.get(); delete ifaceList.get();
} }
NetPkt* MultiSock::recv()
int MultiSock::waitOnSocket()
{ {
fd_set fdcpy; fd_set fdcpy;
while (1) { while (1) {
memcpy(&fdcpy, &fdsel, sizeof(fdcpy)); memcpy(&fdcpy, &fdsel, sizeof(fdcpy));
select(FD_SETSIZE, &fdcpy, NULL, NULL, NULL); select(FD_SETSIZE, &fdcpy, NULL, NULL, NULL);
Iterator<Socket>* it = ifaceList.createIterator(); Iterator<Socket>* it = ifaceList.createIterator();
while (it->hasNext()) { while (it->hasNext()) {
Socket* sock = it->next(); Socket* sock = it->next();
if (FD_ISSET(sock->getFD(), &fdcpy)) { if (FD_ISSET(sock->getFD(), &fdcpy)) {
delete it; delete it;
return sock->getFD(); return sock->recv();
} }
} }
delete it; delete it;
LogSystem::log(LOG_WARN, "MultiSock::recvFrom(): select()");
LogSystem::log(LOG_WARN, "waitOnSocket(): select()");
} }
return NULL;
return -1;
} }
void MultiSock::send(struct in_addr *dstip, int dport, const char* data, int size) int MultiSock::sendto(NetPkt* pkt, struct sockaddr_in* dst)
{ {
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(dport);
addr.sin_addr.s_addr = (dstip ? dstip->s_addr : 0xFFFFFFFF);
Iterator<Socket>* it = ifaceList.createIterator(); Iterator<Socket>* it = ifaceList.createIterator();
while (it->hasNext()) while (it->hasNext())
if (sendto(it->next()->getFD(), data, size, 0, (struct sockaddr *)&addr, sizeof(addr)) < 0) it->next()->sendto(pkt, dst);
LogSystem::log(LOG_WARN, "MultiSock::send()");
delete it; delete it;
usleep(10000); usleep(10000);
} return 0;
void MultiSock::send(struct game_ports* arr, const char* data, int size)
{
while (arr && arr->portlo && arr->porthi) {
int port;
for (port = arr->portlo; port <= arr->porthi; port++)
send(NULL, port, data, size);
arr++;
}
}
void MultiSock::send(int* arr, const char* data, int size)
{
while (*arr)
send(NULL, *arr++, data, size);
} }

View File

@ -4,52 +4,24 @@
#include <net/if.h> #include <net/if.h>
#include <netinet/in.h> #include <netinet/in.h>
#include "list.h"
#include "config.h" #include "config.h"
#include "module.h" #include "netpkt.h"
#include "socket.h"
#include "list.h"
class MultiSock { class MultiSock {
public: public:
MultiSock(Config& conf); MultiSock(Config& conf);
~MultiSock(); ~MultiSock();
void send(struct in_addr *dstip, int dport, const char* data, int size); int sendto(NetPkt* pkt, struct sockaddr_in* dst = NULL);
void send(struct game_ports* arr, const char* data, int size); NetPkt* recv();
void send(int* arr, const char* data, int size);
int waitOnSocket();
protected: protected:
MultiSock(const MultiSock& x); MultiSock(const MultiSock& x);
MultiSock& operator=(const MultiSock& x); MultiSock& operator=(const MultiSock& x);
private: private:
class Socket {
public:
static Socket* createSocket(const char* name, int port);
int show(char* buf, int size);
int getFD() { return fd; }
~Socket();
protected:
Socket(const Socket& s);
Socket& operator=(const Socket& s);
private:
Socket();
bool bindToDevice(const char* name);
bool bindToPort(int port);
int fd;
char devname[IFNAMSIZ];
struct sockaddr_in addr;
};
void addIface(const char* name, int port);
List<Socket> ifaceList; List<Socket> ifaceList;
fd_set fdsel; fd_set fdsel;
}; };

View File

@ -13,78 +13,59 @@
#include "module.h" #include "module.h"
#include "netpkt.h" #include "netpkt.h"
NetPkt::NetPkt(const char* data, int size)
: data(data), used(size), size(0)
{
}
NetPkt::NetPkt(int size) NetPkt::NetPkt(int size)
:size(size) : used(0), size(size)
{ {
data = new char[size]; data = new char[size];
} }
NetPkt::~NetPkt() NetPkt::~NetPkt()
{ {
delete data; if (size > 0)
} delete data;
int NetPkt::readFromSocket(int fd)
{
socklen_t i = sizeof(struct sockaddr_in);
return recvfrom(fd, this->data, this->size, 0, (struct sockaddr *)&this->addr, &i);
} }
int NetPkt::show(char* buf, int size) int NetPkt::show(char* buf, int size)
{ {
return snprintf(buf, size, "(%s:%d) %d bytes", return snprintf(buf, size, "(%s:%d) (%d/%d) bytes",
inet_ntoa(this->addr.sin_addr), inet_ntoa(this->addr.sin_addr),
ntohs(this->addr.sin_port), ntohs(this->addr.sin_port),
this->size); this->used, this->size);
}
NetPkt* NetPkt::createFromSocket(int fd)
{
int recvsize;
if (ioctl(fd, FIONREAD, &recvsize) == -1) {
LogSystem::log(LOG_ERROR, "NetPkt::createFromSocket()");
return NULL;
}
NetPkt* retval = new NetPkt(recvsize);
retval->readFromSocket(fd);
return retval;
}
int NetPkt::checkPortArray(struct game_ports* portarr)
{
int myport = ntohs(this->addr.sin_port);
while (portarr && portarr->portlo) {
int port;
for (port = portarr->portlo; port <= portarr->porthi; port++)
if (port == myport)
return portarr->gameid;
portarr++;
}
return 0;
} }
bool NetPkt::compare(int offset, const char* buf, int len) bool NetPkt::compare(int offset, const char* buf, int len)
{ {
if (offset >= this->size) if (offset >= this->used)
return false; return false;
/* nicht ueber das paket hinaus vergleichen */ /* nicht ueber das paket hinaus vergleichen */
if (offset + len >= this->size) if (offset + len >= this->used)
len = this->size - offset; len = this->used - offset;
return (memcmp(this->data + offset, buf, len) == 0); return (memcmp(this->data + offset, buf, len) == 0);
} }
int NetPkt::find(int offset, const char *buf, int len) int NetPkt::find(int offset, const char *buf, int len)
{ {
if (offset >= this->size) if (offset >= this->used)
return -1; return -1;
void* found = memmem(this->data + offset, this->size, buf, len); void* found = memmem(this->data + offset, this->used, buf, len);
return (found == NULL) ? -1 : ((char*)found - this->data); return (found == NULL) ? -1 : ((char*)found - this->data);
} }
void NetPkt::setAddress(struct sockaddr_in *tmp)
{
memcpy(&addr, tmp, sizeof(addr));
}
struct sockaddr_in * NetPkt::getAddress()
{
return &addr;
}

View File

@ -8,28 +8,33 @@
#define PARSE_ACCEPT_FREED 2 #define PARSE_ACCEPT_FREED 2
#define PARSE_REJECT 4 #define PARSE_REJECT 4
/* avoid cyclic deps */
class Socket;
class NetPkt { class NetPkt {
friend class Socket;
public: public:
NetPkt(const char* data, int size);
NetPkt(int size);
~NetPkt(); ~NetPkt();
static NetPkt* createFromSocket(int fd);
int show(char* buf, int size); int show(char* buf, int size);
int checkPortArray(struct game_ports* arr);
bool compare(int offset, const char* buf, int len); bool compare(int offset, const char* buf, int len);
int find(int offset, const char *buf, int len); int find(int offset, const char *buf, int len);
void setAddress(struct sockaddr_in *addr);
struct sockaddr_in * getAddress();
protected: protected:
NetPkt(const NetPkt& x); NetPkt(const NetPkt& x);
NetPkt& operator=(const NetPkt& x); NetPkt& operator=(const NetPkt& x);
private:
NetPkt(int size);
int readFromSocket(int fd);
struct sockaddr_in addr; struct sockaddr_in addr;
const char *data;
int used;
private:
int size; int size;
char *data;
}; };
#endif // _NETPKT_H_ #endif // _NETPKT_H_

View File

@ -1,9 +1,5 @@
#include "recvqueue.h" #include "recvqueue.h"
RecvQueue::RecvQueue()
{
}
RecvQueue::~RecvQueue() RecvQueue::~RecvQueue()
{ {
while (!pktList.isEmpty()) while (!pktList.isEmpty())

View File

@ -7,9 +7,9 @@
class RecvQueue { class RecvQueue {
public: public:
RecvQueue(); RecvQueue() {};
~RecvQueue(); ~RecvQueue();
void addPkt(NetPkt* pkt); void addPkt(NetPkt* pkt);
NetPkt* getPkt(); NetPkt* getPkt();

View File

@ -10,7 +10,7 @@ public:
~Semaphore() { sem_destroy(&s); } ~Semaphore() { sem_destroy(&s); }
void wait() { sem_wait(&s); } void wait() { sem_wait(&s); }
void post() { sem_post(&s); } void post() { sem_post(&s); }
protected: protected:
Semaphore(const Semaphore& s); Semaphore(const Semaphore& s);
Semaphore& operator=(const Semaphore& s); Semaphore& operator=(const Semaphore& s);

View File

@ -16,10 +16,10 @@ Thread::~Thread()
switch (state) { switch (state) {
case THREAD_RUNNING: case THREAD_RUNNING:
cancel(); cancel();
case THREAD_ENDED: case THREAD_ENDED:
join(); join();
case THREAD_READY: case THREAD_READY:
break; break;
} }
@ -31,7 +31,7 @@ int Thread::start(void* arg_)
if (state != THREAD_READY) if (state != THREAD_READY)
return -1; return -1;
arg = arg_; arg = arg_;
state = THREAD_RUNNING; state = THREAD_RUNNING;