daily work
This commit is contained in:
parent
38542d7ddf
commit
2e728963c7
3
Makefile
3
Makefile
|
@ -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
|
||||||
|
|
||||||
|
|
24
config.cpp
24
config.cpp
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
10
config.h
10
config.h
|
@ -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:
|
||||||
|
|
12
gamelist.cpp
12
gamelist.cpp
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
25
gamelist.h
25
gamelist.h
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
hlswserver.h
16
hlswserver.h
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
7
module.h
7
module.h
|
@ -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_
|
||||||
|
|
155
multisock.cpp
155
multisock.cpp
|
@ -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);
|
|
||||||
}
|
}
|
||||||
|
|
38
multisock.h
38
multisock.h
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
71
netpkt.cpp
71
netpkt.cpp
|
@ -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;
|
||||||
|
}
|
||||||
|
|
23
netpkt.h
23
netpkt.h
|
@ -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_
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
#include "recvqueue.h"
|
#include "recvqueue.h"
|
||||||
|
|
||||||
RecvQueue::RecvQueue()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
RecvQueue::~RecvQueue()
|
RecvQueue::~RecvQueue()
|
||||||
{
|
{
|
||||||
while (!pktList.isEmpty())
|
while (!pktList.isEmpty())
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue