From bb96fb05a313738fbce83c08cabdb131531d993d Mon Sep 17 00:00:00 2001 From: Olaf Rempel Date: Tue, 7 Mar 2006 20:30:11 +0100 Subject: [PATCH] daily work --- Makefile | 20 +++++++++++++------- config.h | 2 -- gamelist.h | 3 ++- hlswmaster.conf | 5 ++--- hlswmaster.cpp | 20 ++++++++++++++------ hlswserver.h | 1 - list.h | 10 +++------- mod_d3engine.h | 2 +- mod_gamespy1.cpp | 45 ++++++++++++++++++++++++++++++++++----------- mod_gamespy1.h | 14 +++++++++++++- mod_gamespy2.h | 2 +- mod_halflife.cpp | 47 +++++++++++++++++++++++++++++------------------ mod_halflife.h | 2 +- mod_q3engine.h | 2 +- modhelper.cpp | 14 ++++++++++++++ modhelper.h | 2 ++ netpkt.cpp | 13 ++++++------- 17 files changed, 136 insertions(+), 68 deletions(-) diff --git a/Makefile b/Makefile index 55b378c..ed2ac9b 100644 --- a/Makefile +++ b/Makefile @@ -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) diff --git a/config.h b/config.h index ec6d0f4..93034c8 100644 --- a/config.h +++ b/config.h @@ -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 tupelList; }; diff --git a/gamelist.h b/gamelist.h index 5f0c095..92de8c6 100644 --- a/gamelist.h +++ b/gamelist.h @@ -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* createIterator(); + void cleanup(); + protected: GameList(const GameList& gl); GameList& operator=(const GameList& gl); diff --git a/hlswmaster.conf b/hlswmaster.conf index 26d110b..a12b6ee 100644 --- a/hlswmaster.conf +++ b/hlswmaster.conf @@ -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 diff --git a/hlswmaster.cpp b/hlswmaster.cpp index b9df7b1..4469cbd 100644 --- a/hlswmaster.cpp +++ b/hlswmaster.cpp @@ -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); diff --git a/hlswserver.h b/hlswserver.h index b645133..4b1a8f3 100644 --- a/hlswserver.h +++ b/hlswserver.h @@ -16,7 +16,6 @@ public: ~HlswServer(); int execute(void* arg); - void rebuild(GameList& gl); protected: diff --git a/list.h b/list.h index 6f27771..6ec974d 100644 --- a/list.h +++ b/list.h @@ -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 Iterator : public IteratorBase { public: virtual T* next() =0; - virtual void add(T* part) =0; }; template @@ -95,13 +94,12 @@ public: bool hasNext() { return false; } T* next() { return NULL; } - void add(T* part) {} void remove() {} void reset() {} }; template -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(); } }; diff --git a/mod_d3engine.h b/mod_d3engine.h index 9df5ff0..25cea26 100644 --- a/mod_d3engine.h +++ b/mod_d3engine.h @@ -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_ diff --git a/mod_gamespy1.cpp b/mod_gamespy1.cpp index 6cb9ddb..9d4bf76 100644 --- a/mod_gamespy1.cpp +++ b/mod_gamespy1.cpp @@ -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* 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; diff --git a/mod_gamespy1.h b/mod_gamespy1.h index 5c62c07..ed6fcf2 100644 --- a/mod_gamespy1.h +++ b/mod_gamespy1.h @@ -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); diff --git a/mod_gamespy2.h b/mod_gamespy2.h index 77dbedc..ccba1f7 100644 --- a/mod_gamespy2.h +++ b/mod_gamespy2.h @@ -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_ diff --git a/mod_halflife.cpp b/mod_halflife.cpp index 026fd59..7bb23ed 100644 --- a/mod_halflife.cpp +++ b/mod_halflife.cpp @@ -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; } diff --git a/mod_halflife.h b/mod_halflife.h index 6d7586c..1eb8d30 100644 --- a/mod_halflife.h +++ b/mod_halflife.h @@ -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_ diff --git a/mod_q3engine.h b/mod_q3engine.h index ff4981e..e62a6cb 100644 --- a/mod_q3engine.h +++ b/mod_q3engine.h @@ -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_ diff --git a/modhelper.cpp b/modhelper.cpp index 81b27ff..ea0b901 100644 --- a/modhelper.cpp +++ b/modhelper.cpp @@ -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; diff --git a/modhelper.h b/modhelper.h index e937e2d..bb5c8ff 100644 --- a/modhelper.h +++ b/modhelper.h @@ -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: diff --git a/netpkt.cpp b/netpkt.cpp index f4d4ffc..63cf499 100644 --- a/netpkt.cpp +++ b/netpkt.cpp @@ -1,6 +1,12 @@ #include #include #include + +// needed for string.h / memmem() +#ifndef __USE_GNU +#define __USE_GNU +#endif + #include #include #include @@ -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; }