* Addition of almost completed p3ranking class - still streaming / ranking to do.

* Major modifications to p3disc to use the new AuthMgr and ConnMgr.
 * Modified RsDiscItems to match new p3disc.
 * Modified ConnMgr to accept information from p3disc.
 * Addition of new Load/Save Certificate From/To Binary to AuthMgr.
 * Corrected default build to Linux.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@325 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2008-02-03 06:29:02 +00:00
parent 3451af6152
commit 06aae24efd
19 changed files with 1541 additions and 2171 deletions

View file

@ -7,8 +7,8 @@ RS_TOP_DIR = ..
include $(RS_TOP_DIR)/scripts/config.mk
###############################################################
RSOBJ = p3service.o p3chatservice.o p3msgservice.o p3gamelauncher.o
#p3disc.o
RSOBJ = p3service.o p3chatservice.o p3msgservice.o \
p3gamelauncher.o p3ranking.o p3disc.o
#TESTOBJ =

File diff suppressed because it is too large Load diff

View file

@ -39,6 +39,7 @@
class p3ConnectMgr;
class p3AuthMgr;
#include "pqi/pqimonitor.h"
#include "serialiser/rsdiscitems.h"
#include "services/p3service.h"
@ -46,20 +47,14 @@ class autoserver
{
public:
autoserver()
:id(NULL), ca(NULL), connect(false), c_ts(0),
listen(false), l_ts(0), discFlags(0) { return;}
:ts(0), discFlags(0) { return;}
std::string id;
std::string ca;
bool connect;
unsigned int c_ts; // this is connect_tf converted to timestamp, 0 invalid.
struct sockaddr_in localAddr;
struct sockaddr_in remoteAddr;
bool listen;
unsigned int l_ts; // this is receive_tf converted to timestamp, 0 invalid.
struct sockaddr_in local_addr;
struct sockaddr_in server_addr;
unsigned long discFlags;
time_t ts;
uint32_t discFlags;
};
@ -67,95 +62,69 @@ class autoneighbour: public autoserver
{
public:
autoneighbour()
:autoserver(), local(false), active(false) {}
:autoserver(), authoritative(false) {}
bool local;
bool active; // meaning in ssl's list.
std::list<autoserver *> neighbour_of;
bool authoritative;
bool validAddrs;
std::map<std::string, autoserver> neighbour_of;
};
class p3AuthMgr;
class p3ConnectMgr;
class p3disc: public p3Service
class p3disc: public p3Service, public pqiMonitor
{
public:
bool local_disc;
bool remote_disc;
//sslroot *sslbase;
p3disc(p3AuthMgr *am, p3ConnectMgr *cm);
virtual ~p3disc();
// Overloaded from p3Service functions.
virtual int tick();
// For Proxy Information.
std::list<sockaddr_in> requestStunServers();
std::list<cert *> potentialproxy(cert *target);
p3disc(p3AuthMgr *am, p3ConnectMgr *cm);
// load and save configuration to sslroot.
int save_configuration();
int load_configuration();
/************* from pqiMonitor *******************/
virtual void statusChange(const std::list<pqipeer> &plist);
/************* from pqiMonitor *******************/
int ts_lastcheck;
int tick();
int idServers();
// Handle Local Discovery.
int localListen();
int localSetup();
int lsock; // local discovery socket.
struct sockaddr_in laddr; // local addr
struct sockaddr_in baddr; // local broadcast addr.
struct sockaddr_in saddr; // pqi ssl server addr.
// bonus configuration flags.
bool local_firewalled;
bool local_forwarded;
private:
// local message construction/destruction.
void *ldata;
int ldlen;
int ldlenmax;
void respondToPeer(std::string id);
/* Network Output */
void sendOwnDetails(std::string to);
void sendPeerDetails(std::string to, std::string about);
bool std_port; // if we have bound to default.
int ts_nextlp; // -1 for never (if on default)
/* Network Input */
int handleIncoming();
void recvPeerOwnMsg(RsDiscItem *item);
void recvPeerFriendMsg(RsDiscReply *item);
// helper functions.
int setLocalAddress(struct sockaddr_in srvaddr);
int determineLocalNetAddr();
int setupLocalPacket(int type, struct sockaddr_in *home,
struct sockaddr_in *server);
int localPing(struct sockaddr_in);
int localReply(struct sockaddr_in);
int addLocalNeighbour(struct sockaddr_in*, struct sockaddr_in*);
/* handle network shape */
int addDiscoveryData(std::string fromId, std::string aboutId,
struct sockaddr_in laddr, struct sockaddr_in raddr,
uint32_t flags, time_t ts);
// remote discovery function.
int newRequests();
int handleReplies();
bool potentialproxies(std::string id, std::list<std::string> proxyIds);
int idServers();
int handleDiscoveryData(RsDiscReply *di);
int handleDiscoveryPing(RsDiscItem *di);
int sendDiscoveryReply(cert *);
int collectCerts();
int distillData();
/* data */
#if 0
//cert *checkDuplicateX509(X509 *x509);
std::list<cert *> &getDiscovered();
private:
// Main Storage
std::list<cert *> ad_init;
std::list<cert *> discovered;
#endif
std::list<autoneighbour *> neighbours;
p3AuthMgr *mAuthMgr;
p3ConnectMgr *mConnMgr;
bool mRemoteDisc;
bool mLocalDisc;
std::map<std::string, autoneighbour> neighbours;
p3AuthMgr *mAuthMgr;
p3ConnectMgr *mConnMgr;
};
#endif // MRK_PQI_AUTODISC_H

