2012-08-06 17:00:38 -04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* libretroshare/src/gxs: rsgxnetservice.cc
|
|
|
|
*
|
|
|
|
* Access to rs network and synchronisation service implementation
|
|
|
|
*
|
|
|
|
* Copyright 2012-2012 by Christopher Evi-Parker
|
|
|
|
*
|
|
|
|
* 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".
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2012-12-16 16:12:26 -05:00
|
|
|
#include <unistd.h>
|
2013-02-07 18:04:16 -05:00
|
|
|
#include <math.h>
|
2012-12-16 16:12:26 -05:00
|
|
|
|
2012-06-07 16:43:12 -04:00
|
|
|
#include "rsgxsnetservice.h"
|
2013-02-28 16:58:38 -05:00
|
|
|
#include "retroshare/rsgxsflags.h"
|
2013-06-04 17:00:43 -04:00
|
|
|
#include "retroshare/rsgxscircles.h"
|
2014-04-27 09:14:07 -04:00
|
|
|
#include "pgp/pgpauxutils.h"
|
|
|
|
|
|
|
|
/***
|
|
|
|
* #define NXS_NET_DEBUG 1
|
|
|
|
***/
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
#define GIXS_CUT_OFF 0
|
2012-07-14 13:59:54 -04:00
|
|
|
|
2014-10-09 13:20:09 -04:00
|
|
|
#define SYNC_PERIOD 60 // every 60 seconds (1 second for testing)
|
|
|
|
#define TRANSAC_TIMEOUT 30 // 30 seconds. Has been increased to avoid epidemic transaction cancelling.
|
2012-07-14 13:59:54 -04:00
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
const uint32_t RsGxsNetService::FRAGMENT_SIZE = 150000;
|
2012-07-12 16:18:58 -04:00
|
|
|
|
2012-07-05 17:26:14 -04:00
|
|
|
RsGxsNetService::RsGxsNetService(uint16_t servType, RsGeneralDataService *gds,
|
2014-03-21 23:53:44 -04:00
|
|
|
RsNxsNetMgr *netMgr, RsNxsObserver *nxsObs,
|
|
|
|
const RsServiceInfo serviceInfo,
|
2014-04-27 09:14:07 -04:00
|
|
|
RsGixsReputation* reputations, RsGcxs* circles,
|
|
|
|
PgpAuxUtils *pgpUtils, bool grpAutoSync)
|
2014-03-29 01:20:57 -04:00
|
|
|
: p3ThreadedService(), p3Config(), mTransactionN(0),
|
2014-03-23 08:13:44 -04:00
|
|
|
mObserver(nxsObs), mDataStore(gds), mServType(servType),
|
|
|
|
mTransactionTimeOut(TRANSAC_TIMEOUT), mNetMgr(netMgr), mNxsMutex("RsGxsNetService"),
|
2014-10-05 15:14:05 -04:00
|
|
|
mSyncTs(0), mLastKeyPublishTs(0), mSYNC_PERIOD(SYNC_PERIOD), mCircles(circles), mReputations(reputations),
|
2014-04-27 09:14:07 -04:00
|
|
|
mPgpUtils(pgpUtils),
|
|
|
|
mGrpAutoSync(grpAutoSync), mGrpServerUpdateItem(NULL),
|
2014-03-21 23:53:44 -04:00
|
|
|
mServiceInfo(serviceInfo)
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-06-07 16:43:12 -04:00
|
|
|
{
|
2012-07-12 16:18:58 -04:00
|
|
|
addSerialType(new RsNxsSerialiser(mServType));
|
2012-07-15 08:38:20 -04:00
|
|
|
mOwnId = mNetMgr->getOwnId();
|
2012-06-07 16:43:12 -04:00
|
|
|
}
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
RsGxsNetService::~RsGxsNetService()
|
|
|
|
{
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
}
|
2012-06-07 16:43:12 -04:00
|
|
|
|
|
|
|
|
2014-04-27 09:14:07 -04:00
|
|
|
int RsGxsNetService::tick()
|
|
|
|
{
|
2012-07-12 16:18:58 -04:00
|
|
|
// always check for new items arriving
|
|
|
|
// from peers
|
2012-06-07 16:43:12 -04:00
|
|
|
if(receivedItems())
|
|
|
|
recvNxsItemQueue();
|
|
|
|
|
2014-10-05 15:14:05 -04:00
|
|
|
time_t now = time(NULL);
|
|
|
|
time_t elapsed = mSYNC_PERIOD + mSyncTs;
|
2012-07-12 16:18:58 -04:00
|
|
|
|
2012-08-28 17:11:54 -04:00
|
|
|
if((elapsed) < now)
|
2012-07-12 16:18:58 -04:00
|
|
|
{
|
|
|
|
syncWithPeers();
|
2012-07-14 13:59:54 -04:00
|
|
|
mSyncTs = now;
|
2012-07-12 16:18:58 -04:00
|
|
|
}
|
|
|
|
|
2014-10-05 15:14:05 -04:00
|
|
|
if(now > 10 + mLastKeyPublishTs)
|
|
|
|
{
|
|
|
|
sharePublishKeysPending() ;
|
|
|
|
mLastKeyPublishTs = now ;
|
|
|
|
}
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RsGxsNetService::syncWithPeers()
|
|
|
|
{
|
2014-04-27 09:14:07 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::syncWithPeers()";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
2012-07-12 16:18:58 -04:00
|
|
|
|
2014-05-01 14:50:07 -04:00
|
|
|
RsStackMutex stack(mNxsMutex);
|
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
std::set<RsPeerId> peers;
|
2014-03-28 23:57:44 -04:00
|
|
|
mNetMgr->getOnlineList(mServiceInfo.mServiceType, peers);
|
2012-07-12 16:18:58 -04:00
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
std::set<RsPeerId>::iterator sit = peers.begin();
|
2012-07-12 16:18:58 -04:00
|
|
|
|
2013-11-03 18:46:34 -05:00
|
|
|
if(mGrpAutoSync)
|
2013-02-07 18:04:16 -05:00
|
|
|
{
|
2013-11-03 18:46:34 -05:00
|
|
|
// for now just grps
|
|
|
|
for(; sit != peers.end(); sit++)
|
|
|
|
{
|
2013-11-16 08:40:04 -05:00
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
const RsPeerId peerId = *sit;
|
2013-11-16 08:40:04 -05:00
|
|
|
|
|
|
|
ClientGrpMap::const_iterator cit = mClientGrpUpdateMap.find(peerId);
|
|
|
|
uint32_t updateTS = 0;
|
|
|
|
if(cit != mClientGrpUpdateMap.end())
|
|
|
|
{
|
|
|
|
const RsGxsGrpUpdateItem *gui = cit->second;
|
|
|
|
updateTS = gui->grpUpdateTS;
|
|
|
|
}
|
|
|
|
RsNxsSyncGrp *grp = new RsNxsSyncGrp(mServType);
|
|
|
|
grp->clear();
|
|
|
|
grp->PeerId(*sit);
|
|
|
|
grp->updateTS = updateTS;
|
|
|
|
sendItem(grp);
|
2013-11-03 18:46:34 -05:00
|
|
|
}
|
2013-02-07 18:04:16 -05:00
|
|
|
}
|
2012-11-24 14:49:23 -05:00
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
#ifndef GXS_DISABLE_SYNC_MSGS
|
2014-05-01 14:50:07 -04:00
|
|
|
|
|
|
|
typedef std::map<RsGxsGroupId, RsGxsGrpMetaData* > GrpMetaMap;
|
|
|
|
GrpMetaMap grpMeta;
|
|
|
|
|
2012-09-04 18:32:52 -04:00
|
|
|
mDataStore->retrieveGxsGrpMetaData(grpMeta);
|
|
|
|
|
2014-05-01 14:50:07 -04:00
|
|
|
GrpMetaMap::iterator
|
2012-09-04 18:32:52 -04:00
|
|
|
mit = grpMeta.begin();
|
|
|
|
|
2014-05-01 14:50:07 -04:00
|
|
|
GrpMetaMap toRequest;
|
2012-09-04 18:32:52 -04:00
|
|
|
|
|
|
|
for(; mit != grpMeta.end(); mit++)
|
|
|
|
{
|
|
|
|
RsGxsGrpMetaData* meta = mit->second;
|
|
|
|
|
2013-03-19 16:13:13 -04:00
|
|
|
if(meta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED )
|
2013-11-16 08:40:04 -05:00
|
|
|
{
|
2014-05-01 14:50:07 -04:00
|
|
|
toRequest.insert(std::make_pair(mit->first, meta));
|
|
|
|
}else
|
|
|
|
delete meta;
|
2012-09-04 18:32:52 -04:00
|
|
|
}
|
|
|
|
|
2014-05-01 14:50:07 -04:00
|
|
|
grpMeta.clear();
|
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
sit = peers.begin();
|
2012-09-04 18:32:52 -04:00
|
|
|
|
2012-09-30 10:21:17 -04:00
|
|
|
// synchronise group msg for groups which we're subscribed to
|
2012-09-01 10:47:22 -04:00
|
|
|
for(; sit != peers.end(); sit++)
|
|
|
|
{
|
2014-05-01 14:50:07 -04:00
|
|
|
const RsPeerId& peerId = *sit;
|
2012-09-30 10:21:17 -04:00
|
|
|
|
|
|
|
|
2013-11-16 08:40:04 -05:00
|
|
|
// now see if you have an updateTS so optimise whether you need
|
|
|
|
// to get a new list of peer data
|
|
|
|
RsGxsMsgUpdateItem* mui = NULL;
|
|
|
|
|
2014-05-01 14:50:07 -04:00
|
|
|
ClientMsgMap::const_iterator cit = mClientMsgUpdateMap.find(peerId);
|
2013-11-16 08:40:04 -05:00
|
|
|
|
|
|
|
if(cit != mClientMsgUpdateMap.end())
|
|
|
|
{
|
|
|
|
mui = cit->second;
|
|
|
|
}
|
|
|
|
|
2014-05-01 14:50:07 -04:00
|
|
|
GrpMetaMap::const_iterator mmit = toRequest.begin();
|
|
|
|
for(; mmit != toRequest.end(); mmit++)
|
2012-09-30 10:21:17 -04:00
|
|
|
{
|
2014-05-01 14:50:07 -04:00
|
|
|
const RsGxsGrpMetaData* meta = mmit->second;
|
|
|
|
const RsGxsGroupId& grpId = mmit->first;
|
|
|
|
|
|
|
|
if(!checkCanRecvMsgFromPeer(peerId, *meta))
|
|
|
|
continue;
|
|
|
|
|
2013-11-16 08:40:04 -05:00
|
|
|
uint32_t updateTS = 0;
|
|
|
|
if(mui)
|
|
|
|
{
|
2014-05-01 14:50:07 -04:00
|
|
|
std::map<RsGxsGroupId, uint32_t>::const_iterator cit2 =
|
|
|
|
mui->msgUpdateTS.find(grpId);
|
2013-11-16 08:40:04 -05:00
|
|
|
|
|
|
|
if(cit2 != mui->msgUpdateTS.end())
|
|
|
|
{
|
|
|
|
updateTS = cit2->second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RsNxsSyncMsg* msg = new RsNxsSyncMsg(mServType);
|
|
|
|
msg->clear();
|
2014-05-01 14:50:07 -04:00
|
|
|
msg->PeerId(peerId);
|
|
|
|
msg->grpId = grpId;
|
2013-11-16 08:40:04 -05:00
|
|
|
msg->updateTS = updateTS;
|
|
|
|
sendItem(msg);
|
2012-09-30 10:21:17 -04:00
|
|
|
}
|
2012-09-01 10:47:22 -04:00
|
|
|
}
|
2014-05-01 14:50:07 -04:00
|
|
|
|
|
|
|
GrpMetaMap::iterator mmit = toRequest.begin();
|
|
|
|
for(; mmit != toRequest.end(); mmit++)
|
|
|
|
{
|
|
|
|
delete mmit->second;
|
|
|
|
}
|
2012-11-24 14:49:23 -05:00
|
|
|
#endif
|
2012-06-07 16:43:12 -04:00
|
|
|
}
|
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
|
|
|
|
bool RsGxsNetService::fragmentMsg(RsNxsMsg& msg, MsgFragments& msgFragments) const
|
|
|
|
{
|
|
|
|
// first determine how many fragments
|
|
|
|
uint32_t msgSize = msg.msg.TlvSize();
|
|
|
|
uint32_t dataLeft = msgSize;
|
|
|
|
uint8_t nFragments = ceil(float(msgSize)/FRAGMENT_SIZE);
|
|
|
|
char buffer[FRAGMENT_SIZE];
|
|
|
|
int currPos = 0;
|
|
|
|
|
|
|
|
|
|
|
|
for(uint8_t i=0; i < nFragments; i++)
|
|
|
|
{
|
|
|
|
RsNxsMsg* msgFrag = new RsNxsMsg(mServType);
|
|
|
|
msgFrag->grpId = msg.grpId;
|
|
|
|
msgFrag->msgId = msg.msgId;
|
|
|
|
msgFrag->meta = msg.meta;
|
2013-03-16 12:44:33 -04:00
|
|
|
msgFrag->transactionNumber = msg.transactionNumber;
|
2013-02-07 18:04:16 -05:00
|
|
|
msgFrag->pos = i;
|
2013-03-16 12:44:33 -04:00
|
|
|
msgFrag->PeerId(msg.PeerId());
|
2013-02-07 18:04:16 -05:00
|
|
|
msgFrag->count = nFragments;
|
|
|
|
uint32_t fragSize = std::min(dataLeft, FRAGMENT_SIZE);
|
|
|
|
|
|
|
|
memcpy(buffer, ((char*)msg.msg.bin_data) + currPos, fragSize);
|
2013-03-16 12:44:33 -04:00
|
|
|
msgFrag->msg.setBinData(buffer, fragSize);
|
2013-02-07 18:04:16 -05:00
|
|
|
|
|
|
|
currPos += fragSize;
|
|
|
|
dataLeft -= fragSize;
|
|
|
|
msgFragments.push_back(msgFrag);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RsGxsNetService::fragmentGrp(RsNxsGrp& grp, GrpFragments& grpFragments) const
|
|
|
|
{
|
|
|
|
// first determine how many fragments
|
|
|
|
uint32_t grpSize = grp.grp.TlvSize();
|
|
|
|
uint32_t dataLeft = grpSize;
|
|
|
|
uint8_t nFragments = ceil(float(grpSize)/FRAGMENT_SIZE);
|
|
|
|
char buffer[FRAGMENT_SIZE];
|
|
|
|
int currPos = 0;
|
|
|
|
|
|
|
|
|
|
|
|
for(uint8_t i=0; i < nFragments; i++)
|
|
|
|
{
|
|
|
|
RsNxsGrp* grpFrag = new RsNxsGrp(mServType);
|
|
|
|
grpFrag->grpId = grp.grpId;
|
|
|
|
grpFrag->meta = grp.meta;
|
|
|
|
grpFrag->pos = i;
|
|
|
|
grpFrag->count = nFragments;
|
|
|
|
uint32_t fragSize = std::min(dataLeft, FRAGMENT_SIZE);
|
|
|
|
|
|
|
|
memcpy(buffer, ((char*)grp.grp.bin_data) + currPos, fragSize);
|
2013-03-16 12:44:33 -04:00
|
|
|
grpFrag->grp.setBinData(buffer, fragSize);
|
2013-02-07 18:04:16 -05:00
|
|
|
|
|
|
|
currPos += fragSize;
|
|
|
|
dataLeft -= fragSize;
|
|
|
|
grpFragments.push_back(grpFrag);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
RsNxsMsg* RsGxsNetService::deFragmentMsg(MsgFragments& msgFragments) const
|
|
|
|
{
|
|
|
|
if(msgFragments.empty()) return NULL;
|
|
|
|
|
2013-03-16 12:44:33 -04:00
|
|
|
// if there is only one fragment with a count 1 or less then
|
|
|
|
// the fragment is the msg
|
|
|
|
if(msgFragments.size() == 1)
|
|
|
|
{
|
|
|
|
RsNxsMsg* m = msgFragments.front();
|
|
|
|
if(m->count > 1)
|
|
|
|
return NULL;
|
|
|
|
else
|
|
|
|
return m;
|
|
|
|
}
|
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
// first determine total size for binary data
|
|
|
|
MsgFragments::iterator mit = msgFragments.begin();
|
|
|
|
uint32_t datSize = 0;
|
|
|
|
|
|
|
|
for(; mit != msgFragments.end(); mit++)
|
|
|
|
datSize += (*mit)->msg.bin_len;
|
|
|
|
|
|
|
|
char* data = new char[datSize];
|
|
|
|
uint32_t currPos = 0;
|
|
|
|
|
|
|
|
for(mit = msgFragments.begin(); mit != msgFragments.end(); mit++)
|
|
|
|
{
|
|
|
|
RsNxsMsg* msg = *mit;
|
|
|
|
memcpy(data + (currPos), msg->msg.bin_data, msg->msg.bin_len);
|
|
|
|
currPos += msg->msg.bin_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
RsNxsMsg* msg = new RsNxsMsg(mServType);
|
|
|
|
const RsNxsMsg& m = *(*(msgFragments.begin()));
|
|
|
|
msg->msg.setBinData(data, datSize);
|
|
|
|
msg->msgId = m.msgId;
|
|
|
|
msg->grpId = m.grpId;
|
|
|
|
msg->transactionNumber = m.transactionNumber;
|
|
|
|
msg->meta = m.meta;
|
|
|
|
|
|
|
|
delete[] data;
|
|
|
|
return msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
RsNxsGrp* RsGxsNetService::deFragmentGrp(GrpFragments& grpFragments) const
|
|
|
|
{
|
|
|
|
if(grpFragments.empty()) return NULL;
|
|
|
|
|
|
|
|
// first determine total size for binary data
|
|
|
|
GrpFragments::iterator mit = grpFragments.begin();
|
|
|
|
uint32_t datSize = 0;
|
|
|
|
|
|
|
|
for(; mit != grpFragments.end(); mit++)
|
|
|
|
datSize += (*mit)->grp.bin_len;
|
|
|
|
|
|
|
|
char* data = new char[datSize];
|
|
|
|
uint32_t currPos = 0;
|
|
|
|
|
|
|
|
for(mit = grpFragments.begin(); mit != grpFragments.end(); mit++)
|
|
|
|
{
|
|
|
|
RsNxsGrp* grp = *mit;
|
|
|
|
memcpy(data + (currPos), grp->grp.bin_data, grp->grp.bin_len);
|
|
|
|
currPos += grp->grp.bin_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
RsNxsGrp* grp = new RsNxsGrp(mServType);
|
|
|
|
const RsNxsGrp& g = *(*(grpFragments.begin()));
|
|
|
|
grp->grp.setBinData(data, datSize);
|
|
|
|
grp->grpId = g.grpId;
|
|
|
|
grp->transactionNumber = g.transactionNumber;
|
|
|
|
grp->meta = g.meta;
|
|
|
|
|
|
|
|
delete[] data;
|
|
|
|
|
|
|
|
return grp;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct GrpFragCollate
|
|
|
|
{
|
|
|
|
RsGxsGroupId mGrpId;
|
|
|
|
GrpFragCollate(const RsGxsGroupId& grpId) : mGrpId(grpId){ }
|
|
|
|
bool operator()(RsNxsGrp* grp) { return grp->grpId == mGrpId;}
|
|
|
|
};
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
void RsGxsNetService::locked_createTransactionFromPending(
|
|
|
|
MsgRespPending* msgPend)
|
|
|
|
{
|
|
|
|
MsgAuthorV::const_iterator cit = msgPend->mMsgAuthV.begin();
|
|
|
|
std::list<RsNxsItem*> reqList;
|
|
|
|
uint32_t transN = locked_getTransactionId();
|
|
|
|
for(; cit != msgPend->mMsgAuthV.end(); cit++)
|
|
|
|
{
|
|
|
|
const MsgAuthEntry& entry = *cit;
|
|
|
|
|
|
|
|
if(entry.mPassedVetting)
|
|
|
|
{
|
|
|
|
RsNxsSyncMsgItem* msgItem = new RsNxsSyncMsgItem(mServType);
|
|
|
|
msgItem->grpId = entry.mGrpId;
|
|
|
|
msgItem->msgId = entry.mMsgId;
|
|
|
|
msgItem->authorId = entry.mAuthorId;
|
|
|
|
msgItem->flag = RsNxsSyncMsgItem::FLAG_REQUEST;
|
|
|
|
msgItem->transactionNumber = transN;
|
|
|
|
msgItem->PeerId(msgPend->mPeerId);
|
|
|
|
reqList.push_back(msgItem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!reqList.empty())
|
|
|
|
locked_pushMsgTransactionFromList(reqList, msgPend->mPeerId, transN);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RsGxsNetService::locked_createTransactionFromPending(
|
|
|
|
GrpRespPending* grpPend)
|
|
|
|
{
|
|
|
|
GrpAuthorV::const_iterator cit = grpPend->mGrpAuthV.begin();
|
|
|
|
std::list<RsNxsItem*> reqList;
|
|
|
|
uint32_t transN = locked_getTransactionId();
|
|
|
|
for(; cit != grpPend->mGrpAuthV.end(); cit++)
|
|
|
|
{
|
|
|
|
const GrpAuthEntry& entry = *cit;
|
|
|
|
|
|
|
|
if(entry.mPassedVetting)
|
|
|
|
{
|
2014-04-27 09:14:07 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "locked_createTransactionFromPending(AUTHOR VETTING) Group Id: " << entry.mGrpId << " PASSED";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
2013-06-04 17:00:43 -04:00
|
|
|
RsNxsSyncGrpItem* msgItem = new RsNxsSyncGrpItem(mServType);
|
|
|
|
msgItem->grpId = entry.mGrpId;
|
|
|
|
msgItem->authorId = entry.mAuthorId;
|
|
|
|
msgItem->flag = RsNxsSyncMsgItem::FLAG_REQUEST;
|
|
|
|
msgItem->transactionNumber = transN;
|
|
|
|
msgItem->PeerId(grpPend->mPeerId);
|
|
|
|
reqList.push_back(msgItem);
|
|
|
|
}
|
2014-04-27 09:14:07 -04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "locked_createTransactionFromPending(AUTHOR VETTING) Group Id: " << entry.mGrpId << " FAILED";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
2013-06-04 17:00:43 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if(!reqList.empty())
|
|
|
|
locked_pushGrpTransactionFromList(reqList, grpPend->mPeerId, transN);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void RsGxsNetService::locked_createTransactionFromPending(GrpCircleIdRequestVetting* grpPend)
|
|
|
|
{
|
|
|
|
std::vector<GrpIdCircleVet>::iterator cit = grpPend->mGrpCircleV.begin();
|
|
|
|
uint32_t transN = locked_getTransactionId();
|
|
|
|
std::list<RsNxsItem*> itemL;
|
|
|
|
for(; cit != grpPend->mGrpCircleV.end(); cit++)
|
|
|
|
{
|
|
|
|
const GrpIdCircleVet& entry = *cit;
|
|
|
|
if(entry.mCleared)
|
|
|
|
{
|
2014-04-27 09:14:07 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "locked_createTransactionFromPending(CIRCLE VETTING) Group Id: " << entry.mGroupId << " PASSED";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
2013-06-04 17:00:43 -04:00
|
|
|
RsNxsSyncGrpItem* gItem = new
|
|
|
|
RsNxsSyncGrpItem(mServType);
|
|
|
|
gItem->flag = RsNxsSyncGrpItem::FLAG_RESPONSE;
|
|
|
|
gItem->grpId = entry.mGroupId;
|
|
|
|
gItem->publishTs = 0;
|
|
|
|
gItem->PeerId(grpPend->mPeerId);
|
|
|
|
gItem->transactionNumber = transN;
|
2014-05-01 14:50:07 -04:00
|
|
|
gItem->authorId = entry.mAuthorId;
|
2014-04-27 09:14:07 -04:00
|
|
|
// why it authorId not set here???
|
2013-06-04 17:00:43 -04:00
|
|
|
itemL.push_back(gItem);
|
|
|
|
}
|
2014-04-27 09:14:07 -04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "locked_createTransactionFromPending(CIRCLE VETTING) Group Id: " << entry.mGroupId << " FAILED";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
2013-06-04 17:00:43 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if(!itemL.empty())
|
|
|
|
locked_pushGrpRespFromList(itemL, grpPend->mPeerId, transN);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RsGxsNetService::locked_createTransactionFromPending(MsgCircleIdsRequestVetting* msgPend)
|
|
|
|
{
|
|
|
|
std::vector<MsgIdCircleVet>::iterator vit = msgPend->mMsgs.begin();
|
|
|
|
std::list<RsNxsItem*> itemL;
|
|
|
|
|
|
|
|
uint32_t transN = locked_getTransactionId();
|
|
|
|
|
|
|
|
for(; vit != msgPend->mMsgs.end(); vit++)
|
|
|
|
{
|
|
|
|
MsgIdCircleVet& mic = *vit;
|
|
|
|
RsNxsSyncMsgItem* mItem = new
|
|
|
|
RsNxsSyncMsgItem(mServType);
|
|
|
|
mItem->flag = RsNxsSyncGrpItem::FLAG_RESPONSE;
|
|
|
|
mItem->grpId = msgPend->mGrpId;
|
|
|
|
mItem->msgId = mic.mMsgId;
|
|
|
|
mItem->authorId = mic.mAuthorId;
|
|
|
|
mItem->PeerId(msgPend->mPeerId);
|
|
|
|
mItem->transactionNumber = transN;
|
|
|
|
itemL.push_back(mItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!itemL.empty())
|
|
|
|
locked_pushMsgRespFromList(itemL, msgPend->mPeerId, transN);
|
|
|
|
}
|
|
|
|
|
2014-10-24 17:31:58 -04:00
|
|
|
/*bool RsGxsNetService::locked_canReceive(const RsGxsGrpMetaData * const grpMeta
|
|
|
|
, const RsPeerId& peerId )
|
2013-06-04 17:00:43 -04:00
|
|
|
{
|
|
|
|
|
|
|
|
double timeDelta = 0.2;
|
|
|
|
|
2014-10-24 17:31:58 -04:00
|
|
|
if(grpMeta->mCircleType == GXS_CIRCLE_TYPE_EXTERNAL) {
|
2013-06-04 17:00:43 -04:00
|
|
|
int i=0;
|
|
|
|
mCircles->loadCircle(grpMeta->mCircleId);
|
|
|
|
|
|
|
|
// check 5 times at most
|
|
|
|
// spin for 1 second at most
|
2014-10-24 17:31:58 -04:00
|
|
|
while(i < 5) {
|
2013-06-04 17:00:43 -04:00
|
|
|
|
2014-10-24 17:31:58 -04:00
|
|
|
if(mCircles->isLoaded(grpMeta->mCircleId)) {
|
2014-04-27 09:14:07 -04:00
|
|
|
const RsPgpId& pgpId = mPgpUtils->getPGPId(peerId);
|
2013-06-04 17:00:43 -04:00
|
|
|
return mCircles->canSend(grpMeta->mCircleId, pgpId);
|
2014-10-24 17:31:58 -04:00
|
|
|
}//if(mCircles->isLoaded(grpMeta->mCircleId))
|
2013-08-28 15:27:04 -04:00
|
|
|
|
2014-10-24 17:31:58 -04:00
|
|
|
usleep((int) (timeDelta * 1000 * 1000));// timeDelta sec
|
2013-06-04 17:00:43 -04:00
|
|
|
i++;
|
2014-10-24 17:31:58 -04:00
|
|
|
}//while(i < 5)
|
2013-06-04 17:00:43 -04:00
|
|
|
|
2014-10-24 17:31:58 -04:00
|
|
|
} else {//if(grpMeta->mCircleType == GXS_CIRCLE_TYPE_EXTERNAL)
|
2013-06-04 17:00:43 -04:00
|
|
|
return true;
|
2014-10-24 17:31:58 -04:00
|
|
|
}//else (grpMeta->mCircleType == GXS_CIRCLE_TYPE_EXTERNAL)
|
2013-06-04 17:00:43 -04:00
|
|
|
|
|
|
|
return false;
|
2014-10-24 17:31:58 -04:00
|
|
|
}*/
|
2013-06-04 17:00:43 -04:00
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
void RsGxsNetService::collateGrpFragments(GrpFragments fragments,
|
|
|
|
std::map<RsGxsGroupId, GrpFragments>& partFragments) const
|
|
|
|
{
|
|
|
|
// get all unique grpIds;
|
|
|
|
GrpFragments::iterator vit = fragments.begin();
|
|
|
|
std::set<RsGxsGroupId> grpIds;
|
|
|
|
|
|
|
|
for(; vit != fragments.end(); vit++)
|
|
|
|
grpIds.insert( (*vit)->grpId );
|
|
|
|
|
|
|
|
std::set<RsGxsGroupId>::iterator sit = grpIds.begin();
|
|
|
|
|
|
|
|
for(; sit != grpIds.end(); sit++)
|
|
|
|
{
|
|
|
|
const RsGxsGroupId& grpId = *sit;
|
|
|
|
GrpFragments::iterator bound = std::partition(
|
|
|
|
fragments.begin(), fragments.end(),
|
|
|
|
GrpFragCollate(grpId));
|
|
|
|
|
|
|
|
// something will always be found for a group id
|
|
|
|
for(vit = fragments.begin(); vit != bound; )
|
|
|
|
{
|
|
|
|
partFragments[grpId].push_back(*vit);
|
|
|
|
vit = fragments.erase(vit);
|
|
|
|
}
|
|
|
|
|
|
|
|
GrpFragments& f = partFragments[grpId];
|
|
|
|
RsNxsGrp* grp = *(f.begin());
|
|
|
|
|
|
|
|
// if counts of fragments is incorrect remove
|
|
|
|
// from coalescion
|
|
|
|
if(grp->count != f.size())
|
|
|
|
{
|
|
|
|
GrpFragments::iterator vit2 = f.begin();
|
|
|
|
|
|
|
|
for(; vit2 != f.end(); vit2++)
|
|
|
|
delete *vit2;
|
|
|
|
|
|
|
|
partFragments.erase(grpId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fragments.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
struct MsgFragCollate
|
|
|
|
{
|
2014-03-17 16:56:06 -04:00
|
|
|
RsGxsMessageId mMsgId;
|
2013-02-07 18:04:16 -05:00
|
|
|
MsgFragCollate(const RsGxsMessageId& msgId) : mMsgId(msgId){ }
|
|
|
|
bool operator()(RsNxsMsg* msg) { return msg->msgId == mMsgId;}
|
|
|
|
};
|
|
|
|
|
|
|
|
void RsGxsNetService::collateMsgFragments(MsgFragments fragments, std::map<RsGxsMessageId, MsgFragments>& partFragments) const
|
|
|
|
{
|
|
|
|
// get all unique message Ids;
|
|
|
|
MsgFragments::iterator vit = fragments.begin();
|
|
|
|
std::set<RsGxsMessageId> msgIds;
|
|
|
|
|
|
|
|
for(; vit != fragments.end(); vit++)
|
|
|
|
msgIds.insert( (*vit)->msgId );
|
|
|
|
|
|
|
|
|
|
|
|
std::set<RsGxsMessageId>::iterator sit = msgIds.begin();
|
|
|
|
|
|
|
|
for(; sit != msgIds.end(); sit++)
|
|
|
|
{
|
|
|
|
const RsGxsMessageId& msgId = *sit;
|
|
|
|
MsgFragments::iterator bound = std::partition(
|
|
|
|
fragments.begin(), fragments.end(),
|
|
|
|
MsgFragCollate(msgId));
|
|
|
|
|
|
|
|
// something will always be found for a group id
|
2013-03-16 12:44:33 -04:00
|
|
|
for(vit = fragments.begin(); vit != bound; vit++ )
|
2013-02-07 18:04:16 -05:00
|
|
|
{
|
|
|
|
partFragments[msgId].push_back(*vit);
|
|
|
|
}
|
|
|
|
|
2013-03-16 12:44:33 -04:00
|
|
|
fragments.erase(fragments.begin(), bound);
|
2013-02-07 18:04:16 -05:00
|
|
|
MsgFragments& f = partFragments[msgId];
|
|
|
|
RsNxsMsg* msg = *(f.begin());
|
|
|
|
|
|
|
|
// if counts of fragments is incorrect remove
|
|
|
|
// from coalescion
|
|
|
|
if(msg->count != f.size())
|
|
|
|
{
|
|
|
|
MsgFragments::iterator vit2 = f.begin();
|
|
|
|
|
|
|
|
for(; vit2 != f.end(); vit2++)
|
|
|
|
delete *vit2;
|
|
|
|
|
|
|
|
partFragments.erase(msgId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fragments.clear();
|
|
|
|
}
|
|
|
|
|
2013-11-16 08:40:04 -05:00
|
|
|
class StoreHere
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
2013-12-20 09:48:32 -05:00
|
|
|
StoreHere(RsGxsNetService::ClientGrpMap& cgm, RsGxsNetService::ClientMsgMap& cmm,
|
2013-11-16 08:40:04 -05:00
|
|
|
RsGxsNetService::ServerMsgMap& smm,
|
|
|
|
RsGxsServerGrpUpdateItem*& sgm) : mClientGrpMap(cgm), mClientMsgMap(cmm),
|
|
|
|
mServerMsgMap(smm), mServerGrpUpdateItem(sgm)
|
|
|
|
{}
|
|
|
|
|
|
|
|
void operator() (RsItem* item)
|
|
|
|
{
|
|
|
|
RsGxsMsgUpdateItem* mui;
|
|
|
|
RsGxsGrpUpdateItem* gui;
|
|
|
|
RsGxsServerGrpUpdateItem* gsui;
|
|
|
|
RsGxsServerMsgUpdateItem* msui;
|
|
|
|
|
|
|
|
if((mui = dynamic_cast<RsGxsMsgUpdateItem*>(item)) != NULL)
|
|
|
|
mClientMsgMap.insert(std::make_pair(mui->peerId, mui));
|
|
|
|
else if((gui = dynamic_cast<RsGxsGrpUpdateItem*>(item)) != NULL)
|
|
|
|
mClientGrpMap.insert(std::make_pair(gui->peerId, gui));
|
|
|
|
else if((msui = dynamic_cast<RsGxsServerMsgUpdateItem*>(item)) != NULL)
|
|
|
|
mServerMsgMap.insert(std::make_pair(msui->grpId, msui));
|
|
|
|
else if((gsui = dynamic_cast<RsGxsServerGrpUpdateItem*>(item)) != NULL)
|
|
|
|
{
|
2013-12-20 09:48:32 -05:00
|
|
|
if(mServerGrpUpdateItem == NULL)
|
2013-11-16 08:40:04 -05:00
|
|
|
{
|
|
|
|
mServerGrpUpdateItem = gsui;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "Error! More than one server group update item exists!" << std::endl;
|
|
|
|
#endif
|
|
|
|
delete gsui;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "Type not expected!" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2013-03-16 12:44:33 -04:00
|
|
|
|
2013-11-16 08:40:04 -05:00
|
|
|
RsGxsNetService::ClientGrpMap& mClientGrpMap;
|
|
|
|
RsGxsNetService::ClientMsgMap& mClientMsgMap;
|
|
|
|
RsGxsNetService::ServerMsgMap& mServerMsgMap;
|
|
|
|
RsGxsServerGrpUpdateItem*& mServerGrpUpdateItem;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
bool RsGxsNetService::loadList(std::list<RsItem *> &load)
|
2012-07-12 16:18:58 -04:00
|
|
|
{
|
2013-11-16 08:40:04 -05:00
|
|
|
std::for_each(load.begin(), load.end(), StoreHere(mClientGrpUpdateMap, mClientMsgUpdateMap,
|
|
|
|
mServerMsgUpdateMap, mGrpServerUpdateItem));
|
2013-12-20 09:48:32 -05:00
|
|
|
|
2013-11-16 08:40:04 -05:00
|
|
|
return true;
|
2012-07-12 16:18:58 -04:00
|
|
|
}
|
|
|
|
|
2013-11-16 08:40:04 -05:00
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
template <typename UpdateMap>
|
|
|
|
struct get_second : public std::unary_function<typename UpdateMap::value_type, RsItem*>
|
|
|
|
{
|
|
|
|
RsItem* operator()(const typename UpdateMap::value_type& value) const
|
|
|
|
{
|
|
|
|
return value.second;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
bool RsGxsNetService::saveList(bool& cleanup, std::list<RsItem*>& save)
|
|
|
|
{
|
2013-11-16 08:40:04 -05:00
|
|
|
RsStackMutex stack(mNxsMutex);
|
|
|
|
|
|
|
|
// hardcore templates
|
|
|
|
std::transform(mClientGrpUpdateMap.begin(), mClientGrpUpdateMap.end(),
|
|
|
|
std::back_inserter(save), get_second<ClientGrpMap>());
|
|
|
|
|
|
|
|
std::transform(mClientMsgUpdateMap.begin(), mClientMsgUpdateMap.end(),
|
|
|
|
std::back_inserter(save), get_second<ClientMsgMap>());
|
|
|
|
|
|
|
|
std::transform(mServerMsgUpdateMap.begin(), mServerMsgUpdateMap.end(),
|
|
|
|
std::back_inserter(save), get_second<ServerMsgMap>());
|
|
|
|
|
|
|
|
save.push_back(mGrpServerUpdateItem);
|
2013-12-20 09:48:32 -05:00
|
|
|
|
|
|
|
cleanup = false;
|
|
|
|
return true;
|
2012-07-12 16:18:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
RsSerialiser *RsGxsNetService::setupSerialiser()
|
|
|
|
{
|
2013-11-16 08:40:04 -05:00
|
|
|
|
|
|
|
RsSerialiser *rss = new RsSerialiser;
|
|
|
|
rss->addSerialType(new RsGxsUpdateSerialiser(mServType));
|
|
|
|
|
|
|
|
return rss;
|
2012-07-12 16:18:58 -04:00
|
|
|
}
|
|
|
|
|
2012-06-07 16:43:12 -04:00
|
|
|
void RsGxsNetService::recvNxsItemQueue(){
|
|
|
|
|
2013-07-23 08:17:50 -04:00
|
|
|
RsItem *item ;
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2013-07-23 08:17:50 -04:00
|
|
|
while(NULL != (item=recvItem()))
|
|
|
|
{
|
2012-06-07 16:43:12 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
2013-02-07 18:04:16 -05:00
|
|
|
std::cerr << "RsGxsNetService Item:" << (void*)item << std::endl ;
|
2014-04-27 09:14:07 -04:00
|
|
|
item->print(std::cerr);
|
2012-06-07 16:43:12 -04:00
|
|
|
#endif
|
2013-02-07 18:04:16 -05:00
|
|
|
// RsNxsItem needs dynamic_cast, since they have derived siblings.
|
|
|
|
//
|
|
|
|
RsNxsItem *ni = dynamic_cast<RsNxsItem*>(item) ;
|
|
|
|
if(ni != NULL)
|
|
|
|
{
|
|
|
|
// a live transaction has a non zero value
|
|
|
|
if(ni->transactionNumber != 0){
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
2013-02-07 18:04:16 -05:00
|
|
|
std::cerr << "recvNxsItemQueue()" << std::endl;
|
|
|
|
std::cerr << "handlingTransaction, transN" << ni->transactionNumber << std::endl;
|
2012-07-14 13:59:54 -04:00
|
|
|
#endif
|
|
|
|
|
2014-07-05 08:29:40 -04:00
|
|
|
if(!handleTransaction(ni))
|
|
|
|
delete ni;
|
|
|
|
|
|
|
|
continue;
|
2013-02-07 18:04:16 -05:00
|
|
|
}
|
2012-06-07 16:43:12 -04:00
|
|
|
|
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
switch(ni->PacketSubType())
|
|
|
|
{
|
|
|
|
case RS_PKT_SUBTYPE_NXS_SYNC_GRP: handleRecvSyncGroup (dynamic_cast<RsNxsSyncGrp*>(ni)) ; break ;
|
|
|
|
case RS_PKT_SUBTYPE_NXS_SYNC_MSG: handleRecvSyncMessage (dynamic_cast<RsNxsSyncMsg*>(ni)) ; break ;
|
2014-10-05 15:14:05 -04:00
|
|
|
case RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY: handleRecvPublishKeys (dynamic_cast<RsNxsGroupPublishKeyItem*>(ni)) ; break ;
|
|
|
|
default:
|
2014-04-29 06:28:46 -04:00
|
|
|
std::cerr << "Unhandled item subtype " << (uint32_t) ni->PacketSubType() << " in RsGxsNetService: " << std::endl; break;
|
2013-02-07 18:04:16 -05:00
|
|
|
}
|
|
|
|
delete item ;
|
|
|
|
}
|
2013-07-23 08:17:50 -04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "Not a RsNxsItem, deleting!" << std::endl;
|
|
|
|
delete(item);
|
|
|
|
}
|
|
|
|
}
|
2012-06-07 16:43:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
bool RsGxsNetService::handleTransaction(RsNxsItem* item)
|
|
|
|
{
|
2012-06-11 17:56:23 -04:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* This attempts to handle a transaction
|
|
|
|
* It first checks if this transaction id already exists
|
2012-07-12 16:18:58 -04:00
|
|
|
* If it does then check this not a initiating transactions
|
2012-06-11 17:56:23 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
RsStackMutex stack(mNxsMutex);
|
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
const RsPeerId& peer = item->PeerId();
|
2012-06-11 17:56:23 -04:00
|
|
|
|
|
|
|
RsNxsTransac* transItem = dynamic_cast<RsNxsTransac*>(item);
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
// if this is a RsNxsTransac item process
|
2013-02-07 18:04:16 -05:00
|
|
|
if(transItem)
|
2012-06-11 17:56:23 -04:00
|
|
|
return locked_processTransac(transItem);
|
2013-02-07 18:04:16 -05:00
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
|
|
|
|
// then this must be transaction content to be consumed
|
|
|
|
// first check peer exist for transaction
|
2012-07-12 16:18:58 -04:00
|
|
|
bool peerTransExists = mTransactions.find(peer) != mTransactions.end();
|
2012-06-11 17:56:23 -04:00
|
|
|
|
|
|
|
// then check transaction exists
|
|
|
|
|
|
|
|
bool transExists = false;
|
|
|
|
NxsTransaction* tr = NULL;
|
|
|
|
uint32_t transN = item->transactionNumber;
|
|
|
|
|
|
|
|
if(peerTransExists)
|
|
|
|
{
|
|
|
|
TransactionIdMap& transMap = mTransactions[peer];
|
|
|
|
|
|
|
|
transExists = transMap.find(transN) != transMap.end();
|
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
if(transExists)
|
|
|
|
{
|
2012-07-14 13:59:54 -04:00
|
|
|
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "handleTransaction() " << std::endl;
|
|
|
|
std::cerr << "Consuming Transaction content, transN: " << item->transactionNumber << std::endl;
|
|
|
|
std::cerr << "Consuming Transaction content, from Peer: " << item->PeerId() << std::endl;
|
|
|
|
#endif
|
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
tr = transMap[transN];
|
|
|
|
tr->mItems.push_back(item);
|
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
return true;
|
|
|
|
}
|
2012-06-11 17:56:23 -04:00
|
|
|
}
|
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
return false;
|
2012-06-11 17:56:23 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool RsGxsNetService::locked_processTransac(RsNxsTransac* item)
|
|
|
|
{
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
/*!
|
|
|
|
* To process the transaction item
|
|
|
|
* It can either be initiating a transaction
|
|
|
|
* or ending one that already exists
|
|
|
|
*
|
|
|
|
* For initiating an incoming transaction the peer
|
|
|
|
* and transaction item need not exists
|
|
|
|
* as the peer will be added and transaction number
|
|
|
|
* added thereafter
|
|
|
|
*
|
|
|
|
* For commencing/starting an outgoing transaction
|
|
|
|
* the transaction must exist already
|
|
|
|
*
|
|
|
|
* For ending a transaction the
|
|
|
|
*/
|
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
RsPeerId peer;
|
2012-07-15 08:38:20 -04:00
|
|
|
|
|
|
|
// for outgoing transaction use own id
|
|
|
|
if(item->transactFlag & (RsNxsTransac::FLAG_BEGIN_P2 | RsNxsTransac::FLAG_END_SUCCESS))
|
|
|
|
peer = mOwnId;
|
|
|
|
else
|
|
|
|
peer = item->PeerId();
|
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
uint32_t transN = item->transactionNumber;
|
2012-07-14 13:59:54 -04:00
|
|
|
item->timestamp = time(NULL); // register time received
|
2012-06-11 17:56:23 -04:00
|
|
|
NxsTransaction* tr = NULL;
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "locked_processTransac() " << std::endl;
|
|
|
|
std::cerr << "locked_processTransac(), Received transaction item: " << transN << std::endl;
|
|
|
|
std::cerr << "locked_processTransac(), With peer: " << item->PeerId() << std::endl;
|
|
|
|
std::cerr << "locked_processTransac(), trans type: " << item->transactFlag << std::endl;
|
|
|
|
#endif
|
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
bool peerTrExists = mTransactions.find(peer) != mTransactions.end();
|
|
|
|
bool transExists = false;
|
|
|
|
|
|
|
|
if(peerTrExists){
|
|
|
|
|
|
|
|
TransactionIdMap& transMap = mTransactions[peer];
|
2012-07-12 16:18:58 -04:00
|
|
|
// record whether transaction exists already
|
2012-06-11 17:56:23 -04:00
|
|
|
transExists = transMap.find(transN) != transMap.end();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
// initiating an incoming transaction
|
2012-06-11 17:56:23 -04:00
|
|
|
if(item->transactFlag & RsNxsTransac::FLAG_BEGIN_P1){
|
|
|
|
|
2013-07-23 18:04:24 -04:00
|
|
|
if(transExists)
|
|
|
|
return false; // should not happen!
|
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
// create a transaction if the peer does not exist
|
|
|
|
if(!peerTrExists){
|
|
|
|
mTransactions[peer] = TransactionIdMap();
|
|
|
|
}
|
|
|
|
|
|
|
|
TransactionIdMap& transMap = mTransactions[peer];
|
|
|
|
|
|
|
|
|
|
|
|
// create new transaction
|
|
|
|
tr = new NxsTransaction();
|
|
|
|
transMap[transN] = tr;
|
|
|
|
tr->mTransaction = item;
|
2014-10-09 13:20:09 -04:00
|
|
|
tr->mTimeOut = item->timestamp + mTransactionTimeOut;
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
// note state as receiving, commencement item
|
|
|
|
// is sent on next run() loop
|
2012-06-11 17:56:23 -04:00
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_STARTING;
|
2014-07-05 16:05:17 -04:00
|
|
|
return true;
|
2012-07-12 16:18:58 -04:00
|
|
|
// commencement item for outgoing transaction
|
2012-06-11 17:56:23 -04:00
|
|
|
}else if(item->transactFlag & RsNxsTransac::FLAG_BEGIN_P2){
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
// transaction must exist
|
2012-06-16 09:59:40 -04:00
|
|
|
if(!peerTrExists || !transExists)
|
2012-06-11 17:56:23 -04:00
|
|
|
return false;
|
2012-06-16 09:59:40 -04:00
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
// alter state so transaction content is sent on
|
|
|
|
// next run() loop
|
2012-06-11 17:56:23 -04:00
|
|
|
TransactionIdMap& transMap = mTransactions[mOwnId];
|
|
|
|
NxsTransaction* tr = transMap[transN];
|
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_SENDING;
|
2014-07-05 08:29:40 -04:00
|
|
|
delete item;
|
|
|
|
return true;
|
2012-07-12 16:18:58 -04:00
|
|
|
// end transac item for outgoing transaction
|
2012-06-11 17:56:23 -04:00
|
|
|
}else if(item->transactFlag & RsNxsTransac::FLAG_END_SUCCESS){
|
|
|
|
|
2012-06-16 09:59:40 -04:00
|
|
|
// transaction does not exist
|
2012-06-11 17:56:23 -04:00
|
|
|
if(!peerTrExists || !transExists){
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
// alter state so that transaction is removed
|
|
|
|
// on next run() loop
|
2012-06-11 17:56:23 -04:00
|
|
|
TransactionIdMap& transMap = mTransactions[mOwnId];
|
|
|
|
NxsTransaction* tr = transMap[transN];
|
2014-07-05 08:29:40 -04:00
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_COMPLETED;
|
|
|
|
delete item;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
2012-06-07 16:43:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void RsGxsNetService::run(){
|
2014-01-28 16:47:51 -05:00
|
|
|
double timeDelta = 0.5;
|
2013-11-24 07:37:17 -05:00
|
|
|
int updateCounter = 0;
|
2012-06-07 16:43:12 -04:00
|
|
|
|
|
|
|
while(isRunning()){
|
2014-10-24 17:31:58 -04:00
|
|
|
//Start waiting as nothing to do in runup
|
|
|
|
usleep((int) (timeDelta * 1000 * 1000)); // timeDelta sec
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2014-10-24 17:31:58 -04:00
|
|
|
if(updateCounter >= 20) {
|
2013-11-24 07:37:17 -05:00
|
|
|
updateServerSyncTS();
|
|
|
|
updateCounter = 0;
|
2014-10-24 17:31:58 -04:00
|
|
|
} else {//if(updateCounter >= 20)
|
2013-11-24 07:37:17 -05:00
|
|
|
updateCounter++;
|
2014-10-24 17:31:58 -04:00
|
|
|
}//else (updateCounter >= 20)
|
2013-11-23 18:39:55 -05:00
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
// process active transactions
|
2012-06-07 16:43:12 -04:00
|
|
|
processTransactions();
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
// process completed transactions
|
2012-06-11 17:56:23 -04:00
|
|
|
processCompletedTransactions();
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
// vetting of id and circle info
|
|
|
|
runVetting();
|
|
|
|
|
2013-10-29 17:29:20 -04:00
|
|
|
processExplicitGroupRequests();
|
|
|
|
|
2014-10-24 17:31:58 -04:00
|
|
|
}//while(isRunning())
|
2012-06-07 16:43:12 -04:00
|
|
|
}
|
|
|
|
|
2013-11-23 18:39:55 -05:00
|
|
|
void RsGxsNetService::updateServerSyncTS()
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mNxsMutex);
|
|
|
|
|
|
|
|
std::map<RsGxsGroupId, RsGxsGrpMetaData*> gxsMap;
|
|
|
|
|
|
|
|
// retrieve all grps and update TS
|
|
|
|
mDataStore->retrieveGxsGrpMetaData(gxsMap);
|
|
|
|
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = gxsMap.begin();
|
|
|
|
|
|
|
|
// as a grp list server also note this is the latest item you have
|
|
|
|
if(mGrpServerUpdateItem == NULL)
|
|
|
|
{
|
|
|
|
mGrpServerUpdateItem = new RsGxsServerGrpUpdateItem(mServType);
|
|
|
|
}
|
|
|
|
|
2013-12-20 09:48:32 -05:00
|
|
|
bool change = false;
|
|
|
|
|
2013-11-23 18:39:55 -05:00
|
|
|
for(; mit != gxsMap.end(); mit++)
|
|
|
|
{
|
|
|
|
const RsGxsGroupId& grpId = mit->first;
|
|
|
|
RsGxsGrpMetaData* grpMeta = mit->second;
|
|
|
|
ServerMsgMap::iterator mapIT = mServerMsgUpdateMap.find(grpId);
|
|
|
|
RsGxsServerMsgUpdateItem* msui = NULL;
|
|
|
|
|
|
|
|
if(mapIT == mServerMsgUpdateMap.end())
|
|
|
|
{
|
|
|
|
msui = new RsGxsServerMsgUpdateItem(mServType);
|
|
|
|
msui->grpId = grpMeta->mGroupId;
|
|
|
|
mServerMsgUpdateMap.insert(std::make_pair(msui->grpId, msui));
|
|
|
|
}else
|
|
|
|
{
|
|
|
|
msui = mapIT->second;
|
|
|
|
}
|
|
|
|
|
2013-12-20 09:48:32 -05:00
|
|
|
if(grpMeta->mLastPost > msui->msgUpdateTS )
|
|
|
|
{
|
|
|
|
change = true;
|
|
|
|
msui->msgUpdateTS = grpMeta->mLastPost;
|
|
|
|
}
|
2013-11-23 18:39:55 -05:00
|
|
|
|
|
|
|
// this might be very inefficient with time
|
|
|
|
if(grpMeta->mRecvTS > mGrpServerUpdateItem->grpUpdateTS)
|
2013-12-20 09:48:32 -05:00
|
|
|
{
|
2013-11-23 18:39:55 -05:00
|
|
|
mGrpServerUpdateItem->grpUpdateTS = grpMeta->mRecvTS;
|
2013-12-20 09:48:32 -05:00
|
|
|
change = true;
|
|
|
|
}
|
2013-11-23 18:39:55 -05:00
|
|
|
}
|
|
|
|
|
2013-12-20 09:48:32 -05:00
|
|
|
// actual change in config settings, then save configuration
|
|
|
|
if(change)
|
|
|
|
IndicateConfigChanged();
|
|
|
|
|
2013-11-23 18:39:55 -05:00
|
|
|
freeAndClearContainerResource<std::map<RsGxsGroupId, RsGxsGrpMetaData*>,
|
|
|
|
RsGxsGrpMetaData*>(gxsMap);
|
2013-12-20 09:48:32 -05:00
|
|
|
|
2013-11-23 18:39:55 -05:00
|
|
|
}
|
2012-07-15 08:38:20 -04:00
|
|
|
bool RsGxsNetService::locked_checkTransacTimedOut(NxsTransaction* tr)
|
2012-07-14 13:59:54 -04:00
|
|
|
{
|
2013-11-03 18:46:34 -05:00
|
|
|
return tr->mTimeOut < ((uint32_t) time(NULL));
|
2012-07-14 13:59:54 -04:00
|
|
|
}
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
void RsGxsNetService::processTransactions(){
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
RsStackMutex stack(mNxsMutex);
|
2012-06-11 17:56:23 -04:00
|
|
|
|
|
|
|
TransactionsPeerMap::iterator mit = mTransactions.begin();
|
|
|
|
|
|
|
|
for(; mit != mTransactions.end(); mit++){
|
|
|
|
|
|
|
|
TransactionIdMap& transMap = mit->second;
|
|
|
|
TransactionIdMap::iterator mmit = transMap.begin(),
|
|
|
|
|
|
|
|
mmit_end = transMap.end();
|
|
|
|
|
2013-07-23 18:04:24 -04:00
|
|
|
// transaction to be removed
|
|
|
|
std::list<uint32_t> toRemove;
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
/*!
|
|
|
|
* Transactions owned by peer
|
|
|
|
*/
|
2012-06-11 17:56:23 -04:00
|
|
|
if(mit->first == mOwnId){
|
|
|
|
|
|
|
|
for(; mmit != mmit_end; mmit++){
|
|
|
|
|
|
|
|
NxsTransaction* tr = mmit->second;
|
|
|
|
uint16_t flag = tr->mFlag;
|
|
|
|
std::list<RsNxsItem*>::iterator lit, lit_end;
|
|
|
|
uint32_t transN = tr->mTransaction->transactionNumber;
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// first check transaction has not expired
|
2012-07-15 08:38:20 -04:00
|
|
|
if(locked_checkTransacTimedOut(tr))
|
2012-07-14 13:59:54 -04:00
|
|
|
{
|
2014-10-09 13:20:09 -04:00
|
|
|
std::cerr << std::dec ;
|
|
|
|
int total_transaction_time = (int)time(NULL) - (tr->mTimeOut - mTransactionTimeOut) ;
|
|
|
|
std::cerr << "Outgoing Transaction has failed, tranN: " << transN << ", Peer: " << mit->first ;
|
|
|
|
std::cerr << ", age: " << total_transaction_time << ", nItems=" << tr->mTransaction->nItems << ". tr->mTimeOut = " << tr->mTimeOut << ", now = " << (uint32_t) time(NULL) << std::endl;
|
2012-07-14 13:59:54 -04:00
|
|
|
|
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_FAILED;
|
|
|
|
toRemove.push_back(transN);
|
2013-07-23 18:04:24 -04:00
|
|
|
mComplTransactions.push_back(tr);
|
2012-07-14 13:59:54 -04:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
// send items requested
|
|
|
|
if(flag & NxsTransaction::FLAG_STATE_SENDING){
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "processTransactions() " << std::endl;
|
|
|
|
std::cerr << "Sending Transaction content, transN: " << transN << std::endl;
|
|
|
|
std::cerr << "with peer: " << tr->mTransaction->PeerId();
|
|
|
|
#endif
|
2012-06-11 17:56:23 -04:00
|
|
|
lit = tr->mItems.begin();
|
|
|
|
lit_end = tr->mItems.end();
|
|
|
|
|
|
|
|
for(; lit != lit_end; lit++){
|
|
|
|
sendItem(*lit);
|
|
|
|
}
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
tr->mItems.clear(); // clear so they don't get deleted in trans cleaning
|
2012-06-11 17:56:23 -04:00
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM;
|
|
|
|
|
|
|
|
}else if(flag & NxsTransaction::FLAG_STATE_WAITING_CONFIRM){
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}else if(flag & NxsTransaction::FLAG_STATE_COMPLETED){
|
|
|
|
|
2014-10-09 13:20:09 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
int total_transaction_time = (int)time(NULL) - (tr->mTimeOut - mTransactionTimeOut) ;
|
|
|
|
|
|
|
|
std::cerr << "RsGxsNetService::processTransactions() outgoing completed " << tr->mTransaction->nItems << " items transaction in " << total_transaction_time << " seconds." << std::endl;
|
|
|
|
#endif
|
|
|
|
// move to completed transactions
|
2012-06-11 17:56:23 -04:00
|
|
|
toRemove.push_back(transN);
|
|
|
|
mComplTransactions.push_back(tr);
|
2012-07-14 13:59:54 -04:00
|
|
|
}else{
|
|
|
|
|
2014-04-27 09:14:07 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
2012-07-14 13:59:54 -04:00
|
|
|
std::cerr << "processTransactions() " << std::endl;
|
|
|
|
std::cerr << "processTransactions(), Unknown flag for active transaction, transN: " << transN
|
|
|
|
<< std::endl;
|
|
|
|
std::cerr << "processTransactions(), Unknown flag, Peer: " << mit->first;
|
2014-04-27 09:14:07 -04:00
|
|
|
#endif
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
toRemove.push_back(transN);
|
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_FAILED;
|
|
|
|
mComplTransactions.push_back(tr);
|
2012-06-11 17:56:23 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* Essentially these are incoming transactions
|
|
|
|
* Several states are dealth with
|
|
|
|
* Receiving: waiting to receive items from peer's transaction
|
|
|
|
* and checking if all have been received
|
|
|
|
* Completed: remove transaction from active and tell peer
|
|
|
|
* involved in transaction
|
|
|
|
* Starting: this is a new transaction and need to teell peer
|
|
|
|
* involved in transaction
|
|
|
|
*/
|
|
|
|
|
|
|
|
for(; mmit != mmit_end; mmit++){
|
|
|
|
|
|
|
|
NxsTransaction* tr = mmit->second;
|
|
|
|
uint16_t flag = tr->mFlag;
|
|
|
|
uint32_t transN = tr->mTransaction->transactionNumber;
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// first check transaction has not expired
|
2012-07-15 08:38:20 -04:00
|
|
|
if(locked_checkTransacTimedOut(tr))
|
2012-07-14 13:59:54 -04:00
|
|
|
{
|
2014-10-09 13:20:09 -04:00
|
|
|
std::cerr << std::dec ;
|
|
|
|
int total_transaction_time = (int)time(NULL) - (tr->mTimeOut - mTransactionTimeOut) ;
|
|
|
|
std::cerr << "Incoming Transaction has failed, tranN: " << transN << ", Peer: " << mit->first ;
|
|
|
|
std::cerr << ", age: " << total_transaction_time << ", nItems=" << tr->mTransaction->nItems << ". tr->mTimeOut = " << tr->mTimeOut << ", now = " << (uint32_t) time(NULL) << std::endl;
|
2012-07-14 13:59:54 -04:00
|
|
|
|
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_FAILED;
|
|
|
|
toRemove.push_back(transN);
|
2013-07-23 18:04:24 -04:00
|
|
|
mComplTransactions.push_back(tr);
|
2012-07-14 13:59:54 -04:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
if(flag & NxsTransaction::FLAG_STATE_RECEIVING){
|
2012-07-12 16:18:58 -04:00
|
|
|
|
|
|
|
// if the number it item received equal that indicated
|
|
|
|
// then transaction is marked as completed
|
|
|
|
// to be moved to complete transations
|
2012-06-11 17:56:23 -04:00
|
|
|
// check if done
|
2014-10-09 13:20:09 -04:00
|
|
|
if(tr->mItems.size() == tr->mTransaction->nItems)
|
2012-06-11 17:56:23 -04:00
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_COMPLETED;
|
|
|
|
|
|
|
|
}else if(flag & NxsTransaction::FLAG_STATE_COMPLETED)
|
|
|
|
{
|
|
|
|
|
|
|
|
// send completion msg
|
|
|
|
RsNxsTransac* trans = new RsNxsTransac(mServType);
|
|
|
|
trans->clear();
|
|
|
|
trans->transactFlag = RsNxsTransac::FLAG_END_SUCCESS;
|
|
|
|
trans->transactionNumber = transN;
|
|
|
|
trans->PeerId(tr->mTransaction->PeerId());
|
|
|
|
sendItem(trans);
|
|
|
|
|
|
|
|
// move to completed transactions
|
|
|
|
mComplTransactions.push_back(tr);
|
2014-10-09 13:20:09 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
int total_transaction_time = (int)time(NULL) - (tr->mTimeOut - mTransactionTimeOut) ;
|
|
|
|
std::cerr << "RsGxsNetService::processTransactions() incoming completed " << tr->mTransaction->nItems << " items transaction in " << total_transaction_time << " seconds." << std::endl;
|
|
|
|
#endif
|
2012-06-11 17:56:23 -04:00
|
|
|
|
|
|
|
// transaction processing done
|
|
|
|
// for this id, add to removal list
|
|
|
|
toRemove.push_back(mmit->first);
|
|
|
|
}else if(flag & NxsTransaction::FLAG_STATE_STARTING){
|
|
|
|
|
|
|
|
// send item to tell peer your are ready to start
|
|
|
|
RsNxsTransac* trans = new RsNxsTransac(mServType);
|
|
|
|
trans->clear();
|
2012-07-14 13:59:54 -04:00
|
|
|
trans->transactFlag = RsNxsTransac::FLAG_BEGIN_P2 |
|
|
|
|
(tr->mTransaction->transactFlag & RsNxsTransac::FLAG_TYPE_MASK);
|
2012-06-11 17:56:23 -04:00
|
|
|
trans->transactionNumber = transN;
|
|
|
|
trans->PeerId(tr->mTransaction->PeerId());
|
2012-07-14 13:59:54 -04:00
|
|
|
sendItem(trans);
|
2012-07-15 08:38:20 -04:00
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_RECEIVING;
|
2012-06-11 17:56:23 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
std::cerr << "processTransactions() " << std::endl;
|
|
|
|
std::cerr << "processTransactions(), Unknown flag for active transaction, transN: " << transN
|
|
|
|
<< std::endl;
|
|
|
|
std::cerr << "processTransactions(), Unknown flag, Peer: " << mit->first;
|
|
|
|
toRemove.push_back(mmit->first);
|
|
|
|
mComplTransactions.push_back(tr);
|
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_FAILED; // flag as a failed transaction
|
2012-06-11 17:56:23 -04:00
|
|
|
}
|
|
|
|
}
|
2013-07-23 18:04:24 -04:00
|
|
|
}
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2013-07-23 18:04:24 -04:00
|
|
|
std::list<uint32_t>::iterator lit = toRemove.begin();
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2013-07-23 18:04:24 -04:00
|
|
|
for(; lit != toRemove.end(); lit++)
|
|
|
|
{
|
|
|
|
transMap.erase(*lit);
|
2012-06-11 17:56:23 -04:00
|
|
|
}
|
2013-07-23 18:04:24 -04:00
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-07 17:42:44 -04:00
|
|
|
int RsGxsNetService::getGroupPopularity(const RsGxsGroupId& gid)
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mNxsMutex);
|
|
|
|
|
|
|
|
std::map<RsGxsGroupId,std::set<RsPeerId> >::const_iterator it = mGroupSuppliers.find(gid) ;
|
|
|
|
|
|
|
|
if(it == mGroupSuppliers.end())
|
|
|
|
return 0 ;
|
|
|
|
else
|
|
|
|
return it->second.size();
|
|
|
|
}
|
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
void RsGxsNetService::processCompletedTransactions()
|
|
|
|
{
|
2012-07-15 08:38:20 -04:00
|
|
|
RsStackMutex stack(mNxsMutex);
|
2012-06-11 17:56:23 -04:00
|
|
|
/*!
|
|
|
|
* Depending on transaction we may have to respond to peer
|
|
|
|
* responsible for transaction
|
|
|
|
*/
|
|
|
|
std::list<NxsTransaction*>::iterator lit = mComplTransactions.begin();
|
|
|
|
|
|
|
|
while(mComplTransactions.size()>0)
|
|
|
|
{
|
|
|
|
|
|
|
|
NxsTransaction* tr = mComplTransactions.front();
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
bool outgoing = tr->mTransaction->PeerId() == mOwnId;
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
if(outgoing){
|
2012-07-15 08:38:20 -04:00
|
|
|
locked_processCompletedOutgoingTrans(tr);
|
2012-07-14 13:59:54 -04:00
|
|
|
}else{
|
2012-07-15 08:38:20 -04:00
|
|
|
locked_processCompletedIncomingTrans(tr);
|
2012-06-11 17:56:23 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
delete tr;
|
|
|
|
mComplTransactions.pop_front();
|
|
|
|
}
|
|
|
|
}
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr)
|
2012-07-14 13:59:54 -04:00
|
|
|
{
|
|
|
|
|
|
|
|
uint16_t flag = tr->mTransaction->transactFlag;
|
|
|
|
|
|
|
|
if(tr->mFlag & NxsTransaction::FLAG_STATE_COMPLETED){
|
|
|
|
// for a completed list response transaction
|
|
|
|
// one needs generate requests from this
|
|
|
|
if(flag & RsNxsTransac::FLAG_TYPE_MSG_LIST_RESP)
|
|
|
|
{
|
|
|
|
// generate request based on a peers response
|
2012-07-15 08:38:20 -04:00
|
|
|
locked_genReqMsgTransaction(tr);
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
}else if(flag & RsNxsTransac::FLAG_TYPE_GRP_LIST_RESP)
|
2012-07-12 16:18:58 -04:00
|
|
|
{
|
2012-07-15 08:38:20 -04:00
|
|
|
locked_genReqGrpTransaction(tr);
|
2012-07-12 16:18:58 -04:00
|
|
|
}
|
2012-07-14 13:59:54 -04:00
|
|
|
// you've finished receiving request information now gen
|
|
|
|
else if(flag & RsNxsTransac::FLAG_TYPE_MSG_LIST_REQ)
|
2012-06-16 09:59:40 -04:00
|
|
|
{
|
2012-07-15 08:38:20 -04:00
|
|
|
locked_genSendMsgsTransaction(tr);
|
2012-06-11 17:56:23 -04:00
|
|
|
}
|
2012-07-14 13:59:54 -04:00
|
|
|
else if(flag & RsNxsTransac::FLAG_TYPE_GRP_LIST_REQ)
|
|
|
|
{
|
2012-07-15 08:38:20 -04:00
|
|
|
locked_genSendGrpsTransaction(tr);
|
2012-07-14 13:59:54 -04:00
|
|
|
}
|
|
|
|
else if(flag & RsNxsTransac::FLAG_TYPE_GRPS)
|
|
|
|
{
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
std::list<RsNxsItem*>::iterator lit = tr->mItems.begin();
|
|
|
|
std::vector<RsNxsGrp*> grps;
|
|
|
|
|
|
|
|
while(tr->mItems.size() != 0)
|
|
|
|
{
|
|
|
|
RsNxsGrp* grp = dynamic_cast<RsNxsGrp*>(tr->mItems.front());
|
|
|
|
|
|
|
|
if(grp)
|
|
|
|
{
|
|
|
|
tr->mItems.pop_front();
|
2014-10-07 17:42:44 -04:00
|
|
|
grps.push_back(grp);
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::processCompletedTransactions(): item did not caste to grp"
|
|
|
|
<< std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// notify listener of grps
|
|
|
|
mObserver->notifyNewGroups(grps);
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2013-11-23 18:39:55 -05:00
|
|
|
// now note this as the latest you've received from this peer
|
2014-03-17 16:56:06 -04:00
|
|
|
RsPeerId peerFrom = tr->mTransaction->PeerId();
|
2013-11-23 18:39:55 -05:00
|
|
|
uint32_t updateTS = tr->mTransaction->updateTS;
|
2013-11-16 08:40:04 -05:00
|
|
|
|
2013-11-23 18:39:55 -05:00
|
|
|
ClientGrpMap::iterator it = mClientGrpUpdateMap.find(peerFrom);
|
2013-11-16 08:40:04 -05:00
|
|
|
|
2013-11-23 18:39:55 -05:00
|
|
|
RsGxsGrpUpdateItem* item = NULL;
|
2013-11-16 08:40:04 -05:00
|
|
|
|
2013-11-23 18:39:55 -05:00
|
|
|
if(it != mClientGrpUpdateMap.end())
|
|
|
|
{
|
|
|
|
item = it->second;
|
|
|
|
}else
|
|
|
|
{
|
|
|
|
item = new RsGxsGrpUpdateItem(mServType);
|
|
|
|
mClientGrpUpdateMap.insert(
|
|
|
|
std::make_pair(peerFrom, item));
|
|
|
|
}
|
2013-11-16 08:40:04 -05:00
|
|
|
|
2013-11-23 18:39:55 -05:00
|
|
|
item->grpUpdateTS = updateTS;
|
|
|
|
item->peerId = peerFrom;
|
2013-11-16 08:40:04 -05:00
|
|
|
|
2013-12-20 09:48:32 -05:00
|
|
|
IndicateConfigChanged();
|
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
}else if(flag & RsNxsTransac::FLAG_TYPE_MSGS)
|
2012-06-16 09:59:40 -04:00
|
|
|
{
|
2012-07-14 13:59:54 -04:00
|
|
|
|
|
|
|
std::vector<RsNxsMsg*> msgs;
|
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
RsGxsGroupId grpId;
|
2012-07-14 13:59:54 -04:00
|
|
|
while(tr->mItems.size() > 0)
|
|
|
|
{
|
|
|
|
RsNxsMsg* msg = dynamic_cast<RsNxsMsg*>(tr->mItems.front());
|
|
|
|
if(msg)
|
|
|
|
{
|
2014-03-17 16:56:06 -04:00
|
|
|
if(grpId.isNull())
|
2013-11-16 08:40:04 -05:00
|
|
|
grpId = msg->grpId;
|
|
|
|
|
|
|
|
tr->mItems.pop_front();
|
|
|
|
msgs.push_back(msg);
|
2012-07-14 13:59:54 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
2013-11-16 08:40:04 -05:00
|
|
|
std::cerr << "RsGxsNetService::processCompletedTransactions(): item did not caste to msg"
|
|
|
|
<< std::endl;
|
2012-07-14 13:59:54 -04:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-16 12:44:33 -04:00
|
|
|
#ifdef NSXS_FRAG
|
|
|
|
std::map<RsGxsGroupId, MsgFragments > collatedMsgs;
|
|
|
|
collateMsgFragments(msgs, collatedMsgs);
|
|
|
|
|
|
|
|
msgs.clear();
|
|
|
|
|
|
|
|
std::map<RsGxsGroupId, MsgFragments >::iterator mit = collatedMsgs.begin();
|
|
|
|
for(; mit != collatedMsgs.end(); mit++)
|
|
|
|
{
|
|
|
|
MsgFragments& f = mit->second;
|
|
|
|
RsNxsMsg* msg = deFragmentMsg(f);
|
|
|
|
|
|
|
|
if(msg)
|
|
|
|
msgs.push_back(msg);
|
|
|
|
}
|
|
|
|
#endif
|
2012-07-14 13:59:54 -04:00
|
|
|
// notify listener of msgs
|
|
|
|
mObserver->notifyNewMessages(msgs);
|
|
|
|
|
2013-11-16 08:40:04 -05:00
|
|
|
// now note that this is the latest you've received from this peer
|
|
|
|
// for the grp id
|
|
|
|
locked_doMsgUpdateWork(tr->mTransaction, grpId);
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
}
|
2012-07-14 13:59:54 -04:00
|
|
|
}else if(tr->mFlag == NxsTransaction::FLAG_STATE_FAILED){
|
|
|
|
// don't do anything transaction will simply be cleaned
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
void RsGxsNetService::locked_doMsgUpdateWork(const RsNxsTransac *nxsTrans, const RsGxsGroupId &grpId)
|
2013-11-16 08:40:04 -05:00
|
|
|
{
|
|
|
|
|
|
|
|
// firts check if peer exists
|
2014-03-17 16:56:06 -04:00
|
|
|
const RsPeerId& peerFrom = nxsTrans->PeerId();
|
2013-11-16 08:40:04 -05:00
|
|
|
|
|
|
|
ClientMsgMap::iterator it = mClientMsgUpdateMap.find(peerFrom);
|
|
|
|
|
|
|
|
RsGxsMsgUpdateItem* mui = NULL;
|
|
|
|
|
|
|
|
// now update the peer's entry for this grp id
|
|
|
|
if(it != mClientMsgUpdateMap.end())
|
|
|
|
{
|
|
|
|
mui = it->second;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mui = new RsGxsMsgUpdateItem(mServType);
|
|
|
|
mClientMsgUpdateMap.insert(std::make_pair(peerFrom, mui));
|
|
|
|
}
|
|
|
|
|
|
|
|
mui->msgUpdateTS[grpId] = nxsTrans->updateTS;
|
|
|
|
mui->peerId = peerFrom;
|
|
|
|
|
2013-12-20 09:48:32 -05:00
|
|
|
IndicateConfigChanged();
|
2013-11-16 08:40:04 -05:00
|
|
|
}
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
void RsGxsNetService::locked_processCompletedOutgoingTrans(NxsTransaction* tr)
|
2012-07-14 13:59:54 -04:00
|
|
|
{
|
|
|
|
uint16_t flag = tr->mTransaction->transactFlag;
|
|
|
|
|
|
|
|
if(tr->mFlag & NxsTransaction::FLAG_STATE_COMPLETED){
|
|
|
|
// for a completed list response transaction
|
|
|
|
// one needs generate requests from this
|
|
|
|
if(flag & RsNxsTransac::FLAG_TYPE_MSG_LIST_RESP)
|
2012-06-16 09:59:40 -04:00
|
|
|
{
|
2012-06-11 17:56:23 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
2012-07-14 13:59:54 -04:00
|
|
|
std::cerr << "processCompletedOutgoingTrans()" << std::endl;
|
|
|
|
std::cerr << "complete Sending Msg List Response, transN: " <<
|
|
|
|
tr->mTransaction->transactionNumber << std::endl;
|
|
|
|
#endif
|
|
|
|
}else if(flag & RsNxsTransac::FLAG_TYPE_GRP_LIST_RESP)
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "processCompletedOutgoingTrans()" << std::endl;
|
|
|
|
std::cerr << "complete Sending Grp Response, transN: " <<
|
|
|
|
tr->mTransaction->transactionNumber << std::endl;
|
2012-06-11 17:56:23 -04:00
|
|
|
#endif
|
|
|
|
}
|
2012-07-14 13:59:54 -04:00
|
|
|
// you've finished sending a request so don't do anything
|
|
|
|
else if( (flag & RsNxsTransac::FLAG_TYPE_MSG_LIST_REQ) ||
|
|
|
|
(flag & RsNxsTransac::FLAG_TYPE_GRP_LIST_REQ) )
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "processCompletedOutgoingTrans()" << std::endl;
|
|
|
|
std::cerr << "complete Sending Msg/Grp Request, transN: " <<
|
|
|
|
tr->mTransaction->transactionNumber << std::endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}else if(flag & RsNxsTransac::FLAG_TYPE_GRPS)
|
|
|
|
{
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "processCompletedOutgoingTrans()" << std::endl;
|
|
|
|
std::cerr << "complete Sending Grp Data, transN: " <<
|
|
|
|
tr->mTransaction->transactionNumber << std::endl;
|
|
|
|
#endif
|
2013-11-16 08:40:04 -05:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
}else if(flag & RsNxsTransac::FLAG_TYPE_MSGS)
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "processCompletedOutgoingTrans()" << std::endl;
|
|
|
|
std::cerr << "complete Sending Msg Data, transN: " <<
|
|
|
|
tr->mTransaction->transactionNumber << std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}else if(tr->mFlag == NxsTransaction::FLAG_STATE_FAILED){
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "processCompletedOutgoingTrans()" << std::endl;
|
|
|
|
std::cerr << "Failed transaction! transN: " <<
|
|
|
|
tr->mTransaction->transactionNumber << std::endl;
|
|
|
|
#endif
|
|
|
|
}else{
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "processCompletedOutgoingTrans()" << std::endl;
|
|
|
|
std::cerr << "Serious error unrecognised trans Flag! transN: " <<
|
|
|
|
tr->mTransaction->transactionNumber << std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
2012-06-07 16:43:12 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
void RsGxsNetService::locked_pushMsgTransactionFromList(
|
2014-03-17 16:56:06 -04:00
|
|
|
std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN)
|
2013-06-04 17:00:43 -04:00
|
|
|
{
|
|
|
|
RsNxsTransac* transac = new RsNxsTransac(mServType);
|
|
|
|
transac->transactFlag = RsNxsTransac::FLAG_TYPE_MSG_LIST_REQ
|
|
|
|
| RsNxsTransac::FLAG_BEGIN_P1;
|
|
|
|
transac->timestamp = 0;
|
|
|
|
transac->nItems = reqList.size();
|
|
|
|
transac->PeerId(peerId);
|
|
|
|
transac->transactionNumber = transN;
|
|
|
|
NxsTransaction* newTrans = new NxsTransaction();
|
|
|
|
newTrans->mItems = reqList;
|
|
|
|
newTrans->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM;
|
2014-10-09 13:20:09 -04:00
|
|
|
newTrans->mTimeOut = time(NULL) + mTransactionTimeOut;
|
2013-06-04 17:00:43 -04:00
|
|
|
// create transaction copy with your id to indicate
|
|
|
|
// its an outgoing transaction
|
2013-11-16 08:40:04 -05:00
|
|
|
newTrans->mTransaction = new RsNxsTransac(*transac);
|
2013-06-04 17:00:43 -04:00
|
|
|
newTrans->mTransaction->PeerId(mOwnId);
|
|
|
|
sendItem(transac);
|
|
|
|
{
|
|
|
|
if (!locked_addTransaction(newTrans))
|
|
|
|
delete newTrans;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
|
2012-06-11 17:56:23 -04:00
|
|
|
{
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
// to create a transaction you need to know who you are transacting with
|
|
|
|
// then what msgs to request
|
|
|
|
// then add an active Transaction for request
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
std::list<RsNxsSyncMsgItem*> msgItemL;
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
std::list<RsNxsItem*>::iterator lit = tr->mItems.begin();
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2013-07-23 18:04:24 -04:00
|
|
|
// first get item list sent from transaction
|
2012-06-11 17:56:23 -04:00
|
|
|
for(; lit != tr->mItems.end(); lit++)
|
|
|
|
{
|
|
|
|
RsNxsSyncMsgItem* item = dynamic_cast<RsNxsSyncMsgItem*>(*lit);
|
|
|
|
if(item)
|
|
|
|
{
|
|
|
|
msgItemL.push_back(item);
|
|
|
|
}else
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
2013-07-23 18:04:24 -04:00
|
|
|
std::cerr << "RsGxsNetService::genReqMsgTransaction(): item failed cast to RsNxsSyncMsgItem* "
|
|
|
|
<< std::endl;
|
2012-06-11 17:56:23 -04:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
if(msgItemL.empty())
|
|
|
|
return;
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// get grp id for this transaction
|
|
|
|
RsNxsSyncMsgItem* item = msgItemL.front();
|
2014-03-17 16:56:06 -04:00
|
|
|
const RsGxsGroupId& grpId = item->grpId;
|
2013-06-04 17:00:43 -04:00
|
|
|
|
2014-03-18 18:29:24 -04:00
|
|
|
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMetaMap;
|
2014-02-22 19:08:11 -05:00
|
|
|
grpMetaMap[grpId] = NULL;
|
|
|
|
mDataStore->retrieveGxsGrpMetaData(grpMetaMap);
|
|
|
|
RsGxsGrpMetaData* grpMeta = grpMetaMap[grpId];
|
|
|
|
|
|
|
|
int cutoff = 0;
|
|
|
|
if(grpMeta != NULL)
|
|
|
|
cutoff = grpMeta->mReputationCutOff;
|
2013-08-28 15:27:04 -04:00
|
|
|
//
|
|
|
|
// // you want to find out if you can receive it
|
|
|
|
// // number polls essentially represent multiple
|
|
|
|
// // of sleep interval
|
|
|
|
// if(grpMeta)
|
|
|
|
// {
|
|
|
|
// // always can receive, only provides weak guaranttee this peer is part of the group
|
|
|
|
// bool can = true;//locked_canReceive(grpMeta, tr->mTransaction->PeerId());
|
|
|
|
//
|
|
|
|
// delete grpMeta;
|
|
|
|
//
|
|
|
|
// if(!can)
|
|
|
|
// return;
|
|
|
|
//
|
|
|
|
// }else
|
|
|
|
// {
|
|
|
|
// return;
|
|
|
|
// }
|
2013-06-04 17:00:43 -04:00
|
|
|
|
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
GxsMsgReq reqIds;
|
|
|
|
reqIds[grpId] = std::vector<RsGxsMessageId>();
|
2012-07-14 13:59:54 -04:00
|
|
|
GxsMsgMetaResult result;
|
2012-09-01 10:47:22 -04:00
|
|
|
mDataStore->retrieveGxsMsgMetaData(reqIds, result);
|
2012-07-14 13:59:54 -04:00
|
|
|
std::vector<RsGxsMsgMetaData*> &msgMetaV = result[grpId];
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
std::vector<RsGxsMsgMetaData*>::const_iterator vit = msgMetaV.begin();
|
2014-03-17 16:56:06 -04:00
|
|
|
std::set<RsGxsMessageId> msgIdSet;
|
2012-06-26 15:52:01 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// put ids in set for each searching
|
|
|
|
for(; vit != msgMetaV.end(); vit++)
|
2013-07-23 18:04:24 -04:00
|
|
|
{
|
2012-07-14 13:59:54 -04:00
|
|
|
msgIdSet.insert((*vit)->mMsgId);
|
2013-07-23 18:04:24 -04:00
|
|
|
delete(*vit);
|
|
|
|
}
|
2013-11-16 08:40:04 -05:00
|
|
|
msgMetaV.clear();
|
2012-06-26 15:52:01 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// get unique id for this transaction
|
2012-07-15 08:38:20 -04:00
|
|
|
uint32_t transN = locked_getTransactionId();
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// add msgs that you don't have to request list
|
|
|
|
std::list<RsNxsSyncMsgItem*>::iterator llit = msgItemL.begin();
|
|
|
|
std::list<RsNxsItem*> reqList;
|
2012-06-26 15:52:01 -04:00
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
const RsPeerId peerFrom = tr->mTransaction->PeerId();
|
2012-09-01 10:47:22 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
MsgAuthorV toVet;
|
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
std::list<RsPeerId> peers;
|
2013-11-04 09:09:32 -05:00
|
|
|
peers.push_back(tr->mTransaction->PeerId());
|
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
for(; llit != msgItemL.end(); llit++)
|
|
|
|
{
|
2013-06-04 17:00:43 -04:00
|
|
|
RsNxsSyncMsgItem*& syncItem = *llit;
|
2014-03-17 16:56:06 -04:00
|
|
|
const RsGxsMessageId& msgId = syncItem->msgId;
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
if(msgIdSet.find(msgId) == msgIdSet.end()){
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2014-02-22 19:08:11 -05:00
|
|
|
// if reputation is in reputations cache then proceed
|
|
|
|
// or if there isn't an author (note as author requirement is
|
|
|
|
// enforced at service level, if no author is needed then reputation
|
|
|
|
// filtering is optional)
|
2014-03-17 16:56:06 -04:00
|
|
|
bool noAuthor = syncItem->authorId.isNull();
|
2013-08-28 15:27:04 -04:00
|
|
|
|
2014-02-22 19:08:11 -05:00
|
|
|
// grp meta must be present if author present
|
|
|
|
if(!noAuthor && grpMeta == NULL)
|
|
|
|
continue;
|
2013-08-28 15:27:04 -04:00
|
|
|
|
2014-02-22 19:08:11 -05:00
|
|
|
if(mReputations->haveReputation(syncItem->authorId) || noAuthor)
|
|
|
|
{
|
2013-06-04 17:00:43 -04:00
|
|
|
GixsReputation rep;
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2014-02-22 19:08:11 -05:00
|
|
|
if(!noAuthor)
|
2013-08-28 15:27:04 -04:00
|
|
|
mReputations->getReputation(syncItem->authorId, rep);
|
|
|
|
|
|
|
|
// if author is required for this message, it will simply get dropped
|
|
|
|
// at genexchange side of things
|
2014-02-22 19:08:11 -05:00
|
|
|
if(rep.score > grpMeta->mReputationCutOff || noAuthor)
|
2013-06-04 17:00:43 -04:00
|
|
|
{
|
|
|
|
RsNxsSyncMsgItem* msgItem = new RsNxsSyncMsgItem(mServType);
|
|
|
|
msgItem->grpId = grpId;
|
|
|
|
msgItem->msgId = msgId;
|
|
|
|
msgItem->flag = RsNxsSyncMsgItem::FLAG_REQUEST;
|
|
|
|
msgItem->transactionNumber = transN;
|
|
|
|
msgItem->PeerId(peerFrom);
|
|
|
|
reqList.push_back(msgItem);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// preload for speed
|
2013-11-04 09:09:32 -05:00
|
|
|
mReputations->loadReputation(syncItem->authorId, peers);
|
2013-06-04 17:00:43 -04:00
|
|
|
MsgAuthEntry entry;
|
|
|
|
entry.mAuthorId = syncItem->authorId;
|
|
|
|
entry.mGrpId = syncItem->grpId;
|
|
|
|
entry.mMsgId = syncItem->msgId;
|
|
|
|
toVet.push_back(entry);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-07-14 13:59:54 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
if(!toVet.empty())
|
|
|
|
{
|
2014-02-22 19:08:11 -05:00
|
|
|
MsgRespPending* mrp = new MsgRespPending(mReputations, tr->mTransaction->PeerId(), toVet, cutoff);
|
2013-06-04 17:00:43 -04:00
|
|
|
mPendingResp.push_back(mrp);
|
|
|
|
}
|
2012-07-14 13:59:54 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
if(!reqList.empty())
|
|
|
|
{
|
|
|
|
locked_pushMsgTransactionFromList(reqList, tr->mTransaction->PeerId(), transN);
|
|
|
|
}
|
|
|
|
}
|
2012-07-14 13:59:54 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
void RsGxsNetService::locked_pushGrpTransactionFromList(
|
2014-03-17 16:56:06 -04:00
|
|
|
std::list<RsNxsItem*>& reqList, const RsPeerId& peerId, const uint32_t& transN)
|
2013-06-04 17:00:43 -04:00
|
|
|
{
|
|
|
|
RsNxsTransac* transac = new RsNxsTransac(mServType);
|
|
|
|
transac->transactFlag = RsNxsTransac::FLAG_TYPE_GRP_LIST_REQ
|
|
|
|
| RsNxsTransac::FLAG_BEGIN_P1;
|
|
|
|
transac->timestamp = 0;
|
|
|
|
transac->nItems = reqList.size();
|
|
|
|
transac->PeerId(peerId);
|
|
|
|
transac->transactionNumber = transN;
|
|
|
|
NxsTransaction* newTrans = new NxsTransaction();
|
|
|
|
newTrans->mItems = reqList;
|
|
|
|
newTrans->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM;
|
2014-10-09 13:20:09 -04:00
|
|
|
newTrans->mTimeOut = time(NULL) + mTransactionTimeOut;
|
2013-06-04 17:00:43 -04:00
|
|
|
newTrans->mTransaction = new RsNxsTransac(*transac);
|
|
|
|
newTrans->mTransaction->PeerId(mOwnId);
|
|
|
|
sendItem(transac);
|
|
|
|
if (!locked_addTransaction(newTrans))
|
|
|
|
delete newTrans;
|
|
|
|
}
|
|
|
|
void RsGxsNetService::addGroupItemToList(NxsTransaction*& tr,
|
2014-03-17 16:56:06 -04:00
|
|
|
const RsGxsGroupId& grpId, uint32_t& transN,
|
2013-06-04 17:00:43 -04:00
|
|
|
std::list<RsNxsItem*>& reqList)
|
|
|
|
{
|
2014-04-27 09:14:07 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::addGroupItemToList() Added GroupID: << grpId";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
RsNxsSyncGrpItem* grpItem = new RsNxsSyncGrpItem(mServType);
|
|
|
|
grpItem->PeerId(tr->mTransaction->PeerId());
|
|
|
|
grpItem->grpId = grpId;
|
|
|
|
grpItem->flag = RsNxsSyncMsgItem::FLAG_REQUEST;
|
|
|
|
grpItem->transactionNumber = transN;
|
|
|
|
reqList.push_back(grpItem);
|
2012-06-11 17:56:23 -04:00
|
|
|
}
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
|
2012-06-11 17:56:23 -04:00
|
|
|
{
|
|
|
|
|
|
|
|
// to create a transaction you need to know who you are transacting with
|
|
|
|
// then what grps to request
|
|
|
|
// then add an active Transaction for request
|
|
|
|
|
|
|
|
std::list<RsNxsSyncGrpItem*> grpItemL;
|
|
|
|
|
|
|
|
std::list<RsNxsItem*>::iterator lit = tr->mItems.begin();
|
|
|
|
|
|
|
|
for(; lit != tr->mItems.end(); lit++)
|
|
|
|
{
|
|
|
|
RsNxsSyncGrpItem* item = dynamic_cast<RsNxsSyncGrpItem*>(*lit);
|
|
|
|
if(item)
|
|
|
|
{
|
|
|
|
grpItemL.push_back(item);
|
|
|
|
}else
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
2013-06-04 17:00:43 -04:00
|
|
|
std::cerr << "RsGxsNetService::genReqGrpTransaction(): item failed to caste to RsNxsSyncMsgItem* "
|
2012-06-11 17:56:23 -04:00
|
|
|
<< std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMetaMap;
|
|
|
|
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::const_iterator metaIter;
|
2012-07-14 13:59:54 -04:00
|
|
|
mDataStore->retrieveGxsGrpMetaData(grpMetaMap);
|
2012-06-11 17:56:23 -04:00
|
|
|
|
|
|
|
// now do compare and add loop
|
|
|
|
std::list<RsNxsSyncGrpItem*>::iterator llit = grpItemL.begin();
|
|
|
|
std::list<RsNxsItem*> reqList;
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
uint32_t transN = locked_getTransactionId();
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
GrpAuthorV toVet;
|
2014-03-17 16:56:06 -04:00
|
|
|
std::list<RsPeerId> peers;
|
2013-11-04 09:09:32 -05:00
|
|
|
peers.push_back(tr->mTransaction->PeerId());
|
2013-06-04 17:00:43 -04:00
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
for(; llit != grpItemL.end(); llit++)
|
|
|
|
{
|
2013-06-04 17:00:43 -04:00
|
|
|
RsNxsSyncGrpItem*& grpSyncItem = *llit;
|
2014-03-17 16:56:06 -04:00
|
|
|
const RsGxsGroupId& grpId = grpSyncItem->grpId;
|
2013-10-05 07:36:31 -04:00
|
|
|
metaIter = grpMetaMap.find(grpId);
|
2014-01-20 06:42:27 -05:00
|
|
|
bool haveItem = false;
|
2013-10-13 17:49:17 -04:00
|
|
|
bool latestVersion = false;
|
2014-01-20 06:42:27 -05:00
|
|
|
if (metaIter != grpMetaMap.end())
|
|
|
|
{
|
|
|
|
haveItem = true;
|
|
|
|
latestVersion = grpSyncItem->publishTs > metaIter->second->mPublishTs;
|
|
|
|
}
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2013-10-13 17:49:17 -04:00
|
|
|
if(!haveItem || (haveItem && latestVersion) ){
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
// determine if you need to check reputation
|
2014-03-17 16:56:06 -04:00
|
|
|
bool checkRep = !grpSyncItem->authorId.isNull();
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
// check if you have reputation, if you don't then
|
|
|
|
// place in holding pen
|
|
|
|
if(checkRep)
|
|
|
|
{
|
|
|
|
if(mReputations->haveReputation(grpSyncItem->authorId))
|
|
|
|
{
|
|
|
|
GixsReputation rep;
|
|
|
|
mReputations->getReputation(grpSyncItem->authorId, rep);
|
2012-09-01 10:47:22 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
if(rep.score > GIXS_CUT_OFF)
|
|
|
|
{
|
|
|
|
addGroupItemToList(tr, grpId, transN, reqList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// preload reputation for later
|
2013-11-04 09:09:32 -05:00
|
|
|
mReputations->loadReputation(grpSyncItem->authorId, peers);
|
2013-06-04 17:00:43 -04:00
|
|
|
GrpAuthEntry entry;
|
|
|
|
entry.mAuthorId = grpSyncItem->authorId;
|
|
|
|
entry.mGrpId = grpSyncItem->grpId;
|
|
|
|
toVet.push_back(entry);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
addGroupItemToList(tr, grpId, transN, reqList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
if(!toVet.empty())
|
|
|
|
{
|
2014-03-17 16:56:06 -04:00
|
|
|
RsPeerId peerId = tr->mTransaction->PeerId();
|
2013-06-04 17:00:43 -04:00
|
|
|
GrpRespPending* grp = new GrpRespPending(mReputations, peerId, toVet);
|
|
|
|
mPendingResp.push_back(grp);
|
|
|
|
}
|
2012-07-14 13:59:54 -04:00
|
|
|
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
if(!reqList.empty())
|
|
|
|
{
|
|
|
|
locked_pushGrpTransactionFromList(reqList, tr->mTransaction->PeerId(), transN);
|
2012-07-15 08:38:20 -04:00
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// clean up meta data
|
2014-03-17 16:56:06 -04:00
|
|
|
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = grpMetaMap.begin();
|
2012-09-01 10:47:22 -04:00
|
|
|
|
|
|
|
for(; mit != grpMetaMap.end(); mit++)
|
|
|
|
delete mit->second;
|
2012-06-11 17:56:23 -04:00
|
|
|
}
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
void RsGxsNetService::locked_genSendGrpsTransaction(NxsTransaction* tr)
|
2012-07-14 13:59:54 -04:00
|
|
|
{
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "locked_genSendGrpsTransaction()" << std::endl;
|
|
|
|
std::cerr << "Generating Grp data send fron TransN: " << tr->mTransaction->transactionNumber
|
|
|
|
<< std::endl;
|
|
|
|
#endif
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// go groups requested in transaction tr
|
|
|
|
|
|
|
|
std::list<RsNxsItem*>::iterator lit = tr->mItems.begin();
|
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
std::map<RsGxsGroupId, RsNxsGrp*> grps;
|
2012-07-14 13:59:54 -04:00
|
|
|
|
|
|
|
for(;lit != tr->mItems.end(); lit++)
|
|
|
|
{
|
|
|
|
RsNxsSyncGrpItem* item = dynamic_cast<RsNxsSyncGrpItem*>(*lit);
|
2013-07-23 18:04:24 -04:00
|
|
|
if (item)
|
|
|
|
{
|
|
|
|
grps[item->grpId] = NULL;
|
|
|
|
}else
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::locked_genSendGrpsTransaction(): item failed to caste to RsNxsSyncGrpItem* "
|
|
|
|
<< std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
2012-07-14 13:59:54 -04:00
|
|
|
}
|
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
if(!grps.empty())
|
|
|
|
{
|
|
|
|
mDataStore->retrieveNxsGrps(grps, false, false);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
return;
|
|
|
|
}
|
2012-07-15 08:38:20 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
NxsTransaction* newTr = new NxsTransaction();
|
|
|
|
newTr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM;
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
uint32_t transN = locked_getTransactionId();
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
// store grp items to send in transaction
|
2014-03-17 16:56:06 -04:00
|
|
|
std::map<RsGxsGroupId, RsNxsGrp*>::iterator mit = grps.begin();
|
|
|
|
RsPeerId peerId = tr->mTransaction->PeerId();
|
2012-07-14 13:59:54 -04:00
|
|
|
for(;mit != grps.end(); mit++)
|
|
|
|
{
|
2013-07-23 18:04:24 -04:00
|
|
|
mit->second->PeerId(peerId); // set so it gets sent to right peer
|
2012-07-15 08:38:20 -04:00
|
|
|
mit->second->transactionNumber = transN;
|
2012-07-14 13:59:54 -04:00
|
|
|
newTr->mItems.push_back(mit->second);
|
|
|
|
}
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
if(newTr->mItems.empty()){
|
|
|
|
delete newTr;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-11-24 07:37:17 -05:00
|
|
|
uint32_t updateTS = 0;
|
|
|
|
if(mGrpServerUpdateItem)
|
|
|
|
updateTS = mGrpServerUpdateItem->grpUpdateTS;
|
2012-07-15 08:38:20 -04:00
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
RsNxsTransac* ntr = new RsNxsTransac(mServType);
|
2012-07-15 08:38:20 -04:00
|
|
|
ntr->transactionNumber = transN;
|
2012-07-14 13:59:54 -04:00
|
|
|
ntr->transactFlag = RsNxsTransac::FLAG_BEGIN_P1 |
|
|
|
|
RsNxsTransac::FLAG_TYPE_GRPS;
|
2013-11-24 07:37:17 -05:00
|
|
|
ntr->updateTS = updateTS;
|
2012-07-14 13:59:54 -04:00
|
|
|
ntr->nItems = grps.size();
|
2013-07-23 18:04:24 -04:00
|
|
|
ntr->PeerId(tr->mTransaction->PeerId());
|
2012-07-14 13:59:54 -04:00
|
|
|
|
|
|
|
newTr->mTransaction = new RsNxsTransac(*ntr);
|
|
|
|
newTr->mTransaction->PeerId(mOwnId);
|
2012-07-15 08:38:20 -04:00
|
|
|
newTr->mTimeOut = time(NULL) + mTransactionTimeOut;
|
2012-07-14 13:59:54 -04:00
|
|
|
|
|
|
|
ntr->PeerId(tr->mTransaction->PeerId());
|
|
|
|
sendItem(ntr);
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
locked_addTransaction(newTr);
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
void RsGxsNetService::runVetting()
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mNxsMutex);
|
|
|
|
|
|
|
|
std::vector<AuthorPending*>::iterator vit = mPendingResp.begin();
|
|
|
|
|
|
|
|
for(; vit != mPendingResp.end(); )
|
|
|
|
{
|
|
|
|
AuthorPending* ap = *vit;
|
|
|
|
|
|
|
|
if(ap->accepted() || ap->expired())
|
|
|
|
{
|
|
|
|
// add to transactions
|
|
|
|
if(AuthorPending::MSG_PEND == ap->getType())
|
|
|
|
{
|
|
|
|
MsgRespPending* mrp = static_cast<MsgRespPending*>(ap);
|
|
|
|
locked_createTransactionFromPending(mrp);
|
|
|
|
}
|
|
|
|
else if(AuthorPending::GRP_PEND == ap->getType())
|
|
|
|
{
|
|
|
|
GrpRespPending* grp = static_cast<GrpRespPending*>(ap);
|
|
|
|
locked_createTransactionFromPending(grp);
|
|
|
|
}else
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::runVetting(): Unknown pending type! Type: " << ap->getType()
|
|
|
|
<< std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
delete ap;
|
|
|
|
vit = mPendingResp.erase(vit);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vit++;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// now lets do circle vetting
|
|
|
|
std::vector<GrpCircleVetting*>::iterator vit2 = mPendingCircleVets.begin();
|
|
|
|
for(; vit2 != mPendingCircleVets.end(); )
|
|
|
|
{
|
|
|
|
GrpCircleVetting*& gcv = *vit2;
|
|
|
|
if(gcv->cleared() || gcv->expired())
|
|
|
|
{
|
|
|
|
if(gcv->getType() == GrpCircleVetting::GRP_ID_PEND)
|
|
|
|
{
|
|
|
|
GrpCircleIdRequestVetting* gcirv =
|
|
|
|
static_cast<GrpCircleIdRequestVetting*>(gcv);
|
|
|
|
|
|
|
|
locked_createTransactionFromPending(gcirv);
|
|
|
|
}
|
|
|
|
else if(gcv->getType() == GrpCircleVetting::MSG_ID_SEND_PEND)
|
|
|
|
{
|
|
|
|
MsgCircleIdsRequestVetting* mcirv =
|
|
|
|
static_cast<MsgCircleIdsRequestVetting*>(gcv);
|
|
|
|
|
2014-05-01 14:50:07 -04:00
|
|
|
if(mcirv->cleared())
|
|
|
|
locked_createTransactionFromPending(mcirv);
|
2013-06-04 17:00:43 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::runVetting(): Unknown Circle pending type! Type: " << gcv->getType()
|
|
|
|
<< std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
delete gcv;
|
|
|
|
vit2 = mPendingCircleVets.erase(vit2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
vit2++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
|
2012-07-14 13:59:54 -04:00
|
|
|
{
|
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "locked_genSendMsgsTransaction()" << std::endl;
|
|
|
|
std::cerr << "Generating Msg data send fron TransN: " << tr->mTransaction->transactionNumber
|
|
|
|
<< std::endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// go groups requested in transaction tr
|
|
|
|
|
|
|
|
std::list<RsNxsItem*>::iterator lit = tr->mItems.begin();
|
|
|
|
|
|
|
|
GxsMsgReq msgIds;
|
|
|
|
GxsMsgResult msgs;
|
|
|
|
|
|
|
|
if(tr->mItems.empty()){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-04-26 19:48:33 -04:00
|
|
|
// hacky assumes a transaction only consist of a single grpId
|
2014-03-17 16:56:06 -04:00
|
|
|
RsGxsGroupId grpId;
|
2013-11-24 07:37:17 -05:00
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
for(;lit != tr->mItems.end(); lit++)
|
|
|
|
{
|
|
|
|
RsNxsSyncMsgItem* item = dynamic_cast<RsNxsSyncMsgItem*>(*lit);
|
2013-07-23 18:04:24 -04:00
|
|
|
if (item)
|
|
|
|
{
|
|
|
|
msgIds[item->grpId].push_back(item->msgId);
|
2013-11-24 07:37:17 -05:00
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
if(grpId.isNull())
|
2013-11-24 07:37:17 -05:00
|
|
|
grpId = item->grpId;
|
2013-07-23 18:04:24 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::locked_genSendMsgsTransaction(): item failed to caste to RsNxsSyncMsgItem* "
|
|
|
|
<< std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
2012-09-01 10:47:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
mDataStore->retrieveNxsMsgs(msgIds, msgs, false, false);
|
|
|
|
|
|
|
|
NxsTransaction* newTr = new NxsTransaction();
|
|
|
|
newTr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM;
|
|
|
|
|
|
|
|
uint32_t transN = locked_getTransactionId();
|
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
// store msg items to send in transaction
|
2012-09-01 10:47:22 -04:00
|
|
|
GxsMsgResult::iterator mit = msgs.begin();
|
2014-03-17 16:56:06 -04:00
|
|
|
RsPeerId peerId = tr->mTransaction->PeerId();
|
2012-09-01 10:47:22 -04:00
|
|
|
uint32_t msgSize = 0;
|
|
|
|
|
|
|
|
for(;mit != msgs.end(); mit++)
|
|
|
|
{
|
|
|
|
std::vector<RsNxsMsg*>& msgV = mit->second;
|
|
|
|
std::vector<RsNxsMsg*>::iterator vit = msgV.begin();
|
|
|
|
|
|
|
|
for(; vit != msgV.end(); vit++)
|
|
|
|
{
|
|
|
|
RsNxsMsg* msg = *vit;
|
|
|
|
msg->PeerId(peerId);
|
|
|
|
msg->transactionNumber = transN;
|
2013-03-16 12:44:33 -04:00
|
|
|
|
|
|
|
#ifndef NXS_FRAG
|
2012-09-01 10:47:22 -04:00
|
|
|
newTr->mItems.push_back(msg);
|
|
|
|
msgSize++;
|
2013-03-16 12:44:33 -04:00
|
|
|
#else
|
|
|
|
MsgFragments fragments;
|
|
|
|
fragmentMsg(*msg, fragments);
|
|
|
|
|
|
|
|
MsgFragments::iterator mit = fragments.begin();
|
|
|
|
|
|
|
|
for(; mit != fragments.end(); mit++)
|
|
|
|
{
|
|
|
|
newTr->mItems.push_back(*mit);
|
|
|
|
msgSize++;
|
|
|
|
}
|
|
|
|
#endif
|
2012-09-01 10:47:22 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(newTr->mItems.empty()){
|
|
|
|
delete newTr;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-11-24 07:37:17 -05:00
|
|
|
uint32_t updateTS = 0;
|
|
|
|
|
|
|
|
ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(grpId);
|
|
|
|
|
|
|
|
if(cit != mServerMsgUpdateMap.end())
|
|
|
|
updateTS = cit->second->msgUpdateTS;
|
|
|
|
|
2012-09-01 10:47:22 -04:00
|
|
|
RsNxsTransac* ntr = new RsNxsTransac(mServType);
|
|
|
|
ntr->transactionNumber = transN;
|
|
|
|
ntr->transactFlag = RsNxsTransac::FLAG_BEGIN_P1 |
|
|
|
|
RsNxsTransac::FLAG_TYPE_MSGS;
|
2013-11-24 07:37:17 -05:00
|
|
|
ntr->updateTS = updateTS;
|
2012-09-01 10:47:22 -04:00
|
|
|
ntr->nItems = msgSize;
|
|
|
|
ntr->PeerId(peerId);
|
|
|
|
|
|
|
|
newTr->mTransaction = new RsNxsTransac(*ntr);
|
|
|
|
newTr->mTransaction->PeerId(mOwnId);
|
2014-10-09 13:20:09 -04:00
|
|
|
newTr->mTimeOut = time(NULL) + mTransactionTimeOut;
|
2012-09-01 10:47:22 -04:00
|
|
|
|
|
|
|
ntr->PeerId(tr->mTransaction->PeerId());
|
|
|
|
sendItem(ntr);
|
|
|
|
|
|
|
|
locked_addTransaction(newTr);
|
|
|
|
|
2012-07-14 13:59:54 -04:00
|
|
|
return;
|
|
|
|
}
|
2012-07-15 08:38:20 -04:00
|
|
|
uint32_t RsGxsNetService::locked_getTransactionId()
|
2012-07-12 16:18:58 -04:00
|
|
|
{
|
2012-07-15 08:38:20 -04:00
|
|
|
return ++mTransactionN;
|
2012-07-12 16:18:58 -04:00
|
|
|
}
|
2012-06-11 17:56:23 -04:00
|
|
|
bool RsGxsNetService::locked_addTransaction(NxsTransaction* tr)
|
|
|
|
{
|
2014-03-17 16:56:06 -04:00
|
|
|
const RsPeerId& peer = tr->mTransaction->PeerId();
|
2012-06-11 17:56:23 -04:00
|
|
|
uint32_t transN = tr->mTransaction->transactionNumber;
|
|
|
|
TransactionIdMap& transMap = mTransactions[peer];
|
|
|
|
bool transNumExist = transMap.find(transN)
|
|
|
|
!= transMap.end();
|
|
|
|
|
|
|
|
|
|
|
|
if(transNumExist){
|
2012-07-14 13:59:54 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "locked_addTransaction() " << std::endl;
|
|
|
|
std::cerr << "Transaction number exist already, transN: " << transN
|
|
|
|
<< std::endl;
|
|
|
|
#endif
|
2012-06-11 17:56:23 -04:00
|
|
|
return false;
|
|
|
|
}else{
|
|
|
|
transMap[transN] = tr;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void RsGxsNetService::cleanTransactionItems(NxsTransaction* tr) const
|
|
|
|
{
|
|
|
|
std::list<RsNxsItem*>::iterator lit = tr->mItems.begin();
|
|
|
|
|
|
|
|
for(; lit != tr->mItems.end(); lit++)
|
|
|
|
{
|
|
|
|
delete *lit;
|
|
|
|
}
|
|
|
|
|
|
|
|
tr->mItems.clear();
|
|
|
|
}
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
void RsGxsNetService::locked_pushGrpRespFromList(std::list<RsNxsItem*>& respList,
|
2014-03-17 16:56:06 -04:00
|
|
|
const RsPeerId& peer, const uint32_t& transN)
|
2013-06-04 17:00:43 -04:00
|
|
|
{
|
|
|
|
NxsTransaction* tr = new NxsTransaction();
|
|
|
|
tr->mItems = respList;
|
|
|
|
|
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM;
|
|
|
|
RsNxsTransac* trItem = new RsNxsTransac(mServType);
|
|
|
|
trItem->transactFlag = RsNxsTransac::FLAG_BEGIN_P1
|
|
|
|
| RsNxsTransac::FLAG_TYPE_GRP_LIST_RESP;
|
|
|
|
trItem->nItems = respList.size();
|
|
|
|
trItem->timestamp = 0;
|
|
|
|
trItem->PeerId(peer);
|
|
|
|
trItem->transactionNumber = transN;
|
|
|
|
// also make a copy for the resident transaction
|
|
|
|
tr->mTransaction = new RsNxsTransac(*trItem);
|
|
|
|
tr->mTransaction->PeerId(mOwnId);
|
2014-10-09 13:20:09 -04:00
|
|
|
tr->mTimeOut = time(NULL) + mTransactionTimeOut;
|
2013-06-04 17:00:43 -04:00
|
|
|
// signal peer to prepare for transaction
|
|
|
|
sendItem(trItem);
|
|
|
|
locked_addTransaction(tr);
|
|
|
|
}
|
|
|
|
|
2013-11-25 17:28:17 -05:00
|
|
|
bool RsGxsNetService::locked_CanReceiveUpdate(const RsNxsSyncGrp *item)
|
|
|
|
{
|
|
|
|
// don't sync if you have no new updates for this peer
|
|
|
|
if(mGrpServerUpdateItem)
|
|
|
|
{
|
|
|
|
if(item->updateTS >= mGrpServerUpdateItem->grpUpdateTS && item->updateTS != 0)
|
|
|
|
{
|
2014-04-27 09:14:07 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::locked_CanReceiveUpdate() No Updates";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
2013-11-25 17:28:17 -05:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrp* item)
|
|
|
|
{
|
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
RsStackMutex stack(mNxsMutex);
|
|
|
|
|
2013-11-25 17:28:17 -05:00
|
|
|
if(!locked_CanReceiveUpdate(item))
|
2014-04-27 09:14:07 -04:00
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::handleRecvSyncGroup() Cannot RecvUpdate";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
2013-11-25 17:28:17 -05:00
|
|
|
return;
|
2014-04-27 09:14:07 -04:00
|
|
|
}
|
2013-11-25 17:28:17 -05:00
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
RsPeerId peer = item->PeerId();
|
2012-07-12 16:18:58 -04:00
|
|
|
|
2013-11-25 17:28:17 -05:00
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grp;
|
2012-07-12 16:18:58 -04:00
|
|
|
mDataStore->retrieveGxsGrpMetaData(grp);
|
|
|
|
|
|
|
|
if(grp.empty())
|
2014-04-27 09:14:07 -04:00
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::handleRecvSyncGroup() Grp Empty";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
2012-07-12 16:18:58 -04:00
|
|
|
return;
|
2014-04-27 09:14:07 -04:00
|
|
|
}
|
2012-07-12 16:18:58 -04:00
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit =
|
2012-07-12 16:18:58 -04:00
|
|
|
grp.begin();
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
std::list<RsNxsItem*> itemL;
|
2012-07-12 16:18:58 -04:00
|
|
|
|
2012-07-15 08:38:20 -04:00
|
|
|
uint32_t transN = locked_getTransactionId();
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
std::vector<GrpIdCircleVet> toVet;
|
2014-02-10 18:50:47 -05:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::handleRecvSyncGroup() \nService: " << mServType << "\nGroup list beings being sent: " << std::endl;
|
|
|
|
#endif
|
2013-06-04 17:00:43 -04:00
|
|
|
|
2012-07-12 16:18:58 -04:00
|
|
|
for(; mit != grp.end(); mit++)
|
|
|
|
{
|
2013-03-06 18:33:23 -05:00
|
|
|
RsGxsGrpMetaData* grpMeta = mit->second;
|
|
|
|
|
2013-03-19 16:13:13 -04:00
|
|
|
if(grpMeta->mSubscribeFlags &
|
|
|
|
GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED)
|
2013-03-06 18:33:23 -05:00
|
|
|
{
|
2013-06-04 17:00:43 -04:00
|
|
|
|
|
|
|
// check if you can send this id to peer
|
|
|
|
// or if you need to add to the holding
|
|
|
|
// pen for peer to be vetted
|
|
|
|
if(canSendGrpId(peer, *grpMeta, toVet))
|
|
|
|
{
|
|
|
|
RsNxsSyncGrpItem* gItem = new
|
|
|
|
RsNxsSyncGrpItem(mServType);
|
|
|
|
gItem->flag = RsNxsSyncGrpItem::FLAG_RESPONSE;
|
|
|
|
gItem->grpId = mit->first;
|
|
|
|
gItem->publishTs = mit->second->mPublishTs;
|
|
|
|
gItem->authorId = grpMeta->mAuthorId;
|
|
|
|
gItem->PeerId(peer);
|
|
|
|
gItem->transactionNumber = transN;
|
|
|
|
itemL.push_back(gItem);
|
2014-02-10 18:50:47 -05:00
|
|
|
#ifdef NXS_NET_DEBUG
|
2014-04-27 09:14:07 -04:00
|
|
|
std::cerr << "RsGxsNetService::handleRecvSyncGroup";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
std::cerr << "Group : " << grpMeta->mGroupName;
|
|
|
|
std::cerr << ", id: " << gItem->grpId;
|
|
|
|
std::cerr << ", authorId: " << gItem->authorId;
|
|
|
|
std::cerr << std::endl;
|
2014-02-10 18:50:47 -05:00
|
|
|
#endif
|
2013-06-04 17:00:43 -04:00
|
|
|
}
|
2013-03-06 18:33:23 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
delete grpMeta; // release resource
|
2012-07-12 16:18:58 -04:00
|
|
|
}
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
if(!toVet.empty())
|
|
|
|
{
|
2014-04-27 09:14:07 -04:00
|
|
|
mPendingCircleVets.push_back(new GrpCircleIdRequestVetting(mCircles, mPgpUtils, toVet, peer));
|
2013-06-04 17:00:43 -04:00
|
|
|
}
|
2012-07-14 13:59:54 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
locked_pushGrpRespFromList(itemL, peer, transN);
|
2012-07-12 16:18:58 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
return;
|
|
|
|
}
|
2012-07-12 16:18:58 -04:00
|
|
|
|
2013-11-25 17:28:17 -05:00
|
|
|
|
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
bool RsGxsNetService::canSendGrpId(const RsPeerId& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet)
|
2013-06-04 17:00:43 -04:00
|
|
|
{
|
2014-04-27 09:14:07 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId()";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
2013-06-04 17:00:43 -04:00
|
|
|
// first do the simple checks
|
|
|
|
uint8_t circleType = grpMeta.mCircleType;
|
2012-07-12 16:18:58 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
if(circleType == GXS_CIRCLE_TYPE_LOCAL)
|
2014-04-27 09:14:07 -04:00
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() LOCAL_CIRCLE, cannot send";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
2013-06-04 17:00:43 -04:00
|
|
|
return false;
|
2014-04-27 09:14:07 -04:00
|
|
|
}
|
2012-07-12 16:18:58 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
if(circleType == GXS_CIRCLE_TYPE_PUBLIC)
|
2014-04-27 09:14:07 -04:00
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() PUBLIC_CIRCLE, can send";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
2013-06-04 17:00:43 -04:00
|
|
|
return true;
|
2014-04-27 09:14:07 -04:00
|
|
|
}
|
2013-06-04 17:00:43 -04:00
|
|
|
|
|
|
|
if(circleType == GXS_CIRCLE_TYPE_EXTERNAL)
|
|
|
|
{
|
2014-04-29 06:28:46 -04:00
|
|
|
const RsGxsCircleId& circleId = grpMeta.mCircleId;
|
|
|
|
if(circleId.isNull())
|
|
|
|
{
|
2014-05-04 08:48:42 -04:00
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() ERROR; EXTERNAL_CIRCLE missing NULL CircleId: ";
|
2014-04-29 06:28:46 -04:00
|
|
|
std::cerr << grpMeta.mGroupId;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2014-05-04 08:48:42 -04:00
|
|
|
// ERROR, will never be shared.
|
|
|
|
return false;
|
2014-04-29 06:28:46 -04:00
|
|
|
}
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
if(mCircles->isLoaded(circleId))
|
|
|
|
{
|
2014-04-27 09:14:07 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() EXTERNAL_CIRCLE, checking mCircles->canSend";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
const RsPgpId& pgpId = mPgpUtils->getPGPId(sslId);
|
2013-06-04 17:00:43 -04:00
|
|
|
return mCircles->canSend(circleId, pgpId);
|
|
|
|
}
|
|
|
|
|
2014-05-01 14:50:07 -04:00
|
|
|
toVet.push_back(GrpIdCircleVet(grpMeta.mGroupId, circleId, grpMeta.mAuthorId));
|
2013-06-04 17:00:43 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(circleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
|
|
|
|
{
|
2014-04-27 09:14:07 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() YOUREYESONLY, checking further";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
2013-06-04 17:00:43 -04:00
|
|
|
// a non empty internal circle id means this
|
|
|
|
// is the personal circle owner
|
2014-03-17 16:56:06 -04:00
|
|
|
if(!grpMeta.mInternalCircle.isNull())
|
2013-06-04 17:00:43 -04:00
|
|
|
{
|
2014-04-21 06:13:35 -04:00
|
|
|
const RsGxsCircleId& internalCircleId = grpMeta.mInternalCircle;
|
2014-04-27 09:14:07 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() have mInternalCircle - we are Group creator";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() mCircleId: " << grpMeta.mCircleId;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() mInternalCircle: " << grpMeta.mInternalCircle;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
if(mCircles->isLoaded(internalCircleId))
|
|
|
|
{
|
2014-04-27 09:14:07 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() circle Loaded - checking mCircles->canSend";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
const RsPgpId& pgpId = mPgpUtils->getPGPId(sslId);
|
2013-06-04 17:00:43 -04:00
|
|
|
return mCircles->canSend(internalCircleId, pgpId);
|
|
|
|
}
|
|
|
|
|
2014-04-27 09:14:07 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() Circle Not Loaded - add to vetting";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
2014-05-01 14:50:07 -04:00
|
|
|
toVet.push_back(GrpIdCircleVet(grpMeta.mGroupId, internalCircleId, grpMeta.mAuthorId));
|
2013-06-04 17:00:43 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// an empty internal circle id means this peer can only
|
|
|
|
// send circle related info from peer he received it
|
2014-04-27 09:14:07 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() mInternalCircle not set, someone else's personal circle";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
2013-06-04 17:00:43 -04:00
|
|
|
if(grpMeta.mOriginator == sslId)
|
2014-04-27 09:14:07 -04:00
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() Originator matches -> can send";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
2013-06-04 17:00:43 -04:00
|
|
|
return true;
|
2014-04-27 09:14:07 -04:00
|
|
|
}
|
2013-06-04 17:00:43 -04:00
|
|
|
else
|
2014-04-27 09:14:07 -04:00
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() Originator doesn't match -> cannot send";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
2013-06-04 17:00:43 -04:00
|
|
|
return false;
|
2014-04-27 09:14:07 -04:00
|
|
|
}
|
2013-06-04 17:00:43 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2012-07-12 16:18:58 -04:00
|
|
|
}
|
|
|
|
|
2014-05-01 14:50:07 -04:00
|
|
|
bool RsGxsNetService::checkCanRecvMsgFromPeer(const RsPeerId& sslId,
|
|
|
|
const RsGxsGrpMetaData& grpMeta) {
|
|
|
|
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::checkCanRecvMsgFromPeer()";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
// first do the simple checks
|
|
|
|
uint8_t circleType = grpMeta.mCircleType;
|
|
|
|
|
|
|
|
if(circleType == GXS_CIRCLE_TYPE_LOCAL)
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::checkCanRecvMsgFromPeer() LOCAL_CIRCLE, cannot request sync from peer";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(circleType == GXS_CIRCLE_TYPE_PUBLIC)
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::checkCanRecvMsgFromPeer() PUBLIC_CIRCLE, can request msg sync";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(circleType == GXS_CIRCLE_TYPE_EXTERNAL)
|
|
|
|
{
|
|
|
|
const RsGxsCircleId& circleId = grpMeta.mCircleId;
|
|
|
|
if(circleId.isNull())
|
|
|
|
{
|
|
|
|
std::cerr << "RsGxsNetService::checkCanRecvMsgFromPeer() ERROR; EXTERNAL_CIRCLE missing NULL CircleId";
|
|
|
|
std::cerr << grpMeta.mGroupId;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
// should just be shared. ? no - this happens for
|
|
|
|
// Circle Groups which lose their CircleIds.
|
|
|
|
// return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(mCircles->isLoaded(circleId))
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::checkCanRecvMsgFromPeer() EXTERNAL_CIRCLE, checking mCircles->canSend";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
const RsPgpId& pgpId = mPgpUtils->getPGPId(sslId);
|
|
|
|
return mCircles->canSend(circleId, pgpId);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
mCircles->loadCircle(circleId); // simply request for next pass
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(circleType == GXS_CIRCLE_TYPE_YOUREYESONLY) // do not attempt to sync msg unless to originator or those permitted
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::checkCanRecvMsgFromPeer() YOUREYESONLY, checking further";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
// a non empty internal circle id means this
|
|
|
|
// is the personal circle owner
|
|
|
|
if(!grpMeta.mInternalCircle.isNull())
|
|
|
|
{
|
|
|
|
const RsGxsCircleId& internalCircleId = grpMeta.mInternalCircle;
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() have mInternalCircle - we are Group creator";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() mCircleId: " << grpMeta.mCircleId;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() mInternalCircle: " << grpMeta.mInternalCircle;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if(mCircles->isLoaded(internalCircleId))
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() circle Loaded - checking mCircles->canSend";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
const RsPgpId& pgpId = mPgpUtils->getPGPId(sslId);
|
|
|
|
return mCircles->canSend(internalCircleId, pgpId);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
mCircles->loadCircle(internalCircleId); // request for next pass
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// an empty internal circle id means this peer can only
|
|
|
|
// send circle related info from peer he received it
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() mInternalCircle not set, someone else's personal circle";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
if(grpMeta.mOriginator == sslId)
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() Originator matches -> can send";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::canSendGrpId() Originator doesn't match -> cannot send";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-11-25 17:28:17 -05:00
|
|
|
bool RsGxsNetService::locked_CanReceiveUpdate(const RsNxsSyncMsg *item)
|
2012-07-12 16:18:58 -04:00
|
|
|
{
|
2013-11-25 17:28:17 -05:00
|
|
|
ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(item->grpId);
|
2012-09-01 10:47:22 -04:00
|
|
|
|
2013-11-25 17:28:17 -05:00
|
|
|
if(cit != mServerMsgUpdateMap.end())
|
|
|
|
{
|
|
|
|
const RsGxsServerMsgUpdateItem *msui = cit->second;
|
2012-09-01 10:47:22 -04:00
|
|
|
|
2013-11-25 17:28:17 -05:00
|
|
|
if(item->updateTS >= msui->msgUpdateTS && item->updateTS != 0)
|
2013-12-20 09:48:32 -05:00
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::locked_CanReceiveUpdate(): Msgs up to date" << std::endl;
|
|
|
|
#endif
|
2013-11-25 17:28:17 -05:00
|
|
|
return false;
|
2013-12-20 09:48:32 -05:00
|
|
|
}
|
2013-11-25 17:28:17 -05:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2012-07-12 16:18:58 -04:00
|
|
|
void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsg* item)
|
|
|
|
{
|
2012-07-15 08:38:20 -04:00
|
|
|
RsStackMutex stack(mNxsMutex);
|
2012-09-01 10:47:22 -04:00
|
|
|
|
2014-10-07 17:42:44 -04:00
|
|
|
// We do that early, so as to get info about who sends data about which group,
|
|
|
|
// even when the group doesn't need update.
|
|
|
|
mGroupSuppliers[item->grpId].insert(item->PeerId()) ;
|
|
|
|
|
2013-11-25 17:28:17 -05:00
|
|
|
if(!locked_CanReceiveUpdate(item))
|
|
|
|
return;
|
2013-11-16 08:40:04 -05:00
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
const RsPeerId& peer = item->PeerId();
|
2012-09-01 10:47:22 -04:00
|
|
|
|
|
|
|
GxsMsgMetaResult metaResult;
|
|
|
|
GxsMsgReq req;
|
2013-06-04 17:00:43 -04:00
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMetas;
|
2013-06-04 17:00:43 -04:00
|
|
|
grpMetas[item->grpId] = NULL;
|
|
|
|
mDataStore->retrieveGxsGrpMetaData(grpMetas);
|
|
|
|
RsGxsGrpMetaData* grpMeta = grpMetas[item->grpId];
|
|
|
|
|
|
|
|
if(grpMeta == NULL)
|
|
|
|
return;
|
|
|
|
|
2014-10-07 17:42:44 -04:00
|
|
|
req[item->grpId] = std::vector<RsGxsMessageId>();
|
2012-09-01 10:47:22 -04:00
|
|
|
mDataStore->retrieveGxsMsgMetaData(req, metaResult);
|
2013-06-04 17:00:43 -04:00
|
|
|
std::vector<RsGxsMsgMetaData*>& msgMetas = metaResult[item->grpId];
|
2012-09-01 10:47:22 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
if(req.empty())
|
|
|
|
{
|
2013-07-23 08:17:50 -04:00
|
|
|
delete(grpMeta);
|
2012-09-01 10:47:22 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
std::list<RsNxsItem*> itemL;
|
2012-09-01 10:47:22 -04:00
|
|
|
|
|
|
|
uint32_t transN = locked_getTransactionId();
|
|
|
|
|
2014-04-26 19:48:33 -04:00
|
|
|
if(canSendMsgIds(msgMetas, *grpMeta, peer))
|
2012-09-01 10:47:22 -04:00
|
|
|
{
|
2013-06-04 17:00:43 -04:00
|
|
|
std::vector<RsGxsMsgMetaData*>::iterator vit = msgMetas.begin();
|
|
|
|
|
|
|
|
for(; vit != msgMetas.end(); vit++)
|
|
|
|
{
|
|
|
|
RsGxsMsgMetaData* m = *vit;
|
|
|
|
|
|
|
|
RsNxsSyncMsgItem* mItem = new
|
|
|
|
RsNxsSyncMsgItem(mServType);
|
|
|
|
mItem->flag = RsNxsSyncGrpItem::FLAG_RESPONSE;
|
|
|
|
mItem->grpId = m->mGroupId;
|
|
|
|
mItem->msgId = m->mMsgId;
|
|
|
|
mItem->authorId = m->mAuthorId;
|
|
|
|
mItem->PeerId(peer);
|
|
|
|
mItem->transactionNumber = transN;
|
|
|
|
itemL.push_back(mItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!itemL.empty())
|
|
|
|
locked_pushMsgRespFromList(itemL, peer, transN);
|
2012-09-01 10:47:22 -04:00
|
|
|
}
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
std::vector<RsGxsMsgMetaData*>::iterator vit = msgMetas.begin();
|
|
|
|
// release meta resource
|
|
|
|
for(vit = msgMetas.begin(); vit != msgMetas.end(); vit++)
|
|
|
|
delete *vit;
|
|
|
|
|
2013-07-23 08:17:50 -04:00
|
|
|
delete(grpMeta);
|
2013-06-04 17:00:43 -04:00
|
|
|
}
|
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
void RsGxsNetService::locked_pushMsgRespFromList(std::list<RsNxsItem*>& itemL, const RsPeerId& sslId,
|
2013-06-04 17:00:43 -04:00
|
|
|
const uint32_t& transN)
|
|
|
|
{
|
|
|
|
NxsTransaction* tr = new NxsTransaction();
|
|
|
|
tr->mItems = itemL;
|
2012-09-01 10:47:22 -04:00
|
|
|
tr->mFlag = NxsTransaction::FLAG_STATE_WAITING_CONFIRM;
|
|
|
|
RsNxsTransac* trItem = new RsNxsTransac(mServType);
|
|
|
|
trItem->transactFlag = RsNxsTransac::FLAG_BEGIN_P1
|
|
|
|
| RsNxsTransac::FLAG_TYPE_MSG_LIST_RESP;
|
|
|
|
|
|
|
|
trItem->nItems = itemL.size();
|
|
|
|
|
|
|
|
trItem->timestamp = 0;
|
2013-06-04 17:00:43 -04:00
|
|
|
trItem->PeerId(sslId);
|
2012-09-01 10:47:22 -04:00
|
|
|
trItem->transactionNumber = transN;
|
|
|
|
|
|
|
|
// also make a copy for the resident transaction
|
|
|
|
tr->mTransaction = new RsNxsTransac(*trItem);
|
|
|
|
tr->mTransaction->PeerId(mOwnId);
|
2014-10-09 13:20:09 -04:00
|
|
|
tr->mTimeOut = time(NULL) + mTransactionTimeOut;
|
2012-09-01 10:47:22 -04:00
|
|
|
|
|
|
|
// signal peer to prepare for transaction
|
|
|
|
sendItem(trItem);
|
|
|
|
|
|
|
|
locked_addTransaction(tr);
|
2012-07-12 16:18:58 -04:00
|
|
|
}
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
bool RsGxsNetService::canSendMsgIds(const std::vector<RsGxsMsgMetaData*>& msgMetas,
|
2014-03-17 16:56:06 -04:00
|
|
|
const RsGxsGrpMetaData& grpMeta, const RsPeerId& sslId)
|
2012-06-11 17:56:23 -04:00
|
|
|
{
|
2014-04-27 09:14:07 -04:00
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::canSendMsgIds() CIRCLE VETTING";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
// first do the simple checks
|
|
|
|
uint8_t circleType = grpMeta.mCircleType;
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
if(circleType == GXS_CIRCLE_TYPE_LOCAL)
|
|
|
|
return false;
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
if(circleType == GXS_CIRCLE_TYPE_PUBLIC)
|
|
|
|
return true;
|
2012-06-11 17:56:23 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
const RsGxsCircleId& circleId = grpMeta.mCircleId;
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
if(circleType == GXS_CIRCLE_TYPE_EXTERNAL)
|
|
|
|
{
|
|
|
|
if(mCircles->isLoaded(circleId))
|
|
|
|
{
|
2014-04-27 09:14:07 -04:00
|
|
|
const RsPgpId& pgpId = mPgpUtils->getPGPId(sslId);
|
2013-06-04 17:00:43 -04:00
|
|
|
return mCircles->canSend(circleId, pgpId);
|
|
|
|
}
|
2012-07-12 16:18:58 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
std::vector<MsgIdCircleVet> toVet;
|
|
|
|
std::vector<RsGxsMsgMetaData*>::const_iterator vit = msgMetas.begin();
|
2012-07-12 16:18:58 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
for(; vit != msgMetas.end(); vit++)
|
|
|
|
{
|
|
|
|
const RsGxsMsgMetaData* const& meta = *vit;
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
MsgIdCircleVet mic(meta->mMsgId, meta->mAuthorId);
|
|
|
|
toVet.push_back(mic);
|
|
|
|
}
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
if(!toVet.empty())
|
2014-04-27 09:14:07 -04:00
|
|
|
mPendingCircleVets.push_back(new MsgCircleIdsRequestVetting(mCircles, mPgpUtils, toVet, grpMeta.mGroupId,
|
2013-06-04 17:00:43 -04:00
|
|
|
sslId, grpMeta.mCircleId));
|
2012-06-07 16:43:12 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
return false;
|
|
|
|
}
|
2012-06-16 09:59:40 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
if(circleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
|
2012-06-16 09:59:40 -04:00
|
|
|
{
|
2013-06-04 17:00:43 -04:00
|
|
|
// a non empty internal circle id means this
|
|
|
|
// is the personal circle owner
|
2014-03-17 16:56:06 -04:00
|
|
|
if(!grpMeta.mInternalCircle.isNull())
|
2013-06-04 17:00:43 -04:00
|
|
|
{
|
2014-04-26 19:48:33 -04:00
|
|
|
const RsGxsCircleId& internalCircleId = grpMeta.mInternalCircle;
|
2013-06-04 17:00:43 -04:00
|
|
|
if(mCircles->isLoaded(internalCircleId))
|
|
|
|
{
|
2014-04-27 09:14:07 -04:00
|
|
|
const RsPgpId& pgpId = mPgpUtils->getPGPId(sslId);
|
2013-06-04 17:00:43 -04:00
|
|
|
return mCircles->canSend(internalCircleId, pgpId);
|
|
|
|
}
|
2012-06-16 09:59:40 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
std::vector<MsgIdCircleVet> toVet;
|
|
|
|
std::vector<RsGxsMsgMetaData*>::const_iterator vit = msgMetas.begin();
|
2012-09-25 17:04:04 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
for(; vit != msgMetas.end(); vit++)
|
|
|
|
{
|
|
|
|
const RsGxsMsgMetaData* const& meta = *vit;
|
2012-09-25 17:04:04 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
MsgIdCircleVet mic(meta->mMsgId, meta->mAuthorId);
|
|
|
|
toVet.push_back(mic);
|
|
|
|
}
|
2012-09-25 17:04:04 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
if(!toVet.empty())
|
2014-04-27 09:14:07 -04:00
|
|
|
mPendingCircleVets.push_back(new MsgCircleIdsRequestVetting(mCircles, mPgpUtils,
|
|
|
|
toVet, grpMeta.mGroupId,
|
2013-06-04 17:00:43 -04:00
|
|
|
sslId, grpMeta.mCircleId));
|
2012-09-25 17:04:04 -04:00
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// an empty internal circle id means this peer can only
|
|
|
|
// send circle related info from peer he received it
|
|
|
|
if(grpMeta.mOriginator == sslId)
|
|
|
|
return true;
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2012-09-25 17:04:04 -04:00
|
|
|
}
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
/** inherited methods **/
|
2012-09-25 17:04:04 -04:00
|
|
|
|
2014-03-23 08:13:44 -04:00
|
|
|
void RsGxsNetService::pauseSynchronisation(bool /* enabled */)
|
2012-09-25 17:04:04 -04:00
|
|
|
{
|
2013-06-04 17:00:43 -04:00
|
|
|
|
2012-09-25 17:04:04 -04:00
|
|
|
}
|
|
|
|
|
2014-03-23 08:13:44 -04:00
|
|
|
void RsGxsNetService::setSyncAge(uint32_t /* age */)
|
2012-09-25 17:04:04 -04:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
int RsGxsNetService::requestGrp(const std::list<RsGxsGroupId>& grpId, const RsPeerId& peerId)
|
2013-10-29 17:29:20 -04:00
|
|
|
{
|
|
|
|
RsStackMutex stack(mNxsMutex);
|
|
|
|
mExplicitRequest[peerId].assign(grpId.begin(), grpId.end());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RsGxsNetService::processExplicitGroupRequests()
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mNxsMutex);
|
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
std::map<RsPeerId, std::list<RsGxsGroupId> >::const_iterator cit = mExplicitRequest.begin();
|
2013-10-29 17:29:20 -04:00
|
|
|
|
|
|
|
for(; cit != mExplicitRequest.end(); cit++)
|
|
|
|
{
|
2014-03-17 16:56:06 -04:00
|
|
|
const RsPeerId& peerId = cit->first;
|
2013-10-29 17:29:20 -04:00
|
|
|
const std::list<RsGxsGroupId>& groupIdList = cit->second;
|
|
|
|
|
|
|
|
std::list<RsNxsItem*> grpSyncItems;
|
|
|
|
std::list<RsGxsGroupId>::const_iterator git = groupIdList.begin();
|
|
|
|
uint32_t transN = locked_getTransactionId();
|
|
|
|
for(; git != groupIdList.end(); git++)
|
|
|
|
{
|
|
|
|
RsNxsSyncGrpItem* item = new RsNxsSyncGrpItem(mServType);
|
|
|
|
item->grpId = *git;
|
|
|
|
item->PeerId(peerId);
|
|
|
|
item->flag = RsNxsSyncGrpItem::FLAG_REQUEST;
|
|
|
|
item->transactionNumber = transN;
|
|
|
|
grpSyncItems.push_back(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!grpSyncItems.empty())
|
|
|
|
locked_pushGrpTransactionFromList(grpSyncItems, peerId, transN);
|
|
|
|
}
|
|
|
|
|
|
|
|
mExplicitRequest.clear();
|
|
|
|
}
|
2014-10-05 15:14:05 -04:00
|
|
|
|
|
|
|
#define NXS_NET_DEBUG
|
|
|
|
int RsGxsNetService::sharePublishKey(const RsGxsGroupId& grpId,const std::list<RsPeerId>& peers)
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mNxsMutex);
|
|
|
|
|
|
|
|
mPendingPublishKeyRecipients[grpId] = peers ;
|
|
|
|
|
|
|
|
std::cerr << "RsGxsNetService::sharePublishKeys() " << (void*)this << " adding publish keys for grp " << grpId << " to sending list" << std::endl;
|
|
|
|
|
|
|
|
return true ;
|
|
|
|
}
|
|
|
|
|
|
|
|
void RsGxsNetService::sharePublishKeysPending()
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mNxsMutex);
|
|
|
|
|
|
|
|
if(mPendingPublishKeyRecipients.empty())
|
|
|
|
return ;
|
|
|
|
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::sharePublishKeys() " << (void*)this << std::endl;
|
|
|
|
#endif
|
|
|
|
// get list of peers that are online
|
|
|
|
|
|
|
|
std::set<RsPeerId> peersOnline;
|
|
|
|
std::list<RsGxsGroupId> toDelete;
|
|
|
|
std::map<RsGxsGroupId,std::list<RsPeerId> >::iterator mit ;
|
|
|
|
|
|
|
|
mNetMgr->getOnlineList(mServiceInfo.mServiceType, peersOnline);
|
|
|
|
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << " " << peersOnline.size() << " peers online." << std::endl;
|
|
|
|
#endif
|
|
|
|
/* send public key to peers online */
|
|
|
|
|
|
|
|
for(mit = mPendingPublishKeyRecipients.begin(); mit != mPendingPublishKeyRecipients.end(); ++mit)
|
|
|
|
{
|
|
|
|
// Compute the set of peers to send to. We start with this, to avoid retrieving the data for nothing.
|
|
|
|
|
|
|
|
std::list<RsPeerId> recipients ;
|
|
|
|
std::list<RsPeerId> offline_recipients ;
|
|
|
|
|
|
|
|
for(std::list<RsPeerId>::const_iterator it(mit->second.begin());it!=mit->second.end();++it)
|
|
|
|
if(peersOnline.find(*it) != peersOnline.end())
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << " " << *it << ": online. Adding." << std::endl;
|
|
|
|
#endif
|
|
|
|
recipients.push_back(*it) ;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << " " << *it << ": offline. Keeping for next try." << std::endl;
|
|
|
|
#endif
|
|
|
|
offline_recipients.push_back(*it) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If empty, skip
|
|
|
|
|
|
|
|
if(recipients.empty())
|
|
|
|
{
|
|
|
|
std::cerr << " No recipients online. Skipping." << std::endl;
|
|
|
|
continue ;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get the meta data for this group Id
|
|
|
|
//
|
|
|
|
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMetaMap;
|
|
|
|
grpMetaMap[mit->first] = NULL;
|
|
|
|
mDataStore->retrieveGxsGrpMetaData(grpMetaMap);
|
|
|
|
|
|
|
|
// Find the publish keys in the retrieved info
|
|
|
|
|
|
|
|
RsGxsGrpMetaData *grpMeta = grpMetaMap[mit->first] ;
|
|
|
|
|
|
|
|
if(grpMeta == NULL)
|
|
|
|
{
|
|
|
|
std::cerr << "(EE) RsGxsNetService::sharePublishKeys() Publish keys cannot be found for group " << mit->first << std::endl;
|
|
|
|
continue ;
|
|
|
|
}
|
|
|
|
|
|
|
|
const RsTlvSecurityKeySet& keys = grpMeta->keys;
|
|
|
|
|
|
|
|
std::map<RsGxsId, RsTlvSecurityKey>::const_iterator kit = keys.keys.begin(), kit_end = keys.keys.end();
|
|
|
|
bool publish_key_found = false;
|
|
|
|
RsTlvSecurityKey publishKey ;
|
|
|
|
|
|
|
|
for(; kit != kit_end && !publish_key_found; ++kit)
|
|
|
|
{
|
|
|
|
publish_key_found = (kit->second.keyFlags == (RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL));
|
|
|
|
publishKey = kit->second ;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!publish_key_found)
|
|
|
|
{
|
|
|
|
std::cerr << "(EE) no publish key in group " << mit->first << ". Cannot share!" << std::endl;
|
|
|
|
continue ;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << " using publish key ID=" << publishKey.keyId << ", flags=" << publishKey.keyFlags << std::endl;
|
|
|
|
#endif
|
|
|
|
for(std::list<RsPeerId>::const_iterator it(recipients.begin());it!=recipients.end();++it)
|
|
|
|
{
|
|
|
|
/* Create publish key sharing item */
|
|
|
|
RsNxsGroupPublishKeyItem *publishKeyItem = new RsNxsGroupPublishKeyItem(mServType);
|
|
|
|
|
|
|
|
publishKeyItem->clear();
|
|
|
|
publishKeyItem->grpId = mit->first;
|
|
|
|
|
|
|
|
publishKeyItem->key = publishKey ;
|
|
|
|
publishKeyItem->PeerId(*it);
|
|
|
|
|
|
|
|
sendItem(publishKeyItem);
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << " sent key item to " << *it << std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
mit->second = offline_recipients ;
|
|
|
|
|
|
|
|
// If given peers have all received key(s) then stop sending for group
|
|
|
|
if(offline_recipients.empty())
|
|
|
|
toDelete.push_back(mit->first);
|
|
|
|
}
|
|
|
|
|
|
|
|
// delete pending peer list which are done with
|
|
|
|
for(std::list<RsGxsGroupId>::const_iterator lit = toDelete.begin(); lit != toDelete.end(); lit++)
|
|
|
|
mPendingPublishKeyRecipients.erase(*lit);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RsGxsNetService::handleRecvPublishKeys(RsNxsGroupPublishKeyItem *item)
|
|
|
|
{
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << "RsGxsNetService::sharePublishKeys() " << std::endl;
|
|
|
|
#endif
|
|
|
|
RsStackMutex stack(mNxsMutex);
|
|
|
|
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
std::cerr << " PeerId : " << item->PeerId() << std::endl;
|
|
|
|
std::cerr << " GrpId: " << item->grpId << std::endl;
|
|
|
|
std::cerr << " Got key Item: " << item->key.keyId << std::endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Get the meta data for this group Id
|
|
|
|
//
|
|
|
|
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMetaMap;
|
|
|
|
grpMetaMap[item->grpId] = NULL;
|
|
|
|
mDataStore->retrieveGxsGrpMetaData(grpMetaMap);
|
|
|
|
|
|
|
|
// update the publish keys in this group meta info
|
|
|
|
|
|
|
|
RsGxsGrpMetaData *grpMeta = grpMetaMap[item->grpId] ;
|
|
|
|
|
|
|
|
// Check that the keys correspond, and that FULL keys are supplied, etc.
|
|
|
|
|
|
|
|
std::cerr << " Key received: " << std::endl;
|
|
|
|
|
|
|
|
bool admin = (item->key.keyFlags & RSTLV_KEY_DISTRIB_ADMIN) && (item->key.keyFlags & RSTLV_KEY_TYPE_FULL) ;
|
|
|
|
bool publi = (item->key.keyFlags & RSTLV_KEY_DISTRIB_PRIVATE) && (item->key.keyFlags & RSTLV_KEY_TYPE_FULL) ;
|
|
|
|
|
|
|
|
std::cerr << " Key id = " << item->key.keyId << " admin=" << admin << ", publish=" << publi << " ts=" << item->key.endTS << std::endl;
|
|
|
|
|
|
|
|
if(!(!admin && publi))
|
|
|
|
{
|
|
|
|
std::cerr << " Key is not a publish private key. Discarding!" << std::endl;
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
// Also check that we don't already have full keys for that group.
|
|
|
|
|
|
|
|
std::map<RsGxsId,RsTlvSecurityKey>::iterator it = grpMeta->keys.keys.find(item->key.keyId) ;
|
|
|
|
|
|
|
|
if(it == grpMeta->keys.keys.end())
|
|
|
|
{
|
|
|
|
std::cerr << " (EE) Key not found in known group keys. This is an inconsistency." << std::endl;
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((it->second.keyFlags & RSTLV_KEY_DISTRIB_PRIVATE) && (it->second.keyFlags & RSTLV_KEY_TYPE_FULL))
|
|
|
|
{
|
|
|
|
std::cerr << " (EE) Publish key already present in database. Discarding message." << std::endl;
|
2014-10-06 16:16:52 -04:00
|
|
|
return ;
|
2014-10-05 15:14:05 -04:00
|
|
|
}
|
|
|
|
|
2014-10-06 16:16:52 -04:00
|
|
|
// Store/update the info.
|
2014-10-05 15:14:05 -04:00
|
|
|
|
|
|
|
it->second = item->key ;
|
|
|
|
bool ret = mDataStore->updateGroupKeys(item->grpId,grpMeta->keys, grpMeta->mSubscribeFlags | GXS_SERV::GROUP_SUBSCRIBE_PUBLISH) ;
|
|
|
|
|
|
|
|
if(!ret)
|
|
|
|
std::cerr << "(EE) could not update database. Something went wrong." << std::endl;
|
|
|
|
#ifdef NXS_NET_DEBUG
|
|
|
|
else
|
|
|
|
std::cerr << " updated database with new publish keys." << std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|