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>
2014-11-02 04:23:37 -05:00
# include <sys/time.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"
2014-11-02 04:23:37 -05:00
# include "retroshare/rsconfig.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
* * */
2015-01-30 15:46:58 -05:00
//#define NXS_NET_DEBUG 1
2015-01-29 15:47:09 -05:00
//#define NXS_NET_DEBUG_0 1
2015-01-28 17:48:59 -05:00
// #define NXS_NET_DEBUG_1 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-12-02 15:06:56 -05:00
// The constant below have a direct influence on how fast forums/channels/posted/identity groups propagate and on the overloading of queues:
//
// Channels/forums will update at a rate of SYNC_PERIOD*MAX_REQLIST_SIZE/60 messages per minute.
// A large TRANSAC_TIMEOUT helps large transactions to finish before anything happens (e.g. disconnexion) or when the server has low upload bandwidth,
// but also uses more memory.
// A small value for MAX_REQLIST_SIZE is likely to help messages to propagate in a chaotic network, but will also slow them down.
// A small SYNC_PERIOD fasten message propagation, but is likely to overload the server side of transactions (e.g. overload outqueues).
//
# define SYNC_PERIOD 60
# define MAX_REQLIST_SIZE 20 // No more than 20 items per msg request list => creates smaller transactions that are less likely to be cancelled.
# define TRANSAC_TIMEOUT 2000 // In seconds. Has been increased to avoid epidemic transaction cancelling due to overloaded outqueues.
2012-07-14 13:59:54 -04:00
2014-12-02 15:06:56 -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 ( )
{
2014-11-26 15:34:24 -05:00
RS_STACK_MUTEX ( mNxsMutex ) ;
2012-06-07 16:43:12 -04:00
2014-11-26 15:34:24 -05:00
for ( TransactionsPeerMap : : iterator it = mTransactions . begin ( ) ; it ! = mTransactions . end ( ) ; + + it )
{
for ( TransactionIdMap : : iterator it2 = it - > second . begin ( ) ; it2 ! = it - > second . end ( ) ; + + it2 )
delete it2 - > second ;
it - > second . clear ( ) ;
}
mTransactions . clear ( ) ;
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
{
2014-11-02 04:23:37 -05: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 ;
}
2014-11-02 04:23:37 -05:00
// This class collects outgoing items due to the broadcast of Nxs messages. It computes
// a probability that can be used to temper the broadcast of items so as to match the
// residual bandwidth (difference between max allowed bandwidth and current outgoing rate.
class NxsBandwidthRecorder
{
public :
2014-11-02 05:21:45 -05:00
static const int OUTQUEUE_CUTOFF_VALUE = 500 ;
static const int BANDWIDTH_ESTIMATE_DELAY = 20 ;
2014-11-02 04:23:37 -05:00
static void recordEvent ( uint16_t service_type , RsItem * item )
{
2014-11-11 14:47:05 -05:00
RS_STACK_MUTEX ( mtx ) ;
2014-11-02 04:23:37 -05:00
uint32_t bw = RsNxsSerialiser ( service_type ) . size ( item ) ; // this is used to estimate bandwidth.
timeval tv ;
gettimeofday ( & tv , NULL ) ;
// compute time(NULL) in msecs, for a more accurate bw estimate.
uint64_t now = tv . tv_sec * 1000 + tv . tv_usec / 1000 ;
total_record + = bw ;
+ + total_events ;
2014-11-02 05:21:45 -05:00
# ifdef NXS_NET_DEBUG
2014-11-02 04:23:37 -05:00
std : : cerr < < " bandwidthRecorder::recordEvent() Recording event time= " < < now < < " . bw= " < < bw < < std : : endl ;
2014-11-02 05:21:45 -05:00
# endif
2014-11-02 04:23:37 -05:00
// Every 20 seconds at min, compute a new estimate of the required bandwidth.
if ( now > last_event_record + BANDWIDTH_ESTIMATE_DELAY * 1000 )
{
// Compute the bandwidth using recorded times, in msecs
float speed = total_record / 1024.0f / ( now - last_event_record ) * 1000.0f ;
// Apply a small temporal convolution.
estimated_required_bandwidth = 0.75 * estimated_required_bandwidth + 0.25 * speed ;
# ifdef NXS_NET_DEBUG
std : : cerr < < std : : dec < < " " < < total_record < < " Bytes ( " < < total_events < < " items) "
< < " received in " < < now - last_event_record < < " seconds. Speed: " < < speed < < " KBytes/sec " < < std : : endl ;
std : : cerr < < " instantaneous speed = " < < speed < < " KB/s " < < std : : endl ;
std : : cerr < < " cumulated estimated = " < < estimated_required_bandwidth < < " KB/s " < < std : : endl ;
# endif
last_event_record = now ;
total_record = 0 ;
total_events = 0 ;
}
}
// Estimate the probability of sending an item so that the expected bandwidth matches the residual bandwidth
static float computeCurrentSendingProbability ( )
{
2014-11-22 07:51:52 -05:00
int maxIn = 50 , maxOut = 50 ;
float currIn = 0 , currOut = 0 ;
2014-11-02 04:23:37 -05:00
rsConfig - > GetMaxDataRates ( maxIn , maxOut ) ;
rsConfig - > GetCurrentDataRates ( currIn , currOut ) ;
2014-11-02 05:21:45 -05:00
RsConfigDataRates rates ;
rsConfig - > getTotalBandwidthRates ( rates ) ;
2014-12-21 14:12:40 -05:00
# ifdef NXS_NET_DEBUG
2014-11-02 05:21:45 -05:00
std : : cerr < < std : : dec < < std : : endl ;
2014-12-21 14:12:40 -05:00
# endif
2014-11-02 05:21:45 -05:00
float outqueue_factor = 1.0f / pow ( std : : max ( 0.02f , rates . mQueueOut / ( float ) OUTQUEUE_CUTOFF_VALUE ) , 5.0f ) ;
float accepted_bandwidth = std : : max ( 0.0f , maxOut - currOut ) ;
float max_bandwidth_factor = std : : min ( accepted_bandwidth / estimated_required_bandwidth , 1.0f ) ;
// We account for two things here:
// 1 - the required max bandwidth
// 2 - the current network overload, measured from the size of the outqueues.
//
// Only the later can limit the traffic if the internet connexion speed is responsible for outqueue overloading.
float sending_probability = std : : min ( outqueue_factor , max_bandwidth_factor ) ;
2014-11-02 04:23:37 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " bandwidthRecorder::computeCurrentSendingProbability() " < < std : : endl ;
2014-11-02 05:21:45 -05:00
std : : cerr < < " current required bandwidth : " < < estimated_required_bandwidth < < " KB/s " < < std : : endl ;
std : : cerr < < " max_bandwidth_factor : " < < max_bandwidth_factor < < std : : endl ;
std : : cerr < < " outqueue size : " < < rates . mQueueOut < < " , factor= " < < outqueue_factor < < std : : endl ;
std : : cerr < < " max out : " < < maxOut < < " , currOut= " < < currOut < < std : : endl ;
std : : cerr < < " computed probability : " < < sending_probability < < std : : endl ;
2014-11-02 04:23:37 -05:00
# endif
return sending_probability ;
}
private :
static RsMutex mtx ;
static uint64_t last_event_record ;
static float estimated_required_bandwidth ;
static uint32_t total_events ;
static uint64_t total_record ;
} ;
2014-12-02 15:06:56 -05:00
uint32_t NxsBandwidthRecorder : : total_events = 0 ; // total number of events. Not used.
2014-11-02 04:23:37 -05:00
uint64_t NxsBandwidthRecorder : : last_event_record = time ( NULL ) * 1000 ; // starting time of bw estimate period (in msec)
2014-12-02 15:06:56 -05:00
uint64_t NxsBandwidthRecorder : : total_record = 0 ; // total bytes recorded in the current time frame
2014-11-02 04:23:37 -05:00
float NxsBandwidthRecorder : : estimated_required_bandwidth = 10.0f ; // Estimated BW for sending sync data. Set to 10KB/s, to avoid 0.
2014-12-02 15:06:56 -05:00
RsMutex NxsBandwidthRecorder : : mtx ( " Bandwidth recorder " ) ; // Protects the recorder since bw events are collected from multiple GXS Net services
2014-11-02 04:23:37 -05:00
2012-07-12 16:18:58 -04:00
void RsGxsNetService : : syncWithPeers ( )
{
2015-01-28 17:48:59 -05:00
# ifdef NXS_NET_DEBUG_0
std : : cerr < < " RsGxsNetService::syncWithPeers() this= " < < ( void * ) this < < " . serviceInfo= " < < mServiceInfo < < std : : endl ;
2014-04-27 09:14:07 -04:00
# endif
2012-07-12 16:18:58 -04:00
2014-11-02 04:23:37 -05:00
static RsNxsSerialiser ser ( mServType ) ; // this is used to estimate bandwidth.
2015-01-28 17:48:59 -05:00
RS_STACK_MUTEX ( mNxsMutex ) ;
2014-05-01 14:50:07 -04:00
2015-01-28 17:48:59 -05:00
std : : set < RsPeerId > peers ;
mNetMgr - > getOnlineList ( mServiceInfo . mServiceType , peers ) ;
2012-07-12 16:18:58 -04:00
2015-01-28 17:48:59 -05:00
std : : set < RsPeerId > : : iterator sit = peers . begin ( ) ;
2012-07-12 16:18:58 -04:00
2015-01-30 15:46:58 -05:00
// for now just grps
for ( ; sit ! = peers . end ( ) ; + + sit )
2014-12-02 15:06:56 -05:00
{
2013-11-16 08:40:04 -05:00
2015-01-30 15:46:58 -05:00
const RsPeerId peerId = * sit ;
2013-11-16 08:40:04 -05:00
2015-01-30 15:46:58 -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 ;
2014-11-02 04:23:37 -05:00
2015-01-30 15:46:58 -05:00
NxsBandwidthRecorder : : recordEvent ( mServType , grp ) ;
2014-11-02 04:23:37 -05:00
2015-01-28 17:48:59 -05:00
# ifdef NXS_NET_DEBUG_0
2015-01-30 15:46:58 -05:00
std : : cerr < < " sending RsNxsSyncGrp item to peer id: " < < * sit < < " ts= " < < updateTS < < std : : endl ;
2014-12-02 15:06:56 -05:00
# endif
2015-01-30 15:46:58 -05:00
sendItem ( grp ) ;
2014-11-02 04:23:37 -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
2015-01-28 17:48:59 -05:00
typedef std : : map < RsGxsGroupId , RsGxsGrpMetaData * > GrpMetaMap ;
GrpMetaMap grpMeta ;
2014-05-01 14:50:07 -04:00
2015-01-28 17:48:59 -05:00
mDataStore - > retrieveGxsGrpMetaData ( grpMeta ) ;
2012-09-04 18:32:52 -04:00
2015-01-28 17:48:59 -05:00
GrpMetaMap : : iterator
mit = grpMeta . begin ( ) ;
2012-09-04 18:32:52 -04:00
2015-01-28 17:48:59 -05:00
GrpMetaMap toRequest ;
2012-09-04 18:32:52 -04:00
2015-01-28 17:48:59 -05:00
for ( ; mit ! = grpMeta . end ( ) ; + + mit )
{
RsGxsGrpMetaData * meta = mit - > second ;
2012-09-04 18:32:52 -04:00
2015-01-28 17:48:59 -05:00
// if(meta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED )
// {
2014-12-16 01:54:15 -05:00
toRequest . insert ( std : : make_pair ( mit - > first , meta ) ) ;
2015-01-28 17:48:59 -05:00
// }else
// delete meta;
}
2012-09-04 18:32:52 -04:00
2015-01-28 17:48:59 -05:00
grpMeta . clear ( ) ;
2014-05-01 14:50:07 -04:00
2015-01-28 17:48:59 -05:00
sit = peers . begin ( ) ;
2012-09-04 18:32:52 -04:00
2014-11-02 04:23:37 -05:00
float sending_probability = NxsBandwidthRecorder : : computeCurrentSendingProbability ( ) ;
2015-01-28 17:48:59 -05:00
# ifdef NXS_NET_DEBUG_0
2014-12-02 15:06:56 -05:00
std : : cerr < < " syncWithPeers(): Sending probability = " < < sending_probability < < std : : endl ;
2014-11-02 04:23:37 -05:00
# endif
2015-01-28 17:48:59 -05:00
// Synchronise group msg for groups which we're subscribed to
// For each peer and each group, we send to the peer the time stamp of the most
// recent message we have. If the peer has more recent messages he will send them.
2012-09-30 10:21:17 -04:00
2015-01-28 17:48:59 -05:00
for ( ; sit ! = peers . end ( ) ; + + sit )
{
const RsPeerId & peerId = * sit ;
2012-09-30 10:21:17 -04:00
2013-11-16 08:40:04 -05:00
2015-01-28 17:48:59 -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 ;
2013-11-16 08:40:04 -05:00
2015-01-28 17:48:59 -05:00
ClientMsgMap : : const_iterator cit = mClientMsgUpdateMap . find ( peerId ) ;
if ( cit ! = mClientMsgUpdateMap . end ( ) )
mui = cit - > second ;
# ifdef NXS_NET_DEBUG_0
2014-12-02 15:06:56 -05:00
std : : cerr < < " syncing messages with peer " < < peerId < < std : : endl ;
# endif
2013-11-16 08:40:04 -05:00
2015-01-28 17:48:59 -05:00
GrpMetaMap : : const_iterator mmit = toRequest . begin ( ) ;
for ( ; mmit ! = toRequest . end ( ) ; + + mmit )
2014-12-02 15:06:56 -05:00
{
const RsGxsGrpMetaData * meta = mmit - > second ;
const RsGxsGroupId & grpId = mmit - > first ;
2014-05-01 14:50:07 -04:00
2014-12-02 15:06:56 -05:00
if ( ! checkCanRecvMsgFromPeer ( peerId , * meta ) )
continue ;
2014-05-01 14:50:07 -04:00
2015-01-28 17:48:59 -05:00
// On default, the info has never been received so the TS is 0.
2014-12-02 15:06:56 -05:00
uint32_t updateTS = 0 ;
2015-01-28 17:48:59 -05:00
2014-12-02 15:06:56 -05:00
if ( mui )
{
std : : map < RsGxsGroupId , uint32_t > : : const_iterator cit2 = mui - > msgUpdateTS . find ( grpId ) ;
2013-11-16 08:40:04 -05:00
2014-12-02 15:06:56 -05:00
if ( cit2 ! = mui - > msgUpdateTS . end ( ) )
updateTS = cit2 - > second ;
}
2013-11-16 08:40:04 -05:00
2014-12-02 15:06:56 -05:00
RsNxsSyncMsg * msg = new RsNxsSyncMsg ( mServType ) ;
msg - > clear ( ) ;
msg - > PeerId ( peerId ) ;
msg - > grpId = grpId ;
msg - > updateTS = updateTS ;
2014-11-02 04:23:37 -05:00
2014-12-02 15:06:56 -05:00
NxsBandwidthRecorder : : recordEvent ( mServType , msg ) ;
2014-11-02 04:23:37 -05:00
2014-12-02 15:06:56 -05:00
if ( RSRandom : : random_f32 ( ) < sending_probability )
{
sendItem ( msg ) ;
2015-01-28 17:48:59 -05:00
# ifdef NXS_NET_DEBUG_0
std : : cerr < < " sending RsNxsSyncMsg req for grpId= " < < grpId < < " to peer " < < * sit < < " , last TS= " < < std : : dec < < time ( NULL ) - updateTS < < " secs ago. " < < std : : endl ;
2014-12-02 15:06:56 -05:00
# endif
}
else
{
delete msg ;
2015-01-28 17:48:59 -05:00
# ifdef NXS_NET_DEBUG_0
std : : cerr < < " cancel RsNxsSyncMsg req for grpId= " < < grpId < < " to peer " < < * sit < < " : not enough bandwidth. " < < std : : endl ;
2014-12-02 15:06:56 -05:00
# endif
}
2014-11-02 04:23:37 -05:00
}
2015-01-28 17:48:59 -05:00
}
2014-05-01 14:50:07 -04:00
2015-01-28 17:48:59 -05: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
}
2015-01-28 17:48:59 -05:00
void RsGxsNetService : : subscribeStatusChanged ( const RsGxsGroupId & grpId , bool subscribed )
{
RS_STACK_MUTEX ( mNxsMutex ) ;
if ( ! subscribed )
return ;
// When we subscribe, we reset the time stamps, so that the entire group list
// gets requested once again, for a proper update.
# ifdef NXS_NET_DEBUG_0
std : : cerr < < " Changing subscribe status for grp " < < grpId < < " to " < < subscribed < < " : reseting all msg time stamps. " < < std : : endl ;
# endif
for ( ClientMsgMap : : iterator it ( mClientMsgUpdateMap . begin ( ) ) ; it ! = mClientMsgUpdateMap . end ( ) ; + + it )
{
std : : map < RsGxsGroupId , uint32_t > : : iterator it2 = it - > second - > msgUpdateTS . find ( grpId ) ;
if ( it2 ! = it - > second - > msgUpdateTS . end ( ) )
it - > second - > msgUpdateTS . erase ( it2 ) ;
}
}
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 ;
2014-10-24 18:07:26 -04:00
for ( uint8_t i = 0 ; i < nFragments ; + + i )
2013-02-07 18:04:16 -05:00
{
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 ;
2014-10-24 18:07:26 -04:00
for ( uint8_t i = 0 ; i < nFragments ; + + i )
2013-02-07 18:04:16 -05:00
{
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 ;
2014-10-24 18:07:26 -04:00
for ( ; mit ! = msgFragments . end ( ) ; + + mit )
2013-02-07 18:04:16 -05:00
datSize + = ( * mit ) - > msg . bin_len ;
char * data = new char [ datSize ] ;
uint32_t currPos = 0 ;
2014-10-24 18:07:26 -04:00
for ( mit = msgFragments . begin ( ) ; mit ! = msgFragments . end ( ) ; + + mit )
2013-02-07 18:04:16 -05:00
{
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 ;
2014-10-24 18:07:26 -04:00
for ( ; mit ! = grpFragments . end ( ) ; + + mit )
2013-02-07 18:04:16 -05:00
datSize + = ( * mit ) - > grp . bin_len ;
char * data = new char [ datSize ] ;
uint32_t currPos = 0 ;
2014-10-24 18:07:26 -04:00
for ( mit = grpFragments . begin ( ) ; mit ! = grpFragments . end ( ) ; + + mit )
2013-02-07 18:04:16 -05:00
{
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
{
2014-12-02 15:06:56 -05:00
RsGxsGroupId mGrpId ;
2013-02-07 18:04:16 -05:00
GrpFragCollate ( const RsGxsGroupId & grpId ) : mGrpId ( grpId ) { }
bool operator ( ) ( RsNxsGrp * grp ) { return grp - > grpId = = mGrpId ; }
} ;
2014-12-02 15:06:56 -05:00
void RsGxsNetService : : locked_createTransactionFromPending ( MsgRespPending * msgPend )
2013-06-04 17:00:43 -04:00
{
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " locked_createTransactionFromPending() " < < std : : endl ;
# endif
MsgAuthorV : : const_iterator cit = msgPend - > mMsgAuthV . begin ( ) ;
2013-06-04 17:00:43 -04:00
std : : list < RsNxsItem * > reqList ;
uint32_t transN = locked_getTransactionId ( ) ;
2014-10-24 18:07:26 -04:00
for ( ; cit ! = msgPend - > mMsgAuthV . end ( ) ; + + cit )
2013-06-04 17:00:43 -04:00
{
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 ) ;
2014-12-02 15:06:56 -05:00
}
# ifdef NXS_NET_DEBUG
else
std : : cerr < < " entry failed vetting: grpId= " < < entry . mGrpId < < " , msgId= " < < entry . mMsgId < < " , peerId= " < < msgPend - > mPeerId < < std : : endl ;
# endif
}
2013-06-04 17:00:43 -04:00
if ( ! reqList . empty ( ) )
locked_pushMsgTransactionFromList ( reqList , msgPend - > mPeerId , transN ) ;
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " added " < < reqList . size ( ) < < " items to transaction. " < < std : : endl ;
# endif
2013-06-04 17:00:43 -04:00
}
2014-12-02 15:06:56 -05:00
void RsGxsNetService : : locked_createTransactionFromPending ( GrpRespPending * grpPend )
2013-06-04 17:00:43 -04:00
{
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " locked_createTransactionFromPending() from peer " < < grpPend - > mPeerId < < std : : endl ;
# endif
2013-06-04 17:00:43 -04:00
GrpAuthorV : : const_iterator cit = grpPend - > mGrpAuthV . begin ( ) ;
2014-12-16 01:54:15 -05:00
std : : list < RsNxsItem * > reqList ;
2013-06-04 17:00:43 -04:00
uint32_t transN = locked_getTransactionId ( ) ;
2014-10-24 18:07:26 -04:00
for ( ; cit ! = grpPend - > mGrpAuthV . end ( ) ; + + cit )
2013-06-04 17:00:43 -04:00
{
const GrpAuthEntry & entry = * cit ;
if ( entry . mPassedVetting )
{
2014-04-27 09:14:07 -04:00
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
std : : cerr < < " entry Group Id: " < < entry . mGrpId < < " PASSED " < < std : : endl ;
2014-04-27 09:14:07 -04:00
# 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
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
else
std : : cerr < < " entry failed vetting: grpId= " < < entry . mGrpId < < " , peerId= " < < grpPend - > mPeerId < < std : : endl ;
2014-04-27 09:14:07 -04:00
# endif
2013-06-04 17:00:43 -04:00
}
if ( ! reqList . empty ( ) )
locked_pushGrpTransactionFromList ( reqList , grpPend - > mPeerId , transN ) ;
}
void RsGxsNetService : : locked_createTransactionFromPending ( GrpCircleIdRequestVetting * grpPend )
{
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " locked_createTransactionFromPending(GrpCircleIdReq) " < < std : : endl ;
# endif
std : : vector < GrpIdCircleVet > : : iterator cit = grpPend - > mGrpCircleV . begin ( ) ;
2013-06-04 17:00:43 -04:00
uint32_t transN = locked_getTransactionId ( ) ;
std : : list < RsNxsItem * > itemL ;
2014-10-24 18:07:26 -04:00
for ( ; cit ! = grpPend - > mGrpCircleV . end ( ) ; + + cit )
2013-06-04 17:00:43 -04:00
{
const GrpIdCircleVet & entry = * cit ;
if ( entry . mCleared )
{
2014-04-27 09:14:07 -04:00
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
std : : cerr < < " Group Id: " < < entry . mGroupId < < " PASSED " < < std : : endl ;
2014-04-27 09:14:07 -04:00
# 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
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
else
std : : cerr < < " Group Id: " < < entry . mGroupId < < " FAILED " < < std : : endl ;
2014-04-27 09:14:07 -04:00
# endif
2014-12-02 15:06:56 -05:00
}
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 ( ) ;
2014-10-24 18:07:26 -04:00
for ( ; vit ! = msgPend - > mMsgs . end ( ) ; + + vit )
2013-06-04 17:00:43 -04:00
{
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 ;
2014-10-24 18:07:26 -04:00
for ( ; vit ! = fragments . end ( ) ; + + vit )
2013-02-07 18:04:16 -05:00
grpIds . insert ( ( * vit ) - > grpId ) ;
std : : set < RsGxsGroupId > : : iterator sit = grpIds . begin ( ) ;
2014-10-24 18:07:26 -04:00
for ( ; sit ! = grpIds . end ( ) ; + + sit )
2013-02-07 18:04:16 -05:00
{
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 ( ) ;
2014-10-24 18:07:26 -04:00
for ( ; vit2 ! = f . end ( ) ; + + vit2 )
2013-02-07 18:04:16 -05:00
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 ;
2014-10-24 18:07:26 -04:00
for ( ; vit ! = fragments . end ( ) ; + + vit )
2013-02-07 18:04:16 -05:00
msgIds . insert ( ( * vit ) - > msgId ) ;
std : : set < RsGxsMessageId > : : iterator sit = msgIds . begin ( ) ;
2014-10-24 18:07:26 -04:00
for ( ; sit ! = msgIds . end ( ) ; + + sit )
2013-02-07 18:04:16 -05:00
{
const RsGxsMessageId & msgId = * sit ;
MsgFragments : : iterator bound = std : : partition (
fragments . begin ( ) , fragments . end ( ) ,
MsgFragCollate ( msgId ) ) ;
// something will always be found for a group id
2014-10-24 18:07:26 -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 ( ) ;
2014-10-24 18:07:26 -04:00
for ( ; vit2 ! = f . end ( ) ; + + vit2 )
2013-02-07 18:04:16 -05:00
delete * vit2 ;
partFragments . erase ( msgId ) ;
}
}
fragments . clear ( ) ;
}
2013-11-16 08:40:04 -05:00
class StoreHere
{
public :
2014-12-02 15:06:56 -05:00
StoreHere ( RsGxsNetService : : ClientGrpMap & cgm , RsGxsNetService : : ClientMsgMap & cmm , RsGxsNetService : : ServerMsgMap & smm , RsGxsServerGrpUpdateItem * & sgm )
: mClientGrpMap ( cgm ) , mClientMsgMap ( cmm ) , mServerMsgMap ( smm ) , mServerGrpUpdateItem ( sgm )
2013-11-16 08:40:04 -05:00
{ }
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
{
std : : cerr < < " Error! More than one server group update item exists! " < < std : : endl ;
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
{
2014-12-02 15:06:56 -05:00
std : : for_each ( load . begin ( ) , load . end ( ) , StoreHere ( mClientGrpUpdateMap , mClientMsgUpdateMap , mServerMsgUpdateMap , mGrpServerUpdateItem ) ) ;
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 )
{
2014-11-11 14:47:05 -05:00
RS_STACK_MUTEX ( mNxsMutex ) ;
2013-11-16 08:40:04 -05:00
// hardcore templates
2015-01-28 17:48:59 -05:00
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 > ( ) ) ;
2013-11-16 08:40:04 -05:00
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
}
2014-12-02 15:06:56 -05:00
void RsGxsNetService : : recvNxsItemQueue ( )
{
2015-01-28 17:48:59 -05:00
RsItem * item ;
2012-06-07 16:43:12 -04:00
2015-01-28 17:48:59 -05:00
while ( NULL ! = ( item = recvItem ( ) ) )
{
# ifdef NXS_NET_DEBUG_1
std : : cerr < < " RsGxsNetService Item: " < < ( void * ) item < < std : : endl ;
2014-12-02 15:06:56 -05:00
//item->print(std::cerr);
2012-06-07 16:43:12 -04:00
# endif
2015-01-28 17:48:59 -05:00
// RsNxsItem needs dynamic_cast, since they have derived siblings.
//
RsNxsItem * ni = dynamic_cast < RsNxsItem * > ( item ) ;
if ( ni ! = NULL )
2014-12-02 15:06:56 -05:00
{
// a live transaction has a non zero value
if ( ni - > transactionNumber ! = 0 )
{
2012-07-14 13:59:54 -04:00
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
std : : cerr < < " recvNxsItemQueue() 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 ;
2014-12-02 15:06:56 -05:00
}
2012-06-07 16:43:12 -04:00
2014-12-02 15:06:56 -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 ;
case RS_PKT_SUBTYPE_NXS_GRP_PUBLISH_KEY : handleRecvPublishKeys ( dynamic_cast < RsNxsGroupPublishKeyItem * > ( ni ) ) ; break ;
default :
std : : cerr < < " Unhandled item subtype " < < ( uint32_t ) ni - > PacketSubType ( ) < < " in RsGxsNetService: " < < std : : endl ; break ;
}
delete item ;
}
2015-01-28 17:48:59 -05: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 )
{
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " handleTransaction(RsNxsItem) number= " < < item - > transactionNumber < < std : : endl ;
# endif
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
/*!
* This attempts to handle a transaction
* It first checks if this transaction id already exists
* If it does then check this not a initiating transactions
*/
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
RS_STACK_MUTEX ( mNxsMutex ) ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
const RsPeerId & peer = item - > PeerId ( ) ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
RsNxsTransac * transItem = dynamic_cast < RsNxsTransac * > ( item ) ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
// if this is a RsNxsTransac item process
if ( transItem )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " this is a RsNxsTransac item. callign process. " < < std : : endl ;
# endif
return locked_processTransac ( transItem ) ;
}
2013-02-07 18:04:16 -05:00
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
// then this must be transaction content to be consumed
// first check peer exist for transaction
bool peerTransExists = mTransactions . find ( peer ) ! = mTransactions . end ( ) ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
// then check transaction exists
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
NxsTransaction * tr = NULL ;
uint32_t transN = item - > transactionNumber ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
if ( peerTransExists )
{
TransactionIdMap & transMap = mTransactions [ peer ] ;
2012-07-14 13:59:54 -04:00
2014-12-02 15:06:56 -05:00
if ( transMap . find ( transN ) ! = transMap . end ( ) )
{
2012-07-14 13:59:54 -04:00
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
std : : cerr < < " Consuming Transaction content, transN: " < < item - > transactionNumber < < std : : endl ;
std : : cerr < < " Consuming Transaction content, from Peer: " < < item - > PeerId ( ) < < std : : endl ;
2012-07-14 13:59:54 -04:00
# endif
2014-12-02 15:06:56 -05:00
tr = transMap [ transN ] ;
tr - > mItems . push_back ( item ) ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
return true ;
}
}
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -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 ;
2014-12-02 15:06:56 -05:00
std : : cerr < < " Received transaction item: " < < transN < < std : : endl ;
std : : cerr < < " With peer: " < < item - > PeerId ( ) < < std : : endl ;
std : : cerr < < " trans type: " < < item - > transactFlag < < std : : endl ;
2012-07-14 13:59:54 -04:00
# endif
2012-06-11 17:56:23 -04:00
bool peerTrExists = mTransactions . find ( peer ) ! = mTransactions . end ( ) ;
bool transExists = false ;
2014-12-02 15:06:56 -05:00
if ( peerTrExists )
{
2012-06-11 17:56:23 -04:00
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
2014-12-02 15:06:56 -05:00
if ( item - > transactFlag & RsNxsTransac : : FLAG_BEGIN_P1 )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " initiating Incoming transaction. " < < std : : endl ;
# endif
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
if ( transExists )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " transaction already exist! ERROR " < < std : : endl ;
# endif
return false ; // should not happen!
}
2013-07-23 18:04:24 -04:00
2014-12-02 15:06:56 -05:00
// create a transaction if the peer does not exist
if ( ! peerTrExists )
mTransactions [ peer ] = TransactionIdMap ( ) ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
TransactionIdMap & transMap = mTransactions [ peer ] ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
// 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 ;
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " Setting timeout of " < < mTransactionTimeOut < < " secs, which is " < < tr - > mTimeOut - time ( NULL ) < < " secs from now. " < < std : : endl ;
# endif
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
// note state as receiving, commencement item
// is sent on next run() loop
tr - > mFlag = NxsTransaction : : FLAG_STATE_STARTING ;
2014-07-05 16:05:17 -04:00
return true ;
2014-12-02 15:06:56 -05:00
// commencement item for outgoing transaction
}
else if ( item - > transactFlag & RsNxsTransac : : FLAG_BEGIN_P2 )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " initiating outgoign transaction. " < < std : : endl ;
# endif
// transaction must exist
if ( ! peerTrExists | | ! transExists )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " transaction does not exist. Cancelling! " < < std : : endl ;
# endif
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05: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
2014-12-02 15:06:56 -05:00
}
else if ( item - > transactFlag & RsNxsTransac : : FLAG_END_SUCCESS )
{
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " marking this transaction succeed " < < std : : endl ;
# endif
// transaction does not exist
if ( ! peerTrExists | | ! transExists )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " transaction does not exist. Cancelling! " < < std : : endl ;
# endif
return false ;
}
2012-06-11 17:56:23 -04:00
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 ( )
{
2014-11-11 14:47:05 -05:00
RS_STACK_MUTEX ( mNxsMutex ) ;
2013-11-23 18:39:55 -05:00
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 )
2015-01-28 17:48:59 -05:00
mGrpServerUpdateItem = new RsGxsServerGrpUpdateItem ( mServType ) ;
2013-11-23 18:39:55 -05:00
2013-12-20 09:48:32 -05:00
bool change = false ;
2014-10-24 18:07:26 -04:00
for ( ; mit ! = gxsMap . end ( ) ; + + mit )
2015-01-30 15:46:58 -05:00
{
2013-11-23 18:39:55 -05:00
const RsGxsGroupId & grpId = mit - > first ;
RsGxsGrpMetaData * grpMeta = mit - > second ;
ServerMsgMap : : iterator mapIT = mServerMsgUpdateMap . find ( grpId ) ;
RsGxsServerMsgUpdateItem * msui = NULL ;
2015-01-30 15:46:58 -05:00
// That accounts for modification of the meta data.
if ( mGrpServerUpdateItem - > grpUpdateTS < grpMeta - > mPublishTs )
{
std : : cerr < < " publish time stamp of group " < < grpId < < " has changed to " < < time ( NULL ) - grpMeta - > mPublishTs < < " secs ago. updating! " < < std : : endl ;
mGrpServerUpdateItem - > grpUpdateTS = grpMeta - > mPublishTs ;
}
2013-11-23 18:39:55 -05:00
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
{
2015-01-30 15:46:58 -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 ( ) ;
2015-01-28 17:48:59 -05:00
freeAndClearContainerResource < std : : map < RsGxsGroupId , RsGxsGrpMetaData * > , RsGxsGrpMetaData * > ( gxsMap ) ;
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
2014-12-02 15:06:56 -05:00
void RsGxsNetService : : processTransactions ( )
{
# ifdef NXS_NET_DEBUG
if ( ! mTransactions . empty ( ) )
std : : cerr < < " processTransactions() " < < std : : endl ;
# endif
RS_STACK_MUTEX ( mNxsMutex ) ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
TransactionsPeerMap : : iterator mit = mTransactions . begin ( ) ;
2013-07-23 18:04:24 -04:00
2014-12-02 15:06:56 -05:00
for ( ; mit ! = mTransactions . end ( ) ; + + mit )
{
TransactionIdMap & transMap = mit - > second ;
TransactionIdMap : : iterator mmit = transMap . begin ( ) , mmit_end = transMap . end ( ) ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
if ( mmit ! = mmit_end )
std : : cerr < < " peerId= " < < mit - > first < < std : : endl ;
# endif
// transaction to be removed
std : : list < uint32_t > toRemove ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
/*!
* Transactions owned by peer
*/
if ( mit - > first = = mOwnId )
{
for ( ; mmit ! = mmit_end ; + + mmit )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " type: outgoing " < < std : : endl ;
std : : cerr < < " transN = " < < mmit - > second - > mTransaction - > transactionNumber < < std : : endl ;
# endif
NxsTransaction * tr = mmit - > second ;
uint16_t flag = tr - > mFlag ;
std : : list < RsNxsItem * > : : iterator lit , lit_end ;
uint32_t transN = tr - > mTransaction - > transactionNumber ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
// first check transaction has not expired
if ( locked_checkTransacTimedOut ( tr ) )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " timeout! " < < std : : endl ;
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 ;
# endif
2012-07-14 13:59:54 -04:00
2014-12-02 15:06:56 -05:00
tr - > mFlag = NxsTransaction : : FLAG_STATE_FAILED ;
toRemove . push_back ( transN ) ;
mComplTransactions . push_back ( tr ) ;
continue ;
}
# ifdef NXS_NET_DEBUG
else
std : : cerr < < " still on time. " < < std : : endl ;
# endif
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
// send items requested
if ( flag & NxsTransaction : : FLAG_STATE_SENDING )
{
2012-07-14 13:59:54 -04:00
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
std : : cerr < < " Sending Transaction content, transN: " < < transN < < " with peer: " < < tr - > mTransaction - > PeerId ( ) < < std : : endl ;
2012-07-14 13:59:54 -04:00
# endif
2014-12-02 15:06:56 -05:00
lit = tr - > mItems . begin ( ) ;
lit_end = tr - > mItems . end ( ) ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
for ( ; lit ! = lit_end ; + + lit ) {
sendItem ( * lit ) ;
}
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
tr - > mItems . clear ( ) ; // clear so they don't get deleted in trans cleaning
tr - > mFlag = NxsTransaction : : FLAG_STATE_WAITING_CONFIRM ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
}
else if ( flag & NxsTransaction : : FLAG_STATE_WAITING_CONFIRM )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " Waiting confirm! returning. " < < std : : endl ;
# endif
continue ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
}
else if ( flag & NxsTransaction : : FLAG_STATE_COMPLETED )
{
2012-06-11 17:56:23 -04:00
2014-10-09 13:20:09 -04:00
# ifdef NXS_NET_DEBUG
int total_transaction_time = ( int ) time ( NULL ) - ( tr - > mTimeOut - mTransactionTimeOut ) ;
2014-12-02 15:06:56 -05:00
std : : cerr < < " Outgoing completed " < < tr - > mTransaction - > nItems < < " items transaction in " < < total_transaction_time < < " seconds. " < < std : : endl ;
2014-10-09 13:20:09 -04:00
# endif
// move to completed transactions
2014-12-02 15:06:56 -05:00
toRemove . push_back ( transN ) ;
mComplTransactions . push_back ( tr ) ;
} else {
2012-07-14 13:59:54 -04:00
2014-04-27 09:14:07 -04:00
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
std : : cerr < < " Unknown flag for active transaction, transN: " < < transN < < " , Peer: " < < mit - > first < < std : : endl ;
2014-04-27 09:14:07 -04:00
# endif
2014-12-02 15:06:56 -05:00
toRemove . push_back ( transN ) ;
tr - > mFlag = NxsTransaction : : FLAG_STATE_FAILED ;
mComplTransactions . push_back ( tr ) ;
}
}
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
} else {
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
/*!
* 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 ) {
2012-07-14 13:59:54 -04:00
2014-12-02 15:06:56 -05:00
NxsTransaction * tr = mmit - > second ;
uint16_t flag = tr - > mFlag ;
uint32_t transN = tr - > mTransaction - > transactionNumber ;
2012-07-12 16:18:58 -04:00
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " type: incoming " < < std : : endl ;
std : : cerr < < " transN = " < < mmit - > second - > mTransaction - > transactionNumber < < std : : endl ;
# endif
// first check transaction has not expired
if ( locked_checkTransacTimedOut ( tr ) )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " timeout! " < < std : : endl ;
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 ;
# endif
tr - > mFlag = NxsTransaction : : FLAG_STATE_FAILED ;
toRemove . push_back ( transN ) ;
mComplTransactions . push_back ( tr ) ;
continue ;
}
if ( flag & NxsTransaction : : FLAG_STATE_RECEIVING )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " received " < < tr - > mItems . size ( ) < < " item over a total of " < < tr - > mTransaction - > nItems < < std : : endl ;
# endif
// if the number it item received equal that indicated
// then transaction is marked as completed
// to be moved to complete transations
// check if done
2014-10-09 13:20:09 -04:00
if ( tr - > mItems . size ( ) = = tr - > mTransaction - > nItems )
2014-12-02 15:06:56 -05:00
{
tr - > mFlag = NxsTransaction : : FLAG_STATE_COMPLETED ;
# ifdef NXS_NET_DEBUG
std : : cerr < < " completed! " < < std : : endl ;
# endif
}
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
} else if ( flag & NxsTransaction : : FLAG_STATE_COMPLETED )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " transaction is completed! " < < std : : endl ;
std : : cerr < < " sending success! " < < std : : endl ;
# endif
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
// 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 ) ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
// move to completed transactions
mComplTransactions . push_back ( tr ) ;
2014-10-09 13:20:09 -04:00
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
int total_transaction_time = ( int ) time ( NULL ) - ( tr - > mTimeOut - mTransactionTimeOut ) ;
std : : cerr < < " incoming completed " < < tr - > mTransaction - > nItems < < " items transaction in " < < total_transaction_time < < " seconds. " < < std : : endl ;
2014-10-09 13:20:09 -04:00
# endif
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
// transaction processing done
// for this id, add to removal list
toRemove . push_back ( mmit - > first ) ;
}
else if ( flag & NxsTransaction : : FLAG_STATE_STARTING )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " transaction is starting! " < < std : : endl ;
std : : cerr < < " setting state to Receiving " < < std : : endl ;
# endif
// send item to tell peer your are ready to start
RsNxsTransac * trans = new RsNxsTransac ( mServType ) ;
trans - > clear ( ) ;
trans - > transactFlag = RsNxsTransac : : FLAG_BEGIN_P2 |
( tr - > mTransaction - > transactFlag & RsNxsTransac : : FLAG_TYPE_MASK ) ;
trans - > transactionNumber = transN ;
trans - > PeerId ( tr - > mTransaction - > PeerId ( ) ) ;
sendItem ( trans ) ;
tr - > mFlag = NxsTransaction : : FLAG_STATE_RECEIVING ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
}
else {
# ifdef NXS_NET_DEBUG
std : : cerr < < " transaction is in unknown state. ERROR! " < < std : : endl ;
std : : cerr < < " transaction FAILS! " < < std : : endl ;
# endif
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
std : : cerr < < " Unknown flag for active transaction, transN: " < < transN < < " , Peer: " < < mit - > first < < std : : endl ;
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
2014-12-02 15:06:56 -05:00
std : : list < uint32_t > : : iterator lit = toRemove . begin ( ) ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
for ( ; lit ! = toRemove . end ( ) ; + + lit )
{
transMap . erase ( * lit ) ;
}
2013-07-23 18:04:24 -04:00
2014-12-02 15:06:56 -05:00
}
2012-06-11 17:56:23 -04:00
}
2014-12-16 01:54:15 -05:00
bool RsGxsNetService : : getGroupNetworkStats ( const RsGxsGroupId & gid , RsGroupNetworkStats & stats )
2014-10-07 17:42:44 -04:00
{
2014-12-16 01:54:15 -05:00
RS_STACK_MUTEX ( mNxsMutex ) ;
2014-10-07 17:42:44 -04:00
2014-12-16 01:54:15 -05:00
std : : map < RsGxsGroupId , RsGroupNetworkStatsRecord > : : const_iterator it = mGroupNetworkStats . find ( gid ) ;
2014-10-07 17:42:44 -04:00
2014-12-16 01:54:15 -05:00
if ( it = = mGroupNetworkStats . end ( ) )
return false ;
stats . mSuppliers = it - > second . suppliers . size ( ) ;
stats . mMaxVisibleCount = it - > second . max_visible_count ;
return true ;
2014-10-07 17:42:44 -04:00
}
2012-06-11 17:56:23 -04:00
void RsGxsNetService : : processCompletedTransactions ( )
{
2014-11-11 14:47:05 -05:00
RS_STACK_MUTEX ( mNxsMutex ) ;
2012-06-11 17:56:23 -04:00
/*!
* Depending on transaction we may have to respond to peer
* responsible for transaction
*/
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 ;
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " Processing complete Incoming transaction with " < < tr - > mTransaction - > nItems < < " items. " < < std : : endl ;
std : : cerr < < " flags = " < < flag < < std : : endl ;
std : : cerr < < " peerId= " < < tr - > mTransaction - > PeerId ( ) < < std : : endl ;
# endif
if ( tr - > mFlag & NxsTransaction : : FLAG_STATE_COMPLETED )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " transaction has completed. " < < std : : endl ;
# endif
// for a completed list response transaction
// one needs generate requests from this
if ( flag & RsNxsTransac : : FLAG_TYPE_MSG_LIST_RESP )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " type = msg list response. " < < std : : endl ;
std : : cerr < < " => generate msg request based on it. " < < std : : endl ;
# endif
// generate request based on a peers response
locked_genReqMsgTransaction ( tr ) ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
} else if ( flag & RsNxsTransac : : FLAG_TYPE_GRP_LIST_RESP )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " type = grp list response. " < < std : : endl ;
std : : cerr < < " => generate group transaction request based on it. " < < std : : endl ;
# endif
locked_genReqGrpTransaction ( tr ) ;
}
// you've finished receiving request information now gen
else if ( flag & RsNxsTransac : : FLAG_TYPE_MSG_LIST_REQ )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " type = msg list request. " < < std : : endl ;
std : : cerr < < " => generate msg list based on it. " < < std : : endl ;
# endif
locked_genSendMsgsTransaction ( tr ) ;
}
else if ( flag & RsNxsTransac : : FLAG_TYPE_GRP_LIST_REQ )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " type = grp list request. " < < std : : endl ;
std : : cerr < < " => generate grp list based on it. " < < std : : endl ;
# endif
locked_genSendGrpsTransaction ( tr ) ;
}
else if ( flag & RsNxsTransac : : FLAG_TYPE_GRPS )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " type = groups. " < < std : : endl ;
# endif
std : : vector < RsNxsGrp * > grps ;
2012-07-14 13:59:54 -04:00
2014-12-02 15:06:56 -05:00
while ( tr - > mItems . size ( ) ! = 0 )
{
RsNxsGrp * grp = dynamic_cast < RsNxsGrp * > ( tr - > mItems . front ( ) ) ;
2012-07-14 13:59:54 -04:00
2014-12-02 15:06:56 -05:00
if ( grp )
{
tr - > mItems . pop_front ( ) ;
grps . push_back ( grp ) ;
# ifdef NXS_NET_DEBUG
std : : cerr < < " pushing new group " < < grp - > grpId < < " to list. " < < std : : endl ;
# endif
}
else
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " /! \\ item did not caste to grp " < < std : : endl ;
# endif
}
}
2014-10-07 17:42:44 -04:00
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " notifying observer " < < std : : endl ;
# endif
// notify listener of grps
mObserver - > notifyNewGroups ( grps ) ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
// now note this as the latest you've received from this peer
RsPeerId peerFrom = tr - > mTransaction - > PeerId ( ) ;
uint32_t updateTS = tr - > mTransaction - > updateTS ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
ClientGrpMap : : iterator it = mClientGrpUpdateMap . find ( peerFrom ) ;
2013-11-16 08:40:04 -05:00
2014-12-02 15:06:56 -05:00
RsGxsGrpUpdateItem * item = NULL ;
2013-11-16 08:40:04 -05:00
2014-12-02 15:06:56 -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
2014-12-02 15:06:56 -05:00
item - > grpUpdateTS = updateTS ;
item - > peerId = peerFrom ;
2013-11-16 08:40:04 -05:00
2014-12-02 15:06:56 -05:00
IndicateConfigChanged ( ) ;
2013-11-16 08:40:04 -05:00
2013-12-20 09:48:32 -05:00
2014-12-02 15:06:56 -05:00
} else if ( flag & RsNxsTransac : : FLAG_TYPE_MSGS )
{
2012-09-01 10:47:22 -04:00
2014-12-02 15:06:56 -05:00
std : : vector < RsNxsMsg * > msgs ;
# ifdef NXS_NET_DEBUG
std : : cerr < < " type = msgs. " < < std : : endl ;
# endif
RsGxsGroupId grpId ;
while ( tr - > mItems . size ( ) > 0 )
{
RsNxsMsg * msg = dynamic_cast < RsNxsMsg * > ( tr - > mItems . front ( ) ) ;
if ( msg )
{
if ( grpId . isNull ( ) )
grpId = msg - > grpId ;
2012-07-14 13:59:54 -04:00
2014-12-02 15:06:56 -05:00
tr - > mItems . pop_front ( ) ;
msgs . push_back ( msg ) ;
# ifdef NXS_NET_DEBUG
std : : cerr < < " pushing grpId= " < < msg - > grpId < < " , msgsId= " < < msg - > msgId < < std : : endl ;
# endif
}
else
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " RsGxsNetService::processCompletedTransactions(): item did not caste to msg "
< < std : : endl ;
# endif
}
}
2012-07-14 13:59:54 -04:00
2013-03-16 12:44:33 -04:00
# ifdef NSXS_FRAG
2014-12-02 15:06:56 -05:00
std : : map < RsGxsGroupId , MsgFragments > collatedMsgs ;
collateMsgFragments ( msgs , collatedMsgs ) ;
2013-03-16 12:44:33 -04:00
2014-12-02 15:06:56 -05:00
msgs . clear ( ) ;
2013-03-16 12:44:33 -04:00
2014-12-02 15:06:56 -05:00
std : : map < RsGxsGroupId , MsgFragments > : : iterator mit = collatedMsgs . begin ( ) ;
for ( ; mit ! = collatedMsgs . end ( ) ; + + mit )
{
MsgFragments & f = mit - > second ;
RsNxsMsg * msg = deFragmentMsg ( f ) ;
2013-03-16 12:44:33 -04:00
2014-12-02 15:06:56 -05:00
if ( msg )
msgs . push_back ( msg ) ;
}
# endif
# ifdef NXS_NET_DEBUG
std : : cerr < < " notifying observer of " < < msgs . size ( ) < < " new messages. " < < std : : endl ;
2013-03-16 12:44:33 -04:00
# endif
2014-12-02 15:06:56 -05:00
// notify listener of msgs
mObserver - > notifyNewMessages ( msgs ) ;
2012-07-14 13:59:54 -04:00
2014-12-02 15:06:56 -05:00
// now note that this is the latest you've received from this peer
// for the grp id
locked_doMsgUpdateWork ( tr - > mTransaction , grpId ) ;
2013-11-16 08:40:04 -05:00
2014-12-02 15:06:56 -05:00
}
}
else if ( tr - > mFlag = = NxsTransaction : : FLAG_STATE_FAILED )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " transaction has failed. Wasting it. " < < std : : endl ;
# endif
// don't do anything transaction will simply be cleaned
}
2012-07-14 13:59:54 -04:00
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
{
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " updating MsgUpdate time stamps for peerId= " < < nxsTrans - > PeerId ( ) < < " , grpId= " < < grpId < < std : : endl ;
# endif
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
{
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " created new entry. " < < std : : endl ;
# endif
2013-11-16 08:40:04 -05:00
mui = new RsGxsMsgUpdateItem ( mServType ) ;
mClientMsgUpdateMap . insert ( std : : make_pair ( peerFrom , mui ) ) ;
}
mui - > peerId = peerFrom ;
2014-12-02 15:06:56 -05:00
if ( mPartialMsgUpdates [ peerFrom ] . find ( grpId ) ! = mPartialMsgUpdates [ peerFrom ] . end ( ) )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " this is a partial update. Not using new time stamp. " < < std : : endl ;
# endif
}
else
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " this is a full update. Updating time stamp. " < < std : : endl ;
# endif
mui - > msgUpdateTS [ grpId ] = nxsTrans - > updateTS ;
2015-01-28 17:48:59 -05:00
IndicateConfigChanged ( ) ;
2014-12-02 15:06:56 -05:00
}
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 ;
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " locked_processCompletedOutgoingTrans(): tr->flags = " < < flag < < std : : endl ;
# endif
if ( tr - > mFlag & NxsTransaction : : FLAG_STATE_COMPLETED )
{
2012-07-14 13:59:54 -04:00
// 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
2014-12-02 15:06:56 -05:00
std : : cerr < < " complete Sending Msg List Response, transN: " < < tr - > mTransaction - > transactionNumber < < std : : endl ;
2012-07-14 13:59:54 -04:00
# endif
} else if ( flag & RsNxsTransac : : FLAG_TYPE_GRP_LIST_RESP )
{
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
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
2014-12-02 15:06:56 -05:00
std : : cerr < < " complete Sending Msg/Grp Request, transN: " < < tr - > mTransaction - > transactionNumber < < std : : endl ;
2012-07-14 13:59:54 -04:00
# 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
2014-12-02 15:06:56 -05:00
std : : cerr < < " complete Sending Grp Data, transN: " < < tr - > mTransaction - > transactionNumber < < std : : endl ;
2012-07-14 13:59:54 -04:00
# 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
2014-12-02 15:06:56 -05:00
std : : cerr < < " complete Sending Msg Data, transN: " < < tr - > mTransaction - > transactionNumber < < std : : endl ;
2012-07-14 13:59:54 -04:00
# endif
}
} else if ( tr - > mFlag = = NxsTransaction : : FLAG_STATE_FAILED ) {
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
std : : cerr < < " Failed transaction! transN: " < < tr - > mTransaction - > transactionNumber < < std : : endl ;
2012-07-14 13:59:54 -04:00
# endif
} else {
2012-06-11 17:56:23 -04:00
2012-07-14 13:59:54 -04:00
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
std : : cerr < < " Serious error unrecognised trans Flag! transN: " < < tr - > mTransaction - > transactionNumber < < std : : endl ;
2012-07-14 13:59:54 -04:00
# endif
}
2012-06-07 16:43:12 -04:00
}
2014-12-02 15:06:56 -05:00
void RsGxsNetService : : locked_pushMsgTransactionFromList ( std : : list < RsNxsItem * > & reqList , const RsPeerId & peerId , const uint32_t & transN )
2013-06-04 17:00:43 -04:00
{
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " locked_pushMsgTransactionFromList() " < < std : : endl ;
std : : cerr < < " nelems = " < < reqList . size ( ) < < std : : endl ;
std : : cerr < < " peerId = " < < peerId < < std : : endl ;
std : : cerr < < " transN = " < < transN < < std : : endl ;
# endif
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 ;
2014-12-02 15:06:56 -05:00
// create transaction copy with your id to indicate
// its an outgoing transaction
newTrans - > mTransaction = new RsNxsTransac ( * transac ) ;
newTrans - > mTransaction - > PeerId ( mOwnId ) ;
sendItem ( transac ) ;
if ( ! locked_addTransaction ( newTrans ) )
delete newTrans ;
std : : cerr < < " Requested new transaction for " < < reqList . size ( ) < < " items. " < < std : : endl ;
2013-06-04 17:00:43 -04:00
}
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
2015-01-30 15:46:58 -05:00
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
std : : cerr < < " RsGxsNetService::genReqMsgTransaction() " < < std : : endl ;
# endif
2012-06-07 16:43:12 -04:00
2014-12-02 15:06:56 -05: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
2014-12-02 15:06:56 -05:00
std : : list < RsNxsSyncMsgItem * > msgItemL ;
std : : list < RsNxsItem * > : : iterator lit = tr - > mItems . begin ( ) ;
2012-06-07 16:43:12 -04:00
2014-12-02 15:06:56 -05:00
// first get item list sent from transaction
for ( ; lit ! = tr - > mItems . end ( ) ; + + lit )
{
RsNxsSyncMsgItem * item = dynamic_cast < RsNxsSyncMsgItem * > ( * lit ) ;
if ( item )
{
msgItemL . push_back ( item ) ;
} else
{
2012-06-11 17:56:23 -04:00
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
std : : cerr < < " RsGxsNetService::genReqMsgTransaction(): item failed cast to RsNxsSyncMsgItem* "
< < std : : endl ;
# endif
}
}
2015-01-30 15:46:58 -05:00
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
std : : cerr < < " found " < < msgItemL . size ( ) < < " messages in this transaction. " < < std : : endl ;
2012-06-11 17:56:23 -04:00
# endif
2014-12-02 15:06:56 -05:00
if ( msgItemL . empty ( ) )
return ;
2013-06-04 17:00:43 -04:00
2014-12-02 15:06:56 -05:00
// get grp id for this transaction
RsNxsSyncMsgItem * item = msgItemL . front ( ) ;
const RsGxsGroupId & grpId = item - > grpId ;
2013-06-04 17:00:43 -04:00
2014-12-16 01:54:15 -05:00
// store the count for the peer who sent the message list
uint32_t mcount = msgItemL . size ( ) ;
RsPeerId pid = msgItemL . front ( ) - > PeerId ( ) ;
RsGroupNetworkStatsRecord & gnsr = mGroupNetworkStats [ grpId ] ;
gnsr . suppliers . insert ( pid ) ;
gnsr . max_visible_count = std : : max ( gnsr . max_visible_count , mcount ) ;
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " grpId = " < < grpId < < std : : endl ;
std : : cerr < < " retrieving grp mesta data... " < < std : : endl ;
# endif
std : : map < RsGxsGroupId , RsGxsGrpMetaData * > grpMetaMap ;
grpMetaMap [ grpId ] = NULL ;
mDataStore - > retrieveGxsGrpMetaData ( grpMetaMap ) ;
RsGxsGrpMetaData * grpMeta = grpMetaMap [ grpId ] ;
2014-02-22 19:08:11 -05:00
2014-12-16 01:54:15 -05:00
if ( ! ( grpMeta - > mSubscribeFlags & GXS_SERV : : GROUP_SUBSCRIBE_SUBSCRIBED ) )
2015-01-28 17:48:59 -05:00
{
// For unsubscribed groups, we update the timestamp to now, so that the group content will not be asked to the same
// peer again, unless the peer has new info about it.
// That needs of course to reset that time to 0 when we subscribe.
2015-01-30 15:46:58 -05:00
locked_stampPeerGroupUpdateTime ( pid , grpId , time ( NULL ) ) ;
2014-12-16 01:54:15 -05:00
return ;
2015-01-28 17:48:59 -05:00
}
2014-12-16 01:54:15 -05:00
2014-12-02 15:06:56 -05:00
int cutoff = 0 ;
if ( grpMeta ! = NULL )
cutoff = grpMeta - > mReputationCutOff ;
2013-06-04 17:00:43 -04:00
2014-12-02 15:06:56 -05:00
GxsMsgReq reqIds ;
reqIds [ grpId ] = std : : vector < RsGxsMessageId > ( ) ;
GxsMsgMetaResult result ;
mDataStore - > retrieveGxsMsgMetaData ( reqIds , result ) ;
std : : vector < RsGxsMsgMetaData * > & msgMetaV = result [ grpId ] ;
2013-06-04 17:00:43 -04:00
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " retrieving grp message list... " < < std : : endl ;
std : : cerr < < " grp locally contains " < < msgMetaV . size ( ) < < " messsages. " < < std : : endl ;
# endif
std : : vector < RsGxsMsgMetaData * > : : const_iterator vit = msgMetaV . begin ( ) ;
std : : set < RsGxsMessageId > msgIdSet ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
// put ids in set for each searching
for ( ; vit ! = msgMetaV . end ( ) ; + + vit )
{
msgIdSet . insert ( ( * vit ) - > mMsgId ) ;
delete ( * vit ) ;
}
msgMetaV . clear ( ) ;
2012-06-26 15:52:01 -04:00
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " grp locally contains " < < msgIdSet . size ( ) < < " unique messsages. " < < std : : endl ;
# endif
// get unique id for this transaction
uint32_t transN = locked_getTransactionId ( ) ;
2012-06-26 15:52:01 -04:00
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " new transaction ID: " < < transN < < std : : endl ;
# endif
// add msgs that you don't have to request list
std : : list < RsNxsSyncMsgItem * > : : iterator llit = msgItemL . begin ( ) ;
std : : list < RsNxsItem * > reqList ;
int reqListSize = 0 ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
const RsPeerId peerFrom = tr - > mTransaction - > PeerId ( ) ;
2012-06-26 15:52:01 -04:00
2014-12-02 15:06:56 -05:00
MsgAuthorV toVet ;
2012-09-01 10:47:22 -04:00
2014-12-02 15:06:56 -05:00
std : : list < RsPeerId > peers ;
peers . push_back ( tr - > mTransaction - > PeerId ( ) ) ;
bool reqListSizeExceeded = false ;
2013-06-04 17:00:43 -04:00
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " sorting items... " < < std : : endl ;
# endif
for ( ; llit ! = msgItemL . end ( ) ; + + llit )
{
RsNxsSyncMsgItem * & syncItem = * llit ;
const RsGxsMessageId & msgId = syncItem - > msgId ;
2013-11-04 09:09:32 -05:00
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " msg ID = " < < msgId ;
# endif
if ( reqListSize > = MAX_REQLIST_SIZE )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " . reqlist too big. Pruning out this item for now. " < < std : : endl ;
# endif
reqListSizeExceeded = true ;
continue ; // we should actually break, but we need to print some debug info.
}
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
if ( reqListSize < MAX_REQLIST_SIZE & & msgIdSet . find ( msgId ) = = msgIdSet . end ( ) )
{
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -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)
bool noAuthor = syncItem - > authorId . isNull ( ) ;
2013-08-28 15:27:04 -04:00
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " , reqlist size= " < < reqListSize < < " , message not present. " ;
# endif
// grp meta must be present if author present
if ( ! noAuthor & & grpMeta = = NULL )
{
std : : cerr < < " , no group meta found. Givign up. " < < std : : endl ;
continue ;
}
2013-08-28 15:27:04 -04:00
2014-12-02 15:06:56 -05:00
if ( mReputations - > haveReputation ( syncItem - > authorId ) | | noAuthor )
{
GixsReputation rep ;
2012-06-11 17:56:23 -04:00
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " , author Id= " < < syncItem - > authorId < < " . Reputation: " ;
# endif
if ( ! noAuthor )
mReputations - > getReputation ( syncItem - > authorId , rep ) ;
2013-08-28 15:27:04 -04:00
2014-12-02 15:06:56 -05:00
// if author is required for this message, it will simply get dropped
// at genexchange side of things
if ( rep . score > ( int ) grpMeta - > mReputationCutOff | | noAuthor )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " , passed! Adding message to req list. " < < std : : endl ;
# endif
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 ) ;
+ + reqListSize ;
}
# ifdef NXS_NET_DEBUG
else
std : : cerr < < " , failed! " < < std : : endl ;
# endif
}
else
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " , no author/no reputation. Pushed to Vetting list. " < < std : : endl ;
# endif
// preload for speed
mReputations - > loadReputation ( syncItem - > authorId , peers ) ;
MsgAuthEntry entry ;
entry . mAuthorId = syncItem - > authorId ;
entry . mGrpId = syncItem - > grpId ;
entry . mMsgId = syncItem - > msgId ;
toVet . push_back ( entry ) ;
}
}
# ifdef NXS_NET_DEBUG
else
std : : cerr < < " . already here. " < < std : : endl ;
# endif
}
2012-07-14 13:59:54 -04:00
2014-12-02 15:06:56 -05:00
if ( ! toVet . empty ( ) )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " Vetting list: " < < toVet . size ( ) < < " elements. " < < std : : endl ;
# endif
MsgRespPending * mrp = new MsgRespPending ( mReputations , tr - > mTransaction - > PeerId ( ) , toVet , cutoff ) ;
mPendingResp . push_back ( mrp ) ;
}
2012-07-14 13:59:54 -04:00
2014-12-02 15:06:56 -05:00
if ( ! reqList . empty ( ) )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " Request list: " < < reqList . size ( ) < < " elements. " < < std : : endl ;
# endif
locked_pushMsgTransactionFromList ( reqList , tr - > mTransaction - > PeerId ( ) , transN ) ;
if ( reqListSizeExceeded )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " Marking update operation as unfinished. " < < std : : endl ;
# endif
mPartialMsgUpdates [ tr - > mTransaction - > PeerId ( ) ] . insert ( item - > grpId ) ;
}
else
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " Marking update operation as terminal. " < < std : : endl ;
# endif
mPartialMsgUpdates [ tr - > mTransaction - > PeerId ( ) ] . erase ( item - > grpId ) ;
}
}
2015-01-30 15:46:58 -05:00
else
{
// The list to req is empty. That means we already have all messages that this peer can
// provide. So we can stamp the group from this peer to be up to date.
locked_stampPeerGroupUpdateTime ( pid , grpId , time ( NULL ) ) ;
}
}
void RsGxsNetService : : locked_stampPeerGroupUpdateTime ( const RsPeerId & pid , const RsGxsGroupId & grpId , time_t tm )
{
RsGxsMsgUpdateItem * & pitem ( mClientMsgUpdateMap [ pid ] ) ;
if ( pitem = = NULL )
{
pitem = new RsGxsMsgUpdateItem ( mServType ) ;
pitem - > peerId = pid ;
}
pitem - > msgUpdateTS [ grpId ] = time ( NULL ) ;
return ;
2013-06-04 17:00:43 -04:00
}
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
{
2015-01-28 17:48:59 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " locked_pushGrpTransactionFromList() " < < std : : endl ;
std : : cerr < < " nelems = " < < reqList . size ( ) < < std : : endl ;
std : : cerr < < " peerId = " < < peerId < < std : : endl ;
std : : cerr < < " transN = " < < transN < < std : : endl ;
# endif
RsNxsTransac * transac = new RsNxsTransac ( mServType ) ;
2013-06-04 17:00:43 -04:00
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
{
2015-01-30 15:46:58 -05: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
2012-06-11 17:56:23 -04:00
2014-12-21 14:12:40 -05:00
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
std : : cerr < < " locked_genReqGrpTransaction(): " < < std : : endl ;
2014-12-21 14:12:40 -05:00
# endif
2012-06-11 17:56:23 -04:00
2015-01-30 15:46:58 -05:00
std : : list < RsNxsSyncGrpItem * > grpItemL ;
std : : list < RsNxsItem * > : : iterator lit = tr - > mItems . begin ( ) ;
2012-06-11 17:56:23 -04:00
2015-01-30 15:46:58 -05:00
for ( ; lit ! = tr - > mItems . end ( ) ; + + lit )
{
RsNxsSyncGrpItem * item = dynamic_cast < RsNxsSyncGrpItem * > ( * lit ) ;
if ( item )
{
grpItemL . push_back ( item ) ;
} else
{
2012-06-11 17:56:23 -04:00
# ifdef NXS_NET_DEBUG
2015-01-30 15:46:58 -05:00
std : : cerr < < " RsGxsNetService::genReqGrpTransaction(): item failed to caste to RsNxsSyncMsgItem* "
2014-12-02 15:06:56 -05:00
< < std : : endl ;
2012-06-11 17:56:23 -04:00
# endif
2015-01-30 15:46:58 -05:00
}
}
2012-06-11 17:56:23 -04:00
2014-03-17 16:56:06 -04:00
std : : map < RsGxsGroupId , RsGxsGrpMetaData * > grpMetaMap ;
std : : map < RsGxsGroupId , RsGxsGrpMetaData * > : : const_iterator metaIter ;
2015-01-30 15:46:58 -05:00
mDataStore - > retrieveGxsGrpMetaData ( grpMetaMap ) ;
2012-06-11 17:56:23 -04:00
2015-01-30 15:46:58 -05:00
// now do compare and add loop
std : : list < RsNxsSyncGrpItem * > : : iterator llit = grpItemL . begin ( ) ;
std : : list < RsNxsItem * > reqList ;
2012-06-11 17:56:23 -04:00
2015-01-30 15:46:58 -05:00
uint32_t transN = locked_getTransactionId ( ) ;
2012-06-11 17:56:23 -04:00
2015-01-30 15:46:58 -05:00
GrpAuthorV toVet ;
std : : list < RsPeerId > peers ;
peers . push_back ( tr - > mTransaction - > PeerId ( ) ) ;
2013-06-04 17:00:43 -04:00
2015-01-30 15:46:58 -05:00
for ( ; llit ! = grpItemL . end ( ) ; + + llit )
{
RsNxsSyncGrpItem * & grpSyncItem = * llit ;
const RsGxsGroupId & grpId = grpSyncItem - > grpId ;
metaIter = grpMetaMap . find ( grpId ) ;
bool haveItem = false ;
bool latestVersion = false ;
if ( metaIter ! = grpMetaMap . end ( ) )
{
haveItem = true ;
latestVersion = grpSyncItem - > publishTs > metaIter - > second - > mPublishTs ;
2014-12-02 15:06:56 -05:00
}
2012-06-11 17:56:23 -04:00
2015-01-30 15:46:58 -05:00
if ( ( mGrpAutoSync & & ! haveItem ) | | latestVersion )
{
// determine if you need to check reputation
bool checkRep = ! grpSyncItem - > authorId . isNull ( ) ;
// 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
2014-12-02 15:06:56 -05:00
if ( rep . score > = GIXS_CUT_OFF )
{
addGroupItemToList ( tr , grpId , transN , reqList ) ;
std : : cerr < < " reputation cut off: limit= " < < GIXS_CUT_OFF < < " value= " < < rep . score < < " : allowed. " < < std : : endl ;
}
else
std : : cerr < < " reputation cut off: limit= " < < GIXS_CUT_OFF < < " value= " < < rep . score < < " : you shall not pass. " < < std : : endl ;
}
2015-01-30 15:46:58 -05:00
else
2014-12-02 15:06:56 -05:00
{
2015-01-30 15:46:58 -05:00
// preload reputation for later
mReputations - > loadReputation ( grpSyncItem - > authorId , peers ) ;
GrpAuthEntry entry ;
entry . mAuthorId = grpSyncItem - > authorId ;
entry . mGrpId = grpSyncItem - > grpId ;
toVet . push_back ( entry ) ;
}
2014-12-02 15:06:56 -05:00
}
2015-01-30 15:46:58 -05:00
else
{
addGroupItemToList ( tr , grpId , transN , reqList ) ;
}
}
}
2012-06-11 17:56:23 -04:00
2015-01-30 15:46:58 -05:00
if ( ! toVet . empty ( ) )
{
RsPeerId peerId = tr - > mTransaction - > PeerId ( ) ;
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
2015-01-30 15:46:58 -05:00
if ( ! reqList . empty ( ) )
{
locked_pushGrpTransactionFromList ( reqList , tr - > mTransaction - > PeerId ( ) , transN ) ;
2012-07-15 08:38:20 -04:00
2015-01-30 15:46:58 -05:00
}
2012-09-01 10:47:22 -04:00
2015-01-30 15:46:58 -05: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
2015-01-30 15:46:58 -05: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
2014-10-24 18:07:26 -04:00
for ( ; lit ! = tr - > mItems . end ( ) ; + + lit )
2012-07-14 13:59:54 -04:00
{
RsNxsSyncGrpItem * item = dynamic_cast < RsNxsSyncGrpItem * > ( * lit ) ;
2013-07-23 18:04:24 -04:00
if ( item )
{
grps [ item - > grpId ] = NULL ;
2014-12-02 15:06:56 -05:00
}
else
2013-07-23 18:04:24 -04:00
{
# 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 ) ;
}
2014-12-02 15:06:56 -05:00
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 ( ) ;
2014-10-24 18:07:26 -04:00
for ( ; mit ! = grps . end ( ) ; + + mit )
2012-07-14 13:59:54 -04:00
{
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 ) ;
2014-12-02 15:06:56 -05:00
return ;
2012-07-14 13:59:54 -04:00
}
2013-06-04 17:00:43 -04:00
void RsGxsNetService : : runVetting ( )
{
2014-11-11 14:47:05 -05:00
RS_STACK_MUTEX ( mNxsMutex ) ;
2013-06-04 17:00:43 -04:00
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
{
2014-10-24 18:07:26 -04:00
+ + vit ;
2013-06-04 17:00:43 -04:00
}
}
// 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
{
2014-10-24 18:07:26 -04:00
+ + vit2 ;
2013-06-04 17:00:43 -04:00
}
}
}
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
2014-10-24 18:07:26 -04:00
for ( ; lit ! = tr - > mItems . end ( ) ; + + lit )
2012-09-01 10:47:22 -04:00
{
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 ;
2014-10-24 18:07:26 -04:00
for ( ; mit ! = msgs . end ( ) ; + + mit )
2012-09-01 10:47:22 -04:00
{
std : : vector < RsNxsMsg * > & msgV = mit - > second ;
std : : vector < RsNxsMsg * > : : iterator vit = msgV . begin ( ) ;
2014-10-24 18:07:26 -04:00
for ( ; vit ! = msgV . end ( ) ; + + vit )
2012-09-01 10:47:22 -04:00
{
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 ( ) ;
2014-10-24 18:07:26 -04:00
for ( ; mit ! = fragments . end ( ) ; + + mit )
2013-03-16 12:44:33 -04:00
{
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 ;
2014-12-02 15:06:56 -05:00
std : : cerr < < " Transaction number exist already, transN: " < < transN < < std : : endl ;
2012-07-14 13:59:54 -04:00
# endif
2012-06-11 17:56:23 -04:00
return false ;
} else {
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " locked_addTransaction() " < < std : : endl ;
std : : cerr < < " Added transaction number " < < transN < < std : : endl ;
# endif
transMap [ transN ] = tr ;
2012-06-11 17:56:23 -04:00
return true ;
}
}
void RsGxsNetService : : cleanTransactionItems ( NxsTransaction * tr ) const
{
std : : list < RsNxsItem * > : : iterator lit = tr - > mItems . begin ( ) ;
2014-10-24 18:07:26 -04:00
for ( ; lit ! = tr - > mItems . end ( ) ; + + lit )
2012-06-11 17:56:23 -04:00
{
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
{
2015-01-28 17:48:59 -05:00
# ifdef NXS_NET_DEBUG_0
std : : cerr < < " locked_pushGrpResponseFromList() " < < std : : endl ;
std : : cerr < < " nelems = " < < respList . size ( ) < < std : : endl ;
std : : cerr < < " peerId = " < < peer < < std : : endl ;
std : : cerr < < " transN = " < < transN < < std : : endl ;
# endif
NxsTransaction * tr = new NxsTransaction ( ) ;
2013-06-04 17:00:43 -04:00
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
2015-01-28 17:48:59 -05:00
2013-11-25 17:28:17 -05:00
if ( mGrpServerUpdateItem )
{
2015-01-28 17:48:59 -05:00
# ifdef NXS_NET_DEBUG_0
std : : cerr < < " local time stamp: " < < std : : dec < < time ( NULL ) - mGrpServerUpdateItem - > grpUpdateTS < < " secs ago. Update sent: " < <
( item - > updateTS = = 0 | | item - > updateTS < mGrpServerUpdateItem - > grpUpdateTS ) < < std : : endl ;
2014-04-27 09:14:07 -04:00
# endif
2015-01-28 17:48:59 -05:00
return ( item - > updateTS = = 0 | | item - > updateTS < mGrpServerUpdateItem - > grpUpdateTS ) ;
2013-11-25 17:28:17 -05:00
}
2015-01-28 17:48:59 -05:00
# ifdef NXS_NET_DEBUG_0
std : : cerr < < " no local time stamp. Client wants to receive the grp list. " < < std : : endl ;
# endif
2013-11-25 17:28:17 -05:00
return true ;
}
2012-07-12 16:18:58 -04:00
void RsGxsNetService : : handleRecvSyncGroup ( RsNxsSyncGrp * item )
{
2014-11-11 14:47:05 -05:00
RS_STACK_MUTEX ( mNxsMutex ) ;
2012-07-15 08:38:20 -04:00
2015-01-28 17:48:59 -05:00
RsPeerId peer = item - > PeerId ( ) ;
# ifdef NXS_NET_DEBUG_0
std : : cerr < < " handleRecvSyncGroup(): from " < < peer < < " , TS = " < < std : : dec < < time ( NULL ) - item - > updateTS < < " secs ago " < < std : : endl ;
# endif
2013-11-25 17:28:17 -05:00
if ( ! locked_CanReceiveUpdate ( item ) )
2014-04-27 09:14:07 -04:00
{
2015-01-28 17:48:59 -05:00
# ifdef NXS_NET_DEBUG_1
2014-04-27 09:14:07 -04:00
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
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
{
2015-01-28 17:48:59 -05:00
# ifdef NXS_NET_DEBUG_1
2014-04-27 09:14:07 -04:00
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 ;
2015-01-28 17:48:59 -05:00
# ifdef NXS_NET_DEBUG_1
2014-02-10 18:50:47 -05:00
std : : cerr < < " RsGxsNetService::handleRecvSyncGroup() \n Service: " < < mServType < < " \n Group list beings being sent: " < < std : : endl ;
# endif
2013-06-04 17:00:43 -04:00
2014-10-24 18:07:26 -04:00
for ( ; mit ! = grp . end ( ) ; + + mit )
2012-07-12 16:18:58 -04:00
{
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 ) ;
2015-01-28 17:48:59 -05:00
# ifdef NXS_NET_DEBUG_0
std : : cerr < < " sending item for Grp " < < mit - > first < < " name= " < < grpMeta - > mGroupName < < " , publishTS= " < < std : : dec < < time ( NULL ) - mit - > second - > mPublishTs < < " secs ago to peer ID " < < peer < < 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
2015-01-28 17:48:59 -05:00
# ifdef NXS_NET_DEBUG_0
std : : cerr < < " final list sent (after vetting): " < < itemL . size ( ) < < " elements. " < < std : : endl ;
# endif
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-12-02 15:06:56 -05:00
bool RsGxsNetService : : checkCanRecvMsgFromPeer ( const RsPeerId & sslId , const RsGxsGrpMetaData & grpMeta )
{
2014-05-01 14:50:07 -04:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " RsGxsNetService::checkCanRecvMsgFromPeer() " ;
2014-12-02 15:06:56 -05:00
std : : cerr < < " peer Id = " < < sslId < < " , grpId= " < < grpMeta . mGroupId < < std : : endl ;
2014-05-01 14:50:07 -04:00
# endif
// first do the simple checks
uint8_t circleType = grpMeta . mCircleType ;
if ( circleType = = GXS_CIRCLE_TYPE_LOCAL )
{
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
std : : cerr < < " LOCAL_CIRCLE, cannot request sync from peer " ;
2014-05-01 14:50:07 -04:00
std : : cerr < < std : : endl ;
# endif
return false ;
}
if ( circleType = = GXS_CIRCLE_TYPE_PUBLIC )
{
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
std : : cerr < < " PUBLIC_CIRCLE, can request msg sync " ;
2014-05-01 14:50:07 -04:00
std : : cerr < < std : : endl ;
# endif
return true ;
}
if ( circleType = = GXS_CIRCLE_TYPE_EXTERNAL )
{
const RsGxsCircleId & circleId = grpMeta . mCircleId ;
if ( circleId . isNull ( ) )
{
2014-12-02 15:06:56 -05:00
std : : cerr < < " ERROR; EXTERNAL_CIRCLE missing NULL CircleId " ;
2014-05-01 14:50:07 -04:00
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
2014-12-02 15:06:56 -05:00
std : : cerr < < " EXTERNAL_CIRCLE, checking mCircles->canSend " ;
2014-05-01 14:50:07 -04:00
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
2014-12-02 15:06:56 -05:00
std : : cerr < < " YOUREYESONLY, checking further " ;
2014-05-01 14:50:07 -04:00
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
2014-12-02 15:06:56 -05:00
std : : cerr < < " have mInternalCircle - we are Group creator " ;
2014-05-01 14:50:07 -04:00
std : : cerr < < std : : endl ;
2014-12-02 15:06:56 -05:00
std : : cerr < < " mCircleId: " < < grpMeta . mCircleId ;
2014-05-01 14:50:07 -04:00
std : : cerr < < std : : endl ;
2014-12-02 15:06:56 -05:00
std : : cerr < < " mInternalCircle: " < < grpMeta . mInternalCircle ;
2014-05-01 14:50:07 -04:00
std : : cerr < < std : : endl ;
# endif
if ( mCircles - > isLoaded ( internalCircleId ) )
{
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
std : : cerr < < " circle Loaded - checking mCircles->canSend " ;
2014-05-01 14:50:07 -04:00
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
2014-12-02 15:06:56 -05:00
std : : cerr < < " mInternalCircle not set, someone else's personal circle " ;
2014-05-01 14:50:07 -04:00
std : : cerr < < std : : endl ;
# endif
if ( grpMeta . mOriginator = = sslId )
{
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
std : : cerr < < " Originator matches -> can send " ;
2014-05-01 14:50:07 -04:00
std : : cerr < < std : : endl ;
# endif
return true ;
}
else
{
# ifdef NXS_NET_DEBUG
2014-12-02 15:06:56 -05:00
std : : cerr < < " Originator doesn't match -> cannot send " ;
2014-05-01 14:50:07 -04:00
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
2015-01-28 17:48:59 -05:00
# ifdef NXS_NET_DEBUG_0
std : : cerr < < " local time stamp: " < < std : : dec < < time ( NULL ) - msui - > msgUpdateTS < < " secs ago. Update sent: " < <
2015-01-29 15:47:09 -05:00
( item - > updateTS = = 0 | | item - > updateTS < msui - > msgUpdateTS ) ;
2013-12-20 09:48:32 -05:00
# endif
2015-01-28 17:48:59 -05:00
return ( item - > updateTS < msui - > msgUpdateTS | | item - > updateTS = = 0 ) ;
2013-11-25 17:28:17 -05:00
}
2015-01-28 17:48:59 -05:00
# ifdef NXS_NET_DEBUG_0
2015-01-29 15:47:09 -05:00
std : : cerr < < " no local time stamp for this grp. " ;
2015-01-28 17:48:59 -05:00
# endif
2013-11-25 17:28:17 -05:00
return true ;
}
2012-07-12 16:18:58 -04:00
void RsGxsNetService : : handleRecvSyncMessage ( RsNxsSyncMsg * item )
{
2014-11-11 14:47:05 -05:00
RS_STACK_MUTEX ( 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.
2014-12-16 01:54:15 -05:00
mGroupNetworkStats [ item - > grpId ] . suppliers . insert ( item - > PeerId ( ) ) ;
2014-10-07 17:42:44 -04:00
2015-01-28 17:48:59 -05:00
const RsPeerId & peer = item - > PeerId ( ) ;
# ifdef NXS_NET_DEBUG_0
2015-01-29 15:47:09 -05:00
std : : cerr < < " handleRecvSyncMsg(): from " < < peer < < " , grpId= " < < item - > grpId < < " , TS = " < < time ( NULL ) - item - > updateTS < < " secs ago. " ;
2015-01-28 17:48:59 -05:00
# endif
2013-11-25 17:28:17 -05:00
if ( ! locked_CanReceiveUpdate ( item ) )
2015-01-29 15:47:09 -05:00
{
# ifdef NXS_NET_DEBUG_0
std : : cerr < < std : : endl ;
# endif
2013-11-25 17:28:17 -05:00
return ;
2015-01-29 15:47:09 -05:00
}
2013-11-16 08:40:04 -05:00
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 ] ;
2015-01-29 15:47:09 -05:00
if ( grpMeta = = NULL )
{
# ifdef NXS_NET_DEBUG_0
std : : cerr < < " Grp is unknown. " < < std : : endl ;
# endif
return ;
}
if ( ! ( grpMeta - > mSubscribeFlags & GXS_SERV : : GROUP_SUBSCRIBE_SUBSCRIBED ) )
{
# ifdef NXS_NET_DEBUG_0
std : : cerr < < " Grp is not subscribed. " < < std : : endl ;
# endif
delete ( grpMeta ) ;
return ;
}
2013-06-04 17:00:43 -04:00
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 ( ) )
{
2015-01-29 15:47:09 -05:00
# ifdef NXS_NET_DEBUG_0
std : : cerr < < " No msg meta data.. " < < std : : endl ;
# endif
delete ( grpMeta ) ;
2012-09-01 10:47:22 -04:00
return ;
2015-01-29 15:47:09 -05:00
}
# ifdef NXS_NET_DEBUG_0
std : : cerr < < " Sending MSG meta data! " < < std : : endl ;
# endif
2012-09-01 10:47:22 -04:00
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 ( ) ;
2014-10-24 18:07:26 -04:00
for ( ; vit ! = msgMetas . end ( ) ; + + vit )
2013-06-04 17:00:43 -04:00
{
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 ) ;
2015-01-28 17:48:59 -05:00
# ifdef NXS_NET_DEBUG_1
std : : cerr < < " sending info item for msg id " < < mItem - > msgId < < std : : endl ;
# endif
}
2013-06-04 17:00:43 -04:00
2015-01-28 17:48:59 -05:00
if ( ! itemL . empty ( ) )
{
# ifdef NXS_NET_DEBUG_0
std : : cerr < < " sending final msg info list of " < < itemL . size ( ) < < " items. " < < std : : endl ;
# endif
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
2014-10-24 18:07:26 -04:00
for ( vit = msgMetas . begin ( ) ; vit ! = msgMetas . end ( ) ; + + vit )
2013-06-04 17:00:43 -04:00
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 )
{
2014-12-02 15:06:56 -05:00
# ifdef NXS_NET_DEBUG
std : : cerr < < " locked_pushMsgResponseFromList() " < < std : : endl ;
std : : cerr < < " nelems = " < < itemL . size ( ) < < std : : endl ;
std : : cerr < < " peerId = " < < sslId < < std : : endl ;
std : : cerr < < " transN = " < < transN < < std : : endl ;
# endif
NxsTransaction * tr = new NxsTransaction ( ) ;
2013-06-04 17:00:43 -04:00
tr - > mItems = itemL ;
2012-09-01 10:47:22 -04:00
tr - > mFlag = NxsTransaction : : FLAG_STATE_WAITING_CONFIRM ;
RsNxsTransac * trItem = new RsNxsTransac ( mServType ) ;
2014-12-02 15:06:56 -05:00
trItem - > transactFlag = RsNxsTransac : : FLAG_BEGIN_P1 | RsNxsTransac : : FLAG_TYPE_MSG_LIST_RESP ;
trItem - > nItems = itemL . size ( ) ;
2012-09-01 10:47:22 -04:00
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
2014-10-24 18:07:26 -04:00
for ( ; vit ! = msgMetas . end ( ) ; + + vit )
2013-06-04 17:00:43 -04:00
{
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
2014-10-24 18:07:26 -04:00
for ( ; vit ! = msgMetas . end ( ) ; + + vit )
2013-06-04 17:00:43 -04:00
{
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
{
2014-11-11 14:47:05 -05:00
RS_STACK_MUTEX ( mNxsMutex ) ;
2013-10-29 17:29:20 -04:00
mExplicitRequest [ peerId ] . assign ( grpId . begin ( ) , grpId . end ( ) ) ;
return 1 ;
}
void RsGxsNetService : : processExplicitGroupRequests ( )
{
2014-11-11 14:47:05 -05:00
RS_STACK_MUTEX ( mNxsMutex ) ;
2013-10-29 17:29:20 -04:00
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
2014-10-24 18:07:26 -04:00
for ( ; cit ! = mExplicitRequest . end ( ) ; + + cit )
2013-10-29 17:29:20 -04:00
{
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 ( ) ;
2014-10-24 18:07:26 -04:00
for ( ; git ! = groupIdList . end ( ) ; + + git )
2013-10-29 17:29:20 -04:00
{
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
int RsGxsNetService : : sharePublishKey ( const RsGxsGroupId & grpId , const std : : list < RsPeerId > & peers )
{
2014-11-11 14:47:05 -05:00
RS_STACK_MUTEX ( mNxsMutex ) ;
2014-10-05 15:14:05 -04:00
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 ( )
{
2014-11-11 14:47:05 -05:00
RS_STACK_MUTEX ( mNxsMutex ) ;
2014-10-05 15:14:05 -04:00
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
2014-10-24 18:07:26 -04:00
for ( std : : list < RsGxsGroupId > : : const_iterator lit = toDelete . begin ( ) ; lit ! = toDelete . end ( ) ; + + lit )
2014-10-05 15:14:05 -04:00
mPendingPublishKeyRecipients . erase ( * lit ) ;
}
void RsGxsNetService : : handleRecvPublishKeys ( RsNxsGroupPublishKeyItem * item )
{
# ifdef NXS_NET_DEBUG
std : : cerr < < " RsGxsNetService::sharePublishKeys() " < < std : : endl ;
# endif
2014-11-11 14:47:05 -05:00
RS_STACK_MUTEX ( mNxsMutex ) ;
2014-10-05 15:14:05 -04:00
# 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
}