daily work

This commit is contained in:
Olaf Rempel 2006-03-07 20:30:11 +01:00
parent 33e97b1eaa
commit bb96fb05a3
17 changed files with 136 additions and 68 deletions

View File

@ -1,15 +1,20 @@
CFLAGS := -O2 -pipe -Wall -Wunused -Wno-deprecated
LIBS := -lpthread
SRC := $(wildcard *.cpp)
OBJS := $(SRC:.cpp=.o)
DEPS := $(SRC:.cpp=.d)
HLSWMASTER_SRC := config.o gameentry.o gamelist.o gameparser.o gamescanner.o \
hlswmaster.o hlswserver.o list.o logging.o modhelper.o modulelist.o \
multisock.o netpkt.o recvqueue.o socket.o timerservice.o thread.o \
mod_d3engine.o mod_gamespy1.o mod_gamespy2.o mod_halflife.o \
mod_hlswproxy.o mod_q3engine.o mod_quake2.o mod_ut.o
all: hlswmaster
all: hlswmaster masterquery
hlswmaster: $(OBJS)
hlswmaster: $(HLSWMASTER_SRC) hlswmaster.o
$(CXX) $(CFLAGS) $^ $(LIBS) -o $@
masterquery: masterquery.o
$(CC) $(CFLAGS) $^ $(LIBS) -o $@
%.o: %.cpp
$(CXX) $(CFLAGS) -c $< -o $@
@ -20,6 +25,7 @@ dist:
git-tar-tree HEAD hlswmaster-ng | gzip -9 -c > hlswmaster-ng.tar.gz
clean:
rm -f hlswmaster *.d *.o *.log
rm -f hlswmaster masterquery *.d *.o *.log
-include $(DEPS)
##DEPS := $(wildcard *.cpp)
##-include $(DEPS:.cpp=.d)

View File

@ -34,7 +34,6 @@ private:
~SectionIterator();
bool hasNext();
char* next();
void add(char* part) {}
void remove() {}
void reset();
@ -53,7 +52,6 @@ private:
const char* name;
private:
List<Tupel> tupelList;
};

View File

@ -12,12 +12,13 @@ public:
GameList(Config& conf);
~GameList();
void cleanup();
void addGame(int gameid, NetPkt* pkt, int port2 = 0, bool swap = false);
long getLastUpdate();
Iterator<GameEntry>* createIterator();
void cleanup();
protected:
GameList(const GameList& gl);
GameList& operator=(const GameList& gl);

View File

@ -14,7 +14,7 @@ game_timeout 30
# master answers with this source IP
master_ip 0.0.0.0
# rebuild master liste every X seconds
# rebuild master list every X seconds
rebuild_interval 5
# logging
@ -22,5 +22,4 @@ logfile hlswmaster.log
logprio DEBUG
[hlswproxy]
parent 1.1.1.1 2.2.2.2
parent 3.3.3.3
master_ip 10.10.0.30 10.10.0.31

View File