View file

@ -0,0 +1,435 @@
/*
* libretroshare/src/services p3ranking.cc
*
* 3P/PQI network interface for RetroShare.
*
* 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/p3ranking.h"
#include "pqi/pqibin.h"
#include "pqi/p3authmgr.h"
const uint32_t RANK_MAX_FWD_OFFSET = (60 * 60 * 24 * 2); /* 2 Days */
std::string generateRandomLinkId();
/*****
* TODO
* (1) Streaming.
* (2) Ranking.
*
*/
p3Ranking::p3Ranking(uint16_t subtype, CacheTransfer *cft,
std::string sourcedir, std::string storedir,
uint32_t storePeriod)
:CacheSource(subtype, true, sourcedir),
CacheStore(subtype, true, cft, storedir),
mStorePeriod(storePeriod)
{
mOwnId = getAuthMgr()->OwnId();
createDummyData();
return;
}
bool p3Ranking::loadLocalCache(const CacheData &data)
{
return true;
}
int p3Ranking::loadCache(const CacheData &data)
{
return 1;
}
void p3Ranking::loadRankFile(std::string filename, std::string src)
{
#if 0
/* create the serialiser to load info */
pqistreamer *streamer = createStreamer(filename, src, BIN_FLAGS_READABLE);
time_t now = time(NULL);
time_t min = now - mStorePeriod;
time_t max = now + RANK_MAX_FWD_OFFSET;
RsItem *item;
RsRankMsg *newMsg;
while(NULL != (item = streamer->GetItem()))
{
newMsg = (RsRankMsg *) item;
/* check timestamp */
if ((newMsg->timestamp < min) || (newMsg->timestamp > max))
{
/* if outside range -> remove */
delete newMsg;
}
else
{
addRankMsg(newMsg);
}
}
#endif
}
void p3Ranking::publishMsgs()
{
#if 0
/* create a serialiser */
std::string file;
pqistreamer *stream = createStreamer(file, mOwnId, BIN_FLAGS_NO_DELETE | BIN_FLAGS_HASH_DATA);
/* iterate through list */
std::map<std::string, RankGroup>::iterator it;
for(it = mData.begin(); it != mData.end(); it++)
{
if (it->second.ownTag)
{
/* write to serialiser */
RsItem *item = it->second.comments[mOwnId];
if (item)
stream->SendItem(item);
}
}
CacheData data;
data.pid = mOwnId;
data.cid = CacheId(CacheSource::getCacheType(), 0);
data.name = file;
refreshCache(data);
#endif
}
void p3Ranking::addRankMsg(RsRankMsg *msg)
{
/* find msg */
std::string id = msg->PeerId();
std::string rid = msg->rid;
std::map<std::string, RankGroup>::iterator it;
it = mData.find(rid);
if (it == mData.end())
{
/* add a new one */
RankGroup grp;
grp.rid = rid;
grp.ownTag = false;
/******** LINK SPECIFIC ****/
grp.link = msg->link;
grp.title = msg->title;
mData[rid] = grp;
it = mData.find(rid);
}
/* check for old comment */
std::map<std::string, RsRankMsg *>::iterator cit;
cit = (it->second).comments.find(id);
if ((it->second).comments.end() != cit)
{
(it->second).comments.erase(cit);
}
(it->second).comments[id] = msg;
if (id == mOwnId)
{
it->second.ownTag = true;
mRepublish = true;
}
reSortGroup(it->second);
}
/***************** Sorting ****************/
bool p3Ranking::setSortPeriod(uint32_t period)
{
mViewPeriod = period;
return true;
}
bool p3Ranking::setSortMethod(uint32_t type)
{
mSortType = type;
return true;
}
bool p3Ranking::clearPeerFilter()
{
mPeerFilter.clear();
return true;
}
bool p3Ranking::setPeerFilter(std::list<std::string> peers)
{
mPeerFilter = peers;
return true;
}
float p3Ranking::locked_calcRank(RankGroup &grp) /* returns 0->100 */
{
#if 0
/* where all the work is done */
bool doScore = (mSortType ==
bool doTime = (mSortType ==
bool doFilter = (mPeerFilter.size() > 0);
float rank = 0;
for(it = grp.comments.begin(); it != grp.comments.end(); it++)
{
if (doFilter)
{
/* do first so we can discard */
if (doScore)
if (mSortType
#endif
return 100;
}
void p3Ranking::reSortGroup(RankGroup &grp)
{
std::string rid = grp.rid;
float rank = grp.rank;
/* remove from existings rankings */
std::multimap<float, std::string>::iterator rit;
rit = mRankings.lower_bound(grp.rank);
for(; (rit != mRankings.end()) && (rit->first == grp.rank); rit++)
{
if (rit->second == rid)
{
mRankings.erase(rit);
break;
}
}
/* add it back in */
grp.rank = locked_calcRank(grp);
mRankings.insert(
std::pair<float, std::string>(grp.rank, rid));
}
void p3Ranking::sortAllMsgs()
{
/* iterate through list and re-score each one */
std::map<std::string, RankGroup>::iterator it;
mRankings.clear();
for(it = mData.begin(); it != mData.end(); it++)
{
(it->second).rank = locked_calcRank(it->second);
if (it->second.rank > 0)
{
mRankings.insert(
std::pair<float, std::string>
(it->second.rank, it->first));
}
}
}
/******** ACCESS *************/
/* get Ids */
uint32_t p3Ranking::getRankingsCount()
{
return mRankings.size();
}
float p3Ranking::getMaxRank()
{
if (mRankings.size() == 0)
return 0;
return mRankings.rbegin()->first;
}
bool p3Ranking::getRankings(uint32_t first, uint32_t count, std::list<std::string> &rids)
{
uint32_t i = 0;
std::multimap<float, std::string>::iterator rit;
for(rit = mRankings.begin(); (i < first) && (rit != mRankings.end()); rit++);
i = 0;
for(; (i < count) && (rit != mRankings.end()); rit++)
{
rids.push_back(rit->second);
}
return true;
}
bool p3Ranking::getRankDetails(std::string rid, RsRankDetails &details)
{
/* get the details. */
std::map<std::string, RankGroup>::iterator it;
it = mData.find(rid);
if (mData.end() == it)
{
return false;
}
details.rid = it->first;
details.link = (it->second).link;
details.title = (it->second).title;
details.rank = (it->second).rank;
details.ownTag = (it->second).ownTag;
std::map<std::string, RsRankMsg *>::iterator cit;
for(cit = (it->second).comments.begin();
cit != (it->second).comments.end(); cit++)
{
RsRankComment comm;
comm.id = (cit->second)->PeerId();
comm.timestamp = (cit->second)->timestamp;
comm.comment = (cit->second)->comment;
details.comments.push_back(comm);
}
return true;
}
void p3Ranking::tick()
{
if (mRepublish)
{
publishMsgs();
mRepublish = false;
}
}
/***** NEW CONTENT *****/
std::string p3Ranking::newRankMsg(std::wstring link, std::wstring title, std::wstring comment)
{
/* generate an id */
std::string rid = generateRandomLinkId();
RsRankMsg *msg = new RsRankMsg();
time_t now = time(NULL);
msg->PeerId(mOwnId);
msg->rid = rid;
msg->title = title;
msg->timestamp = now;
msg->link = link;
msg->comment = comment;
addRankMsg(msg);
return rid;
}
bool p3Ranking::updateComment(std::string rid, std::wstring comment)
{
return true;
}
pqistreamer *createStreamer(std::string file, std::string src, uint32_t bioflags)
{
#if 0
RsSerialiser *rsSerialiser = new RsSerialiser();
RsSerialType *serialType = new RsRankSerial(); /* TODO */
rsSerialiser->addSerialType(serialType);
BinInterface *bio = BinFileInterface(file.c_str(), bioflags);
pqistreamer *streamer = new pqistreamer(rsSerialiser, src, bio, 0);
return streamer;
#endif
return NULL;
}
std::string generateRandomLinkId()
{
std::ostringstream out;
out << std::hex;
/* 4 bytes per random number: 4 x 4 = 16 bytes */
for(int i = 0; i < 4; i++)
{
uint32_t rint = random();
out << rint;
}
return out.str();
}
void p3Ranking::createDummyData()
{
RsRankMsg *msg = new RsRankMsg();
time_t now = time(NULL);
msg->PeerId(mOwnId);
msg->rid = "0001";
msg->title = L"Original Awesome Site!";
msg->timestamp = now - 12345;
msg->link = L"http://www.retroshare.org";
msg->comment = L"Retroshares Website";
addRankMsg(msg);
msg = new RsRankMsg();
msg->PeerId(mOwnId);
msg->rid = "0002";
msg->title = L"Awesome Site!";
msg->timestamp = now - 123;
msg->link = L"http://www.lunamutt.org";
msg->comment = L"Lunamutt's Website";
addRankMsg(msg);
msg = new RsRankMsg();
msg->PeerId("ALTID");
msg->rid = "0002";
msg->title = L"Awesome Site!";
msg->timestamp = now - 12345;
msg->link = L"http://www.lunamutt.org";
msg->comment = L"Lunamutt's Website (TWO) How Long can this comment be!\n";
msg->comment += L"What happens to the second line?\n";
msg->comment += L"And a 3rd!";
addRankMsg(msg);
}

View file

@ -0,0 +1,158 @@
/*
* libretroshare/src/services: p3ranking.h
*
* 3P/PQI network interface for RetroShare.
*
* 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".
*
*/
#ifndef P3_GENERIC_RANKING_HEADER
#define P3_GENERIC_RANKING_HEADER
#include "dbase/cachestrapper.h"
#include "pqi/pqiservice.h"
#include "pqi/pqistreamer.h"
//#include "util/rsthreads.h"
#include "serialiser/rsserial.h"
#include "rsiface/rsrank.h"
/*
* A Generic Ranking system.
* Each User provides one cache...
*
* can be overloaded for specific types
* (links, shares, photos etc)
*/
class RsRankMsg: public RsItem
{
public:
//std::string peerId; /* From */
std::string rid; /* Random Id */
time_t timestamp;
std::wstring link;
std::wstring title;
std::wstring comment;
RsRankMsg():RsItem(0) { return; }
virtual void clear()
{ return; }
virtual std::ostream& print(std::ostream &out, uint16_t)
{ return out; }
};
class RsRankSerial: public RsSerialType
{
public:
RsRankSerial()
:RsSerialType(0,0,0)
{ return; }
};
/* group these together */
class RankGroup
{
public:
std::string rid; /* Random Id */
std::wstring link;
std::wstring title;
float rank;
bool ownTag;
std::map<std::string, RsRankMsg *> comments;
};
class p3Ranking: public CacheSource, public CacheStore
{
public:
p3Ranking(uint16_t subtype, CacheTransfer *cft,
std::string sourcedir, std::string storedir,
uint32_t storePeriod);
/******************************* CACHE SOURCE / STORE Interface *********************/
/* overloaded functions from Cache Source */
virtual bool loadLocalCache(const CacheData &data);
/* overloaded functions from Cache Store */
virtual int loadCache(const CacheData &data);
/******************************* CACHE SOURCE / STORE Interface *********************/
public:
/************* Extern Interface *******/
/* Set Sort Methods */
virtual bool setSortPeriod(uint32_t period);
virtual bool setSortMethod(uint32_t type);
virtual bool clearPeerFilter();
virtual bool setPeerFilter(std::list<std::string> peers);
/* get Ids */
virtual uint32_t getRankingsCount();
virtual float getMaxRank();
virtual bool getRankings(uint32_t first, uint32_t count, std::list<std::string> &rids);
virtual bool getRankDetails(std::string rid, RsRankDetails &details);
/* Add New Comment / Msg */
virtual std::string newRankMsg(std::wstring link, std::wstring title, std::wstring comment);
virtual bool updateComment(std::string rid, std::wstring comment);
void tick();
void loadRankFile(std::string filename, std::string src);
void addRankMsg(RsRankMsg *msg);
void publishMsgs();
float locked_calcRank(RankGroup &grp); /* returns 0->100 */
void reSortGroup(RankGroup &grp);
void sortAllMsgs();
pqistreamer *createStreamer(std::string file, std::string src, uint32_t bioflags);
private:
void createDummyData();
bool mRepublish;
uint32_t mStorePeriod;
std::string mOwnId;
std::map<std::string, RankGroup> mData;
std::multimap<float, std::string> mRankings;
/* Filter/Sort params */
std::list<std::string> mPeerFilter;
uint32_t mViewPeriod;
uint32_t mSortType;
};
#endif