get it working
This commit is contained in:
parent
c4df94c900
commit
17f64ec0f9
|
@ -3,3 +3,5 @@
|
|||
hlswmaster
|
||||
hlswmaster.log
|
||||
doc/*
|
||||
masterquery
|
||||
hlswmaster-ng.tar.gz
|
||||
|
|
24
Makefile
24
Makefile
|
@ -1,8 +1,9 @@
|
|||
CFLAGS := -O2 -pipe -Wall -Wunused -Wno-deprecated
|
||||
CFLAGS := -O2 -pipe -Wall
|
||||
CXXFLAGS := -O2 -pipe -Wall -Wunused -Wno-deprecated
|
||||
LIBS := -lpthread
|
||||
|
||||
HLSWMASTER_SRC := config.o gameentry.o gamelist.o gameparser.o gamescanner.o \
|
||||
hlswmaster.o hlswserver.o list.o logging.o modhelper.o modulelist.o \
|
||||
hlswmaster.o hlswserver.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
|
||||
|
@ -10,22 +11,29 @@ HLSWMASTER_SRC := config.o gameentry.o gamelist.o gameparser.o gamescanner.o \
|
|||
all: hlswmaster masterquery
|
||||
|
||||
hlswmaster: $(HLSWMASTER_SRC) hlswmaster.o
|
||||
$(CXX) $(CFLAGS) $^ $(LIBS) -o $@
|
||||
$(CXX) $(CXXFLAGS) $^ $(LIBS) -o $@
|
||||
|
||||
masterquery: masterquery.o
|
||||
$(CC) $(CFLAGS) $^ $(LIBS) -o $@
|
||||
|
||||
%.o: %.cpp
|
||||
$(CXX) $(CFLAGS) -c $< -o $@
|
||||
$(CXX) $(CXXFLAGS) -c $< -o $@
|
||||
|
||||
%.d: %.cpp
|
||||
$(CXX) $(CFLAGS) -MM -c $< -o $@
|
||||
$(CXX) $(CXXFLAGS) -MM -c $< -o $@
|
||||
|
||||
dist:
|
||||
git-tar-tree HEAD hlswmaster-ng | gzip -9 -c > hlswmaster-ng.tar.gz
|
||||
dist: clean
|
||||
ln -s . hlswmaster-ng
|
||||
tar -czhf hlswmaster-ng.tar.gz hlswmaster-ng/ \
|
||||
--exclude hlswmaster-ng/.git \
|
||||
--exclude hlswmaster-ng/.gitignore \
|
||||
--exclude hlswmaster-ng/hlswmaster-ng.tar.gz \
|
||||
--exclude hlswmaster-ng/hlswmaster-ng
|
||||
rm hlswmaster-ng
|
||||
|
||||
clean:
|
||||
rm -f hlswmaster masterquery *.d *.o *.log
|
||||
rm -f hlswmaster masterquery *.d *.o *.log \
|
||||
hlswmaster-ng hlswmaster-ng.tar.gz
|
||||
|
||||
##DEPS := $(wildcard *.cpp)
|
||||
##-include $(DEPS:.cpp=.d)
|
||||
|
|
18
config.cpp
18
config.cpp
|
@ -42,12 +42,12 @@ bool Config::Section::addTupel(const char* name, const char* value)
|
|||
return false;
|
||||
|
||||
Tupel* t = new Tupel(name, value);
|
||||
tupelList.addTail(t);
|
||||
tupelList.add(t);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Config::Section::show() const
|
||||
void Config::Section::show()
|
||||
{
|
||||
Iterator<Tupel>* it = tupelList.createIterator();
|
||||
LogSystem::log(LOG_INFO, "[%s]", name);
|
||||
|
@ -60,7 +60,7 @@ void Config::Section::show() const
|
|||
delete it;
|
||||
}
|
||||
|
||||
const char* Config::Section::getTupelValue(const char* name) const
|
||||
const char* Config::Section::getTupelValue(const char* name)
|
||||
{
|
||||
const char* retval = 0;
|
||||
Iterator<Tupel>* it = this->tupelList.createIterator();
|
||||
|
@ -121,7 +121,7 @@ Config::~Config()
|
|||
Config::Section* Config::addSection(const char* name)
|
||||
{
|
||||
Section* s = new Section(name);
|
||||
sectionList.addTail(s);
|
||||
sectionList.add(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ bool Config::parseFile(const char* name)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void Config::show() const
|
||||
void Config::show()
|
||||
{
|
||||
LogSystem::log(LOG_INFO, "Config Dump:");
|
||||
Iterator<Section>* it = sectionList.createIterator();
|
||||
|
@ -194,7 +194,7 @@ void Config::show() const
|
|||
delete it;
|
||||
}
|
||||
|
||||
Config::Section* Config::getSection(const char* name) const
|
||||
Config::Section* Config::getSection(const char* name)
|
||||
{
|
||||
Section* retval = 0;
|
||||
|
||||
|
@ -211,13 +211,13 @@ Config::Section* Config::getSection(const char* name) const
|
|||
return retval;
|
||||
}
|
||||
|
||||
const char* Config::getParameter(const char* section, const char* option) const
|
||||
const char* Config::getParameter(const char* section, const char* option)
|
||||
{
|
||||
Section* s = getSection(section);
|
||||
return s ? s->getTupelValue(option) : 0;
|
||||
}
|
||||
|
||||
const char* Config::getString(const char* section, const char* option, char* def) const
|
||||
const char* Config::getString(const char* section, const char* option, char* def)
|
||||
{
|
||||
const char* retval = getParameter(section, option);
|
||||
if (!retval) {
|
||||
|
@ -229,7 +229,7 @@ const char* Config::getString(const char* section, const char* option, char* def
|
|||
return retval;
|
||||
}
|
||||
|
||||
int Config::getInteger(const char* section, const char* option, int def) const
|
||||
int Config::getInteger(const char* section, const char* option, int def)
|
||||
{
|
||||
const char* retval = getParameter(section, option);
|
||||
if (!retval) {
|
||||
|
|
18
config.h
18
config.h
|
@ -8,16 +8,16 @@ public:
|
|||
~Config();
|
||||
|
||||
bool parseFile(const char* name);
|
||||
void show() const;
|
||||
void show();
|
||||
|
||||
const char* getParameter(const char* section, const char* name) const;
|
||||
const char* getString(const char* section, const char* name, char* def) const;
|
||||
int getInteger(const char* section, const char* name, int def) const;
|
||||
const char* getParameter(const char* section, const char* name);
|
||||
const char* getString(const char* section, const char* name, char* def);
|
||||
int getInteger(const char* section, const char* name, int def);
|
||||
|
||||
Iterator<char>* createIterator(const char* section, const char* name);
|
||||
|
||||
private:
|
||||
class Tupel {
|
||||
class Tupel : private ListEntry<Tupel> {
|
||||
public:
|
||||
Tupel(const char* name, const char* value);
|
||||
~Tupel();
|
||||
|
@ -26,7 +26,7 @@ private:
|
|||
const char* value;
|
||||
};
|
||||
|
||||
class Section {
|
||||
class Section : private ListEntry<Section> {
|
||||
public:
|
||||
class SectionIterator : public Iterator<char> {
|
||||
public:
|
||||
|
@ -47,8 +47,8 @@ private:
|
|||
~Section();
|
||||
|
||||
bool addTupel(const char* name, const char* option);
|
||||
const char* getTupelValue(const char* name) const;
|
||||
void show() const;
|
||||
const char* getTupelValue(const char* name);
|
||||
void show();
|
||||
|
||||
const char* name;
|
||||
|
||||
|
@ -56,7 +56,7 @@ private:
|
|||
};
|
||||
|
||||
Section* addSection(const char* name);
|
||||
Section* getSection(const char* name) const;
|
||||
Section* getSection(const char* name);
|
||||
|
||||
List<Section> sectionList;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,24 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "gameentry.h"
|
||||
|
||||
GameEntry::GameEntry(int gameid, NetPkt* pkt, int port2)
|
||||
: port2(port2), gameid(gameid)
|
||||
{
|
||||
memcpy(&addr, &pkt->getAddress()->sin_addr, sizeof(addr));
|
||||
this->port1 = pkt->getPort();
|
||||
|
||||
if (port2 != 0) {
|
||||
this->port2 = this->port1;
|
||||
this->port1 = port2;
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
int GameEntry::compare(const GameEntry* ge)
|
||||
{
|
||||
if (this->addr.s_addr > ge->addr.s_addr)
|
||||
|
@ -14,5 +33,36 @@ int GameEntry::compare(const GameEntry* ge)
|
|||
if (this->port1 < ge->port1)
|
||||
return 1;
|
||||
|
||||
// only compare IP:port
|
||||
// gameid and port2 are useless
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GameEntry::hash(int max)
|
||||
{
|
||||
unsigned int hash = 0x12345678;
|
||||
|
||||
// IP
|
||||
hash = ((hash<<5) ^ (hash>>27)) ^ ((addr.s_addr>>0) & 0xFF);
|
||||
hash = ((hash<<5) ^ (hash>>27)) ^ ((addr.s_addr>>8) & 0xFF);
|
||||
hash = ((hash<<5) ^ (hash>>27)) ^ ((addr.s_addr>>16) & 0xFF);
|
||||
hash = ((hash<<5) ^ (hash>>27)) ^ ((addr.s_addr>>24) & 0xFF);
|
||||
|
||||
// port
|
||||
hash = ((hash<<5) ^ (hash>>27)) ^ ((port1>>0) & 0xFF);
|
||||
hash = ((hash<<5) ^ (hash>>27)) ^ ((port1>>8) & 0xFF);
|
||||
|
||||
return hash % max;
|
||||
}
|
||||
|
||||
void GameEntry::update()
|
||||
{
|
||||
modtime = time(NULL);
|
||||
}
|
||||
|
||||
int GameEntry::show(char* buf, int size)
|
||||
{
|
||||
return snprintf(buf, size, "(%2d:%15s:%5d:%5d)",
|
||||
this->gameid, inet_ntoa(this->addr),
|
||||
this->port1, this->port2);
|
||||
}
|
||||
|
|
12
gameentry.h
12
gameentry.h
|
@ -4,12 +4,18 @@
|
|||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
class GameEntry {
|
||||
#include "netpkt.h"
|
||||
|
||||
class GameEntry : private ListEntry<GameEntry> {
|
||||
public:
|
||||
GameEntry() {};
|
||||
~GameEntry() {};
|
||||
GameEntry(int gameid, NetPkt* pkt, int port2);
|
||||
~GameEntry() {}
|
||||
|
||||
int compare(const GameEntry* ge);
|
||||
int hash(int max);
|
||||
void update();
|
||||
|
||||
int show(char* buf, int size);
|
||||
|
||||
struct in_addr addr;
|
||||
int port1;
|
||||
|
|
118
gamelist.cpp
118
gamelist.cpp
|
@ -3,43 +3,123 @@
|
|||
|
||||
#define DEFAULT_TIMEOUT 180
|
||||
|
||||
/*
|
||||
** TODO: replace list with sorted list, or even better with a hash
|
||||
*/
|
||||
|
||||
GameList::GameList(Config& conf)
|
||||
: lastUpdate(0)
|
||||
{
|
||||
int interval = conf.getInteger("global", "game_timeout", DEFAULT_TIMEOUT);
|
||||
TimerService::registerTimer(new Timer(new CleanupEvent(*this), interval));
|
||||
timeout = conf.getInteger("global", "game_timeout", DEFAULT_TIMEOUT);
|
||||
TimerService::registerTimer(new Timer(new CleanupEvent(*this), timeout));
|
||||
}
|
||||
|
||||
GameList::~GameList()
|
||||
{
|
||||
while (!glist.isEmpty())
|
||||
delete glist.get();
|
||||
Iterator<GameEntry>* it = createIterator();
|
||||
while (it->hasNext())
|
||||
delete it->next();
|
||||
|
||||
delete it;
|
||||
}
|
||||
|
||||
void GameList::cleanup()
|
||||
{
|
||||
long now = time(NULL);
|
||||
|
||||
Iterator<GameEntry>* it = createIterator();
|
||||
while (it->hasNext()) {
|
||||
GameEntry* ge = it->next();
|
||||
|
||||
if (ge->modtime + timeout <= now) {
|
||||
it->remove();
|
||||
|
||||
char buf[64];
|
||||
ge->show(buf, sizeof(buf));
|
||||
LogSystem::log(LOG_NOTICE, "Game Timeout: %s", buf);
|
||||
delete ge;
|
||||
}
|
||||
}
|
||||
delete it;
|
||||
}
|
||||
|
||||
long GameList::getLastUpdate()
|
||||
void GameList::addGame(int gameid, NetPkt* pkt, int port2)
|
||||
{
|
||||
return lastUpdate;
|
||||
GameEntry* ge = new GameEntry(gameid, pkt, port2);
|
||||
int hash = ge->hash(MAX_BUCKETS);
|
||||
bool found = false;
|
||||
|
||||
Iterator<GameEntry>* it = buckets[hash].createIterator();
|
||||
while (it->hasNext()) {
|
||||
GameEntry* tmp = it->next();
|
||||
if (ge->compare(tmp) == 0) {
|
||||
tmp->update();
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
char buf[64];
|
||||
ge->show(buf, sizeof(buf));
|
||||
LogSystem::log(LOG_NOTICE, "Adding Game : %s", buf);
|
||||
|
||||
buckets[hash].add(ge);
|
||||
|
||||
} else {
|
||||
delete ge;
|
||||
}
|
||||
|
||||
// it holds the lock!
|
||||
delete it;
|
||||
}
|
||||
|
||||
Iterator<GameEntry>* GameList::createIterator()
|
||||
{
|
||||
return glist.createIterator();
|
||||
return new GameListIterator(this);
|
||||
}
|
||||
|
||||
void GameList::addGame(int gameid, NetPkt* pkt, int port2, bool swap)
|
||||
|
||||
GameList::GameListIterator::GameListIterator(GameList* gl)
|
||||
: gl(gl), it(0)
|
||||
{
|
||||
char buf[64];
|
||||
pkt->show(buf, sizeof(buf));
|
||||
LogSystem::log(LOG_NOTICE, "Adding Game %d: %s", gameid, buf);
|
||||
|
||||
glist.add(new GameEntry());
|
||||
lastUpdate++;
|
||||
gl->mutex.lock();
|
||||
reset();
|
||||
}
|
||||
|
||||
GameList::GameListIterator::~GameListIterator()
|
||||
{
|
||||
delete it;
|
||||
gl->mutex.unlock();
|
||||
}
|
||||
|
||||
bool GameList::GameListIterator::hasNext()
|
||||
{
|
||||
if (it->hasNext())
|
||||
return true;
|
||||
|
||||
while (bucket < MAX_BUCKETS -1) {
|
||||
delete it;
|
||||
bucket++;
|
||||
|
||||
it = gl->buckets[bucket].createIterator();
|
||||
if (it->hasNext())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
GameEntry* GameList::GameListIterator::next()
|
||||
{
|
||||
return it->next();
|
||||
}
|
||||
|
||||
void GameList::GameListIterator::remove()
|
||||
{
|
||||
it->remove();
|
||||
}
|
||||
|
||||
void GameList::GameListIterator::reset()
|
||||
{
|
||||
if (it != NULL)
|
||||
delete it;
|
||||
|
||||
bucket = 0;
|
||||
it = gl->buckets[bucket].createIterator();
|
||||
}
|
||||
|
|
33
gamelist.h
33
gamelist.h
|
@ -6,18 +6,19 @@
|
|||
#include "gameentry.h"
|
||||
#include "timerservice.h"
|
||||
#include "list.h"
|
||||
#include "mutex.h"
|
||||
|
||||
// 127 is prime!
|
||||
#define MAX_BUCKETS 127
|
||||
|
||||
class GameList {
|
||||
public:
|
||||
GameList(Config& conf);
|
||||
~GameList();
|
||||
|
||||
void addGame(int gameid, NetPkt* pkt, int port2 = 0, bool swap = false);
|
||||
|
||||
long getLastUpdate();
|
||||
Iterator<GameEntry>* createIterator();
|
||||
|
||||
void cleanup();
|
||||
void addGame(int gameid, NetPkt* pkt, int port2 = 0);
|
||||
Iterator<GameEntry>* createIterator();
|
||||
|
||||
protected:
|
||||
GameList(const GameList& gl);
|
||||
|
@ -34,8 +35,26 @@ private:
|
|||
GameList& gl;
|
||||
};
|
||||
|
||||
List<GameEntry> glist;
|
||||
long lastUpdate;
|
||||
class GameListIterator : public Iterator<GameEntry> {
|
||||
public:
|
||||
GameListIterator(GameList* gl);
|
||||
~GameListIterator();
|
||||
|
||||
bool hasNext();
|
||||
GameEntry* next();
|
||||
void remove();
|
||||
void reset();
|
||||
|
||||
private:
|
||||
GameList* gl;
|
||||
Iterator<GameEntry>* it;
|
||||
int bucket;
|
||||
};
|
||||
|
||||
Mutex mutex;
|
||||
List<GameEntry> buckets[MAX_BUCKETS];
|
||||
|
||||
int timeout;
|
||||
};
|
||||
|
||||
#endif // _GAMELIST_H_
|
||||
|
|
|
@ -35,7 +35,7 @@ int GameParser::execute(void* arg)
|
|||
|
||||
p = pkt->showfull();
|
||||
LogSystem::log(LOG_DEBUG, "%s", p);
|
||||
delete p;
|
||||
delete [] p;
|
||||
delete pkt;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
scan_port 7130
|
||||
|
||||
# broadcast scan every X seconds
|
||||
scan_interval 30
|
||||
scan_interval 60
|
||||
|
||||
# use this interface(s)
|
||||
scan_deny_iface
|
||||
|
||||
# server timeout after X seconds
|
||||
game_timeout 30
|
||||
game_timeout 180
|
||||
|
||||
# master answers with this source IP
|
||||
master_ip 0.0.0.0
|
||||
|
@ -20,6 +20,3 @@ rebuild_interval 5
|
|||
# logging
|
||||
logfile hlswmaster.log
|
||||
logprio DEBUG
|
||||
|
||||
[hlswproxy]
|
||||
master_ip 10.10.0.30 10.10.0.31
|
||||
|
|
|
@ -33,6 +33,11 @@ static struct option opts[] = {
|
|||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
LogSystem::init(DEFAULT_LOGPRIO, new StdErrLog());
|
||||
|
|
105
hlswserver.cpp
105
hlswserver.cpp
|
@ -22,45 +22,7 @@ struct hlsw_entry {
|
|||
#define HLSW_MAX_PACKET_SIZE (sizeof(hlsw_header) + 140 * sizeof(struct hlsw_entry))
|
||||
#define DEFAULT_REBUILD_INTERVAL 5
|
||||
|
||||
HlswServer::HlswPacket::HlswPacket(HlswPacket* next)
|
||||
: NetPkt(HLSW_MAX_PACKET_SIZE), next(next)
|
||||
{
|
||||
memcpy((void*)data, hlsw_header, sizeof(hlsw_header));
|
||||
size = sizeof(hlsw_header);
|
||||
}
|
||||
|
||||
HlswServer::HlswPacket::~HlswPacket()
|
||||
{
|
||||
if (next)
|
||||
delete next;
|
||||
}
|
||||
|
||||
bool HlswServer::HlswPacket::addGame(GameEntry* ge)
|
||||
{
|
||||
if (size >= HLSW_MAX_PACKET_SIZE)
|
||||
return false;
|
||||
|
||||
struct hlsw_entry tmp;
|
||||
tmp.gameid = ge->gameid;
|
||||
tmp.ip = ge->addr.s_addr;
|
||||
tmp.port1 = ge->port1;
|
||||
tmp.port2 = ge->port2;
|
||||
|
||||
memcpy((void*)(data + size), &tmp, sizeof(tmp));
|
||||
size += sizeof(tmp);
|
||||
return true;
|
||||
}
|
||||
|
||||
void HlswServer::HlswPacket::send(Socket* socket, struct sockaddr_in* dst)
|
||||
{
|
||||
if (next)
|
||||
next->send(socket, dst);
|
||||
|
||||
socket->sendto(this, dst);
|
||||
}
|
||||
|
||||
HlswServer::HlswServer(Config& conf, GameList& glist)
|
||||
: lastUpdate(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);
|
||||
|
@ -74,11 +36,14 @@ HlswServer::HlswServer(Config& conf, GameList& glist)
|
|||
int interval = conf.getInteger("global", "rebuild_interval", DEFAULT_REBUILD_INTERVAL);
|
||||
TimerService::registerTimer(new Timer(new RebuildEvent(*this, glist), interval));
|
||||
|
||||
pktlist = new HlswPacket(NULL);
|
||||
pktlist = new List<NetPkt>();
|
||||
}
|
||||
|
||||
HlswServer::~HlswServer()
|
||||
{
|
||||
while (!pktlist->isEmpty())
|
||||
delete pktlist->get();
|
||||
|
||||
delete pktlist;
|
||||
delete socket;
|
||||
}
|
||||
|
@ -87,39 +52,61 @@ int HlswServer::execute(void* arg)
|
|||
{
|
||||
while (1) {
|
||||
NetPkt* pkt = socket->recv();
|
||||
if (!pkt->compare(0, hlsw_header, sizeof(hlsw_header))) {
|
||||
if (!pkt->compare(0, hlsw_header, strlen(hlsw_header))) {
|
||||
LogSystem::log(LOG_NOTICE, "HlswServer: not a hlsw packet");
|
||||
continue;
|
||||
}
|
||||
|
||||
mutex.lock();
|
||||
pktlist->send(socket, pkt->getAddress());
|
||||
mutex.unlock();
|
||||
Iterator<NetPkt>* it = pktlist->createIterator();
|
||||
while (it->hasNext())
|
||||
socket->sendto(it->next(), pkt->getAddress());
|
||||
|
||||
delete it;
|
||||
mutex.unlock();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HlswServer::rebuild(GameList& glist) {
|
||||
if (glist.getLastUpdate() > lastUpdate) {
|
||||
HlswPacket* newlist = new HlswPacket(NULL);
|
||||
List<NetPkt>* newlist = new List<NetPkt>();
|
||||
|
||||
Iterator<GameEntry>* it = glist.createIterator();
|
||||
while (it->hasNext()) {
|
||||
GameEntry* d = it->next();
|
||||
if (!newlist->addGame(d)) {
|
||||
newlist = new HlswPacket(newlist);
|
||||
newlist->addGame(d);
|
||||
}
|
||||
// header
|
||||
NetPkt* pkt = new NetPkt(HLSW_MAX_PACKET_SIZE);
|
||||
pkt->append(hlsw_header, sizeof(hlsw_header));
|
||||
newlist->add(pkt);
|
||||
|
||||
Iterator<GameEntry>* it = glist.createIterator();
|
||||
while (it->hasNext()) {
|
||||
NetPkt* last = newlist->peekTail();
|
||||
if (last->getSize() == HLSW_MAX_PACKET_SIZE) {
|
||||
last = new NetPkt(HLSW_MAX_PACKET_SIZE);
|
||||
last->append(hlsw_header, sizeof(hlsw_header));
|
||||
newlist->add(last);
|
||||
}
|
||||
lastUpdate = glist.getLastUpdate();
|
||||
delete it;
|
||||
|
||||
mutex.lock();
|
||||
HlswPacket* oldlist = pktlist;
|
||||
pktlist = newlist;
|
||||
mutex.unlock();
|
||||
|
||||
delete oldlist;
|
||||
addGame(last, it->next());
|
||||
}
|
||||
delete it;
|
||||
|
||||
mutex.lock();
|
||||
List<NetPkt>* oldlist = pktlist;
|
||||
pktlist = newlist;
|
||||
mutex.unlock();
|
||||
|
||||
while (!oldlist->isEmpty())
|
||||
delete oldlist->get();
|
||||
|
||||
delete oldlist;
|
||||
}
|
||||
|
||||
void HlswServer::addGame(NetPkt* pkt, GameEntry* entry)
|
||||
{
|
||||
struct hlsw_entry tmp;
|
||||
tmp.gameid = entry->gameid;
|
||||
tmp.ip = entry->addr.s_addr;
|
||||
tmp.port1 = entry->port1;
|
||||
tmp.port2 = entry->port2;
|
||||
|
||||
pkt->append((char*)&tmp, sizeof(tmp));
|
||||
}
|
||||
|
|
18
hlswserver.h
18
hlswserver.h
|
@ -34,23 +34,11 @@ private:
|
|||
GameList& gl;
|
||||
};
|
||||
|
||||
class HlswPacket : private NetPkt {
|
||||
public:
|
||||
HlswPacket(HlswPacket* next);
|
||||
~HlswPacket();
|
||||
void addGame(NetPkt* pkt, GameEntry* entry);
|
||||
|
||||
bool addGame(GameEntry* ge);
|
||||
void send(Socket* socket, struct sockaddr_in* dst);
|
||||
|
||||
private:
|
||||
HlswPacket* next;
|
||||
};
|
||||
|
||||
Socket* socket;
|
||||
HlswPacket* pktlist;
|
||||
List<NetPkt>* pktlist;
|
||||
Mutex mutex;
|
||||
|
||||
long lastUpdate;
|
||||
Socket* socket;
|
||||
};
|
||||
|
||||
#endif // _HLSWSERVER_H_
|
||||
|
|
150
list.cpp
150
list.cpp
|
@ -1,150 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "list.h"
|
||||
|
||||
ListBase::ListBase()
|
||||
{
|
||||
}
|
||||
|
||||
ListBase::~ListBase()
|
||||
{
|
||||
AutoMutex am(mutex);
|
||||
while(!head.isEmpty())
|
||||
head.getNext()->del();
|
||||
}
|
||||
|
||||
void ListBase::add(const void* part)
|
||||
{
|
||||
ListEntryBase* entry = new ListEntryBase(part);
|
||||
|
||||
AutoMutex am(mutex);
|
||||
entry->add(&head, head.getNext());
|
||||
}
|
||||
|
||||
void ListBase::addTail(const void* part)
|
||||
{
|
||||
ListEntryBase* entry = new ListEntryBase(part);
|
||||
|
||||
AutoMutex am(mutex);
|
||||
entry->add(head.getPrev(), &head);
|
||||
}
|
||||
|
||||
void* ListBase::get()
|
||||
{
|
||||
AutoMutex am(mutex);
|
||||
ListEntryBase* entry = head.getNext();
|
||||
void* retval = entry->getPart();
|
||||
|
||||
if (!head.isEmpty()) {
|
||||
entry->del();
|
||||
delete entry;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
void* ListBase::getTail()
|
||||
{
|
||||
AutoMutex am(mutex);
|
||||
ListEntryBase* entry = head.getPrev();
|
||||
void* retval = entry->getPart();
|
||||
|
||||
if (!head.isEmpty()) {
|
||||
entry->del();
|
||||
delete entry;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool ListBase::isEmpty() const
|
||||
{
|
||||
AutoMutex am((Mutex&)mutex);
|
||||
return head.isEmpty();
|
||||
}
|
||||
|
||||
IteratorBase* ListBase::createIterator()
|
||||
{
|
||||
return new ListIteratorBase(this);
|
||||
}
|
||||
|
||||
ListBase::ListEntryBase::ListEntryBase(const void* part)
|
||||
: prev(this), next(this), part(part)
|
||||
{
|
||||
}
|
||||
|
||||
ListBase::ListEntryBase::~ListEntryBase()
|
||||
{
|
||||
}
|
||||
|
||||
void ListBase::ListEntryBase::add(ListEntryBase* prev_, ListEntryBase* next_)
|
||||
{
|
||||
this->next = next_;
|
||||
this->prev = prev_;
|
||||
next_->prev = this;
|
||||
prev_->next = this;
|
||||
}
|
||||
|
||||
void ListBase::ListEntryBase::del()
|
||||
{
|
||||
next->prev = prev;
|
||||
prev->next = next;
|
||||
next = prev = this;
|
||||
}
|
||||
|
||||
bool ListBase::ListEntryBase::isEmpty() const
|
||||
{
|
||||
return (this->prev == this) && (this->next == this);
|
||||
}
|
||||
|
||||
void* ListBase::ListEntryBase::getPart() const
|
||||
{
|
||||
// const void* -> void*
|
||||
return (void*)part;
|
||||
}
|
||||
|
||||
ListBase::ListEntryBase* ListBase::ListEntryBase::getPrev() const
|
||||
{
|
||||
return prev;
|
||||
}
|
||||
|
||||
ListBase::ListEntryBase* ListBase::ListEntryBase::getNext() const
|
||||
{
|
||||
return next;
|
||||
}
|
||||
|
||||
ListBase::ListIteratorBase::ListIteratorBase(ListBase* list)
|
||||
: list(list)
|
||||
{
|
||||
list->mutex.lock();
|
||||
reset();
|
||||
}
|
||||
|
||||
ListBase::ListIteratorBase::~ListIteratorBase()
|
||||
{
|
||||
list->mutex.unlock();
|
||||
}
|
||||
|
||||
bool ListBase::ListIteratorBase::hasNext()
|
||||
{
|
||||
return (pos->getNext() != &list->head);
|
||||
}
|
||||
|
||||
void* ListBase::ListIteratorBase::next()
|
||||
{
|
||||
pos = pos->getNext();
|
||||
return pos->getPart();
|
||||
}
|
||||
|
||||
void ListBase::ListIteratorBase::remove()
|
||||
{
|
||||
ListEntryBase* tmp = pos->getPrev();
|
||||
pos->del();
|
||||
pos = tmp;
|
||||
}
|
||||
|
||||
void ListBase::ListIteratorBase::reset()
|
||||
{
|
||||
pos = &list->head;
|
||||
}
|
||||
|
314
list.h
314
list.h
|
@ -3,141 +3,229 @@
|
|||
|
||||
#include "mutex.h"
|
||||
|
||||
class IteratorBase {
|
||||
public:
|
||||
virtual ~IteratorBase() {}
|
||||
virtual bool hasNext() =0;
|
||||
virtual void* next() =0;
|
||||
virtual void remove() =0;
|
||||
virtual void reset() =0;
|
||||
|
||||
protected:
|
||||
IteratorBase() {}
|
||||
IteratorBase(const IteratorBase& it);
|
||||
IteratorBase& operator=(const IteratorBase& it);
|
||||
};
|
||||
|
||||
class ListBase {
|
||||
public:
|
||||
ListBase();
|
||||
~ListBase();
|
||||
|
||||
void add(const void* part);
|
||||
void addTail(const void* part);
|
||||
void* get();
|
||||
void* getTail();
|
||||
bool isEmpty() const;
|
||||
|
||||
IteratorBase* createIterator();
|
||||
|
||||
protected:
|
||||
ListBase(const ListBase& l);
|
||||
ListBase& operator=(const ListBase& l);
|
||||
|
||||
class ListEntryBase {
|
||||
public:
|
||||
ListEntryBase(const void* part = 0);
|
||||
~ListEntryBase();
|
||||
|
||||
void add(ListEntryBase* prev, ListEntryBase* next);
|
||||
void del();
|
||||
bool isEmpty() const;
|
||||
|
||||
void* getPart() const;
|
||||
ListEntryBase* getPrev() const;
|
||||
ListEntryBase* getNext() const;
|
||||
|
||||
protected:
|
||||
ListEntryBase(const ListEntryBase& l);
|
||||
ListEntryBase& operator=(const ListEntryBase& l);
|
||||
|
||||
private:
|
||||
ListEntryBase* prev;
|
||||
ListEntryBase* next;
|
||||
const void* part;
|
||||
};
|
||||
|
||||
class ListIteratorBase : public IteratorBase {
|
||||
public:
|
||||
ListIteratorBase(ListBase* list);
|
||||
~ListIteratorBase();
|
||||
|
||||
bool hasNext();
|
||||
void* next();
|
||||
void remove();
|
||||
void reset();
|
||||
|
||||
private:
|
||||
ListBase* list;
|
||||
ListEntryBase* pos;
|
||||
};
|
||||
|
||||
private:
|
||||
ListEntryBase head;
|
||||
Mutex mutex;
|
||||
|
||||
friend class ListIteratorBase;
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
class Iterator : public IteratorBase {
|
||||
class Iterator {
|
||||
public:
|
||||
virtual T* next() =0;
|
||||
virtual ~Iterator() {}
|
||||
virtual bool hasNext() =0;
|
||||
virtual T* next() =0;
|
||||
virtual void remove() =0;
|
||||
virtual void reset() =0;
|
||||
|
||||
protected:
|
||||
Iterator() {}
|
||||
Iterator(const Iterator& it);
|
||||
Iterator& operator=(const Iterator& it);
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
class NullIterator : public Iterator<T> {
|
||||
public:
|
||||
NullIterator() {}
|
||||
~NullIterator() {}
|
||||
|
||||
bool hasNext() { return false; }
|
||||
T* next() { return NULL; }
|
||||
void remove() {}
|
||||
void reset() {}
|
||||
virtual ~NullIterator() {}
|
||||
virtual bool hasNext() { return false; }
|
||||
virtual T* next() { return NULL; }
|
||||
virtual void remove() {}
|
||||
virtual void reset() {}
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
class List : public ListBase {
|
||||
class ListEntry;
|
||||
|
||||
|
||||
template <class T>
|
||||
class List {
|
||||
public:
|
||||
List() {}
|
||||
List() : head(0), tail(0) {}
|
||||
~List() {}
|
||||
|
||||
void add(const T* part) { ListBase::add(part); }
|
||||
void addTail(const T* part) { ListBase::addTail(part); }
|
||||
T* get() { return (T*)ListBase::get(); }
|
||||
T* getTail() { return (T*)ListBase::getTail(); }
|
||||
bool isEmpty() const { return ListBase::isEmpty(); }
|
||||
void add(T* entry)
|
||||
{
|
||||
ListEntry<T>* tmp = (ListEntry<T>*)entry;
|
||||
tmp->next = NULL;
|
||||
|
||||
Iterator<T>* createIterator() const { return new ListIteratorRO<T>(this); }
|
||||
Iterator<T>* createIteratorRW() { return new ListIteratorRW<T>(this); }
|
||||
if (!head)
|
||||
head = tmp;
|
||||
|
||||
if (tail)
|
||||
tail->next = tmp;
|
||||
tail = tmp;
|
||||
}
|
||||
|
||||
T* get()
|
||||
{
|
||||
ListEntry<T>* retval = head;
|
||||
|
||||
if (head)
|
||||
head = head->next;
|
||||
|
||||
if (!head)
|
||||
tail = NULL;
|
||||
|
||||
return (T*)retval;
|
||||
}
|
||||
|
||||
T* peekHead()
|
||||
{
|
||||
return (T*)head;
|
||||
}
|
||||
|
||||
T* peekTail()
|
||||
{
|
||||
return (T*)tail;
|
||||
}
|
||||
|
||||
bool isEmpty()
|
||||
{
|
||||
return (head == NULL);
|
||||
}
|
||||
|
||||
Iterator<T>* createIterator()
|
||||
{
|
||||
return new ListIterator<T>(this);
|
||||
}
|
||||
|
||||
protected:
|
||||
List(const List& l);
|
||||
List& operator=(const List& l);
|
||||
|
||||
template <class TT>
|
||||
class ListIterator : public Iterator<TT> {
|
||||
public:
|
||||
ListIterator(List<TT>* list)
|
||||
: list(list)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
virtual ~ListIterator() {}
|
||||
|
||||
virtual bool hasNext()
|
||||
{
|
||||
return (pos == NULL) ? (list->head != NULL) : (pos->next != NULL);
|
||||
}
|
||||
|
||||
virtual TT* next()
|
||||
{
|
||||
prev = pos;
|
||||
pos = (pos == NULL) ? list->head : pos->next;
|
||||
return (TT*)pos;
|
||||
}
|
||||
|
||||
virtual void remove()
|
||||
{
|
||||
// remove pre-head -> bail out
|
||||
if (pos == NULL)
|
||||
return;
|
||||
|
||||
// remove first
|
||||
if (pos == list->head)
|
||||
list->head = pos->next;
|
||||
|
||||
// remove middle
|
||||
if (prev)
|
||||
prev->next = pos->next;
|
||||
|
||||
// remove last
|
||||
if (pos == list->tail)
|
||||
list->tail = (prev == NULL) ? NULL : prev;
|
||||
|
||||
pos = prev;
|
||||
}
|
||||
|
||||
virtual void reset()
|
||||
{
|
||||
pos = NULL;
|
||||
prev = NULL;
|
||||
}
|
||||
|
||||
protected:
|
||||
ListIterator(const ListIterator& li);
|
||||
ListIterator& operator=(const ListIterator& li);
|
||||
|
||||
List<TT>* list;
|
||||
|
||||
private:
|
||||
ListEntry<TT>* pos;
|
||||
ListEntry<TT>* prev;
|
||||
};
|
||||
|
||||
private:
|
||||
ListEntry<T> *head;
|
||||
ListEntry<T> *tail;
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
class ListEntry {
|
||||
friend class List<T>;
|
||||
friend class List<T>::ListIterator<T>;
|
||||
public:
|
||||
ListEntry() {}
|
||||
~ListEntry() {}
|
||||
|
||||
private:
|
||||
ListEntry* next;
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
class LockedList : private List<T> {
|
||||
public:
|
||||
LockedList() {}
|
||||
~LockedList() {}
|
||||
void add(T* entry)
|
||||
{
|
||||
AutoMutex am(mutex);
|
||||
List<T>::add(entry);
|
||||
}
|
||||
|
||||
T* get()
|
||||
{
|
||||
AutoMutex am(mutex);
|
||||
return List<T>::get();
|
||||
}
|
||||
|
||||
T* peekFirst()
|
||||
{
|
||||
return NULL; // not with lockedlist
|
||||
}
|
||||
|
||||
T* peekLast()
|
||||
{
|
||||
return NULL; // not with lockedlist
|
||||
}
|
||||
|
||||
bool isEmpty()
|
||||
{
|
||||
AutoMutex am(mutex);
|
||||
return List<T>::isEmpty();
|
||||
}
|
||||
|
||||
Iterator<T>* createIterator()
|
||||
{
|
||||
return new LockedListIterator<T>(this);
|
||||
}
|
||||
|
||||
private:
|
||||
template <class TT>
|
||||
class ListIteratorRO : public Iterator<TT>, private ListIteratorBase {
|
||||
class LockedListIterator : public List<TT>::ListIterator<TT> {
|
||||
public:
|
||||
ListIteratorRO(const List<TT>* list) : ListIteratorBase((ListBase*)list) {}
|
||||
~ListIteratorRO() {}
|
||||
LockedListIterator(LockedList<TT>* list)
|
||||
: List<TT>::ListIterator<TT>(list)
|
||||
{
|
||||
list->mutex.lock();
|
||||
}
|
||||
|
||||
bool hasNext() { return ListIteratorBase::hasNext(); }
|
||||
TT* next() { return (TT*)ListIteratorBase::next(); }
|
||||
void remove() {}
|
||||
void reset() { ListIteratorBase::reset(); }
|
||||
};
|
||||
|
||||
template <class TT>
|
||||
class ListIteratorRW : public Iterator<TT>, private ListIteratorBase {
|
||||
public:
|
||||
ListIteratorRW(List<TT>* list) : ListIteratorBase(list) {}
|
||||
~ListIteratorRW() {}
|
||||
|
||||
bool hasNext() { return ListIteratorBase::hasNext(); }
|
||||
TT* next() { return (TT*)ListIteratorBase::next(); }
|
||||
void remove() { ListIteratorBase::remove(); }
|
||||
void reset() { ListIteratorBase::reset(); }
|
||||
virtual ~LockedListIterator()
|
||||
{
|
||||
((LockedList<TT>*)list)->mutex.unlock();
|
||||
}
|
||||
};
|
||||
|
||||
Mutex mutex;
|
||||
};
|
||||
|
||||
#endif //_LIST_H_
|
||||
|
|
|
@ -45,11 +45,8 @@ ModGameSpy1::ModGameSpy1()
|
|||
|
||||
ModGameSpy1::~ModGameSpy1()
|
||||
{
|
||||
while (!list.isEmpty()) {
|
||||
MultiPart* mp = list.get();
|
||||
delete mp->pkt;
|
||||
delete mp;
|
||||
}
|
||||
while (!list.isEmpty())
|
||||
delete list.get();
|
||||
}
|
||||
|
||||
void ModGameSpy1::scan(MultiSock* msock)
|
||||
|
@ -98,7 +95,7 @@ int ModGameSpy1::parse(NetPkt* pkt, GameList* glist)
|
|||
/* non-final multi-part */
|
||||
} else if (!final) {
|
||||
LogSystem::log(LOG_DEBUG, "non final %s (%d/%d)", buf, queryid, subid);
|
||||
list.addTail(new MultiPart(pkt, queryid, subid));
|
||||
list.add(new MultiPart(pkt, queryid, subid));
|
||||
return PARSE_ACCEPT_FREED; // parser must not free pkt
|
||||
|
||||
/* final multipart */
|
||||
|
@ -125,9 +122,14 @@ ModGameSpy1::MultiPart::MultiPart(NetPkt* pkt, int queryid, int subid)
|
|||
timeout = time(NULL) + MODGS1_GC_TIMEOUT;
|
||||
}
|
||||
|
||||
ModGameSpy1::MultiPart::~MultiPart()
|
||||
{
|
||||
delete pkt;
|
||||
}
|
||||
|
||||
NetPkt* ModGameSpy1::merge(NetPkt* pkt, int queryid, int subid)
|
||||
{
|
||||
Iterator<MultiPart>* it = list.createIteratorRW();
|
||||
Iterator<MultiPart>* it = list.createIterator();
|
||||
|
||||
NetPkt* tmppkt = new NetPkt(NULL, 0);
|
||||
tmppkt->setAddress(pkt->getAddress());
|
||||
|
@ -148,8 +150,8 @@ NetPkt* ModGameSpy1::merge(NetPkt* pkt, int queryid, int subid)
|
|||
found = true;
|
||||
|
||||
if (searchid == mp->subid) {
|
||||
tmppkt->append(mp->pkt);
|
||||
delete mp->pkt;
|
||||
tmppkt->merge(mp->pkt);
|
||||
delete mp;
|
||||
searchid++;
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +161,7 @@ NetPkt* ModGameSpy1::merge(NetPkt* pkt, int queryid, int subid)
|
|||
|
||||
delete it;
|
||||
|
||||
tmppkt->append(pkt);
|
||||
tmppkt->merge(pkt);
|
||||
|
||||
if (!found) {
|
||||
delete tmppkt;
|
||||
|
@ -171,7 +173,7 @@ NetPkt* ModGameSpy1::merge(NetPkt* pkt, int queryid, int subid)
|
|||
|
||||
void ModGameSpy1::gc()
|
||||
{
|
||||
Iterator<MultiPart>* it = list.createIteratorRW();
|
||||
Iterator<MultiPart>* it = list.createIterator();
|
||||
long now = time(NULL);
|
||||
char buf[64];
|
||||
|
||||
|
@ -182,9 +184,9 @@ void ModGameSpy1::gc()
|
|||
LogSystem::log(LOG_NOTICE, "ModGameSpy1 gc removed: %s (%d/%d)",
|
||||
buf, mp->queryid, mp->subid);
|
||||
it->remove();
|
||||
delete mp;
|
||||
}
|
||||
}
|
||||
|
||||
delete it;
|
||||
}
|
||||
|
||||
|
@ -281,7 +283,7 @@ int ModGameSpy1::parse_real(NetPkt* pkt, GameList* glist, int gameid)
|
|||
* beide ports in die serverliste uebernehmen
|
||||
*/
|
||||
if ((offset != -1) && (port != pkt->getPort())) {
|
||||
glist->addGame(gameid, pkt, port, true);
|
||||
glist->addGame(gameid, pkt, port);
|
||||
|
||||
} else {
|
||||
glist->addGame(gameid, pkt);
|
||||
|
|
|
@ -17,10 +17,10 @@ public:
|
|||
void gc();
|
||||
|
||||
private:
|
||||
class MultiPart {
|
||||
class MultiPart : private ListEntry<MultiPart> {
|
||||
public:
|
||||
MultiPart(NetPkt* pkt, int queryid, int subid);
|
||||
~MultiPart() {}
|
||||
~MultiPart();
|
||||
|
||||
NetPkt* pkt;
|
||||
int queryid;
|
||||
|
@ -42,7 +42,7 @@ private:
|
|||
NetPkt* merge(NetPkt* pkt, int queryid, int subid);
|
||||
int parse_real(NetPkt* pkt, GameList* glist, int gameid);
|
||||
|
||||
List<MultiPart> list;
|
||||
LockedList<MultiPart> list;
|
||||
};
|
||||
|
||||
#endif // _MODGAMESPY1_H_
|
||||
|
|
|
@ -78,7 +78,7 @@ int ModGameSpy2::parse(NetPkt* pkt, GameList* glist)
|
|||
* beide ports in die serverliste uebernehmen
|
||||
*/
|
||||
if ((pos2 != -1) && (port != pkt->getPort())) {
|
||||
glist->addGame(gameid, pkt, port, true);
|
||||
glist->addGame(gameid, pkt, port);
|
||||
|
||||
} else {
|
||||
glist->addGame(gameid, pkt);
|
||||
|
|
2
module.h
2
module.h
|
@ -64,7 +64,7 @@ struct game_ports {
|
|||
int gameid;
|
||||
};
|
||||
|
||||
class Module {
|
||||
class Module : private ListEntry<Module> {
|
||||
public:
|
||||
virtual ~Module() {};
|
||||
virtual void init(Config* conf) {}
|
||||
|
|
|
@ -16,7 +16,7 @@ void ModuleList::reg(Module* mod)
|
|||
{
|
||||
LogSystem::log(LOG_NOTICE, "Registering module '%s'", mod->getName());
|
||||
mod->init(&conf);
|
||||
mlist.addTail(mod);
|
||||
mlist.add(mod);
|
||||
}
|
||||
|
||||
void ModuleList::scan(MultiSock* msock)
|
||||
|
|
13
netpkt.cpp
13
netpkt.cpp
|
@ -163,7 +163,7 @@ bool NetPkt::sameAddress(NetPkt* pkt)
|
|||
(this->addr.sin_port == pkt->addr.sin_port);
|
||||
}
|
||||
|
||||
void NetPkt::append(NetPkt* pkt)
|
||||
void NetPkt::merge(NetPkt* pkt)
|
||||
{
|
||||
unsigned int new_alloc = size + pkt->size;
|
||||
|
||||
|
@ -179,3 +179,14 @@ void NetPkt::append(NetPkt* pkt)
|
|||
memcpy((void*)(data + size), pkt->data, pkt->size);
|
||||
size += pkt->size;
|
||||
}
|
||||
|
||||
bool NetPkt::append(const char* buf, unsigned int len)
|
||||
{
|
||||
if (alloc < size + len)
|
||||
return false;
|
||||
|
||||
memcpy((void*)(data + size), buf, len);
|
||||
size += len;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
7
netpkt.h
7
netpkt.h
|
@ -4,6 +4,8 @@
|
|||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "list.h"
|
||||
|
||||
#define PARSE_ACCEPT 1
|
||||
#define PARSE_ACCEPT_FREED 2
|
||||
#define PARSE_ACCEPT_FAKE 3
|
||||
|
@ -13,7 +15,7 @@
|
|||
/* avoid cyclic deps */
|
||||
class Socket;
|
||||
|
||||
class NetPkt {
|
||||
class NetPkt : private ListEntry<NetPkt> {
|
||||
friend class Socket;
|
||||
public:
|
||||
NetPkt(const char* data, int size);
|
||||
|
@ -33,7 +35,8 @@ public:
|
|||
struct sockaddr_in * getAddress();
|
||||
bool sameAddress(NetPkt* pkt);
|
||||
|
||||
void append(NetPkt* pkt);
|
||||
void merge(NetPkt* pkt);
|
||||
bool append(const char* buf, unsigned int len);
|
||||
|
||||
int getPort();
|
||||
int getSize();
|
||||
|
|
|
@ -9,7 +9,7 @@ RecvQueue::~RecvQueue()
|
|||
void RecvQueue::addPkt(NetPkt* pkt)
|
||||
{
|
||||
if (pkt != NULL) {
|
||||
pktList.addTail(pkt);
|
||||
pktList.add(pkt);
|
||||
pktCount.post();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ protected:
|
|||
|
||||
private:
|
||||
Semaphore pktCount;
|
||||
List<NetPkt> pktList;
|
||||
LockedList<NetPkt> pktList;
|
||||
};
|
||||
|
||||
#endif // _RECVQUEUE_H_
|
||||
|
|
Loading…
Reference in New Issue