@ -13,11 +13,14 @@
#include "hlswserver.h"
#include "timerservice.h"
#include "mod_halflife.h"
#include "mod_q3engine.h"
#include "mod_d3engine.h"
#include "mod_gamespy1.h"
#include "mod_gamespy2.h"
#include "mod_halflife.h"
#include "mod_hlswproxy.h"
#include "mod_q3engine.h"
#include "mod_quake2.h"
#include "mod_ut.h"
#define DEFAULT_CONFIG "hlswmaster.conf"
#define DEFAULT_LOGFILE "hlswmaster.log"
@ -90,16 +93,21 @@ int main(int argc, char *argv[])
GameParser parser(rxQueue, modList, gameList);
HlswServer server(conf, gameList);
// modList.reg(new ModHalfLife());
// modList.reg(new ModQ3Engine());
// modList.reg(new ModD3Engine());
modList.reg(new ModD3Engine());
modList.reg(new ModGameSpy1());
// modList.reg(new ModGameSpy2());
modList.reg(new ModGameSpy2());
modList.reg(new ModHalfLife());
modList.reg(new ModHlswProxy(conf));
modList.reg(new ModQ3Engine());
modList.reg(new ModQuake2());
modList.reg(new ModUT());
server.start();
parser.start();
scanner.start();
LogSystem::log(LOG_EVERYTIME, "hlswmaster-ng running...");
while (1) {
TimerService::checkTimers();
usleep(500000);

View File

@ -16,7 +16,6 @@ public:
~HlswServer();
int execute(void* arg);
void rebuild(GameList& gl);
protected:

10
list.h
View File

@ -8,7 +8,6 @@ public:
virtual ~IteratorBase() {}
virtual bool hasNext() =0;
virtual void* next() =0;
virtual void add(void* part) {}; // TODO: why not =0;
virtual void remove() =0;
virtual void reset() =0;
@ -65,7 +64,6 @@ protected:
bool hasNext();
void* next();
void add(void* part);
void remove();
void reset();
@ -77,6 +75,8 @@ protected:
private:
ListEntryBase head;
Mutex mutex;
friend class ListIteratorBase;
};
@ -84,7 +84,6 @@ template <class T>
class Iterator : public IteratorBase {
public:
virtual T* next() =0;
virtual void add(T* part) =0;
};
template <class T>
@ -95,13 +94,12 @@ public:
bool hasNext() { return false; }
T* next() { return NULL; }
void add(T* part) {}
void remove() {}
void reset() {}
};
template <class T>
class List : private ListBase {
class List : public ListBase {
public:
List() {}
~List() {}
@ -124,7 +122,6 @@ private:
bool hasNext() { return ListIteratorBase::hasNext(); }
TT* next() { return (TT*)ListIteratorBase::next(); }
void add(TT* part) {}
void remove() {}
void reset() { ListIteratorBase::reset(); }
};
@ -137,7 +134,6 @@ private:
bool hasNext() { return ListIteratorBase::hasNext(); }
TT* next() { return (TT*)ListIteratorBase::next(); }
void add(TT* part) { ListIteratorBase::add(part); }
void remove() { ListIteratorBase::remove(); }
void reset() { ListIteratorBase::reset(); }
};

View File

@ -11,7 +11,7 @@ public:
void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* slist);
const char* getName() { return "Doom3 engine"; }
const char* getName() { return "Doom3 protocol"; }
};
#endif // _MODD3ENGINE_H_

View File

