mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
Fixed upnp issues
* Removed periodic Check and thread. * Added Shutdown. * switched to terminating background thread. * removed temporary lease. * A bit of a HACK - this class could be cleaned up significantly. Adding the start of forums/channels. * Dummy Interface and Forum data (so GUI work can start) * rough p3distrib - needs a lot of work. Added shutdown function to p3connmgr, to shutdown Upnp. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@493 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
20c9e7d224
commit
94371600be
@ -34,10 +34,10 @@ RSOBJ = $(BASE_OBJ) $(LOOP_OBJ) \
|
|||||||
$(GRP_OBJ) \
|
$(GRP_OBJ) \
|
||||||
$(OTHER_OBJ)
|
$(OTHER_OBJ)
|
||||||
|
|
||||||
TESTOBJ = xpgp_id.o net_test.o dht_test.o
|
TESTOBJ = xpgp_id.o net_test.o dht_test.o net_test1.o
|
||||||
#conn_test.o
|
#conn_test.o
|
||||||
|
|
||||||
TESTS = xpgp_id net_test dht_test
|
TESTS = xpgp_id net_test dht_test net_test1
|
||||||
#conn_test
|
#conn_test
|
||||||
|
|
||||||
|
|
||||||
@ -55,6 +55,9 @@ conn_test: conn_test.o
|
|||||||
net_test: net_test.o
|
net_test: net_test.o
|
||||||
$(CC) $(CFLAGS) -o net_test net_test.o $(LIBS)
|
$(CC) $(CFLAGS) -o net_test net_test.o $(LIBS)
|
||||||
|
|
||||||
|
net_test1: net_test1.o
|
||||||
|
$(CC) $(CFLAGS) -o net_test1 net_test1.o $(LIBS)
|
||||||
|
|
||||||
###############################################################
|
###############################################################
|
||||||
include $(RS_TOP_DIR)/scripts/rules.mk
|
include $(RS_TOP_DIR)/scripts/rules.mk
|
||||||
###############################################################
|
###############################################################
|
||||||
|
@ -45,7 +45,7 @@ const uint32_t RS_STUN_DONE = 0x0002;
|
|||||||
const uint32_t RS_STUN_LIST_MIN = 100;
|
const uint32_t RS_STUN_LIST_MIN = 100;
|
||||||
const uint32_t RS_STUN_FOUND_MIN = 10;
|
const uint32_t RS_STUN_FOUND_MIN = 10;
|
||||||
|
|
||||||
const uint32_t MAX_UPNP_INIT = 30; /* seconds UPnP timeout */
|
const uint32_t MAX_UPNP_INIT = 10; /* seconds UPnP timeout */
|
||||||
|
|
||||||
/****
|
/****
|
||||||
* #define CONN_DEBUG 1
|
* #define CONN_DEBUG 1
|
||||||
@ -300,6 +300,21 @@ void p3ConnectMgr::tick()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool p3ConnectMgr::shutdown() /* blocking shutdown call */
|
||||||
|
{
|
||||||
|
connMtx.lock(); /* LOCK MUTEX */
|
||||||
|
|
||||||
|
bool upnpActive = ownState.netMode & RS_NET_MODE_UPNP;
|
||||||
|
|
||||||
|
connMtx.unlock(); /* UNLOCK MUTEX */
|
||||||
|
|
||||||
|
if (upnpActive)
|
||||||
|
{
|
||||||
|
mUpnpMgr->shutdownUPnP();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void p3ConnectMgr::statusTick()
|
void p3ConnectMgr::statusTick()
|
||||||
{
|
{
|
||||||
|
@ -165,6 +165,8 @@ void setUpnpMgr(p3UpnpMgr *umgr) { mUpnpMgr = umgr; }
|
|||||||
bool checkNetAddress(); /* check our address is sensible */
|
bool checkNetAddress(); /* check our address is sensible */
|
||||||
|
|
||||||
/*************** External Control ****************/
|
/*************** External Control ****************/
|
||||||
|
bool shutdown(); /* blocking shutdown call */
|
||||||
|
|
||||||
bool retryConnect(std::string id);
|
bool retryConnect(std::string id);
|
||||||
|
|
||||||
bool getUPnPState();
|
bool getUPnPState();
|
||||||
|
@ -31,15 +31,16 @@
|
|||||||
#include "util/rsthreads.h"
|
#include "util/rsthreads.h"
|
||||||
#include "pqi/pqinetwork.h"
|
#include "pqi/pqinetwork.h"
|
||||||
|
|
||||||
class p3UpnpMgr: public RsThread
|
class p3UpnpMgr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual ~p3UpnpMgr() { return; }
|
virtual ~p3UpnpMgr() { return; }
|
||||||
|
|
||||||
/* External Interface */
|
/* External Interface */
|
||||||
virtual void enableUPnP(bool on) = 0;
|
virtual void enableUPnP(bool on) = 0; /* launches thread to start it up */
|
||||||
virtual void shutdownUPnP() = 0;
|
virtual void shutdownUPnP() = 0; /* blocking shutdown call */
|
||||||
|
virtual void restartUPnP() = 0; /* must be called if ports change */
|
||||||
|
|
||||||
virtual bool getUPnPEnabled() = 0;
|
virtual bool getUPnPEnabled() = 0;
|
||||||
virtual bool getUPnPActive() = 0;
|
virtual bool getUPnPActive() = 0;
|
||||||
|
120
libretroshare/src/rsiface/rsforums.h
Normal file
120
libretroshare/src/rsiface/rsforums.h
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
#ifndef RS_FORUM_GUI_INTERFACE_H
|
||||||
|
#define RS_FORUM_GUI_INTERFACE_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libretroshare/src/rsiface: rsforums.h
|
||||||
|
*
|
||||||
|
* RetroShare C++ Interface.
|
||||||
|
*
|
||||||
|
* Copyright 2007-2008 by Robert Fernie.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License Version 2 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "rsiface/rstypes.h"
|
||||||
|
|
||||||
|
#define RS_FORUM_PUBLIC 0x0001 /* anyone can publish */
|
||||||
|
#define RS_FORUM_PRIVATE 0x0002 /* anyone with key can publish */
|
||||||
|
#define RS_FORUM_ENCRYPTED 0x0004 /* need admin key */
|
||||||
|
|
||||||
|
#define RS_FORUM_ADMIN 0x0100 /* anyone can publish */
|
||||||
|
#define RS_FORUM_SUBSCRIBED 0x0200 /* anyone can publish */
|
||||||
|
|
||||||
|
|
||||||
|
class ForumInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ForumInfo() {}
|
||||||
|
std::string forumId;
|
||||||
|
std::wstring forumName;
|
||||||
|
std::wstring forumDesc;
|
||||||
|
|
||||||
|
uint32_t forumFlags;
|
||||||
|
uint32_t pop;
|
||||||
|
|
||||||
|
time_t lastPost;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ForumMsgInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ForumMsgInfo() {}
|
||||||
|
std::string forumId;
|
||||||
|
std::string threadId;
|
||||||
|
std::string msgId;
|
||||||
|
|
||||||
|
unsigned int msgflags;
|
||||||
|
|
||||||
|
std::wstring title;
|
||||||
|
std::wstring msg;
|
||||||
|
time_t ts;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ThreadInfoSummary
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ThreadInfoSummary() {}
|
||||||
|
|
||||||
|
std::string msgId;
|
||||||
|
std::string srcId;
|
||||||
|
|
||||||
|
uint32_t msgflags;
|
||||||
|
|
||||||
|
std::wstring title;
|
||||||
|
int count; /* file count */
|
||||||
|
time_t ts;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const ForumInfo &info);
|
||||||
|
std::ostream &operator<<(std::ostream &out, const ThreadInfoSummary &info);
|
||||||
|
std::ostream &operator<<(std::ostream &out, const ForumMsgInfo &info);
|
||||||
|
|
||||||
|
class RsForums;
|
||||||
|
extern RsForums *rsForums;
|
||||||
|
|
||||||
|
class RsForums
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
RsForums() { return; }
|
||||||
|
virtual ~RsForums() { return; }
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
|
||||||
|
virtual bool forumsChanged(std::list<std::string> &forumIds) = 0;
|
||||||
|
|
||||||
|
virtual bool getForumList(std::list<ForumInfo> &forumList) = 0;
|
||||||
|
virtual bool getForumThreadList(std::string fId, std::list<ThreadInfoSummary> &msgs) = 0;
|
||||||
|
virtual bool getForumThreadMsgList(std::string fId, std::string tId, std::list<ThreadInfoSummary> &msgs) = 0;
|
||||||
|
virtual bool getForumMessage(std::string fId, std::string mId, ForumMsgInfo &msg) = 0;
|
||||||
|
|
||||||
|
virtual bool ForumMessageSend(ForumMsgInfo &info) = 0;
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -329,9 +329,6 @@ int RsServer::UpdateAllConfig()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void RsServer::ConfigFinalSave()
|
void RsServer::ConfigFinalSave()
|
||||||
{
|
{
|
||||||
/* force saving of transfers */
|
/* force saving of transfers */
|
||||||
@ -344,4 +341,6 @@ void RsServer::ConfigFinalSave()
|
|||||||
void RsServer::rsGlobalShutDown()
|
void RsServer::rsGlobalShutDown()
|
||||||
{
|
{
|
||||||
ConfigFinalSave(); // save configuration before exit
|
ConfigFinalSave(); // save configuration before exit
|
||||||
|
mConnMgr->shutdown(); /* Handles UPnP */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include "services/p3gamelauncher.h"
|
#include "services/p3gamelauncher.h"
|
||||||
#include "services/p3ranking.h"
|
#include "services/p3ranking.h"
|
||||||
#include "services/p3photoservice.h"
|
#include "services/p3photoservice.h"
|
||||||
|
#include "services/p3forums.h"
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -68,8 +69,10 @@
|
|||||||
#include "pqi/p3notify.h" // HACK - moved to pqi for compilation order.
|
#include "pqi/p3notify.h" // HACK - moved to pqi for compilation order.
|
||||||
|
|
||||||
|
|
||||||
// UNCOMMENT THIS FOR UNFINISHED SERVICES
|
// COMMENT THIS FOR UNFINISHED SERVICES
|
||||||
|
/****
|
||||||
#define RS_RELEASE 1
|
#define RS_RELEASE 1
|
||||||
|
****/
|
||||||
|
|
||||||
|
|
||||||
/**************** PQI_USE_XPGP ******************/
|
/**************** PQI_USE_XPGP ******************/
|
||||||
@ -557,6 +560,8 @@ int RsServer::StartupRetroShare(RsInit *config)
|
|||||||
|
|
||||||
CachePair cp2(photoService, photoService, CacheId(RS_SERVICE_TYPE_PHOTO, 0));
|
CachePair cp2(photoService, photoService, CacheId(RS_SERVICE_TYPE_PHOTO, 0));
|
||||||
mCacheStrapper -> addCachePair(cp2);
|
mCacheStrapper -> addCachePair(cp2);
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
mRanking = NULL;
|
mRanking = NULL;
|
||||||
|
|
||||||
@ -682,7 +687,6 @@ int RsServer::StartupRetroShare(RsInit *config)
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
server->StartupMonitor();
|
server->StartupMonitor();
|
||||||
mUpnpMgr->start();
|
|
||||||
mDhtMgr->start();
|
mDhtMgr->start();
|
||||||
|
|
||||||
|
|
||||||
@ -710,10 +714,12 @@ int RsServer::StartupRetroShare(RsInit *config)
|
|||||||
rsGameLauncher = gameLauncher;
|
rsGameLauncher = gameLauncher;
|
||||||
rsPhoto = new p3Photo(photoService);
|
rsPhoto = new p3Photo(photoService);
|
||||||
rsRanks = new p3Rank(mRanking);
|
rsRanks = new p3Rank(mRanking);
|
||||||
|
rsForums = new p3Forums();
|
||||||
#else
|
#else
|
||||||
rsGameLauncher = NULL;
|
rsGameLauncher = NULL;
|
||||||
rsPhoto = NULL;
|
rsPhoto = NULL;
|
||||||
rsRanks = NULL;
|
rsRanks = NULL;
|
||||||
|
rsForums = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,7 +9,10 @@ include $(RS_TOP_DIR)/scripts/config.mk
|
|||||||
|
|
||||||
RSOBJ = p3service.o p3chatservice.o p3msgservice.o \
|
RSOBJ = p3service.o p3chatservice.o p3msgservice.o \
|
||||||
p3gamelauncher.o p3ranking.o p3disc.o \
|
p3gamelauncher.o p3ranking.o p3disc.o \
|
||||||
p3photoservice.o
|
p3photoservice.o \
|
||||||
|
p3forums.o
|
||||||
|
|
||||||
|
# p3distrib.o
|
||||||
|
|
||||||
#TESTOBJ =
|
#TESTOBJ =
|
||||||
|
|
||||||
|
976
libretroshare/src/services/p3distrib.cc
Normal file
976
libretroshare/src/services/p3distrib.cc
Normal file
@ -0,0 +1,976 @@
|
|||||||
|
/*
|
||||||
|
* libretroshare/src/services: p3distrib.h
|
||||||
|
*
|
||||||
|
* 3P/PQI network interface for RetroShare.
|
||||||
|
*
|
||||||
|
* Copyright 2004-2008 by Robert Fernie.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License Version 2 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "services/p3distrib.h"
|
||||||
|
#include "pqi/pqibin.h"
|
||||||
|
|
||||||
|
|
||||||
|
//#include "pqi/pqiservice.h"
|
||||||
|
//#include "util/rsthreads.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Group Messages....
|
||||||
|
*
|
||||||
|
* Forums / Channels / Blogs...
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Plan.
|
||||||
|
*
|
||||||
|
* (1) First create basic structures .... algorithms.
|
||||||
|
*
|
||||||
|
* (2) integrate with Cache Source/Store for data transmission.
|
||||||
|
* (3) integrate with Serialiser for messages
|
||||||
|
* (4) bring over the final key parts from existing p3channel.
|
||||||
|
*
|
||||||
|
*****************************************************************
|
||||||
|
*
|
||||||
|
* Group Description:
|
||||||
|
*
|
||||||
|
* Master Public/Private Key: (Admin Key) used to control
|
||||||
|
* Group Name/Description/Icon.
|
||||||
|
* Filter Lists.
|
||||||
|
* Publish Keys.
|
||||||
|
*
|
||||||
|
* Publish Keys. (multiple possible)
|
||||||
|
* Filters: blacklist or whitelist.
|
||||||
|
* TimeStore Length ??? (could make it a minimum of this and system one)
|
||||||
|
*
|
||||||
|
* Everyone gets:
|
||||||
|
* Master Public Key.
|
||||||
|
* Publish Public Keys.
|
||||||
|
* blacklist, or whitelist filter. (Only useful for Non-Anonymous groups)
|
||||||
|
* Name, Desc,
|
||||||
|
* etc.
|
||||||
|
*
|
||||||
|
* Admins get Master Private Key.
|
||||||
|
* Publishers get Publish Private Key.
|
||||||
|
* - Channels only some get publish key.
|
||||||
|
* - Forums everyone gets publish private key.
|
||||||
|
*
|
||||||
|
* Create a Signing structure for Messages in general.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
p3GroupDistrib::p3GroupDistrib(uint16_t subtype,
|
||||||
|
CacheStrapper *cs, CacheTransfer *cft,
|
||||||
|
std::string sourcedir, std::string storedir,
|
||||||
|
uint32_t configId,
|
||||||
|
uint32_t storePeriod, uint32_t pubPeriod)
|
||||||
|
|
||||||
|
:CacheSource(subtype, true, cs, sourcedir),
|
||||||
|
CacheStore(subtype, true, cs, cft, storedir),
|
||||||
|
p3Config(configId),
|
||||||
|
mStorePeriod(storePeriod),
|
||||||
|
mPubPeriod(pubPeriod)
|
||||||
|
{
|
||||||
|
/* not much yet */
|
||||||
|
time_t now = time(NULL);
|
||||||
|
|
||||||
|
/* set this a little in the future -> so we can
|
||||||
|
* adjust the publish point if needed
|
||||||
|
*/
|
||||||
|
|
||||||
|
mNextPublishTime = now + mPubPeriod / 4;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void p3GroupDistrib::tick()
|
||||||
|
{
|
||||||
|
time_t now = time(NULL);
|
||||||
|
bool toPublish;
|
||||||
|
|
||||||
|
{
|
||||||
|
RsStackMutex stack(distribMtx); /**** STACK LOCKED MUTEX ****/
|
||||||
|
toPublish = (now > mNextPublishTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toPublish)
|
||||||
|
{
|
||||||
|
publishPendingMsgs();
|
||||||
|
|
||||||
|
RsStackMutex stack(distribMtx); /**** STACK LOCKED MUTEX ****/
|
||||||
|
mNextPublishTime = now + mPubPeriod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/********************** overloaded functions from Cache Store ******************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
|
||||||
|
int p3GroupDistrib::loadAnyCache(const CacheData &data, bool local)
|
||||||
|
{
|
||||||
|
/* if subtype = 0 -> FileGroup, else -> FileMsgs */
|
||||||
|
|
||||||
|
std::string file = data.path;
|
||||||
|
file += "/";
|
||||||
|
file += data.name;
|
||||||
|
|
||||||
|
if (data.cid.subid == 0)
|
||||||
|
{
|
||||||
|
loadFileGroups(file, data.pid, local);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
loadFileMsgs(file, data.cid.subid, data.pid, local);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int p3GroupDistrib::loadCache(const CacheData &data)
|
||||||
|
{
|
||||||
|
return loadAnyCache(data, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool p3GroupDistrib::loadLocalCache(const CacheData &data)
|
||||||
|
{
|
||||||
|
return loadAnyCache(data, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/********************** load Cache Files ***************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* No need for special treatment for 'own' groups.
|
||||||
|
* configuration should be loaded before cache files.
|
||||||
|
*/
|
||||||
|
void p3GroupDistrib::loadFileGroups(std::string filename, std::string src, bool local)
|
||||||
|
{
|
||||||
|
/* create the serialiser to load info */
|
||||||
|
BinInterface *bio = new BinFileInterface(filename.c_str(), BIN_FLAGS_READABLE);
|
||||||
|
pqistreamer *streamer = createStreamer(bio, src, 0);
|
||||||
|
|
||||||
|
RsItem *item;
|
||||||
|
RsDistribGrp *newGrp;
|
||||||
|
while(NULL != (item = streamer->GetItem()))
|
||||||
|
{
|
||||||
|
if (NULL == (newGrp = dynamic_cast<RsDistribGrp *>(item)))
|
||||||
|
{
|
||||||
|
/* wrong message type */
|
||||||
|
delete item;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
loadGroup(newGrp);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete streamer;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void p3GroupDistrib::loadFileMsgs(std::string filename, uint16_t cacheSubId, std::string src, bool local)
|
||||||
|
{
|
||||||
|
time_t now = time(NULL);
|
||||||
|
time_t start = now;
|
||||||
|
time_t end = 0;
|
||||||
|
|
||||||
|
/* create the serialiser to load msgs */
|
||||||
|
BinInterface *bio = new BinFileInterface(filename.c_str(), BIN_FLAGS_READABLE);
|
||||||
|
pqistreamer *streamer = createStreamer(bio, src, 0);
|
||||||
|
|
||||||
|
RsItem *item;
|
||||||
|
RsDistribMsg *newMsg;
|
||||||
|
while(NULL != (item = streamer->GetItem()))
|
||||||
|
{
|
||||||
|
if (NULL == (newMsg = dynamic_cast<RsDistribMsg *>(item)))
|
||||||
|
{
|
||||||
|
/* wrong message type */
|
||||||
|
delete item;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (local)
|
||||||
|
{
|
||||||
|
/* calc the range */
|
||||||
|
if (newMsg->timestamp < start)
|
||||||
|
start = newMsg->timestamp;
|
||||||
|
if (newMsg->timestamp > end)
|
||||||
|
end = newMsg->timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
loadMsg(newMsg, src, local);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check the Hash? */
|
||||||
|
|
||||||
|
delete streamer;
|
||||||
|
|
||||||
|
if (local)
|
||||||
|
{
|
||||||
|
GroupCache newCache;
|
||||||
|
|
||||||
|
newCache.filename = filename;
|
||||||
|
newCache.cacheSubId = cacheSubId;
|
||||||
|
newCache.start = start;
|
||||||
|
newCache.end = end;
|
||||||
|
|
||||||
|
distribMtx.lock(); /******************** LOCKED MUTEX ************/
|
||||||
|
|
||||||
|
mLocalCaches.push_back(newCache);
|
||||||
|
|
||||||
|
|
||||||
|
/******************** This probably ain't necessary *******************/
|
||||||
|
#if 0
|
||||||
|
/* adjust next Publish Time if needed */
|
||||||
|
if ((end < now) && (end + mPubPeriod > mNextPublishTime))
|
||||||
|
{
|
||||||
|
mNextPublishTime = end + mPubPeriod;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/******************** This probably ain't necessary *******************/
|
||||||
|
|
||||||
|
distribMtx.unlock(); /******************** UNLOCKED MUTEX ************/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************
|
||||||
|
********************************
|
||||||
|
********************************
|
||||||
|
***** COMPLETED TO HERE ******
|
||||||
|
********************************
|
||||||
|
********************************
|
||||||
|
********************************/
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/********************** load Cache Msgs ***************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
void p3GroupDistrib::loadGroup(RsDistribGrp *newGrp)
|
||||||
|
{
|
||||||
|
/* load groupInfo */
|
||||||
|
|
||||||
|
/* look for duplicate */
|
||||||
|
|
||||||
|
|
||||||
|
/* check signature */
|
||||||
|
|
||||||
|
/* add in */
|
||||||
|
|
||||||
|
/* */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void p3GroupDistrib::loadMsg(RsDistribMsg *msg, std::string src, bool local)
|
||||||
|
{
|
||||||
|
/****************** check the msg ******************/
|
||||||
|
/* Do the most likely checks to fail first....
|
||||||
|
*
|
||||||
|
* timestamp (too old)
|
||||||
|
* group (non existant)
|
||||||
|
* msg (already have it)
|
||||||
|
*
|
||||||
|
* -> then do the expensive Hash / signature checks.
|
||||||
|
*/
|
||||||
|
|
||||||
|
distribMtx.lock(); /******************** LOCKED MUTEX ************/
|
||||||
|
|
||||||
|
/* check timestamp */
|
||||||
|
time_t now = time(NULL);
|
||||||
|
time_t min = now - mStorePeriod;
|
||||||
|
time_t minPub = now - mStorePeriod / 2.0;
|
||||||
|
time_t max = now + GROUP_MAX_FWD_OFFSET;
|
||||||
|
|
||||||
|
distribMtx.unlock(); /******************** UNLOCKED MUTEX ************/
|
||||||
|
|
||||||
|
if ((msg->timestamp < min) || (msg->timestamp > max))
|
||||||
|
{
|
||||||
|
/* if outside range -> remove */
|
||||||
|
delete msg;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
distribMtx.lock(); /******************** LOCKED MUTEX ************/
|
||||||
|
|
||||||
|
/* find group */
|
||||||
|
std::map<std::string, GroupInfo>::iterator git;
|
||||||
|
if (mGroups.end() == (git = mGroups.find(msg->grpId)))
|
||||||
|
{
|
||||||
|
/* if not there -> remove */
|
||||||
|
distribMtx.unlock(); /******************** UNLOCKED MUTEX ************/
|
||||||
|
|
||||||
|
delete msg;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for duplicate message */
|
||||||
|
std::map<std::string, RsDistribMsg *>::iterator mit;
|
||||||
|
if ((git->second).msgs.end() != (git->second).msgs.find(msg->msgId))
|
||||||
|
{
|
||||||
|
distribMtx.unlock(); /******************** UNLOCKED MUTEX ************/
|
||||||
|
|
||||||
|
/* if already there -> remove */
|
||||||
|
delete msg;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
distribMtx.unlock(); /******************** UNLOCKED MUTEX ************/
|
||||||
|
|
||||||
|
/* save and reset hash/signatures */
|
||||||
|
std::string hash = msg->msgId;
|
||||||
|
std::string grpSign = msg->grpSignature;
|
||||||
|
std::string srcSign = msg->sourceSignature;
|
||||||
|
|
||||||
|
msg->msgId = "";
|
||||||
|
msg->grpSignature = "";
|
||||||
|
msg->sourceSignature = "";
|
||||||
|
|
||||||
|
std::string computedHash = HashRsItem(msg);
|
||||||
|
|
||||||
|
/* restore data */
|
||||||
|
msg->msgId = hash;
|
||||||
|
msg->grpSignature = grpSign;
|
||||||
|
msg->sourceSignature = srcSign;
|
||||||
|
|
||||||
|
if (computedHash != hash)
|
||||||
|
{
|
||||||
|
/* hash is wrong */
|
||||||
|
delete msg;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calc group signature */
|
||||||
|
/* if fails -> remove */
|
||||||
|
|
||||||
|
/* check peer signature */
|
||||||
|
/* if !allowedAnon & anon -> remove */
|
||||||
|
/* if !allowedUnknown & unknown -> remove */
|
||||||
|
|
||||||
|
/****************** check the msg ******************/
|
||||||
|
|
||||||
|
/* accept message */
|
||||||
|
(git->second).msgs[msg->msgId] = msg;
|
||||||
|
|
||||||
|
if (local)
|
||||||
|
{
|
||||||
|
/* if from local -> already published */
|
||||||
|
/* All local loads - will also come in as Remote loads.
|
||||||
|
* but should be discarded because of duplicates
|
||||||
|
* (Local load must happen first!)
|
||||||
|
*/
|
||||||
|
//delete msg;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (msg->timestamp < minPub)
|
||||||
|
{
|
||||||
|
/* outside publishing range */
|
||||||
|
//delete msg;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* else if group = subscribed | listener -> publish */
|
||||||
|
toPublishMsg(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/****************** create/mod Cache Content **********************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
|
||||||
|
void p3GroupDistrib::toPublishMsg(RsDistribMsg *msg)
|
||||||
|
{
|
||||||
|
RsStackMutex stack(distribMtx); /****** STACK MUTEX LOCKED *******/
|
||||||
|
|
||||||
|
mPendingPublish.push_back(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void p3GroupDistrib::locked_publishPendingMsgs()
|
||||||
|
{
|
||||||
|
/* get the next message id */
|
||||||
|
CacheData newCache;
|
||||||
|
|
||||||
|
newCache.pid = mOwnId;
|
||||||
|
newCache.cid.type = CacheSource::getCacheType();
|
||||||
|
newCache.cid.subid = determineCacheSubId(); // NOT fixed - should rotate.
|
||||||
|
|
||||||
|
/* create filename */
|
||||||
|
std::string path = CacheSource::getCacheDir();
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "grpdist-t" << CacheSource::getCacheType() << "-msgs-" << time(NULL) << ".dist";
|
||||||
|
|
||||||
|
std::string tmpname = out.str();
|
||||||
|
std::string filename = path + "/" + tmpname;
|
||||||
|
|
||||||
|
BinInterface *bio = new BinFileInterface(filename.c_str(),
|
||||||
|
BIN_FLAGS_WRITEABLE | BIN_FLAGS_HASH_DATA);
|
||||||
|
pqistreamer *streamer = createStreamer(bio, mOwnId,
|
||||||
|
BIN_FLAGS_NO_DELETE);
|
||||||
|
|
||||||
|
RsStackMutex stack(distribMtx); /****** STACK MUTEX LOCKED *******/
|
||||||
|
|
||||||
|
|
||||||
|
std::list<RsDistribMsg *>::iterator it;
|
||||||
|
for(it = mPendingPublish.begin(); it != mPendingPublish.end(); it++)
|
||||||
|
{
|
||||||
|
streamer->SendItem(*it); /* doesnt delete it */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cleanup */
|
||||||
|
mPendingPublish.clear();
|
||||||
|
delete streamer;
|
||||||
|
|
||||||
|
/* Extract File Information from pqistreamer */
|
||||||
|
newCache.path = path;
|
||||||
|
newCache.name = tmpname;
|
||||||
|
|
||||||
|
newCache.hash = bio->gethash();
|
||||||
|
newCache.size = bio->bytecount();
|
||||||
|
newCache.recvd = time(NULL);
|
||||||
|
|
||||||
|
/* push file to CacheSource */
|
||||||
|
refreshCache(newCache);
|
||||||
|
|
||||||
|
/* flag to store config (saying we've published messages) */
|
||||||
|
IndicateConfigChanged(); /**** INDICATE CONFIG CHANGED! *****/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void p3GroupDistrib::publishDistribGroups()
|
||||||
|
{
|
||||||
|
/* set subid = 0 */
|
||||||
|
CacheData newCache;
|
||||||
|
|
||||||
|
newCache.pid = mOwnId;
|
||||||
|
newCache.cid.type = CacheSource::getCacheType();
|
||||||
|
newCache.cid.subid = 0;
|
||||||
|
|
||||||
|
/* create filename */
|
||||||
|
std::string path = CacheSource::getCacheDir();
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "grpdist-t" << CacheSource::getCacheType() << "-grps-" << time(NULL) << ".dist";
|
||||||
|
|
||||||
|
std::string tmpname = out.str();
|
||||||
|
std::string filename = path + "/" + tmpname;
|
||||||
|
|
||||||
|
BinInterface *bio = new BinFileInterface(filename.c_str(),
|
||||||
|
BIN_FLAGS_WRITEABLE | BIN_FLAGS_HASH_DATA);
|
||||||
|
pqistreamer *streamer = createStreamer(bio, mOwnId, 0);
|
||||||
|
|
||||||
|
RsStackMutex stack(distribMtx); /****** STACK MUTEX LOCKED *******/
|
||||||
|
|
||||||
|
|
||||||
|
/* Iterate through all the Groups */
|
||||||
|
std::map<std::string, GroupInfo>::iterator it;
|
||||||
|
for(it = mGroups.begin(); it != mGroups.end(); it++)
|
||||||
|
{
|
||||||
|
/* if subscribed or listener -> do stuff */
|
||||||
|
|
||||||
|
/* extract public info to RsDistribGrp */
|
||||||
|
RsDistribGrp *grp = new RsDistribGrp();
|
||||||
|
|
||||||
|
|
||||||
|
/* store in Cache File */
|
||||||
|
streamer->SendItem(grp); /* deletes it */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extract File Information from pqistreamer */
|
||||||
|
newCache.path = path;
|
||||||
|
newCache.name = tmpname;
|
||||||
|
|
||||||
|
newCache.hash = bio->gethash();
|
||||||
|
newCache.size = bio->bytecount();
|
||||||
|
newCache.recvd = time(NULL);
|
||||||
|
|
||||||
|
/* cleanup */
|
||||||
|
delete streamer;
|
||||||
|
|
||||||
|
/* push file to CacheSource */
|
||||||
|
refreshCache(newCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* clearing old data */
|
||||||
|
void p3GroupDistrib::clear_local_caches(time_t now)
|
||||||
|
{
|
||||||
|
RsStackMutex stack(distribMtx); /****** STACK MUTEX LOCKED *******/
|
||||||
|
|
||||||
|
time_t cutoff = now - mStorePeriod;
|
||||||
|
std::list<GroupCache>::iterator it;
|
||||||
|
for(it = mLocalCaches.begin(); it != mLocalCaches.end();)
|
||||||
|
{
|
||||||
|
if (it->end < cutoff)
|
||||||
|
{
|
||||||
|
/* Call to CacheSource Function */
|
||||||
|
CacheId cid(CacheSource::getCacheType(), it->cacheSubId);
|
||||||
|
clearCache(cid);
|
||||||
|
it = mLocalCaches.erase(it);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/********************** Access Content ***************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* get Group Lists */
|
||||||
|
bool p3GroupDistrib::getAllGroupList(std::list<std::string> &grpids)
|
||||||
|
{
|
||||||
|
RsStackMutex stack(distribMtx); /************* STACK MUTEX ************/
|
||||||
|
std::map<std::string, GroupInfo>::iterator git;
|
||||||
|
for(git = mGroups.begin(); git != mGroups.end(); git++)
|
||||||
|
{
|
||||||
|
grpids.push_back(git->first);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool p3GroupDistrib::getSubscribedGroupList(std::list<std::string> &grpids)
|
||||||
|
{
|
||||||
|
RsStackMutex stack(distribMtx); /************* STACK MUTEX ************/
|
||||||
|
std::map<std::string, GroupInfo>::iterator git;
|
||||||
|
for(git = mGroups.begin(); git != mGroups.end(); git++)
|
||||||
|
{
|
||||||
|
if (git->second.flags & RS_GRPDISTRIB_SUBSCRIBED)
|
||||||
|
{
|
||||||
|
grpids.push_back(git->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool p3GroupDistrib::getPublishGroupList(std::list<std::string> &grpids)
|
||||||
|
{
|
||||||
|
RsStackMutex stack(distribMtx); /************* STACK MUTEX ************/
|
||||||
|
std::map<std::string, GroupInfo>::iterator git;
|
||||||
|
for(git = mGroups.begin(); git != mGroups.end(); git++)
|
||||||
|
{
|
||||||
|
if (git->second.flags & RS_GRPDISTRIB_PUBLISH)
|
||||||
|
{
|
||||||
|
grpids.push_back(git->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool p3GroupDistrib::getPopularGroupList(uint32_t popMin, uint32_t popMax, std::list<std::string> &grpids)
|
||||||
|
{
|
||||||
|
RsStackMutex stack(distribMtx); /************* STACK MUTEX ************/
|
||||||
|
std::map<std::string, GroupInfo>::iterator git;
|
||||||
|
for(git = mGroups.begin(); git != mGroups.end(); git++)
|
||||||
|
{
|
||||||
|
if ((git->second.pop >= popMin) &&
|
||||||
|
(git->second.pop <= popMax))
|
||||||
|
{
|
||||||
|
grpids.push_back(git->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* get Msg Lists */
|
||||||
|
bool p3GroupDistrib::getAllMsgList(std::string grpId, std::list<std::string> &msgIds)
|
||||||
|
{
|
||||||
|
RsStackMutex stack(distribMtx); /************* STACK MUTEX ************/
|
||||||
|
std::map<std::string, GroupInfo>::iterator git;
|
||||||
|
if (mGroups.end() == (git = mGroups.find(grpId)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, RsDistribMsg *>::iterator mit;
|
||||||
|
std::map<std::string, RsDistribMsg *> msgs;
|
||||||
|
|
||||||
|
for(mit = git->second.msgs.begin(); mit != git->second.msgs.end(); mit++)
|
||||||
|
{
|
||||||
|
msgIds.push_back(mit->first);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool p3GroupDistrib::getTimePeriodMsgList(std::string grpId, uint32_t timeMin,
|
||||||
|
uint32_t timeMax, std::list<std::string> &msgIds)
|
||||||
|
{
|
||||||
|
RsStackMutex stack(distribMtx); /************* STACK MUTEX ************/
|
||||||
|
std::map<std::string, GroupInfo>::iterator git;
|
||||||
|
if (mGroups.end() == (git = mGroups.find(grpId)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, RsDistribMsg *>::iterator mit;
|
||||||
|
|
||||||
|
for(mit = git->second.msgs.begin(); mit != git->second.msgs.end(); mit++)
|
||||||
|
{
|
||||||
|
if ((mit->second->timestamp >= timeMin) &&
|
||||||
|
(mit->second->timestamp <= timeMax))
|
||||||
|
{
|
||||||
|
msgIds.push_back(mit->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GroupInfo *p3GroupDistrib::locked_getGroupInfo(std::string grpId)
|
||||||
|
{
|
||||||
|
/************* ALREADY LOCKED ************/
|
||||||
|
std::map<std::string, GroupInfo>::iterator git;
|
||||||
|
if (mGroups.end() == (git = mGroups.find(grpId)))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return &(git->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RsDistribMsg *p3GroupDistrib::locked_getGroupMsg(std::string grpId, std::string msgId)
|
||||||
|
{
|
||||||
|
/************* ALREADY LOCKED ************/
|
||||||
|
std::map<std::string, GroupInfo>::iterator git;
|
||||||
|
if (mGroups.end() == (git = mGroups.find(grpId)))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, RsDistribMsg *>::iterator mit;
|
||||||
|
if (git->second.msgs.end() == (mit = git->second.msgs.find(msgId)))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mit->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**** These must be created in derived classes ****/
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
/* get Group Details */
|
||||||
|
bool p3GroupDistrib::getGroupDetails(std::string grpId, RsExternalDistribGroup &grp)
|
||||||
|
{
|
||||||
|
RsStackMutex stack(distribMtx); /************* STACK MUTEX ************/
|
||||||
|
std::map<std::string, GroupInfo>::iterator git;
|
||||||
|
if (mGroups.end() == (git = mGroups.find(grpId)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill in details */
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get Msg */
|
||||||
|
bool p3GroupDistrib::getGroupMsgDetails(std::string grpId, std::string msgId, RsExternalDistribMsg &msg)
|
||||||
|
{
|
||||||
|
RsStackMutex stack(distribMtx); /************* STACK MUTEX ************/
|
||||||
|
std::map<std::string, GroupInfo>::iterator git;
|
||||||
|
if (mGroups.end() == (git = mGroups.find(grpId)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, RsDistribMsg *>::iterator mit;
|
||||||
|
if (git->second.msgs.end() == (mit = git->second.msgs.find(msgId)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill in the message details */
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/************************************* p3Config *************************************/
|
||||||
|
|
||||||
|
RsSerialiser *p3GroupDistrib::setupSerialiser()
|
||||||
|
{
|
||||||
|
RsSerialiser *rss = new RsSerialiser();
|
||||||
|
|
||||||
|
rss->addSerialType(new RsSerialDistrib());
|
||||||
|
rss->addSerialType(new RsConfigDistrib());
|
||||||
|
|
||||||
|
return rss;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<RsItem *> p3GroupDistrib::saveList(bool &cleanup)
|
||||||
|
{
|
||||||
|
std::list<RsItem *> saveData;
|
||||||
|
|
||||||
|
/* store private information for OUR lists */
|
||||||
|
/* store information on subscribed lists */
|
||||||
|
/* store messages for pending Publication */
|
||||||
|
|
||||||
|
return saveData;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool p3GroupDistrib::loadList(std::list<RsItem *> load)
|
||||||
|
{
|
||||||
|
std::list<RsItem *>::iterator lit;
|
||||||
|
for(lit = load.begin(); lit != load.end(); lit++)
|
||||||
|
{
|
||||||
|
/* decide what type it is */
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************* p3Config *************************************/
|
||||||
|
|
||||||
|
pqistreamer *p3GroupDistrib::createStreamer(BinInterface *bio, std::string src, uint32_t bioflags)
|
||||||
|
{
|
||||||
|
RsSerialiser *rsSerialiser = new RsSerialiser();
|
||||||
|
RsSerialType *serialType = new RsSerialDistrib(); /* TODO */
|
||||||
|
|
||||||
|
rsSerialiser->addSerialType(serialType);
|
||||||
|
|
||||||
|
pqistreamer *streamer = new pqistreamer(rsSerialiser, src, bio, bioflags);
|
||||||
|
|
||||||
|
return streamer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string HashRsItem(RsItem *item)
|
||||||
|
{
|
||||||
|
/* calc/check hash (of serialised data) */
|
||||||
|
RsSerialType *serial = new RsSerialDistrib();
|
||||||
|
|
||||||
|
uint32_t size = serial->size(item);
|
||||||
|
RsRawItem *ri = new RsRawItem(0, size);
|
||||||
|
serial->serialise(item, ri->getRawData(), &size);
|
||||||
|
|
||||||
|
pqihash hash;
|
||||||
|
std::string computedHash;
|
||||||
|
|
||||||
|
hash.addData(ri->getRawData(), size);
|
||||||
|
hash.Complete(computedHash);
|
||||||
|
|
||||||
|
delete ri;
|
||||||
|
delete serial;
|
||||||
|
|
||||||
|
return computedHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/********************** Create Content ***************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
|
||||||
|
std::string p3GroupDistrib::createGroup(std::string name, uint32_t flags)
|
||||||
|
{
|
||||||
|
/* Create a Group */
|
||||||
|
GroupInfo grpInfo;
|
||||||
|
std::string grpId;
|
||||||
|
|
||||||
|
#ifdef GROUP_SIGNATURES
|
||||||
|
|
||||||
|
/* Create Key Set (Admin) */
|
||||||
|
EVP_PKEY *key_admin = EVP_PKEY_new();
|
||||||
|
mAuthMgr->generateKeyPair(key_admin, 0);
|
||||||
|
|
||||||
|
/* extract AdminKey Id -> groupId */
|
||||||
|
grpId = mAuthMgr->getKeyId(key_admin);
|
||||||
|
|
||||||
|
/* setup GroupInfo */
|
||||||
|
grpInfo.adminKey = key_admin;
|
||||||
|
|
||||||
|
#else
|
||||||
|
grpInfo.id = generateRandomId();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
grpInfo.id = grpId;
|
||||||
|
grpInfo.flags = flags;
|
||||||
|
grpInfo.name = name;
|
||||||
|
|
||||||
|
/* generate a set of keys */
|
||||||
|
|
||||||
|
/* generate RsDistribGrp */
|
||||||
|
|
||||||
|
/* sign Grp (with date) */
|
||||||
|
|
||||||
|
/* store new GroupInfo */
|
||||||
|
|
||||||
|
return grpId;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string p3GroupDistrib::addPublishKey(std::string grpId, uint32_t keyflags, time_t startDate, time_t endDate)
|
||||||
|
{
|
||||||
|
/* Find the Group */
|
||||||
|
GroupInfo *grpInfo = locked_getGroupInfo(grpId);
|
||||||
|
std::string keyId;
|
||||||
|
|
||||||
|
if (!grpInfo)
|
||||||
|
{
|
||||||
|
return keyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we don't have the admin key -> then we cannot add a key */
|
||||||
|
if (!(grpInfo->grpFlags & RS_GRPDISTRIB_ADMIN_KEY))
|
||||||
|
{
|
||||||
|
return keyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create Key Set (Publish) */
|
||||||
|
EVP_PKEY *key_publish = EVP_PKEY_new();
|
||||||
|
mAuthMgr->generateKeyPair(key_publish, 0);
|
||||||
|
|
||||||
|
/* extract Key Id -> keyId */
|
||||||
|
keyId = mAuthMgr->getKeyId(key_publish);
|
||||||
|
|
||||||
|
/* setup RsKey */
|
||||||
|
RsKey *publishKey = new RsKey();
|
||||||
|
publishKey -> key = key_publish;
|
||||||
|
publishKey -> keyId = keyId;
|
||||||
|
publishKey -> startDate = startDate;
|
||||||
|
publishKey -> endDate = endDate;
|
||||||
|
|
||||||
|
/* setup data packet for signing */
|
||||||
|
|
||||||
|
|
||||||
|
/* sign key with Admin Key */
|
||||||
|
publishKey -> adminSignature = ...;
|
||||||
|
|
||||||
|
|
||||||
|
grpInfo.publishKeys.push_back(publishKey);
|
||||||
|
|
||||||
|
return keyId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int p3channel::signRsKey(RsKey *pubkey, EVP_PKEY *signKey, std::string &signature)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// sslroot will generate the pair...
|
||||||
|
// we need to split it into an pub/private.
|
||||||
|
|
||||||
|
EVP_PKEY *keypair = EVP_PKEY_new();
|
||||||
|
EVP_PKEY *pubkey = EVP_PKEY_new();
|
||||||
|
|
||||||
|
mAuthMgr->generateKeyPair(keypair, 0);
|
||||||
|
|
||||||
|
RSA *rsa1 = EVP_PKEY_get1_RSA(keypair);
|
||||||
|
RSA *rsa2 = RSAPublicKey_dup(rsa1);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "p3channel::generateRandomKeys()" << std::endl;
|
||||||
|
out << "Rsa1: " << (void *) rsa1 << " & Rsa2: ";
|
||||||
|
out << (void *) rsa2 << std::endl;
|
||||||
|
|
||||||
|
pqioutput(PQL_DEBUG_BASIC, pqichannelzone, out.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
EVP_PKEY_assign_RSA(pubkey, rsa1);
|
||||||
|
RSA_free(rsa1); // decrement ref count!
|
||||||
|
|
||||||
|
priv -> setKey(keypair);
|
||||||
|
pub -> setKey(pubkey);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "p3channel::generateRandomKey(): ";
|
||||||
|
priv -> print(out);
|
||||||
|
pqioutput(PQL_DEBUG_BASIC, pqichannelzone, out.str());
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void p3GroupDistrib::publishMsg(RsDistribMsg *msg, bool personalSign)
|
||||||
|
{
|
||||||
|
/* extract grpId */
|
||||||
|
std::string grpId = msg->grpId;
|
||||||
|
|
||||||
|
/* ensure Group exists */
|
||||||
|
|
||||||
|
/* hash message */
|
||||||
|
|
||||||
|
/* sign message */
|
||||||
|
|
||||||
|
/* personal signature? */
|
||||||
|
|
||||||
|
/* Message now Complete */
|
||||||
|
|
||||||
|
/* Insert in Group */
|
||||||
|
|
||||||
|
/* add to PublishPending */
|
||||||
|
|
||||||
|
/* done */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
/* Modify Group */
|
||||||
|
std::string p3GroupDistrib::modGroupDescription(std::string grpId, std::string description)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string p3GroupDistrib::modGroupIcon(std::string grpId, PIXMAP icon)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
375
libretroshare/src/services/p3distrib.h
Normal file
375
libretroshare/src/services/p3distrib.h
Normal file
@ -0,0 +1,375 @@
|
|||||||
|
/*
|
||||||
|
* libretroshare/src/services: p3distrib.h
|
||||||
|
*
|
||||||
|
* 3P/PQI network interface for RetroShare.
|
||||||
|
*
|
||||||
|
* Copyright 2004-2008 by Robert Fernie.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License Version 2 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef P3_GENERIC_DISTRIB_HEADER
|
||||||
|
#define P3_GENERIC_DISTRIB_HEADER
|
||||||
|
|
||||||
|
#include "pqi/pqi.h"
|
||||||
|
#include "pqi/pqistreamer.h"
|
||||||
|
#include "pqi/p3cfgmgr.h"
|
||||||
|
#include "services/p3service.h"
|
||||||
|
#include "dbase/cachestrapper.h"
|
||||||
|
|
||||||
|
//#include "util/rsthreads.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Group Messages....
|
||||||
|
*
|
||||||
|
* Forums / Channels / Blogs...
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Plan.
|
||||||
|
*
|
||||||
|
* (1) First create basic structures .... algorithms.
|
||||||
|
*
|
||||||
|
* (2) integrate with Cache Source/Store for data transmission.
|
||||||
|
* (3) integrate with Serialiser for messages
|
||||||
|
* (4) bring over the final key parts from existing p3channel.
|
||||||
|
*
|
||||||
|
*****************************************************************
|
||||||
|
*
|
||||||
|
* Group Description:
|
||||||
|
*
|
||||||
|
* Master Public/Private Key: (Admin Key) used to control
|
||||||
|
* Group Name/Description/Icon.
|
||||||
|
* Filter Lists.
|
||||||
|
* Publish Keys.
|
||||||
|
*
|
||||||
|
* Publish Keys. (multiple possible)
|
||||||
|
* Filters: blacklist or whitelist.
|
||||||
|
* TimeStore Length ??? (could make it a minimum of this and system one)
|
||||||
|
*
|
||||||
|
* Everyone gets:
|
||||||
|
* Master Public Key.
|
||||||
|
* Publish Public Keys.
|
||||||
|
* blacklist, or whitelist filter. (Only useful for Non-Anonymous groups)
|
||||||
|
* Name, Desc,
|
||||||
|
* etc.
|
||||||
|
*
|
||||||
|
* Admins get Master Private Key.
|
||||||
|
* Publishers get Publish Private Key.
|
||||||
|
* - Channels only some get publish key.
|
||||||
|
* - Forums everyone gets publish private key.
|
||||||
|
*
|
||||||
|
* Create a Signing structure for Messages in general.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Our Mode for the Group */
|
||||||
|
const uint32_t RS_GRPDISTRIB_SUBSCRIBED = 0x0001;
|
||||||
|
const uint32_t RS_GRPDISTRIB_PUBLISH = 0x0002;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Group Type */
|
||||||
|
const uint32_t RS_DISTRIB_PRIVATE = 0x0001; /* retain Private Key ( Default ) */
|
||||||
|
const uint32_t RS_DISTRIB_PUBLIC = 0x0002; /* share All Keys */
|
||||||
|
const uint32_t RS_DISTRIB_ENCRYPTED = 0x0004; /* encrypt Msgs */
|
||||||
|
|
||||||
|
class RsSignature
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
uint32_t type; /* MASTER, PUBLISH, PERSONAL */
|
||||||
|
std::string signerId;
|
||||||
|
std::string signature;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RsAuthMsg
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
RsItem *msg;
|
||||||
|
std::string hash;
|
||||||
|
std::map<std::string, RsSignature> signs;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class RsKey
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
uint32_t type; /* PUBLIC, PRIVATE */
|
||||||
|
uint32_t type2; /* MASTER, PUBLISH, PERSONAL (not sent) */
|
||||||
|
|
||||||
|
EVP_PKEY *key;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const uint32_t GROUP_MAX_FWD_OFFSET = (60 * 60 * 24 * 2); /* 2 Days */
|
||||||
|
|
||||||
|
/************* The Messages that are serialised ****************/
|
||||||
|
class RsDistribMsg: public RsItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RsDistribMsg(); //uint16_t type);
|
||||||
|
|
||||||
|
virtual void clear();
|
||||||
|
virtual std::ostream& print(std::ostream&, uint16_t);
|
||||||
|
|
||||||
|
std::string grpId;
|
||||||
|
std::string headId; /* head of the thread */
|
||||||
|
std::string parentId; /* parent id */
|
||||||
|
time_t timestamp;
|
||||||
|
|
||||||
|
/* This data is not Hashed (set to zero - before hash calced) */
|
||||||
|
std::string msgId; /* SHA1 Hash */
|
||||||
|
std::string grpSignature; /* sign of msgId */
|
||||||
|
std::string sourceSignature; /* sign of msgId */
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class RsDistribGrp: public RsItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RsDistribGrp(); //uint16_t type);
|
||||||
|
|
||||||
|
virtual void clear();
|
||||||
|
virtual std::ostream& print(std::ostream&, uint16_t);
|
||||||
|
|
||||||
|
RsKey rsKey;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RsConfigDistrib: public RsSerialType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
RsConfigDistrib();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class RsSerialDistrib: public RsSerialType
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
RsSerialDistrib();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************* The Messages that are serialised ****************/
|
||||||
|
|
||||||
|
//class PIXMAP;
|
||||||
|
|
||||||
|
class GroupInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
std::string grpId;
|
||||||
|
std::string grpName;
|
||||||
|
std::string grpDesc;
|
||||||
|
|
||||||
|
std::string category;
|
||||||
|
//PIXMAP *GroupIcon;
|
||||||
|
|
||||||
|
//RSA_KEY privateKey;
|
||||||
|
//RSA_KEY publicKey;
|
||||||
|
|
||||||
|
bool publisher, allowAnon, allowUnknown;
|
||||||
|
bool subscribed, listener;
|
||||||
|
|
||||||
|
uint32_t type;
|
||||||
|
uint32_t pop;
|
||||||
|
uint32_t flags;
|
||||||
|
|
||||||
|
std::list<std::string> sources;
|
||||||
|
|
||||||
|
std::map<std::string, RsDistribMsg *> msgs;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GroupCache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
std::string filename;
|
||||||
|
time_t start, end;
|
||||||
|
uint16_t cacheSubId;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
p3GroupDistrib(uint16_t subtype,
|
||||||
|
CacheStrapper *cs, CacheTransfer *cft,
|
||||||
|
std::string sourcedir, std::string storedir,
|
||||||
|
uint32_t configId,
|
||||||
|
uint32_t storePeriod, uint32_t pubPeriod);
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/******************************* CACHE SOURCE / STORE Interface ************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/* TO FINISH */
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual bool loadLocalCache(const CacheData &data); /* overloaded from Cache Source */
|
||||||
|
virtual int loadCache(const CacheData &data); /* overloaded from Cache Store */
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* top level load */
|
||||||
|
int loadAnyCache(const CacheData &data, bool local);
|
||||||
|
|
||||||
|
/* load cache files */
|
||||||
|
void loadFileGroups(std::string filename, std::string src, bool local);
|
||||||
|
void loadFileMsgs(std::string filename, uint16_t cacheSubId, std::string src, bool local);
|
||||||
|
|
||||||
|
/* load cache msgs */
|
||||||
|
void loadMsg(RsDistribMsg *msg, std::string src, bool local);
|
||||||
|
void loadGroup(RsDistribGrp *newGrp);
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/**************************** Create Content *******************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/* TO FINISH */
|
||||||
|
|
||||||
|
public:
|
||||||
|
std::string createGroup(std::string name, uint32_t flags);
|
||||||
|
//std::string modGroupDescription(std::string grpId, std::string discription);
|
||||||
|
//std::string modGroupIcon(std::string grpId, PIXMAP *icon);
|
||||||
|
|
||||||
|
void publishMsg(RsDistribMsg *msg, bool personalSign);
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/****************************** Access Content ***************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
public:
|
||||||
|
/* get Group Lists */
|
||||||
|
bool getAllGroupList(std::list<std::string> &grpids);
|
||||||
|
bool getSubscribedGroupList(std::list<std::string> &grpids);
|
||||||
|
bool getPublishGroupList(std::list<std::string> &grpids);
|
||||||
|
bool getPopularGroupList(uint32_t popMin, uint32_t popMax, std::list<std::string> &grpids);
|
||||||
|
|
||||||
|
|
||||||
|
/* get Msg Lists */
|
||||||
|
bool getAllMsgList(std::string grpId, std::list<std::string> &msgIds);
|
||||||
|
bool getTimePeriodMsgList(std::string grpId, uint32_t timeMin,
|
||||||
|
uint32_t timeMax, std::list<std::string> &msgIds);
|
||||||
|
|
||||||
|
RsDistribMsg *locked_getGroupMsg(std::string grpId, std::string msgId);
|
||||||
|
|
||||||
|
/* TO FINISH DEFINITIONS */
|
||||||
|
|
||||||
|
/* get Details */
|
||||||
|
//bool getGroupDetails(std::string grpId, RsExternalDistribGroup &grp);
|
||||||
|
//bool getGroupMsgDetails(std::string grpId, std::string msgId, RsExternalDistribMsg &msg);
|
||||||
|
|
||||||
|
/* Filter Messages */
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/********************************* p3Config ********************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/* TO FINISH */
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual RsSerialiser *setupSerialiser();
|
||||||
|
virtual std::list<RsItem *> saveList(bool &cleanup);
|
||||||
|
virtual bool loadList(std::list<RsItem *> load);
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/* TO FINISH */
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
void tick();
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/**************************** Publish Content ******************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/* TO FINISH */
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/* create/mod cache content */
|
||||||
|
void toPublishMsg(RsDistribMsg *msg);
|
||||||
|
void publishPendingMsgs();
|
||||||
|
void publishDistribGroups();
|
||||||
|
void clear_local_caches(time_t now);
|
||||||
|
|
||||||
|
void locked_publishPendingMsgs();
|
||||||
|
uint16_t determineCacheSubId();
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************** Utility Functions ***************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/* TO FINISH */
|
||||||
|
/* utilities */
|
||||||
|
pqistreamer *createStreamer(BinInterface *bio, std::string src, uint32_t bioflags);
|
||||||
|
std::string HashRsItem(const RsItem *item);
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
|
||||||
|
/* key cache functions - we use .... (not overloaded)
|
||||||
|
*/
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/* storage */
|
||||||
|
|
||||||
|
RsMutex distribMtx; /* Protects All Data Below */
|
||||||
|
|
||||||
|
std::string mOwnId;
|
||||||
|
std::list<GroupCache> mLocalCaches;
|
||||||
|
std::map<std::string, GroupInfo> mGroups;
|
||||||
|
uint32_t mStorePeriod, mPubPeriod;
|
||||||
|
time_t mNextPublishTime;
|
||||||
|
|
||||||
|
std::list<RsDistribMsg *> mPendingPublish;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/*
|
||||||
|
* Structure of the Storage:
|
||||||
|
*
|
||||||
|
* map<std::string(id) -> GroupInfo>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
/***************************************************************************************/
|
||||||
|
/***************************************************************************************/
|
||||||
|
|
||||||
|
#endif // P3_GENERIC_DISTRIB_HEADER
|
216
libretroshare/src/services/p3forums.cc
Normal file
216
libretroshare/src/services/p3forums.cc
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
/*
|
||||||
|
* libretroshare/src/services: rsforums.cc
|
||||||
|
*
|
||||||
|
* RetroShare C++ Interface.
|
||||||
|
*
|
||||||
|
* Copyright 2007-2008 by Robert Fernie.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License Version 2 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "services/p3forums.h"
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const ForumInfo &info)
|
||||||
|
{
|
||||||
|
std::string name(info.forumName.begin(), info.forumName.end());
|
||||||
|
std::string desc(info.forumDesc.begin(), info.forumDesc.end());
|
||||||
|
|
||||||
|
out << "ForumInfo:";
|
||||||
|
out << std::endl;
|
||||||
|
out << "ForumId: " << info.forumId << std::endl;
|
||||||
|
out << "ForumName: " << name << std::endl;
|
||||||
|
out << "ForumDesc: " << desc << std::endl;
|
||||||
|
out << "ForumFlags: " << info.forumFlags << std::endl;
|
||||||
|
out << "Pop: " << info.pop << std::endl;
|
||||||
|
out << "LastPost: " << info.lastPost << std::endl;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const ThreadInfoSummary &info)
|
||||||
|
{
|
||||||
|
out << "ThreadInfoSummary:";
|
||||||
|
out << std::endl;
|
||||||
|
//out << "ForumId: " << forumId << std::endl;
|
||||||
|
//out << "ThreadId: " << threadId << std::endl;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const ForumMsgInfo &info)
|
||||||
|
{
|
||||||
|
out << "ForumMsgInfo:";
|
||||||
|
out << std::endl;
|
||||||
|
//out << "ForumId: " << forumId << std::endl;
|
||||||
|
//out << "ThreadId: " << threadId << std::endl;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RsForums *rsForums = NULL;
|
||||||
|
|
||||||
|
p3Forums::p3Forums()
|
||||||
|
:mForumsChanged(false)
|
||||||
|
{
|
||||||
|
loadDummyData();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
p3Forums::~p3Forums()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
|
||||||
|
bool p3Forums::forumsChanged(std::list<std::string> &forumIds)
|
||||||
|
{
|
||||||
|
bool changed = mForumsChanged;
|
||||||
|
mForumsChanged = false;
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool p3Forums::getForumList(std::list<ForumInfo> &forumList)
|
||||||
|
{
|
||||||
|
std::list<ForumInfo>::iterator it;
|
||||||
|
for(it = mForums.begin(); it != mForums.end(); it++)
|
||||||
|
{
|
||||||
|
forumList.push_back(*it);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool p3Forums::getForumThreadList(std::string fId, std::list<ThreadInfoSummary> &msgs)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool p3Forums::getForumThreadMsgList(std::string fId, std::string tId, std::list<ThreadInfoSummary> &msgs)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool p3Forums::getForumMessage(std::string fId, std::string mId, ForumMsgInfo &msg)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool p3Forums::ForumMessageSend(ForumMsgInfo &info)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
|
||||||
|
void p3Forums::loadDummyData()
|
||||||
|
{
|
||||||
|
ForumInfo fi;
|
||||||
|
time_t now = time(NULL);
|
||||||
|
|
||||||
|
fi.forumId = "FID1234";
|
||||||
|
fi.forumName = L"Forum 1";
|
||||||
|
fi.forumDesc = L"Forum 1";
|
||||||
|
fi.forumFlags = RS_FORUM_ADMIN;
|
||||||
|
fi.pop = 2;
|
||||||
|
fi.lastPost = now - 123;
|
||||||
|
|
||||||
|
mForums.push_back(fi);
|
||||||
|
|
||||||
|
fi.forumId = "FID2345";
|
||||||
|
fi.forumName = L"Forum 2";
|
||||||
|
fi.forumDesc = L"Forum 2";
|
||||||
|
fi.forumFlags = RS_FORUM_SUBSCRIBED;
|
||||||
|
fi.pop = 3;
|
||||||
|
fi.lastPost = now - 1234;
|
||||||
|
|
||||||
|
mForums.push_back(fi);
|
||||||
|
|
||||||
|
fi.forumId = "FID3456";
|
||||||
|
fi.forumName = L"Forum 3";
|
||||||
|
fi.forumDesc = L"Forum 3";
|
||||||
|
fi.forumFlags = 0;
|
||||||
|
fi.pop = 3;
|
||||||
|
fi.lastPost = now - 1234;
|
||||||
|
|
||||||
|
mForums.push_back(fi);
|
||||||
|
|
||||||
|
fi.forumId = "FID4567";
|
||||||
|
fi.forumName = L"Forum 4";
|
||||||
|
fi.forumDesc = L"Forum 4";
|
||||||
|
fi.forumFlags = 0;
|
||||||
|
fi.pop = 5;
|
||||||
|
fi.lastPost = now - 1234;
|
||||||
|
|
||||||
|
mForums.push_back(fi);
|
||||||
|
fi.forumId = "FID5678";
|
||||||
|
fi.forumName = L"Forum 5";
|
||||||
|
fi.forumDesc = L"Forum 5";
|
||||||
|
fi.forumFlags = 0;
|
||||||
|
fi.pop = 1;
|
||||||
|
fi.lastPost = now - 1234;
|
||||||
|
|
||||||
|
mForums.push_back(fi);
|
||||||
|
fi.forumId = "FID6789";
|
||||||
|
fi.forumName = L"Forum 6";
|
||||||
|
fi.forumDesc = L"Forum 6";
|
||||||
|
fi.forumFlags = 0;
|
||||||
|
fi.pop = 2;
|
||||||
|
fi.lastPost = now - 1234;
|
||||||
|
|
||||||
|
mForums.push_back(fi);
|
||||||
|
fi.forumId = "FID7890";
|
||||||
|
fi.forumName = L"Forum 7";
|
||||||
|
fi.forumDesc = L"Forum 7";
|
||||||
|
fi.forumFlags = 0;
|
||||||
|
fi.pop = 4;
|
||||||
|
fi.lastPost = now - 1234;
|
||||||
|
|
||||||
|
mForums.push_back(fi);
|
||||||
|
fi.forumId = "FID8901";
|
||||||
|
fi.forumName = L"Forum 8";
|
||||||
|
fi.forumDesc = L"Forum 8";
|
||||||
|
fi.forumFlags = 0;
|
||||||
|
fi.pop = 3;
|
||||||
|
fi.lastPost = now - 1234;
|
||||||
|
|
||||||
|
mForums.push_back(fi);
|
||||||
|
fi.forumId = "FID9012";
|
||||||
|
fi.forumName = L"Forum 9";
|
||||||
|
fi.forumDesc = L"Forum 9";
|
||||||
|
fi.forumFlags = 0;
|
||||||
|
fi.pop = 2;
|
||||||
|
fi.lastPost = now - 1234;
|
||||||
|
|
||||||
|
mForums.push_back(fi);
|
||||||
|
|
||||||
|
fi.forumId = "FID9123";
|
||||||
|
fi.forumName = L"Forum 10";
|
||||||
|
fi.forumDesc = L"Forum 10";
|
||||||
|
fi.forumFlags = 0;
|
||||||
|
fi.pop = 1;
|
||||||
|
fi.lastPost = now - 1234;
|
||||||
|
|
||||||
|
mForums.push_back(fi);
|
||||||
|
|
||||||
|
mForumsChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
60
libretroshare/src/services/p3forums.h
Normal file
60
libretroshare/src/services/p3forums.h
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#ifndef RS_P3_FORUMS_INTERFACE_H
|
||||||
|
#define RS_P3_FORUMS_INTERFACE_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libretroshare/src/services: p3forums.h
|
||||||
|
*
|
||||||
|
* RetroShare C++ Interface.
|
||||||
|
*
|
||||||
|
* Copyright 2008 by Robert Fernie.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License Version 2 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rsiface/rsforums.h"
|
||||||
|
|
||||||
|
class p3Forums: public RsForums
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
p3Forums();
|
||||||
|
virtual ~p3Forums();
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
/********* rsForums Interface ***********/
|
||||||
|
|
||||||
|
virtual bool forumsChanged(std::list<std::string> &forumIds);
|
||||||
|
|
||||||
|
virtual bool getForumList(std::list<ForumInfo> &forumList);
|
||||||
|
virtual bool getForumThreadList(std::string fId, std::list<ThreadInfoSummary> &msgs);
|
||||||
|
virtual bool getForumThreadMsgList(std::string fId, std::string tId, std::list<ThreadInfoSummary> &msgs);
|
||||||
|
virtual bool getForumMessage(std::string fId, std::string mId, ForumMsgInfo &msg);
|
||||||
|
|
||||||
|
virtual bool ForumMessageSend(ForumMsgInfo &info);
|
||||||
|
|
||||||
|
/****************************************/
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void loadDummyData();
|
||||||
|
std::list<ForumInfo> mForums;
|
||||||
|
bool mForumsChanged;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -27,106 +27,6 @@ class uPnPConfigData
|
|||||||
|
|
||||||
#include "util/rsnet.h"
|
#include "util/rsnet.h"
|
||||||
|
|
||||||
|
|
||||||
void upnphandler::run()
|
|
||||||
{
|
|
||||||
|
|
||||||
/* infinite loop */
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
std::cerr << "UPnPHandler::Run()" << std::endl;
|
|
||||||
int allowedSleep = 30; /* check every 30 seconds */
|
|
||||||
|
|
||||||
/* lock it up */
|
|
||||||
dataMtx.lock(); /* LOCK MUTEX */
|
|
||||||
|
|
||||||
bool shutdown = toShutdown;
|
|
||||||
int state = upnpState;
|
|
||||||
|
|
||||||
dataMtx.unlock(); /* UNLOCK MUTEX */
|
|
||||||
|
|
||||||
if (shutdown)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* do the work! */
|
|
||||||
checkUPnPState();
|
|
||||||
|
|
||||||
/* check new state for sleep period */
|
|
||||||
|
|
||||||
dataMtx.lock(); /* LOCK MUTEX */
|
|
||||||
|
|
||||||
state = upnpState;
|
|
||||||
|
|
||||||
dataMtx.unlock(); /* UNLOCK MUTEX */
|
|
||||||
|
|
||||||
|
|
||||||
/* state machine */
|
|
||||||
switch(state)
|
|
||||||
{
|
|
||||||
case RS_UPNP_S_UNINITIALISED:
|
|
||||||
case RS_UPNP_S_UNAVAILABLE:
|
|
||||||
/* failed ... try again in 30 min. */
|
|
||||||
allowedSleep = 1800;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RS_UPNP_S_READY:
|
|
||||||
case RS_UPNP_S_TCP_FAILED:
|
|
||||||
case RS_UPNP_S_UDP_FAILED:
|
|
||||||
case RS_UPNP_S_ACTIVE:
|
|
||||||
/* working ... normal 10 seconds */
|
|
||||||
allowedSleep = 10;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* default??? how did it get here? */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cerr << "UPnPHandler::Run() sleeping for:" << allowedSleep << std::endl;
|
|
||||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
|
||||||
#ifndef WINDOWS_SYS
|
|
||||||
sleep(allowedSleep);
|
|
||||||
#else
|
|
||||||
Sleep(1000 * allowedSleep);
|
|
||||||
#endif
|
|
||||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void upnphandler::checkUPnPState()
|
|
||||||
{
|
|
||||||
dataMtx.lock(); /* LOCK MUTEX */
|
|
||||||
|
|
||||||
int state = upnpState;
|
|
||||||
|
|
||||||
dataMtx.unlock(); /* UNLOCK MUTEX */
|
|
||||||
|
|
||||||
/* state machine */
|
|
||||||
switch(state)
|
|
||||||
{
|
|
||||||
case RS_UPNP_S_UNINITIALISED:
|
|
||||||
case RS_UPNP_S_UNAVAILABLE:
|
|
||||||
initUPnPState();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RS_UPNP_S_READY:
|
|
||||||
case RS_UPNP_S_TCP_FAILED:
|
|
||||||
case RS_UPNP_S_UDP_FAILED:
|
|
||||||
case RS_UPNP_S_ACTIVE:
|
|
||||||
printUPnPState();
|
|
||||||
checkUPnPActive();
|
|
||||||
updateUPnP();
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool upnphandler::initUPnPState()
|
bool upnphandler::initUPnPState()
|
||||||
{
|
{
|
||||||
/* allocate memory */
|
/* allocate memory */
|
||||||
@ -160,13 +60,15 @@ bool upnphandler::initUPnPState()
|
|||||||
upnp_iaddr.sin_port = htons(iport);
|
upnp_iaddr.sin_port = htons(iport);
|
||||||
|
|
||||||
upnpState = RS_UPNP_S_READY;
|
upnpState = RS_UPNP_S_READY;
|
||||||
|
if (upnpConfig)
|
||||||
|
{
|
||||||
|
delete upnpConfig;
|
||||||
|
}
|
||||||
upnpConfig = upcd; /* */
|
upnpConfig = upcd; /* */
|
||||||
|
|
||||||
dataMtx.unlock(); /* UNLOCK MUTEX */
|
dataMtx.unlock(); /* UNLOCK MUTEX */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* done -> READY */
|
/* done -> READY */
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@ -240,6 +142,7 @@ bool upnphandler::checkUPnPActive()
|
|||||||
char eport2[256];
|
char eport2[256];
|
||||||
|
|
||||||
struct sockaddr_in localAddr = upnp_iaddr;
|
struct sockaddr_in localAddr = upnp_iaddr;
|
||||||
|
uint32_t linaddr = ntohl(localAddr.sin_addr.s_addr);
|
||||||
|
|
||||||
snprintf(in_port1, 256, "%d", ntohs(localAddr.sin_port));
|
snprintf(in_port1, 256, "%d", ntohs(localAddr.sin_port));
|
||||||
snprintf(in_port2, 256, "%d", ntohs(localAddr.sin_port));
|
snprintf(in_port2, 256, "%d", ntohs(localAddr.sin_port));
|
||||||
@ -249,6 +152,12 @@ bool upnphandler::checkUPnPActive()
|
|||||||
((localAddr.sin_addr.s_addr >> 16) & 0xff),
|
((localAddr.sin_addr.s_addr >> 16) & 0xff),
|
||||||
((localAddr.sin_addr.s_addr >> 24) & 0xff));
|
((localAddr.sin_addr.s_addr >> 24) & 0xff));
|
||||||
|
|
||||||
|
snprintf(in_addr, 256, "%d.%d.%d.%d",
|
||||||
|
((linaddr >> 24) & 0xff),
|
||||||
|
((linaddr >> 16) & 0xff),
|
||||||
|
((linaddr >> 8) & 0xff),
|
||||||
|
((linaddr >> 0) & 0xff));
|
||||||
|
|
||||||
snprintf(eport1, 256, "%d", eport_curr);
|
snprintf(eport1, 256, "%d", eport_curr);
|
||||||
snprintf(eport2, 256, "%d", eport_curr);
|
snprintf(eport2, 256, "%d", eport_curr);
|
||||||
|
|
||||||
@ -280,13 +189,63 @@ bool upnphandler::checkUPnPActive()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class upnpThreadData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
upnphandler *handler;
|
||||||
|
bool start;
|
||||||
|
bool stop;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Thread routines */
|
||||||
|
extern "C" void* doSetupUPnP(void* p)
|
||||||
|
{
|
||||||
|
upnpThreadData *data = (upnpThreadData *) p;
|
||||||
|
if ((!data) || (!data->handler))
|
||||||
|
{
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
bool upnphandler::updateUPnP()
|
/* publish it! */
|
||||||
|
if (data -> stop)
|
||||||
|
{
|
||||||
|
data->handler->shutdown_upnp();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data -> start)
|
||||||
|
{
|
||||||
|
data->handler->initUPnPState();
|
||||||
|
data->handler->start_upnp();
|
||||||
|
}
|
||||||
|
|
||||||
|
data->handler->printUPnPState();
|
||||||
|
|
||||||
|
delete data;
|
||||||
|
pthread_exit(NULL);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool upnphandler::background_setup_upnp(bool start, bool stop)
|
||||||
|
{
|
||||||
|
pthread_t tid;
|
||||||
|
|
||||||
|
/* launch thread */
|
||||||
|
upnpThreadData *data = new upnpThreadData();
|
||||||
|
data->handler = this;
|
||||||
|
data->start = start;
|
||||||
|
data->stop = stop;
|
||||||
|
|
||||||
|
pthread_create(&tid, 0, &doSetupUPnP, (void *) data);
|
||||||
|
pthread_detach(tid); /* so memory is reclaimed in linux */
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool upnphandler::start_upnp()
|
||||||
{
|
{
|
||||||
dataMtx.lock(); /* LOCK MUTEX */
|
dataMtx.lock(); /* LOCK MUTEX */
|
||||||
|
|
||||||
|
|
||||||
uPnPConfigData *config = upnpConfig;
|
uPnPConfigData *config = upnpConfig;
|
||||||
if (!((upnpState >= RS_UPNP_S_READY) && (config)))
|
if (!((upnpState >= RS_UPNP_S_READY) && (config)))
|
||||||
{
|
{
|
||||||
@ -296,10 +255,117 @@ bool upnphandler::updateUPnP()
|
|||||||
char eprot1[] = "TCP";
|
char eprot1[] = "TCP";
|
||||||
char eprot2[] = "UDP";
|
char eprot2[] = "UDP";
|
||||||
|
|
||||||
/* if we're to unload -> unload */
|
/* if we're to load -> load */
|
||||||
if ((toStop) && (eport_curr > 0))
|
/* select external ports */
|
||||||
|
eport_curr = eport;
|
||||||
|
if (!eport_curr)
|
||||||
|
{
|
||||||
|
/* use local port if eport is zero */
|
||||||
|
eport_curr = iport;
|
||||||
|
std::cerr << "Using LocalPort for extPort!";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eport_curr)
|
||||||
|
{
|
||||||
|
std::cerr << "Invalid eport ... ";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* our port */
|
||||||
|
char in_addr[256];
|
||||||
|
char in_port1[256];
|
||||||
|
char in_port2[256];
|
||||||
|
char eport1[256];
|
||||||
|
char eport2[256];
|
||||||
|
|
||||||
|
upnp_iaddr.sin_port = htons(iport);
|
||||||
|
struct sockaddr_in localAddr = upnp_iaddr;
|
||||||
|
uint32_t linaddr = ntohl(localAddr.sin_addr.s_addr);
|
||||||
|
|
||||||
|
snprintf(in_port1, 256, "%d", ntohs(localAddr.sin_port));
|
||||||
|
snprintf(in_port2, 256, "%d", ntohs(localAddr.sin_port));
|
||||||
|
snprintf(in_addr, 256, "%d.%d.%d.%d",
|
||||||
|
((linaddr >> 24) & 0xff),
|
||||||
|
((linaddr >> 16) & 0xff),
|
||||||
|
((linaddr >> 8) & 0xff),
|
||||||
|
((linaddr >> 0) & 0xff));
|
||||||
|
|
||||||
|
snprintf(eport1, 256, "%d", eport_curr);
|
||||||
|
snprintf(eport2, 256, "%d", eport_curr);
|
||||||
|
|
||||||
|
std::cerr << "Attempting Redirection: InAddr: " << in_addr;
|
||||||
|
std::cerr << " InPort: " << in_port1;
|
||||||
|
std::cerr << " ePort: " << eport1;
|
||||||
|
std::cerr << " eProt: " << eprot1;
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
|
if (!SetRedirectAndTest(&(config -> urls), &(config->data),
|
||||||
|
in_addr, in_port1, eport1, eprot1))
|
||||||
|
{
|
||||||
|
upnpState = RS_UPNP_S_TCP_FAILED;
|
||||||
|
}
|
||||||
|
else if (!SetRedirectAndTest(&(config -> urls), &(config->data),
|
||||||
|
in_addr, in_port2, eport2, eprot2))
|
||||||
|
{
|
||||||
|
upnpState = RS_UPNP_S_UDP_FAILED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
upnpState = RS_UPNP_S_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* now store the external address */
|
||||||
|
char externalIPAddress[32];
|
||||||
|
UPNP_GetExternalIPAddress(config -> urls.controlURL,
|
||||||
|
config->data.servicetype,
|
||||||
|
externalIPAddress);
|
||||||
|
|
||||||
|
sockaddr_clear(&upnp_eaddr);
|
||||||
|
|
||||||
|
if(externalIPAddress[0])
|
||||||
|
{
|
||||||
|
std::cerr << "Stored External address: " << externalIPAddress;
|
||||||
|
std::cerr << ":" << eport_curr;
|
||||||
|
std::cerr << std::endl;
|
||||||
|
|
||||||
|
inet_aton(externalIPAddress, &(upnp_eaddr.sin_addr));
|
||||||
|
upnp_eaddr.sin_family = AF_INET;
|
||||||
|
upnp_eaddr.sin_port = htons(eport_curr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "FAILED To get external Address";
|
||||||
|
std::cerr << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
toStart = false;
|
||||||
|
|
||||||
|
dataMtx.unlock(); /* UNLOCK MUTEX */
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool upnphandler::shutdown_upnp()
|
||||||
|
{
|
||||||
|
dataMtx.lock(); /* LOCK MUTEX */
|
||||||
|
|
||||||
|
uPnPConfigData *config = upnpConfig;
|
||||||
|
if (!((upnpState >= RS_UPNP_S_READY) && (config)))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char eprot1[] = "TCP";
|
||||||
|
char eprot2[] = "UDP";
|
||||||
|
|
||||||
|
/* always attempt this (unless no port number) */
|
||||||
|
if (eport_curr > 0)
|
||||||
{
|
{
|
||||||
toStop = false;
|
|
||||||
|
|
||||||
char eport1[256];
|
char eport1[256];
|
||||||
char eport2[256];
|
char eport2[256];
|
||||||
@ -323,97 +389,7 @@ bool upnphandler::updateUPnP()
|
|||||||
eport2, eprot2);
|
eport2, eprot2);
|
||||||
|
|
||||||
upnpState = RS_UPNP_S_READY;
|
upnpState = RS_UPNP_S_READY;
|
||||||
}
|
toStop = false;
|
||||||
|
|
||||||
|
|
||||||
/* if we're to load -> load */
|
|
||||||
if (toStart)
|
|
||||||
{
|
|
||||||
/* select external ports */
|
|
||||||
eport_curr = eport;
|
|
||||||
if (!eport_curr)
|
|
||||||
{
|
|
||||||
/* use local port if eport is zero */
|
|
||||||
eport_curr = iport;
|
|
||||||
std::cerr << "Using LocalPort for extPort!";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!eport_curr)
|
|
||||||
{
|
|
||||||
std::cerr << "Invalid eport ... ";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
toStart = false;
|
|
||||||
|
|
||||||
/* our port */
|
|
||||||
char in_addr[256];
|
|
||||||
char in_port1[256];
|
|
||||||
char in_port2[256];
|
|
||||||
char eport1[256];
|
|
||||||
char eport2[256];
|
|
||||||
|
|
||||||
upnp_iaddr.sin_port = htons(iport);
|
|
||||||
struct sockaddr_in localAddr = upnp_iaddr;
|
|
||||||
|
|
||||||
snprintf(in_port1, 256, "%d", ntohs(localAddr.sin_port));
|
|
||||||
snprintf(in_port2, 256, "%d", ntohs(localAddr.sin_port));
|
|
||||||
snprintf(in_addr, 256, "%d.%d.%d.%d",
|
|
||||||
((localAddr.sin_addr.s_addr >> 0) & 0xff),
|
|
||||||
((localAddr.sin_addr.s_addr >> 8) & 0xff),
|
|
||||||
((localAddr.sin_addr.s_addr >> 16) & 0xff),
|
|
||||||
((localAddr.sin_addr.s_addr >> 24) & 0xff));
|
|
||||||
|
|
||||||
snprintf(eport1, 256, "%d", eport_curr);
|
|
||||||
snprintf(eport2, 256, "%d", eport_curr);
|
|
||||||
|
|
||||||
std::cerr << "Attempting Redirection: InAddr: " << in_addr;
|
|
||||||
std::cerr << " InPort: " << in_port1;
|
|
||||||
std::cerr << " ePort: " << eport1;
|
|
||||||
std::cerr << " eProt: " << eprot1;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
|
|
||||||
if (!SetRedirectAndTest(&(config -> urls), &(config->data),
|
|
||||||
in_addr, in_port1, eport1, eprot1))
|
|
||||||
{
|
|
||||||
upnpState = RS_UPNP_S_TCP_FAILED;
|
|
||||||
}
|
|
||||||
else if (!SetRedirectAndTest(&(config -> urls), &(config->data),
|
|
||||||
in_addr, in_port2, eport2, eprot2))
|
|
||||||
{
|
|
||||||
upnpState = RS_UPNP_S_UDP_FAILED;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
upnpState = RS_UPNP_S_ACTIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* now store the external address */
|
|
||||||
char externalIPAddress[32];
|
|
||||||
UPNP_GetExternalIPAddress(config -> urls.controlURL,
|
|
||||||
config->data.servicetype,
|
|
||||||
externalIPAddress);
|
|
||||||
|
|
||||||
sockaddr_clear(&upnp_eaddr);
|
|
||||||
|
|
||||||
if(externalIPAddress[0])
|
|
||||||
{
|
|
||||||
std::cerr << "Stored External address: " << externalIPAddress;
|
|
||||||
std::cerr << ":" << eport_curr;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
|
|
||||||
inet_aton(externalIPAddress, &(upnp_eaddr.sin_addr));
|
|
||||||
upnp_eaddr.sin_family = AF_INET;
|
|
||||||
upnp_eaddr.sin_port = htons(eport_curr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::cerr << "FAILED To get external Address";
|
|
||||||
std::cerr << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dataMtx.unlock(); /* UNLOCK MUTEX */
|
dataMtx.unlock(); /* UNLOCK MUTEX */
|
||||||
@ -422,7 +398,6 @@ bool upnphandler::updateUPnP()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************ External Interface *****************************
|
/************************ External Interface *****************************
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
@ -430,8 +405,7 @@ bool upnphandler::updateUPnP()
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
upnphandler::upnphandler()
|
upnphandler::upnphandler()
|
||||||
:toShutdown(false), toEnable(false),
|
:toEnable(false), toStart(false), toStop(false),
|
||||||
toStart(false), toStop(false),
|
|
||||||
eport(0), eport_curr(0),
|
eport(0), eport_curr(0),
|
||||||
upnpState(RS_UPNP_S_UNINITIALISED),
|
upnpState(RS_UPNP_S_UNINITIALISED),
|
||||||
upnpConfig(NULL)
|
upnpConfig(NULL)
|
||||||
@ -462,19 +436,36 @@ void upnphandler::enableUPnP(bool active)
|
|||||||
}
|
}
|
||||||
toEnable = active;
|
toEnable = active;
|
||||||
|
|
||||||
|
bool start = toStart;
|
||||||
|
|
||||||
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
||||||
|
|
||||||
|
if (start)
|
||||||
|
{
|
||||||
|
/* make background thread to startup UPnP */
|
||||||
|
background_setup_upnp(true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void upnphandler::shutdownUPnP()
|
void upnphandler::shutdownUPnP()
|
||||||
{
|
{
|
||||||
dataMtx.lock(); /*** LOCK MUTEX ***/
|
/* blocking call to shutdown upnp */
|
||||||
|
|
||||||
toShutdown = true;
|
shutdown_upnp();
|
||||||
|
|
||||||
dataMtx.unlock(); /*** UNLOCK MUTEX ***/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void upnphandler::restartUPnP()
|
||||||
|
{
|
||||||
|
/* non-blocking call to shutdown upnp, and startup again. */
|
||||||
|
background_setup_upnp(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool upnphandler::getUPnPEnabled()
|
bool upnphandler::getUPnPEnabled()
|
||||||
{
|
{
|
||||||
dataMtx.lock(); /*** LOCK MUTEX ***/
|
dataMtx.lock(); /*** LOCK MUTEX ***/
|
||||||
|
@ -52,6 +52,7 @@ virtual ~upnphandler();
|
|||||||
/* External Interface */
|
/* External Interface */
|
||||||
virtual void enableUPnP(bool active);
|
virtual void enableUPnP(bool active);
|
||||||
virtual void shutdownUPnP();
|
virtual void shutdownUPnP();
|
||||||
|
virtual void restartUPnP();
|
||||||
|
|
||||||
virtual bool getUPnPEnabled();
|
virtual bool getUPnPEnabled();
|
||||||
virtual bool getUPnPActive();
|
virtual bool getUPnPActive();
|
||||||
@ -61,25 +62,24 @@ virtual void setExternalPort(unsigned short eport_in);
|
|||||||
virtual bool getInternalAddress(struct sockaddr_in &addr);
|
virtual bool getInternalAddress(struct sockaddr_in &addr);
|
||||||
virtual bool getExternalAddress(struct sockaddr_in &addr);
|
virtual bool getExternalAddress(struct sockaddr_in &addr);
|
||||||
|
|
||||||
/* must run thread */
|
/* Public functions - for background thread operation,
|
||||||
virtual void run();
|
* but effectively private from rest of RS, as in derived class
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool start_upnp();
|
||||||
|
bool shutdown_upnp();
|
||||||
|
|
||||||
|
bool initUPnPState();
|
||||||
|
bool printUPnPState();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool initUPnPState();
|
bool background_setup_upnp(bool, bool);
|
||||||
void checkUPnPState();
|
|
||||||
bool printUPnPState();
|
|
||||||
|
|
||||||
bool checkUPnPActive();
|
bool checkUPnPActive();
|
||||||
bool updateUPnP();
|
|
||||||
|
|
||||||
|
|
||||||
/* Mutex for data below */
|
/* Mutex for data below */
|
||||||
RsMutex dataMtx;
|
RsMutex dataMtx;
|
||||||
|
|
||||||
/* requested from rs */
|
|
||||||
bool toShutdown; /* if set shuts down the thread. */
|
|
||||||
|
|
||||||
bool toEnable; /* overall on/off switch */
|
bool toEnable; /* overall on/off switch */
|
||||||
bool toStart; /* if set start forwarding */
|
bool toStart; /* if set start forwarding */
|
||||||
bool toStop; /* if set stop forwarding */
|
bool toStop; /* if set stop forwarding */
|
||||||
|
@ -47,7 +47,6 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
upnphandler upnp;
|
upnphandler upnp;
|
||||||
|
|
||||||
upnp.start();
|
|
||||||
upnp.setInternalPort(12122);
|
upnp.setInternalPort(12122);
|
||||||
|
|
||||||
for(int i = 0; 1; i++)
|
for(int i = 0; 1; i++)
|
||||||
@ -62,19 +61,24 @@ int main(int argc, char **argv)
|
|||||||
#endif
|
#endif
|
||||||
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
/********************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||||
|
|
||||||
if (i % 300 == 10)
|
if (i % 120 == 10)
|
||||||
{
|
{
|
||||||
/* start up a forward */
|
/* start up a forward */
|
||||||
upnp.enableUPnP(true);
|
upnp.enableUPnP(true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i % 300 == 120)
|
if (i % 120 == 60)
|
||||||
{
|
{
|
||||||
/* shutdown a forward */
|
/* shutdown a forward */
|
||||||
upnp.enableUPnP(false);
|
upnp.restartUPnP();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i % 120 == 100)
|
||||||
|
{
|
||||||
|
/* shutdown a forward */
|
||||||
|
upnp.shutdownUPnP();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,10 @@ bool SetRedirectAndTest(struct UPNPUrls * urls,
|
|||||||
|
|
||||||
// Unix at the moment!
|
// Unix at the moment!
|
||||||
r = UPNP_AddPortMapping(urls->controlURL, data->servicetype,
|
r = UPNP_AddPortMapping(urls->controlURL, data->servicetype,
|
||||||
eport, iport, iaddr, 0, leaseDuration, proto);
|
eport, iport, iaddr, 0, 0, proto);
|
||||||
|
|
||||||
|
// r = UPNP_AddPortMapping(urls->controlURL, data->servicetype,
|
||||||
|
// eport, iport, iaddr, 0, leaseDuration, proto);
|
||||||
|
|
||||||
// r = UPNP_AddPortMapping(urls->controlURL, data->servicetype,
|
// r = UPNP_AddPortMapping(urls->controlURL, data->servicetype,
|
||||||
// eport, iport, iaddr, 0, proto);
|
// eport, iport, iaddr, 0, proto);
|
||||||
|
Loading…
Reference in New Issue
Block a user