@ -3,6 +3,8 @@
#include "modhelper.h"
#include "mod_gamespy1.h"
#define MODGS1_GC_TIMEOUT 5
static struct game_ports port_arr[] = {
{ 7777, 7788, ID_UT }, // ut, ut2k3, rune, ut2k4, aao, POSTAL2
{ 22000, 22010, ID_BF1942 }, // bf1942(16)
@ -38,7 +40,7 @@ static const char reply_fear[] = "fear\\";
ModGameSpy1::ModGameSpy1()
{
// TODO: cleanup event
TimerService::registerTimer(new Timer(new GcEvent(*this), MODGS1_GC_TIMEOUT));
}
ModGameSpy1::~ModGameSpy1()
@ -86,39 +88,41 @@ int ModGameSpy1::parse(NetPkt* pkt, GameList* glist)
offset = pkt->find(0, search_final, strlen(search_final));
final = (offset != -1);
char buf[64];
pkt->show(buf, sizeof(buf));
/* single final packet -> shortcut */
if (final && (subid == 1)) {
LogSystem::log(LOG_DEBUG, "single final");
pkt2 = pkt;
/* non-final multi-part */
} else if (!final) {
LogSystem::log(LOG_DEBUG, "non final");
LogSystem::log(LOG_DEBUG, "non final %s (%d/%d)", buf, queryid, subid);
list.addTail(new MultiPart(pkt, queryid, subid));
return PARSE_ACCEPT_FREED;
return PARSE_ACCEPT_FREED; // parser must not free pkt
/* final multipart */
} else {
LogSystem::log(LOG_DEBUG, "multi final");
LogSystem::log(LOG_DEBUG, "multi final %s (%d/%d)", buf, queryid, subid);
pkt2 = merge(pkt, queryid, subid);
if (pkt2 == NULL) {
LogSystem::log(LOG_NOTICE, "GameSpy1: unable to merge");
return PARSE_ACCEPT_FREED;
LogSystem::log(LOG_NOTICE, "ModGameSpy1: failed to merge");
return PARSE_ACCEPT; // let parser free pkt
}
}
retval = parse_real(pkt2, glist, gameid);
if (pkt2 != pkt)
delete pkt2;
delete pkt2; // free merged packet
return retval;
return retval; // ACCPET/REJECT -> let parser free pkt
}
ModGameSpy1::MultiPart::MultiPart(NetPkt* pkt, int queryid, int subid)
: pkt(pkt), queryid(queryid), subid(subid)
{
timeout = time(NULL) + 5;
timeout = time(NULL) + MODGS1_GC_TIMEOUT;
}
NetPkt* ModGameSpy1::merge(NetPkt* pkt, int queryid, int subid)
@ -145,6 +149,7 @@ NetPkt* ModGameSpy1::merge(NetPkt* pkt, int queryid, int subid)
if (searchid == mp->subid) {
tmppkt->append(mp->pkt);
delete mp->pkt;
searchid++;
}
}
@ -155,7 +160,6 @@ NetPkt* ModGameSpy1::merge(NetPkt* pkt, int queryid, int subid)
delete it;
tmppkt->append(pkt);
delete pkt;
if (!found) {
delete tmppkt;
@ -165,6 +169,25 @@ NetPkt* ModGameSpy1::merge(NetPkt* pkt, int queryid, int subid)
return tmppkt;
}
void ModGameSpy1::gc()
{
Iterator<MultiPart>* it = list.createIteratorRW();
long now = time(NULL);
char buf[64];
while (it->hasNext()) {
MultiPart* mp = it->next();
if (mp->timeout <= now) {
mp->pkt->show(buf, sizeof(buf));
LogSystem::log(LOG_NOTICE, "ModGameSpy1 gc removed: %s (%d/%d)",
buf, mp->queryid, mp->subid);
it->remove();
}
}
delete it;
}
int ModGameSpy1::parse_real(NetPkt* pkt, GameList* glist, int gameid)
{
int port, offset, pos1, pos2;

View File

@ -12,7 +12,9 @@ public:
void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* glist);
const char* getName() { return "GameSpy 1 Protocol"; }
const char* getName() { return "GameSpy 1 protocol"; }
void gc();
private:
class MultiPart {
@ -27,6 +29,16 @@ private:
long timeout;
};
class GcEvent : public Event {
public:
GcEvent(ModGameSpy1& mgs1) : mgs1(mgs1) {}
~GcEvent() {}
void execute() { mgs1.gc(); }
private:
ModGameSpy1& mgs1;
};
NetPkt* merge(NetPkt* pkt, int queryid, int subid);
int parse_real(NetPkt* pkt, GameList* glist, int gameid);

View File

@ -11,7 +11,7 @@ public:
void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* glist);
const char* getName() { return "GameSpy 2 Protocol"; }
const char* getName() { return "GameSpy 2 protocol"; }
};
#endif // _MODGAMESPY1_H_

View File

@ -11,8 +11,8 @@ static const char scanmsg1[] = "\xff\xff\xff\xff""details";
static const char scanmsg2[] = "\xff\xff\xff\xff\x54";
static const char scanmsg3[] = "\xff\xff\xff\xff""TSource Engine Query";
static const char reply1[] = "m\x00";
static const char reply2[] = "I\x07";
static const char reply1[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x07 }; // I.
static const char reply2[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0x6D, 0x00 }; // m
void ModHalfLife::scan(MultiSock* msock)
{
@ -29,25 +29,29 @@ int ModHalfLife::parse(NetPkt* pkt, GameList* glist)
if (ModHelper::checkPorts(pkt, port_arr) == 0)
return PARSE_REJECT;
// check 0xFF 0xFF 0xFF 0xFF
if (!pkt->compare(0, scanmsg1, 4))
return PARSE_REJECT;
// eat weird connection attempts
if (pkt->getSize() <= 4)
return PARSE_ACCEPT_QUIRK;
/* check for short answer without ip/port */
if (pkt->compare(4, reply1, 2)) {
glist->addGame(ID_HL, pkt);
return PARSE_ACCEPT;
}
/* second query?! */
if (pkt->compare(4, reply2, 2)) {
/* Halflife2 answer */
if (pkt->compare(0, reply1, sizeof(reply1))) {
glist->addGame(ID_HL2, pkt);
return PARSE_ACCEPT;
}
/* parse server IP */
/* Halflife1 short answer */
if (pkt->compare(0, reply2, sizeof(reply2))) {
glist->addGame(ID_HL, pkt);
return PARSE_ACCEPT;
}
/* Halflife1 answer (with IP:port) */
if (!pkt->compare(0, reply2, sizeof(reply2) -1))
return PARSE_REJECT;
/* try to parse server IP */
pos = 5;
if ((count = pkt->parse_ip(pos, &tmp)) == 0)
if ((count = pkt->parse_ip(pos, &tmp)) < 7)
return PARSE_REJECT;
/* parse server port */
@ -55,8 +59,15 @@ int ModHalfLife::parse(NetPkt* pkt, GameList* glist)
if ((count = pkt->parse_int(pos, &port)) == 0)
return PARSE_REJECT;
// TODO: check server IP?
//glist->add(ID_HL, &tmp, port, 0);
glist->addGame(ID_HL, pkt);
// IP is 0.0.0.0 or 127.0.0.1 -> do not use IP info
if (tmp.s_addr == 0x00000000 || tmp.s_addr == 0x0100007F) {
glist->addGame(ID_HL, pkt);
} else {
// TODO: implement
glist->addGame(ID_HL, pkt);
//glist->add(ID_HL, &tmp, port, false);
}
return PARSE_ACCEPT;
}

View File

@ -11,7 +11,7 @@ public:
void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* glist);
const char* getName() { return "HalfLife engine"; }
const char* getName() { return "Half-Life protocol"; }
};
#endif // _MODHALFLIFE_H_

View File

@ -11,7 +11,7 @@ public:
void scan(MultiSock* msock);
int parse(NetPkt* pkt, GameList* glist);
const char* getName() { return "Quake3 engine"; }
const char* getName() { return "Quake3 protocol"; }
};
#endif // _MODQ3ENGINE_H_

View File

@ -1,5 +1,19 @@
#include "modhelper.h"
void ModHelper::send(MultiSock* msock, int port, const char* data, int size)
{
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = 0xFFFFFFFF;
addr.sin_port = htons(port);
NetPkt* pkt = new NetPkt(data, size);
pkt->setAddress(&addr);
msock->sendto(pkt);
delete pkt;
}
void ModHelper::send(MultiSock* msock, struct game_ports* arr, const char* data, int size)
{
struct sockaddr_in addr;

View File

@ -7,7 +7,9 @@
class ModHelper {
public:
static void send(MultiSock* msock, int port, const char* data, int size);
static void send(MultiSock* msock, struct game_ports* arr, const char* data, int size);
static int checkPorts(NetPkt* pkt, struct game_ports* arr);
protected:

View File

@ -1,6 +1,12 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
// needed for string.h / memmem()
#ifndef __USE_GNU
#define __USE_GNU
#endif
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
@ -159,11 +165,6 @@ bool NetPkt::sameAddress(NetPkt* pkt)
void NetPkt::append(NetPkt* pkt)
{
char buf1[64], buf2[64];
this->show(buf1, sizeof(buf1));
pkt->show(buf2, sizeof(buf2));
LogSystem::log(LOG_DEBUG, "append (%s) + (%s)", buf1, buf2);
unsigned int new_alloc = size + pkt->size;
char* new_data = new char[new_alloc];
@ -177,6 +178,4 @@ void NetPkt::append(NetPkt* pkt)
memcpy((void*)(data + size), pkt->data, pkt->size);
size += pkt->size;
delete pkt;
}