Merge pull request #1875 from csoler/v0.6-GxsGroup

Add group change notifications (e.g. circle invites, forum moderation, etc)
This commit is contained in:
csoler 2020-05-17 22:37:03 +02:00 committed by GitHub
commit d52d9c909b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
64 changed files with 2678 additions and 2188 deletions

View file

@ -289,7 +289,7 @@ bool GxsSecurity::generateKeyPair(RsTlvPublicRSAKey& public_key,RsTlvPrivateRSAK
if(!(private_key.checkKey() && public_key.checkKey()))
{
std::cerr << "(EE) ERROR while generating keys. Something inconsistent in flags. This is probably a bad sign!" << std::endl;
return false ;
return false ;
}
return true ;
@ -418,13 +418,11 @@ bool GxsSecurity::validateNxsMsg(const RsNxsMsg& msg, const RsTlvKeySignature& s
/* check signature timeperiod */
if ((msgMeta.mPublishTs < key.startTS) || (key.endTS != 0 && msgMeta.mPublishTs > key.endTS))
{
#ifdef GXS_SECURITY_DEBUG
std::cerr << " GxsSecurity::validateNxsMsg() TS out of range";
std::cerr << std::endl;
#endif
return false;
}
{
RsWarn() << __PRETTY_FUNCTION__ << " GxsSecurity::validateNxsMsg() TS out of range for key " << msgMeta.mAuthorId
<< " usage is limited to TS=[" << key.startTS << "," << key.endTS << "] and msg publish time is " << msgMeta.mPublishTs << std::endl;
return false;
}
/* decode key */
const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data;

View file

@ -149,7 +149,7 @@ public:
bool withMeta = false ) = 0;
/*!
* Retrieves all groups stored
* Retrieves all groups stored. Caller owns the memory and is supposed to delete the RsNxsGrp pointers after use.
* @param grp retrieved groups
* @param withMeta if true the meta handle of nxs grps is intitialised
* @param cache whether to store retrieval in mem for faster later retrieval

View file

@ -236,14 +236,17 @@ void RsGenExchange::tick()
if (!grpIds.empty())
{
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, false);
gc->mGrpIdList = grpIds;
for(auto& groupId:grpIds)
{
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_GROUP_DELETED,groupId, false);
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
for(std::list<RsGxsGroupId>::const_iterator it(grpIds.begin());it!=grpIds.end();++it)
std::cerr << " " << *it << std::endl;
std::cerr << " adding the following grp ids to notification: " << std::endl;
for(std::list<RsGxsGroupId>::const_iterator it(grpIds.begin());it!=grpIds.end();++it)
std::cerr << " " << *it << std::endl;
#endif
mNotifications.push_back(gc);
mNotifications.push_back(gc);
}
// also notify the network exchange service that these groups no longer exist.
@ -251,12 +254,12 @@ void RsGenExchange::tick()
mNetService->removeGroups(grpIds) ;
}
if (!msgIds.empty())
{
RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, false);
c->msgChangeMap = msgIds;
mNotifications.push_back(c);
}
for(auto it(msgIds.begin());it!=msgIds.end();++it)
for(auto& msgId:it->second)
{
RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_MESSAGE_DELETED,it->first, msgId, false);
mNotifications.push_back(c);
}
delete mIntegrityCheck;
mIntegrityCheck = NULL;
@ -770,7 +773,7 @@ int RsGenExchange::createMessage(RsNxsMsg* msg)
hash.addData(allMsgData, allMsgDataLen);
RsFileHash hashId;
hash.Complete(hashId);
msg->msgId = hashId;
msg->msgId = RsGxsMessageId(hashId);
// assign msg id to msg meta
msg->metaData->mMsgId = msg->msgId;
@ -934,7 +937,7 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin
RsReputationLevel::LOCALLY_NEGATIVE )
{
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation level (" << details.mReputation.mOverallReputationLevel <<") indicate that you banned this ID." << std::endl;
std::cerr << "RsGenExchange::validateMsg(): message from " << metaData.mAuthorId << ", rejected because reputation level (" << static_cast<int>(details.mReputation.mOverallReputationLevel) <<") indicate that you banned this ID." << std::endl;
#endif
idValidate = false ;
}
@ -1110,6 +1113,7 @@ static void addMessageChanged(std::map<RsGxsGroupId, std::set<RsGxsMessageId> >
}
}
#ifdef TO_REMOVE
void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& changes)
{
std::cerr << "*********************************** RsGenExchange::receiveChanges()" << std::endl;
@ -1155,6 +1159,7 @@ void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& changes)
if(rsEvents) rsEvents->postEvent(std::move(evt));
}
#endif
bool RsGenExchange::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe)
{
@ -1683,8 +1688,7 @@ void RsGenExchange::notifyReceivePublishKey(const RsGxsGroupId &grpId)
{
RS_STACK_MUTEX(mGenMtx);
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY, true);
gc->mGrpIdList.push_back(grpId);
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY,grpId, true);
mNotifications.push_back(gc);
}
@ -1692,8 +1696,8 @@ void RsGenExchange::notifyChangedGroupStats(const RsGxsGroupId &grpId)
{
RS_STACK_MUTEX(mGenMtx);
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_STATISTICS_CHANGED, false);
gc->mGrpIdList.push_back(grpId);
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_STATISTICS_CHANGED,grpId, false);
mNotifications.push_back(gc);
}
@ -1790,19 +1794,20 @@ void RsGenExchange::publishGroup(uint32_t& token, RsGxsGrpItem *grpItem)
void RsGenExchange::updateGroup(uint32_t& token, RsGxsGrpItem* grpItem)
{
if(!checkGroupMetaConsistency(grpItem->meta))
{
std::cerr << "(EE) Cannot update group. Some information was not supplied." << std::endl;
return ;
}
if(!checkGroupMetaConsistency(grpItem->meta))
{
std::cerr << "(EE) Cannot update group. Some information was not supplied." << std::endl;
delete grpItem;
return ;
}
RS_STACK_MUTEX(mGenMtx) ;
RS_STACK_MUTEX(mGenMtx) ;
token = mDataAccess->generatePublicToken();
mGroupUpdatePublish.push_back(GroupUpdatePublish(grpItem, token));
mGroupUpdatePublish.push_back(GroupUpdatePublish(grpItem, token));
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::updateGroup() token: " << token;
std::cerr << std::endl;
std::cerr << "RsGenExchange::updateGroup() token: " << token;
std::cerr << std::endl;
#endif
}
@ -2049,11 +2054,13 @@ void RsGenExchange::processMsgMetaChanges()
}
}
if (!msgIds.empty()) {
if (!msgIds.empty())
{
RS_STACK_MUTEX(mGenMtx);
RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, false);
c->msgChangeMap = msgIds;
mNotifications.push_back(c);
for(auto it(msgIds.begin());it!=msgIds.end();++it)
for(auto& msg_id:it->second)
mNotifications.push_back(new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, it->first, msg_id, false));
}
}
@ -2099,17 +2106,11 @@ void RsGenExchange::processGrpMetaChanges()
}
}
if(!grpChanged.empty())
for(auto& groupId:grpChanged)
{
RS_STACK_MUTEX(mGenMtx);
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED, true);
gc->mGrpIdList = grpChanged;
mNotifications.push_back(gc);
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
for(std::list<RsGxsGroupId>::const_iterator it(grpChanged.begin());it!=grpChanged.end();++it)
std::cerr << " " << *it << std::endl;
#endif
mNotifications.push_back(new RsGxsGroupChange(RsGxsNotify::TYPE_PROCESSED,groupId, true));
}
}
@ -2186,7 +2187,7 @@ void RsGenExchange::publishMsgs()
mMsgsToPublish.insert(std::make_pair(sign_it->first, item.mItem));
}
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > msgChangeMap;
std::map<RsGxsGroupId, std::list<RsGxsMsgItem*> > msgChangeMap;
std::map<uint32_t, RsGxsMsgItem*>::iterator mit = mMsgsToPublish.begin();
for(; mit != mMsgsToPublish.end(); ++mit)
@ -2315,9 +2316,12 @@ void RsGenExchange::publishMsgs()
mPublishedMsgs[token] = *msg->metaData;
RsGxsMsgItem *msg_item = dynamic_cast<RsGxsMsgItem*>(mSerialiser->deserialise(msg->msg.bin_data,&msg->msg.bin_len)) ;
msg_item->meta = *msg->metaData;
delete msg ;
msgChangeMap[grpId].insert(msgId);
msgChangeMap[grpId].push_back(msg_item);
delete[] metaDataBuff;
@ -2356,13 +2360,14 @@ void RsGenExchange::publishMsgs()
// entries are invalid
mMsgsToPublish.clear();
if(!msgChangeMap.empty())
{
RsGxsMsgChange* ch = new RsGxsMsgChange(RsGxsNotify::TYPE_PUBLISHED, false);
ch->msgChangeMap = msgChangeMap;
mNotifications.push_back(ch);
}
for(auto it(msgChangeMap.begin());it!=msgChangeMap.end();++it)
for(auto& msg_item: it->second)
{
RsGxsMsgChange* ch = new RsGxsMsgChange(RsGxsNotify::TYPE_PUBLISHED,msg_item->meta.mGroupId, msg_item->meta.mMsgId, false);
ch->mNewMsgItem = msg_item;
mNotifications.push_back(ch);
}
}
RsGenExchange::ServiceCreate_Return RsGenExchange::service_CreateGroup(RsGxsGrpItem* /* grpItem */,
@ -2381,15 +2386,14 @@ RsGenExchange::ServiceCreate_Return RsGenExchange::service_CreateGroup(RsGxsGrpI
void RsGenExchange::processGroupUpdatePublish()
{
RS_STACK_MUTEX(mGenMtx) ;
RS_STACK_MUTEX(mGenMtx) ;
// get keys for group update publish
// first build meta request map for groups to be updated
RsGxsGrpMetaTemporaryMap grpMeta;
std::vector<GroupUpdatePublish>::iterator vit = mGroupUpdatePublish.begin();
for(; vit != mGroupUpdatePublish.end(); ++vit)
for(auto vit = mGroupUpdatePublish.begin(); vit != mGroupUpdatePublish.end(); ++vit)
{
GroupUpdatePublish& gup = *vit;
const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId;
@ -2402,8 +2406,7 @@ void RsGenExchange::processGroupUpdatePublish()
mDataStore->retrieveGxsGrpMetaData(grpMeta);
// now
vit = mGroupUpdatePublish.begin();
for(; vit != mGroupUpdatePublish.end(); ++vit)
for(auto vit = mGroupUpdatePublish.begin(); vit != mGroupUpdatePublish.end(); ++vit)
{
GroupUpdatePublish& gup = *vit;
const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId;
@ -2421,14 +2424,14 @@ void RsGenExchange::processGroupUpdatePublish()
meta = mit->second;
//gup.grpItem->meta = *meta;
GxsGrpPendingSign ggps(gup.grpItem, gup.mToken);
GxsGrpPendingSign ggps(gup.grpItem, gup.mToken);
if(checkKeys(meta->keys))
{
ggps.mKeys = meta->keys;
GxsSecurity::createPublicKeysFromPrivateKeys(ggps.mKeys) ;
GxsSecurity::createPublicKeysFromPrivateKeys(ggps.mKeys) ;
ggps.mHaveKeys = true;
ggps.mStartTS = time(NULL);
ggps.mLastAttemptTS = 0;
@ -2438,8 +2441,8 @@ void RsGenExchange::processGroupUpdatePublish()
}
else
{
std::cerr << "(EE) publish group fails because RS cannot find the private publish and author keys" << std::endl;
std::cerr << "(EE) publish group fails because RS cannot find the private publish and author keys" << std::endl;
delete gup.grpItem;
mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::FAILED);
}
@ -2494,15 +2497,15 @@ void RsGenExchange::processGroupDelete()
grpDeleted.push_back(note.second);
}
if(!grpDeleted.empty())
for(auto& groupId:grpDeleted)
{
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISHED, false);
gc->mGrpIdList = grpDeleted;
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_GROUP_DELETED, groupId,false);
mNotifications.push_back(gc);
}
mGroupDeletePublish.clear();
}
void RsGenExchange::processMessageDelete()
{
RS_STACK_MUTEX(mGenMtx) ;
@ -2521,31 +2524,24 @@ void RsGenExchange::processMessageDelete()
mDataStore->removeMsgs( (*vit).mMsgs );
}
// std::list<RsGxsGroupId> grpDeleted;
// std::map<uint32_t, GrpNote>::iterator mit = toNotify.begin();
// for(; mit != toNotify.end(); ++mit)
// {
// GrpNote& note = mit->second;
// uint8_t status = note.first ? RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE
// : RsTokenService::GXS_REQUEST_V2_STATUS_FAILED;
//
// mGrpNotify.insert(std::make_pair(mit->first, note.second));
// mDataAccess->updatePublicRequestStatus(mit->first, status);
//
// if(note.first)
// grpDeleted.push_back(note.second);
// }
#warning csoler: TODO: notify for deleted messages
#ifdef SUSPENDED
std::list<RsGxsGroupId> grpDeleted;
std::map<uint32_t, GrpNote>::iterator mit = toNotify.begin();
for(; mit != toNotify.end(); ++mit)
{
GrpNote& note = mit->second;
uint8_t status = note.first ? RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE
: RsTokenService::GXS_REQUEST_V2_STATUS_FAILED;
mGrpNotify.insert(std::make_pair(mit->first, note.second));
mDataAccess->updatePublicRequestStatus(mit->first, status);
if(note.first)
grpDeleted.push_back(note.second);
}
if(!grpDeleted.empty())
{
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISH, false);
gc->mGrpIdList = grpDeleted;
mNotifications.push_back(gc);
}
#endif
for(uint32_t i=0;i<mMsgDeletePublish.size();++i)
for(auto it(mMsgDeletePublish[i].mMsgs.begin());it!=mMsgDeletePublish[i].mMsgs.end();++it)
mNotifications.push_back(new RsGxsGroupChange(RsGxsNotify::TYPE_MESSAGE_DELETED,it->first, false));
mMsgDeletePublish.clear();
}
@ -2805,17 +2801,8 @@ void RsGenExchange::publishGrps()
grpChanged.push_back(note.second);
}
if(!grpChanged.empty())
{
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, true);
gc->mGrpIdList = grpChanged;
mNotifications.push_back(gc);
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
for(std::list<RsGxsGroupId>::const_iterator it(grpChanged.begin());it!=grpChanged.end();++it)
std::cerr << " " << *it << std::endl;
#endif
}
for(auto& groupId:grpChanged)
mNotifications.push_back(new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW,groupId, true));
}
// This is done off-mutex to avoid possible cross deadlocks with the net service.
@ -3072,11 +3059,19 @@ void RsGenExchange::processRecvdMessages()
#ifdef GEN_EXCH_DEBUG
std::cerr << " storing remaining messages" << std::endl;
#endif
mDataStore->storeMessage(msgs_to_store);
RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_RECEIVED_NEW, false);
c->msgChangeMap = msgIds;
mNotifications.push_back(c);
for(auto& nxs_msg: msgs_to_store)
{
RsGxsMsgItem *item = dynamic_cast<RsGxsMsgItem*>(mSerialiser->deserialise(nxs_msg->msg.bin_data,&nxs_msg->msg.bin_len));
item->meta = *nxs_msg->metaData;
RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_RECEIVED_NEW, item->meta.mGroupId, item->meta.mMsgId,false);
c->mNewMsgItem = item;
mNotifications.push_back(c);
}
mDataStore->storeMessage(msgs_to_store); // we do that late because it destroys the items in msgs_to_store
}
}
@ -3205,11 +3200,17 @@ void RsGenExchange::processRecvdGroups()
vit = tmp ;
}
if(!grpIds.empty())
if(!grps_to_store.empty())
{
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, false);
c->mGrpIdList = grpIds;
mNotifications.push_back(c);
for(auto Grp:grps_to_store)
{
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, Grp->grpId, false);
c->mNewGroupItem = dynamic_cast<RsGxsGrpItem*>(mSerialiser->deserialise(Grp->grp.bin_data,&Grp->grp.bin_len));
mNotifications.push_back(c);
}
mDataStore->storeGroup(grps_to_store);
#ifdef GEN_EXCH_DEBUG
std::cerr << " adding the following grp ids to notification: " << std::endl;
@ -3230,39 +3231,42 @@ void RsGenExchange::performUpdateValidation()
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
#endif
RsGxsGrpMetaTemporaryMap grpMetas;
RsNxsGrpDataTemporaryMap grpDatas;
std::vector<GroupUpdate>::iterator vit = mGroupUpdates.begin();
for(; vit != mGroupUpdates.end(); ++vit)
grpMetas.insert(std::make_pair(vit->newGrp->grpId, (RsGxsGrpMetaData*)NULL));
for(auto vit(mGroupUpdates.begin()); vit != mGroupUpdates.end(); ++vit)
grpDatas.insert(std::make_pair(vit->newGrp->grpId, (RsNxsGrp*)NULL));
if(grpDatas.empty() || !mDataStore->retrieveNxsGrps(grpDatas,true,false))
{
if(grpDatas.empty())
RsErr() << __PRETTY_FUNCTION__ << " Validation of multiple group updates failed: no group in list!" << std::endl;
else
RsErr() << __PRETTY_FUNCTION__ << " Validation of multiple group updates failed: cannot retrieve froup data for these groups!" << std::endl;
if(!grpMetas.empty())
mDataStore->retrieveGxsGrpMetaData(grpMetas);
else
return;
vit = mGroupUpdates.begin();
for(; vit != mGroupUpdates.end(); ++vit)
{
GroupUpdate& gu = *vit;
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = grpMetas.find(gu.newGrp->grpId);
gu.oldGrpMeta = mit->second;
gu.validUpdate = updateValid(*(gu.oldGrpMeta), *(gu.newGrp));
}
}
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
#endif
vit = mGroupUpdates.begin();
RsNxsGrpDataTemporaryList grps ;
for(; vit != mGroupUpdates.end(); ++vit)
for(auto vit(mGroupUpdates.begin()); vit != mGroupUpdates.end(); ++vit)
{
GroupUpdate& gu = *vit;
if(gu.validUpdate)
auto mit = grpDatas.find(gu.newGrp->grpId);
if(mit == grpDatas.end())
{
RsErr() << __PRETTY_FUNCTION__ << " Validation of group update failed for group " << gu.newGrp->grpId << " because previous grp version cannot be found." << std::endl;
continue;
}
RsGxsGrpMetaData *oldGrpMeta(mit->second->metaData);
RsNxsGrp *oldGrp(mit->second);
if(updateValid(*oldGrpMeta, *gu.newGrp))
{
if(gu.newGrp->metaData->mCircleType == GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY)
gu.newGrp->metaData->mOriginator = gu.newGrp->PeerId();
@ -3270,42 +3274,39 @@ void RsGenExchange::performUpdateValidation()
// Keep subscriptionflag to what it was. This avoids clearing off the flag when updates to group meta information
// is received.
gu.newGrp->metaData->mSubscribeFlags = gu.oldGrpMeta->mSubscribeFlags ;
gu.newGrp->metaData->mSubscribeFlags = oldGrpMeta->mSubscribeFlags ;
// Also keep private keys if present
if(!gu.newGrp->metaData->keys.private_keys.empty())
std::cerr << "(EE) performUpdateValidation() group " <<gu.newGrp->metaData->mGroupId << " has been received with private keys. This is very unexpected!" << std::endl;
else
gu.newGrp->metaData->keys.private_keys = gu.oldGrpMeta->keys.private_keys ;
gu.newGrp->metaData->keys.private_keys = oldGrpMeta->keys.private_keys ;
// Now prepare notification of the client
RsGxsGroupChange *c = new RsGxsGroupChange(RsGxsNotify::TYPE_UPDATED,gu.newGrp->metaData->mGroupId,false);
c->mNewGroupItem = dynamic_cast<RsGxsGrpItem*>(mSerialiser->deserialise(gu.newGrp->grp.bin_data,&gu.newGrp->grp.bin_len));
c->mNewGroupItem->meta = *gu.newGrp->metaData; // gu.newGrp will be deleted because mDataStore will destroy it on update
c->mOldGroupItem = dynamic_cast<RsGxsGrpItem*>(mSerialiser->deserialise(oldGrp->grp.bin_data,&oldGrp->grp.bin_len));
c->mOldGroupItem->meta = *oldGrpMeta; // no need to delete mit->second, as it will be deleted automatically in the temporary map
mNotifications.push_back(c);
// finally, add the group to the list to send to mDataStore
grps.push_back(gu.newGrp);
}
else
{
delete gu.newGrp;
delete gu.newGrp; // delete here because mDataStore will not take care of this one. no need to delete mit->second, as it will be deleted automatically in the temporary map
gu.newGrp = NULL ;
}
gu.oldGrpMeta = NULL ;
}
// notify the client
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVED_NEW, true);
for(uint32_t i=0;i<mGroupUpdates.size();++i)
if(mGroupUpdates[i].newGrp != NULL)
{
c->mGrpIdList.push_back(mGroupUpdates[i].newGrp->grpId) ;
#ifdef GEN_EXCH_DEBUG
std::cerr << " " << mGroupUpdates[i].newGrp->grpId << std::endl;
#endif
}
mNotifications.push_back(c);
// Warning: updateGroup will destroy the objects in grps. Dont use it afterwards!
mDataStore->updateGroup(grps);
#ifdef GEN_EXCH_DEBUG

View file

@ -33,6 +33,7 @@
#include "rsnxsobserver.h"
#include "retroshare/rsgxsservice.h"
#include "rsitems/rsnxsitems.h"
#include "gxs/rsgxsnotify.h"
#include "rsgxsutil.h"
template<class GxsItem, typename Identity = std::string>
@ -262,12 +263,14 @@ public:
*/
bool getPublishedMsgMeta(const uint32_t& token,RsMsgMetaData& meta);
#ifdef TO_REMOVE
/*!
* Gxs services should call this for automatic handling of
* changes, send
* @param changes
*/
virtual void receiveChanges(std::vector<RsGxsNotify*>& changes);
#endif
/*!
* \brief acceptNewGroup
@ -748,9 +751,6 @@ protected:
*/
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes) = 0;
private:
void processRecvdData();

View file

@ -1038,7 +1038,7 @@ bool RsGxsDataAccess::getMsgMetaDataList( const GxsMsgReq& msgIds, const RsTokRe
// Because msgs are stored in a std::vector we build a map to convert each vector to its position in metaV.
std::vector<bool> keep(metaV.size(),true); // this vector will tell wether we keep or not a given Meta
std::map<RsMessageId,uint32_t> index_in_metaV; // holds the index of each group Id in metaV
std::map<RsGxsMessageId,uint32_t> index_in_metaV; // holds the index of each group Id in metaV
for(uint32_t i=0;i<metaV.size();++i)
index_in_metaV[metaV[i]->mMsgId] = i;

View file

@ -320,9 +320,9 @@ static const uint32_t RS_NXS_ITEM_ENCRYPTION_STATUS_GXS_KEY_MISSING = 0x05 ;
|| defined(NXS_NET_DEBUG_4) || defined(NXS_NET_DEBUG_5) || defined(NXS_NET_DEBUG_6) || defined(NXS_NET_DEBUG_7) \
|| defined(NXS_NET_DEBUG_8)
static const RsPeerId peer_to_print = RsPeerId(std::string("")) ;
static const RsGxsGroupId group_id_to_print = RsGxsGroupId(std::string("")) ; // use this to allow to this group id only, or "" for all IDs
static const uint32_t service_to_print = RS_SERVICE_GXS_TYPE_CHANNELS ; // use this to allow to this service id only, or 0 for all services
static const RsPeerId peer_to_print = RsPeerId();//std::string("a97fef0e2dc82ddb19200fb30f9ac575")) ;
static const RsGxsGroupId group_id_to_print = RsGxsGroupId(std::string("66052380f5d1d0c5992e2b55dc402ce6")) ; // use this to allow to this group id only, or "" for all IDs
static const uint32_t service_to_print = RS_SERVICE_GXS_TYPE_GXSCIRCLE; // use this to allow to this service id only, or 0 for all services
// warning. Numbers should be SERVICE IDS (see serialiser/rsserviceids.h. E.g. 0x0215 for forums)
class nullstream: public std::ostream {};
@ -3598,6 +3598,10 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
msg->count = 1; // only one piece. This is to keep compatibility if we ever implement fragmenting in the future.
msg->pos = 0;
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(tr->mTransaction->PeerId(),msg->grpId) << " sending msg Id " << msg->msgId << " in Group " << msg->grpId << std::endl;
#endif
newTr->mItems.push_back(msg);
msgSize++;
#endif

View file

@ -0,0 +1,107 @@
/*******************************************************************************
* libretroshare/src/gxs/: rsgxsnotify.h *
* *
* libretroshare: retroshare core library *
* *
* Copyright (C) 2015 Retroshare Team <retroshare.project@gmail.com> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of the *
* License, or (at your option) any later version. *
* *
* This program 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 Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#pragma once
/*!
* The aim of this class is to implement notifications internally to GXS, which are
* mostly used by RsGenExchange to send information to specific services. These services
* then interpret these changes and turn them into human-readable/processed service-specific changes.
*/
#include "retroshare/rsids.h"
class RsGxsNotify
{
public:
RsGxsNotify(const RsGxsGroupId& gid): mGroupId(gid){}
virtual ~RsGxsNotify()=default;
enum NotifyType
{
TYPE_UNKNOWN = 0x00,
TYPE_PUBLISHED = 0x01,
TYPE_RECEIVED_NEW = 0x02,
TYPE_PROCESSED = 0x03,
TYPE_RECEIVED_PUBLISHKEY = 0x04,
TYPE_RECEIVED_DISTANT_SEARCH_RESULTS = 0x05,
TYPE_STATISTICS_CHANGED = 0x06,
TYPE_UPDATED = 0x07,
TYPE_MESSAGE_DELETED = 0x08,
TYPE_GROUP_DELETED = 0x09,
};
virtual NotifyType getType() = 0;
RsGxsGroupId mGroupId; // Group id of the group we're talking about. When the group is deleted, it's useful to know which group
// that was although there is no pointers to the actual group data anymore.
};
/*!
* Relevant to group changes
*/
class RsGxsGroupChange : public RsGxsNotify
{
public:
RsGxsGroupChange(NotifyType type, const RsGxsGroupId& gid,bool metaChange) : RsGxsNotify(gid),mNewGroupItem(nullptr),mOldGroupItem(nullptr), mNotifyType(type), mMetaChange(metaChange) {}
virtual ~RsGxsGroupChange() override { delete mOldGroupItem; delete mNewGroupItem ; }
NotifyType getType() override { return mNotifyType;}
bool metaChange() { return mMetaChange; }
RsGxsGrpItem *mNewGroupItem; // Valid when a group has changed, or a new group is received.
RsGxsGrpItem *mOldGroupItem; // only valid when mNotifyType is TYPE_UPDATED
protected:
NotifyType mNotifyType;
bool mMetaChange;
};
class RsGxsDistantSearchResultChange: public RsGxsNotify
{
public:
RsGxsDistantSearchResultChange(TurtleRequestId id,const RsGxsGroupId& gid) : RsGxsNotify(gid), mRequestId(id){}
NotifyType getType() { return TYPE_RECEIVED_DISTANT_SEARCH_RESULTS ; }
TurtleRequestId mRequestId ;
};
/*!
* Relevant to message changes
*/
class RsGxsMsgChange : public RsGxsNotify
{
public:
RsGxsMsgChange(NotifyType type, const RsGxsGroupId& gid, const RsGxsMessageId& msg_id,bool metaChange)
: RsGxsNotify(gid), mMsgId(msg_id), mNewMsgItem(nullptr),NOTIFY_TYPE(type), mMetaChange(metaChange) {}
RsGxsMessageId mMsgId;
RsGxsMsgItem *mNewMsgItem;
NotifyType getType(){ return NOTIFY_TYPE;}
bool metaChange() { return mMetaChange; }
private:
const NotifyType NOTIFY_TYPE;
bool mMetaChange;
};

View file

@ -656,6 +656,9 @@ void p3GxsTrans::notifyChanges(std::vector<RsGxsNotify*>& changes)
#ifdef DEBUG_GXSTRANS
std::cout << "p3GxsTrans::notifyChanges(...)" << std::endl;
#endif
std::list<RsGxsGroupId> grps_to_request;
GxsMsgReq msgs_to_request;
for( auto it = changes.begin(); it != changes.end(); ++it )
{
RsGxsGroupChange* grpChange = dynamic_cast<RsGxsGroupChange *>(*it);
@ -666,18 +669,15 @@ void p3GxsTrans::notifyChanges(std::vector<RsGxsNotify*>& changes)
#ifdef DEBUG_GXSTRANS
std::cout << "p3GxsTrans::notifyChanges(...) grpChange" << std::endl;
#endif
requestGroupsData(&(grpChange->mGrpIdList));
grps_to_request.push_back(grpChange->mGroupId);
}
else if(msgChange)
{
#ifdef DEBUG_GXSTRANS
std::cout << "p3GxsTrans::notifyChanges(...) msgChange" << std::endl;
#endif
uint32_t token;
RsTokReqOptions opts; opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
RsGenExchange::getTokenService()->requestMsgInfo( token, 0xcaca,
opts, msgChange->msgChangeMap );
GxsTokenQueue::queueRequest(token, MAILS_UPDATE);
msgs_to_request[msgChange->mGroupId].insert(msgChange->mMsgId);
#ifdef DEBUG_GXSTRANS
for( GxsMsgReq::const_iterator it = msgChange->msgChangeMap.begin();
@ -698,6 +698,20 @@ void p3GxsTrans::notifyChanges(std::vector<RsGxsNotify*>& changes)
}
delete *it;
}
if(!msgs_to_request.empty())
{
uint32_t token;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_MSG_DATA;
RsGenExchange::getTokenService()->requestMsgInfo( token, 0xcaca, opts, msgs_to_request);
GxsTokenQueue::queueRequest(token, MAILS_UPDATE);
}
if(!grps_to_request.empty())
requestGroupsData(&grps_to_request);
}
uint32_t p3GxsTrans::AuthenPolicy()

View file

@ -672,6 +672,7 @@ HEADERS += rsitems/rsnxsitems.h \
util/rsdbbind.h \
util/contentvalue.h \
gxs/rsgxsutil.h \
gxs/rsgxsnotify.h \
gxs/gxssecurity.h \
gxs/rsgds.h \
gxs/rsgxs.h \

View file

@ -1110,10 +1110,16 @@ int pqissl::SSL_Connection_Complete()
if(rsEvents)
{
X509 *x509 = SSL_get_peer_certificate(ssl_connection);
auto ev = std::make_shared<RsAuthSslConnectionAutenticationEvent>();
ev->mSslId = RsX509Cert::getCertSslId(*x509);
ev->mErrorCode = RsAuthSslError::PEER_REFUSED_CONNECTION;
rsEvents->postEvent(ev);
if(x509)
{
auto ev = std::make_shared<RsAuthSslConnectionAutenticationEvent>();
ev->mSslId = RsX509Cert::getCertSslId(*x509);
ev->mErrorCode = RsAuthSslError::PEER_REFUSED_CONNECTION;
if(!ev->mSslId.isNull())
rsEvents->postEvent(ev);
}
}
std::string out;

View file

@ -45,25 +45,23 @@ extern RsGxsCircles* rsGxsCircles;
enum class RsGxsCircleType : uint32_t // 32 bit overkill, just for retrocompat
{
UNKNOWN = 0, /// Used to detect uninizialized values.
PUBLIC = 1, /// Public distribution
EXTERNAL = 2, /// Restricted to an external circle
UNKNOWN = 0, /// Used to detect uninizialized values.
PUBLIC = 1, /// Public distribution, based on GxsIds
EXTERNAL = 2, /// Restricted to an external circle, based on GxsIds
/** Restricted to a group of friend nodes, the administrator of the circle
* behave as a hub for them */
NODES_GROUP = 3,
NODES_GROUP = 3, /// Restricted to a group of friend nodes, the administrator of the circle behave as a hub for them
/// Based on PGP nodes ids.
LOCAL = 4, /// not distributed at all
/** Self-restricted. Used only at creation time of self-restricted circles
* when the circle id isn't known yet. Once the circle id is known the type
* is set to EXTERNAL, and the external circle id is set to the id of the
* circle itself.
* circle itself. Based on GxsIds.
*/
EXT_SELF = 5,
/// distributed to nodes signed by your own PGP key only.
YOUR_EYES_ONLY = 6
YOUR_EYES_ONLY = 6 /// distributed to nodes signed by your own PGP key only.
};
// TODO: convert to enum class
@ -98,22 +96,32 @@ struct RsGxsCircleGroup : RsSerializable
~RsGxsCircleGroup() override;
};
enum class RsGxsCircleSubscriptionType:uint8_t {
UNKNOWN = 0x00,
SUBSCRIBE = 0x01,
UNSUBSCRIBE = 0x02
};
struct RsGxsCircleMsg : RsSerializable
{
RsMsgMetaData mMeta;
#ifdef TO_REMOVE
// This item is actually totally unused, so we can change it no problem
#ifndef V07_NON_BACKWARD_COMPATIBLE_CHANGE_UNNAMED
/* This is horrible and should be changed into yet to be defined something
* reasonable in next non-retrocompatible version */
std::string stuff;
#endif
#endif
RsGxsCircleSubscriptionType mSubscriptionType;
/// @see RsSerializable
void serial_process( RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx) override
{
RS_SERIAL_PROCESS(mMeta);
RS_SERIAL_PROCESS(stuff);
RS_SERIAL_PROCESS(mSubscriptionType);
}
~RsGxsCircleMsg() override;
@ -121,15 +129,29 @@ struct RsGxsCircleMsg : RsSerializable
struct RsGxsCircleDetails : RsSerializable
{
RsGxsCircleDetails() :
mCircleType(static_cast<uint32_t>(RsGxsCircleType::EXTERNAL)),
mAmIAllowed(false),mAmIAdmin(false) {}
RsGxsCircleDetails() : mCircleType(RsGxsCircleType::EXTERNAL), mAmIAllowed(false),mAmIAdmin(false) {}
~RsGxsCircleDetails() override;
// helper functions.
bool isIdInCircle(const RsGxsId& id) const { return mAllowedGxsIds.find(id) != mAllowedGxsIds.end(); }
bool isIdInInviteeList(const RsGxsId& id) const
{
auto it = mSubscriptionFlags.find(id);
return (it != mSubscriptionFlags.end()) && (it->second & GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST );
}
bool isIdRequestingMembership(const RsGxsId& id) const
{
auto it = mSubscriptionFlags.find(id);
return it != mSubscriptionFlags.end() && (it->second & GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED );
}
bool isGxsIdBased() const { return mCircleType==RsGxsCircleType::PUBLIC || mCircleType==RsGxsCircleType::EXTERNAL || mCircleType==RsGxsCircleType::EXT_SELF; }
// Members
RsGxsCircleId mCircleId;
std::string mCircleName;
uint32_t mCircleType;
RsGxsCircleType mCircleType;
RsGxsCircleId mRestrictedCircleId;
/** true when one of load GXS ids belong to the circle allowed list (admin
@ -165,32 +187,54 @@ struct RsGxsCircleDetails : RsSerializable
enum class RsGxsCircleEventCode: uint8_t
{
// Notifications be only have 4 different possibilities:
//
// invitee list join/leave and
// membership request / leave request
//
// From there, depending on what the client displays, it is possible to interpret these
// as "some user joined the circle", or "membership pending for that Id", etc, depending
// on whether the current node owns the circle, or the admin is or is not yours.
//
// These should be decided in the UI based on what the circle cache is displaying.
//
UNKNOWN = 0x00,
/** mCircleId contains the circle id and mGxsId is the id requesting
* membership */
CIRCLE_MEMBERSHIP_REQUEST = 0x01,
/**
* Sent when we receive a membership request msg for a particular circle.
*
* mCircleId contains the circle id and mGxsId is the id requesting membership */
CIRCLE_MEMBERSHIP_REQUEST = 0x01,
/** mCircleId is the circle that invites me, and mGxsId is my own Id that is
* invited */
CIRCLE_MEMBERSHIP_INVITE = 0x02,
/**
* Sent when the ID has been added to the circle invitee list.
*
* mCircleId is the circle that invites me, and mGxsId is my own Id that is invited */
CIRCLE_MEMBERSHIP_ID_ADDED_TO_INVITEE_LIST = 0x02,
/** mCircleId contains the circle id and mGxsId is the id dropping
* membership */
CIRCLE_MEMBERSHIP_LEAVE = 0x03,
/**
* Sent when a GxsId annouces its will to not be in the circle.
*
* mCircleId contains the circle id and mGxsId is the id dropping membership */
CIRCLE_MEMBERSHIP_LEAVE = 0x03,
/// mCircleId contains the circle id and mGxsId is the id of the new member
CIRCLE_MEMBERSHIP_JOIN = 0x04,
/**
* Sent when the Id has been removed from the invitee list.
*
* mCircleId contains the circle id and mGxsId is the id that was revoqued * by admin */
CIRCLE_MEMBERSHIP_ID_REMOVED_FROM_INVITEE_LIST = 0x04,
/** mCircleId contains the circle id and mGxsId is the id that was revoqued * by admin */
CIRCLE_MEMBERSHIP_REVOQUED= 0x05,
/** mCircleId contains the circle id */
NEW_CIRCLE = 0x06,
/** no additional information. Simply means that the info previously from the cache has changed. */
CACHE_DATA_UPDATED = 0x07,
/**
* Means a new circle has been received.
*
* mCircleId contains the circle id */
NEW_CIRCLE = 0x05,
/**
* Means that the circle cache has updated, and membership status that is displayed should probably be updated to.
*
* no additional information. Simply means that the info previously from the cache has changed. */
CACHE_DATA_UPDATED = 0x06,
};
struct RsGxsCircleEvent: RsEvent

View file

@ -112,6 +112,7 @@ enum class RsForumEventCode: uint8_t
SUBSCRIBE_STATUS_CHANGED = 0x05, /// forum was subscribed or unsubscribed
READ_STATUS_CHANGED = 0x06, /// msg was read or marked unread
STATISTICS_CHANGED = 0x07, /// suppliers and how many messages they have changed
MODERATOR_LIST_CHANGED = 0x08, /// forum moderation list has changed.
};
struct RsGxsForumEvent: RsEvent
@ -123,6 +124,8 @@ struct RsGxsForumEvent: RsEvent
RsForumEventCode mForumEventCode;
RsGxsGroupId mForumGroupId;
RsGxsMessageId mForumMsgId;
std::list<RsGxsId> mModeratorsAdded;
std::list<RsGxsId> mModeratorsRemoved;
///* @see RsEvent @see RsSerializable
void serial_process(
@ -133,6 +136,9 @@ struct RsGxsForumEvent: RsEvent
RS_SERIAL_PROCESS(mForumEventCode);
RS_SERIAL_PROCESS(mForumGroupId);
RS_SERIAL_PROCESS(mForumMsgId);
RS_SERIAL_PROCESS(mForumMsgId);
RS_SERIAL_PROCESS(mModeratorsAdded);
RS_SERIAL_PROCESS(mModeratorsRemoved);
}
~RsGxsForumEvent() override;

View file

@ -116,12 +116,14 @@ struct RsGxsIface
*/
virtual uint16_t serviceType() const =0;
#ifdef TO_REMOVE
/*!
* Gxs services should call this for automatic handling of
* changes, send
* @param changes
*/
virtual void receiveChanges(std::vector<RsGxsNotify*>& changes) = 0;
#endif
/*!
* @return handle to token service for this GXS service

View file

@ -72,6 +72,7 @@ public:
~RsGxsIfaceHelper() = default;
#ifdef TO_REMOVE
/*!
* Gxs services should call this for automatic handling of
* changes, send
@ -81,6 +82,7 @@ public:
{
mGxs.receiveChanges(changes);
}
#endif
/* Generic Lists */

View file

@ -34,8 +34,6 @@
#include "serialiser/rstypeserializer.h"
#include "util/rstime.h"
typedef Sha1CheckSum RsGxsMessageId;
typedef std::map<RsGxsGroupId, std::set<RsGxsMessageId> > GxsMsgIdResult;
typedef std::pair<RsGxsGroupId, RsGxsMessageId> RsGxsGrpMsgIdPair;
typedef std::map<RsGxsGrpMsgIdPair, std::set<RsGxsMessageId> > MsgRelatedIdResult;

View file

@ -32,69 +32,6 @@ typedef uint32_t TurtleRequestId;
typedef std::map<RsGxsGroupId, std::vector<RsMsgMetaData> > GxsMsgMetaMap;
typedef std::map<RsGxsGrpMsgIdPair, std::vector<RsMsgMetaData> > GxsMsgRelatedMetaMap;
/*!
* The aim of this class is to abstract how changes are represented so they can
* be determined outside the client API without explcitly enumerating all
* possible changes at the interface
*/
struct RsGxsNotify
{
enum NotifyType
{
TYPE_UNKNOWN = 0x00,
TYPE_PUBLISHED = 0x01,
TYPE_RECEIVED_NEW = 0x02,
TYPE_PROCESSED = 0x03,
TYPE_RECEIVED_PUBLISHKEY = 0x04,
TYPE_RECEIVED_DISTANT_SEARCH_RESULTS = 0x05,
TYPE_STATISTICS_CHANGED = 0x06
};
virtual ~RsGxsNotify() {}
virtual NotifyType getType() = 0;
};
/*!
* Relevant to group changes
*/
class RsGxsGroupChange : public RsGxsNotify
{
public:
RsGxsGroupChange(NotifyType type, bool metaChange) : NOTIFY_TYPE(type), mMetaChange(metaChange) {}
std::list<RsGxsGroupId> mGrpIdList;
NotifyType getType(){ return NOTIFY_TYPE;}
bool metaChange() { return mMetaChange; }
private:
const NotifyType NOTIFY_TYPE;
bool mMetaChange;
};
class RsGxsDistantSearchResultChange: public RsGxsNotify
{
public:
RsGxsDistantSearchResultChange(TurtleRequestId id,const RsGxsGroupId& group_id) : mRequestId(id),mGroupId(group_id){}
NotifyType getType() { return TYPE_RECEIVED_DISTANT_SEARCH_RESULTS ; }
TurtleRequestId mRequestId ;
RsGxsGroupId mGroupId;
};
/*!
* Relevant to message changes
*/
class RsGxsMsgChange : public RsGxsNotify
{
public:
RsGxsMsgChange(NotifyType type, bool metaChange) : NOTIFY_TYPE(type), mMetaChange(metaChange) {}
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > msgChangeMap;
NotifyType getType(){ return NOTIFY_TYPE;}
bool metaChange() { return mMetaChange; }
private:
const NotifyType NOTIFY_TYPE;
bool mMetaChange;
};
#endif // RSGXSSERVICE_H

View file

@ -328,6 +328,7 @@ using Sha256CheckSum = t_RsGenericIdType<_RsIdSize::SHA256 , false, R
using RsPgpFingerprint = t_RsGenericIdType<_RsIdSize::PGP_FINGERPRINT, true, RsGenericIdType::PGP_FINGERPRINT>;
using Bias20Bytes = t_RsGenericIdType<_RsIdSize::SHA1 , true, RsGenericIdType::BIAS_20_BYTES >;
using RsGxsGroupId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_GROUP >;
using RsGxsMessageId = t_RsGenericIdType<_RsIdSize::SHA1 , false, RsGenericIdType::GXS_MSG >;
using RsGxsId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_ID >;
using RsGxsCircleId = t_RsGenericIdType<_RsIdSize::CERT_SIGN , false, RsGenericIdType::GXS_CIRCLE >;
using RsGxsTunnelId = t_RsGenericIdType<_RsIdSize::SSL_ID , false, RsGenericIdType::GXS_TUNNEL >;

View file

@ -115,11 +115,13 @@ const uint32_t RS_FEED_ITEM_CHAT_NEW = RS_FEED_TYPE_CHAT | 0x0001;
const uint32_t RS_FEED_ITEM_MESSAGE = RS_FEED_TYPE_MSG | 0x0001;
const uint32_t RS_FEED_ITEM_FILES_NEW = RS_FEED_TYPE_FILES | 0x0001;
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REQ = RS_FEED_TYPE_CIRCLE | 0x0001;
const uint32_t RS_FEED_ITEM_CIRCLE_INVIT_REC = RS_FEED_TYPE_CIRCLE | 0x0002;
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_LEAVE = RS_FEED_TYPE_CIRCLE | 0x0003;
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_JOIN = RS_FEED_TYPE_CIRCLE | 0x0004;
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REVOQUED = RS_FEED_TYPE_CIRCLE | 0x0005;
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REQ = RS_FEED_TYPE_CIRCLE | 0x0001;
const uint32_t RS_FEED_ITEM_CIRCLE_INVITE_REC = RS_FEED_TYPE_CIRCLE | 0x0002;
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_LEAVE = RS_FEED_TYPE_CIRCLE | 0x0003;
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_JOIN = RS_FEED_TYPE_CIRCLE | 0x0004;
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_ACCEPTED = RS_FEED_TYPE_CIRCLE | 0x0005;
const uint32_t RS_FEED_ITEM_CIRCLE_MEMB_REVOKED = RS_FEED_TYPE_CIRCLE | 0x0006;
const uint32_t RS_FEED_ITEM_CIRCLE_INVITE_CANCELLED= RS_FEED_TYPE_CIRCLE | 0x0007;
const uint32_t RS_MESSAGE_CONNECT_ATTEMPT = 0x0001;

View file

@ -38,7 +38,6 @@
#define USE_NEW_CHUNK_CHECKING_CODE
typedef Sha1CheckSum RsFileHash ;
typedef Sha1CheckSum RsMessageId ;
const uint32_t FT_STATE_FAILED = 0x0000 ;
const uint32_t FT_STATE_OKAY = 0x0001 ;

View file

@ -35,7 +35,9 @@ RsItem *RsGxsCircleSerialiser::create_item(uint16_t service, uint8_t item_sub_id
switch(item_sub_id)
{
case RS_PKT_SUBTYPE_GXSCIRCLE_GROUP_ITEM: return new RsGxsCircleGroupItem();
#ifdef TO_REMOVE
case RS_PKT_SUBTYPE_GXSCIRCLE_MSG_ITEM: return new RsGxsCircleMsgItem();
#endif
case RS_PKT_SUBTYPE_GXSCIRCLE_SUBSCRIPTION_REQUEST_ITEM: return new RsGxsCircleSubscriptionRequestItem();
default:
return NULL ;
@ -46,20 +48,27 @@ void RsGxsCircleSubscriptionRequestItem::clear()
{
time_stamp = 0 ;
time_out = 0 ;
subscription_type = SUBSCRIPTION_REQUEST_UNKNOWN;
subscription_type = RsGxsCircleSubscriptionType::UNKNOWN;
}
#ifdef TO_REMOVE
void RsGxsCircleMsgItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
//RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,mMsg.stuff,"mMsg.stuff") ;//Should be this but not retrocompatible...
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_MSG,mMsg.stuff,"msg.stuff") ;
}
void RsGxsCircleMsgItem::clear()
{
mMsg.stuff.clear();
}
#endif
void RsGxsCircleSubscriptionRequestItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
{
RsTypeSerializer::serial_process<uint32_t>(j,ctx,time_stamp,"time_stamp") ;
RsTypeSerializer::serial_process<uint32_t>(j,ctx,time_out ,"time_out") ;
RsTypeSerializer::serial_process<uint8_t> (j,ctx,subscription_type ,"subscription_type") ;
RsTypeSerializer::serial_process<RsGxsCircleSubscriptionType> (j,ctx,subscription_type ,"subscription_type") ;
}
void RsGxsCircleGroupItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
@ -69,11 +78,6 @@ void RsGxsCircleGroupItem::serial_process(RsGenericSerializer::SerializeJob j,Rs
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,subCircleSet,"subCircleSet") ;
}
void RsGxsCircleMsgItem::clear()
{
mMsg.stuff.clear();
}
void RsGxsCircleGroupItem::clear()
{
pgpIdSet.TlvClear();

View file

@ -64,6 +64,7 @@ public:
RsTlvGxsCircleIdSet subCircleSet;
};
#ifdef TO_REMOVE
class RsGxsCircleMsgItem : public RsGxsMsgItem
{
public:
@ -76,6 +77,7 @@ public:
RsGxsCircleMsg mMsg;
};
#endif
class RsGxsCircleSubscriptionRequestItem: public RsGxsMsgItem
{
@ -86,17 +88,11 @@ public:
void clear();
enum {
SUBSCRIPTION_REQUEST_UNKNOWN = 0x00,
SUBSCRIPTION_REQUEST_SUBSCRIBE = 0x01,
SUBSCRIPTION_REQUEST_UNSUBSCRIBE = 0x02
};
virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx);
uint32_t time_stamp ;
uint32_t time_out ;
uint8_t subscription_type ;
RsGxsCircleSubscriptionType subscription_type ;
};
class RsGxsCircleSerialiser : public RsServiceSerializer

View file

@ -92,11 +92,15 @@ template<class ID_CLASS,uint32_t TLV_TYPE> class RS_DEPRECATED_FOR(std::set<>) t
ids.insert(id) ;
}
if(*offset != tlvend)
{
std::cerr << "(EE) deserialisaiton error in " << __PRETTY_FUNCTION__ << std::endl;
else if(!ok)
ok = false;
}
if(!ok)
std::cerr << "(WW) something wrong in ID_CLASS.deserialise in " << __PRETTY_FUNCTION__ << std::endl;
return *offset == tlvend ;
return ok;
}
virtual std::ostream &print(std::ostream &out, uint16_t /* indent */) const
{

View file

@ -239,7 +239,7 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
#endif
/* iterate through and grab any new messages */
std::list<RsGxsGroupId> unprocessedGroups;
std::set<RsGxsGroupId> unprocessedGroups;
std::vector<RsGxsNotify *>::iterator it;
for(it = changes.begin(); it != changes.end(); ++it)
@ -253,16 +253,12 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
/* message received */
if (rsEvents)
{
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
for (auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
for (auto mit1 = mit->second.begin(); mit1 != mit->second.end(); ++mit1)
{
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelMsgId = *mit1;
ev->mChannelGroupId = mit->first;
ev->mChannelEventCode = RsChannelEventCode::NEW_MESSAGE;
rsEvents->postEvent(ev);
}
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelMsgId = msgChange->mMsgId;
ev->mChannelGroupId = msgChange->mGroupId;
ev->mChannelEventCode = RsChannelEventCode::NEW_MESSAGE;
rsEvents->postEvent(ev);
}
}
@ -273,25 +269,21 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
std::cerr << std::endl;
#endif
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
for(auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
#ifdef GXSCHANNELS_DEBUG
std::cerr << "p3GxsChannels::notifyChanges() Msgs for Group: " << mit->first;
std::cerr << std::endl;
#endif
{
#ifdef GXSCHANNELS_DEBUG
std::cerr << "p3GxsChannels::notifyChanges() Msgs for Group: " << mit->first;
std::cerr << "p3GxsChannels::notifyChanges() AutoDownload for Group: " << mit->first;
std::cerr << std::endl;
#endif
bool enabled = false;
if (autoDownloadEnabled(mit->first, enabled) && enabled)
{
#ifdef GXSCHANNELS_DEBUG
std::cerr << "p3GxsChannels::notifyChanges() AutoDownload for Group: " << mit->first;
std::cerr << std::endl;
#endif
/* problem is most of these will be comments and votes,
* should make it occasional - every 5mins / 10minutes TODO */
unprocessedGroups.push_back(mit->first);
}
/* problem is most of these will be comments and votes, should make it occasional - every 5mins / 10minutes TODO */
// We do not call if(autoDownLoadEnabled()) here, because it would be too costly when
// many msgs are received from the same group. We back the groupIds and then request one by one.
unprocessedGroups.insert(msgChange->mGroupId);
}
}
}
@ -304,71 +296,52 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
{
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = *git;
ev->mChannelEventCode = RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED;
rsEvents->postEvent(ev);
}
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = grpChange->mGroupId;
ev->mChannelEventCode = RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED;
rsEvents->postEvent(ev);
}
break;
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = *git;
ev->mChannelEventCode = RsChannelEventCode::STATISTICS_CHANGED;
rsEvents->postEvent(ev);
}
}
{
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = grpChange->mGroupId;
ev->mChannelEventCode = RsChannelEventCode::STATISTICS_CHANGED;
rsEvents->postEvent(ev);
}
break;
case RsGxsNotify::TYPE_PUBLISHED:
case RsGxsNotify::TYPE_RECEIVED_NEW:
{
/* group received */
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
RS_STACK_MUTEX(mKnownChannelsMutex);
for (git = grpList.begin(); git != grpList.end(); ++git)
{
if(mKnownChannels.find(*git) == mKnownChannels.end())
{
mKnownChannels.insert(std::make_pair(*git,time(NULL))) ;
IndicateConfigChanged();
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = *git;
ev->mChannelEventCode = RsChannelEventCode::NEW_CHANNEL;
rsEvents->postEvent(ev);
}
else
std::cerr << "(II) Not notifying already known channel " << *git << std::endl;
RS_STACK_MUTEX(mKnownChannelsMutex);
if(mKnownChannels.find(grpChange->mGroupId) == mKnownChannels.end())
{
mKnownChannels.insert(std::make_pair(grpChange->mGroupId,time(NULL))) ;
IndicateConfigChanged();
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = grpChange->mGroupId;
ev->mChannelEventCode = RsChannelEventCode::NEW_CHANNEL;
rsEvents->postEvent(ev);
}
break;
else
std::cerr << "(II) Not notifying already known channel " << grpChange->mGroupId << std::endl;
}
break;
case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY:
{
/* group received */
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = *git;
ev->mChannelEventCode = RsChannelEventCode::RECEIVED_PUBLISH_KEY;
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = grpChange->mGroupId;
ev->mChannelEventCode = RsChannelEventCode::RECEIVED_PUBLISH_KEY;
rsEvents->postEvent(ev);
}
rsEvents->postEvent(ev);
}
break;
@ -395,8 +368,16 @@ void p3GxsChannels::notifyChanges(std::vector<RsGxsNotify *> &changes)
delete *it;
}
if(!unprocessedGroups.empty())
request_SpecificSubscribedGroups(unprocessedGroups);
std::list<RsGxsGroupId> grps;
for(auto& grp_id:unprocessedGroups)
{
bool enabled = false;
if (autoDownloadEnabled(grp_id, enabled) && enabled) // costly call, that's why it's packed down here.
grps.push_back(grp_id);
}
if(!grps.empty())
request_SpecificSubscribedGroups(grps);
}
void p3GxsChannels::service_tick()
@ -724,8 +705,7 @@ void p3GxsChannels::request_AllSubscribedGroups()
}
void p3GxsChannels::request_SpecificSubscribedGroups(
const std::list<RsGxsGroupId> &groups )
void p3GxsChannels::request_SpecificSubscribedGroups( const std::list<RsGxsGroupId> &groups )
{
#ifdef GXSCHANNELS_DEBUG
std::cerr << "p3GxsChannels::request_SpecificSubscribedGroups()";
@ -738,8 +718,7 @@ void p3GxsChannels::request_SpecificSubscribedGroups(
uint32_t token = 0;
if(!RsGenExchange::getTokenService()->
requestGroupInfo(token, ansType, opts, groups))
if(!RsGenExchange::getTokenService()-> requestGroupInfo(token, ansType, opts, groups))
{
std::cerr << __PRETTY_FUNCTION__ << " Failed requesting groups info!"
<< std::endl;

File diff suppressed because it is too large Load diff

View file

@ -128,11 +128,20 @@ public:
uint32_t subscription_flags ; // combination of GXS_EXTERNAL_CIRCLE_FLAGS_IN_ADMIN_LIST and GXS_EXTERNAL_CIRCLE_FLAGS_SUBSCRIBED
};
enum CircleEntryCacheStatus: uint8_t {
UNKNOWN = 0x00, // Used to detect uninitialized memory
NO_DATA_YET = 0x01, // Used in the constuctor
LOADING = 0x02, // When the token request to load cache has been sent and no data is present
UPDATING = 0x03, // Starting from this level the cache entry can be used
CHECKING_MEMBERSHIP = 0x04, // Means we're actually looking into msgs to update membership status
UP_TO_DATE = 0x05 // Everything should be loaded here.
};
class RsGxsCircleCache
{
public:
public:
RsGxsCircleCache();
bool loadBaseCircle(const RsGxsCircleGroup &circle);
bool loadSubCircle(const RsGxsCircleCache &subcircle);
@ -142,33 +151,62 @@ class RsGxsCircleCache
bool addAllowedPeer(const RsPgpId &pgpid);
bool addLocalFriend(const RsPgpId &pgpid);
// Cache related data
rstime_t mLastUpdatedMembershipTS ; // Last time the subscribe messages have been requested. Should be reset when new messages arrive.
rstime_t mLastUpdateTime; // Last time the cache entry was loaded
CircleEntryCacheStatus mStatus; // Overall state of the cache entry
bool mAllIdsHere ; // True when all ids are knwon and available.
// GxsCircle related data
RsGxsCircleId mCircleId;
std::string mCircleName;
uint32_t mCircleType;
RsGxsCircleType mCircleType;
bool mIsExternal;
RsGxsCircleId mRestrictedCircleId ; // circle ID that circle is restricted to.
RsGxsCircleId mRestrictedCircleId ; // circle ID that circle is restricted to.
uint32_t mGroupStatus;
uint32_t mGroupSubscribeFlags;
rstime_t mUpdateTime;
#ifdef SUBSCIRCLES
std::set<RsGxsCircleId> mUnprocessedCircles;
std::set<RsGxsCircleId> mProcessedCircles;
#endif
std::map<RsGxsId,RsGxsCircleMembershipStatus> mMembershipStatus;
rstime_t mLastUpdatedMembershipTS ; // last time the subscribe messages have been requested. Should be reset when new messages arrive.
std::set<RsGxsId> mAllowedGxsIds; // IDs that are allowed in the circle and have requested membership. This is the official members list.
std::set<RsPgpId> mAllowedNodes;
RsPeerId mOriginator ; // peer who sent the data, in case we need to ask for ids
RsPeerId mOriginator ; // peer who sent the data, in case we need to ask for ids
};
class PgpAuxUtils;
class RsCirclesMemCache : public std::map<RsGxsCircleId,RsGxsCircleCache>
{
public:
RsCirclesMemCache() : std::map<RsGxsCircleId,RsGxsCircleCache>(){}
bool is_cached(const RsGxsCircleId& id) { return end() != find(id) ; }
RsGxsCircleCache& ref(const RsGxsCircleId& id) { return operator[](id) ; }
void printStats() { std::cerr << "CircleMemCache: " << size() << " elements." << std::endl; }
template<class ClientClass> void applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(RsGxsCircleCache&))
{
for(auto& it:*this)
(c.*method)(it.second);
}
template<class ClientClass> void applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(const RsGxsCircleCache&))
{
for(const auto& it:*this)
(c.*method)(it.second);
}
};
class p3GxsCircles: public RsGxsCircleExchange, public RsGxsCircles,
public GxsTokenQueue, public RsTickEvent
{
@ -264,7 +302,7 @@ public:
protected:
bool pushCircleMembershipRequest(const RsGxsId& own_gxsid,const RsGxsCircleId& circle_id,uint32_t request_type) ;
bool pushCircleMembershipRequest(const RsGxsId& own_gxsid, const RsGxsCircleId& circle_id, RsGxsCircleSubscriptionType request_type) ;
static uint32_t circleAuthenPolicy();
/** Notifications **/
@ -319,20 +357,18 @@ public:
std::list<RsGxsCircleId> mCirclePersonalIdList;
/***** Caching Circle Info, *****/
// initial load queue
std::list<RsGxsCircleId> mCacheLoad_ToCache;
// waiting for subcircle to load. (first is part of each of the second list)
// TODO.
//std::map<RsGxsCircleId, std::list<RsGxsCircleId> > mCacheLoad_SubCircle;
// Circles that are being loaded.
std::map<RsGxsCircleId, RsGxsCircleCache> mLoadingCache;
std::set<RsGxsCircleId> mCirclesToLoad; // list of circles to update/load, so that we can treat them by groups.
RsCirclesMemCache mCircleCache;
//RsMemCache<RsGxsCircleId, RsGxsCircleCache> mCircleCache; // actual cache data
// actual cache.
RsMemCache<RsGxsCircleId, RsGxsCircleCache> mCircleCache;
private:
void debug_dumpCache(); // debug method to overview what's going on
bool debug_dumpCacheEntry(RsGxsCircleCache &cache);
private:
std::string genRandomId();
@ -345,8 +381,9 @@ public:
uint32_t mDummyIdToken;
std::list<RsGxsId> mDummyPgpLinkedIds;
std::list<RsGxsId> mDummyOwnIds;
bool mCacheUpdated ;
bool mShouldSendCacheUpdateNotification ;
rstime_t mLastCacheUpdateEvent;
rstime_t mLastDebugPrintTS;
RS_SET_CONTEXT_DEBUG_LEVEL(2)
};

View file

@ -189,21 +189,17 @@ void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
for(it = changes.begin(); it != changes.end(); ++it)
{
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(*it);
if (msgChange)
{
if (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW || msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED) /* message received */
if (rsEvents)
{
std::map<RsGxsGroupId, std::set<RsGxsMessageId> >& msgChangeMap = msgChange->msgChangeMap;
for (auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
for (auto mit1 = mit->second.begin(); mit1 != mit->second.end(); ++mit1)
{
auto ev = std::make_shared<RsGxsForumEvent>();
ev->mForumMsgId = *mit1;
ev->mForumGroupId = mit->first;
ev->mForumEventCode = RsForumEventCode::NEW_MESSAGE;
rsEvents->postEvent(ev);
}
auto ev = std::make_shared<RsGxsForumEvent>();
ev->mForumMsgId = msgChange->mMsgId;
ev->mForumGroupId = msgChange->mGroupId;
ev->mForumEventCode = RsForumEventCode::NEW_MESSAGE;
rsEvents->postEvent(ev);
}
#ifdef NOT_USED_YET
@ -248,16 +244,10 @@ void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
{
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsForumEvent>();
ev->mForumGroupId = *git;
ev->mForumGroupId = grpChange->mGroupId;
ev->mForumEventCode = RsForumEventCode::SUBSCRIBE_STATUS_CHANGED;
rsEvents->postEvent(ev);
}
}
break;
@ -265,67 +255,79 @@ void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
case RsGxsNotify::TYPE_RECEIVED_NEW:
{
/* group received */
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
RS_STACK_MUTEX(mKnownForumsMutex);
for (git = grpList.begin(); git != grpList.end(); ++git)
{
if(mKnownForums.find(*git) == mKnownForums.end())
{
mKnownForums.insert(
std::make_pair(*git, time(nullptr)));
IndicateConfigChanged();
auto ev = std::make_shared<RsGxsForumEvent>();
ev->mForumGroupId = *git;
ev->mForumEventCode = RsForumEventCode::NEW_FORUM;
rsEvents->postEvent(ev);
}
else
RsInfo() << __PRETTY_FUNCTION__
<< " Not notifying already known forum "
<< *git << std::endl;
if(mKnownForums.find(grpChange->mGroupId) == mKnownForums.end())
{
mKnownForums.insert( std::make_pair(grpChange->mGroupId, time(nullptr)));
IndicateConfigChanged();
auto ev = std::make_shared<RsGxsForumEvent>();
ev->mForumGroupId = grpChange->mGroupId;
ev->mForumEventCode = RsForumEventCode::NEW_FORUM;
rsEvents->postEvent(ev);
}
else
RsInfo() << __PRETTY_FUNCTION__
<< " Not notifying already known forum "
<< grpChange->mGroupId << std::endl;
}
break;
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
auto ev = std::make_shared<RsGxsForumEvent>();
ev->mForumGroupId = grpChange->mGroupId;
ev->mForumEventCode = RsForumEventCode::STATISTICS_CHANGED;
rsEvents->postEvent(ev);
}
break;
case RsGxsNotify::TYPE_UPDATED:
{
// Happens when the group data has changed. In this case we need to analyse the old and new group in order to detect possible notifications for clients
RsGxsForumGroupItem *old_forum_grp_item = dynamic_cast<RsGxsForumGroupItem*>(grpChange->mOldGroupItem);
RsGxsForumGroupItem *new_forum_grp_item = dynamic_cast<RsGxsForumGroupItem*>(grpChange->mNewGroupItem);
if(old_forum_grp_item == nullptr || new_forum_grp_item == nullptr)
{
RsErr() << __PRETTY_FUNCTION__ << " received GxsGroupUpdate item with mOldGroup and mNewGroup not of type RsGxsForumGroupItem. This is inconsistent!" << std::endl;
delete grpChange;
continue;
}
// First of all, we check if there is a difference between the old and new list of moderators
std::list<RsGxsId> added_mods, removed_mods;
for(auto& gxs_id: new_forum_grp_item->mGroup.mAdminList.ids)
if(old_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) == old_forum_grp_item->mGroup.mAdminList.ids.end())
added_mods.push_back(gxs_id);
for(auto& gxs_id: old_forum_grp_item->mGroup.mAdminList.ids)
if(new_forum_grp_item->mGroup.mAdminList.ids.find(gxs_id) == new_forum_grp_item->mGroup.mAdminList.ids.end())
removed_mods.push_back(gxs_id);
if(!added_mods.empty() || !removed_mods.empty())
{
auto ev = std::make_shared<RsGxsForumEvent>();
ev->mForumGroupId = *git;
ev->mForumEventCode = RsForumEventCode::STATISTICS_CHANGED;
ev->mForumGroupId = new_forum_grp_item->meta.mGroupId;
ev->mModeratorsAdded = added_mods;
ev->mModeratorsRemoved = removed_mods;
ev->mForumEventCode = RsForumEventCode::MODERATOR_LIST_CHANGED;
rsEvents->postEvent(ev);
}
}
break;
break;
default:
RsErr() << " Got a GXS event of type " << grpChange->getType() << " Currently not handled." << std::endl;
break;
#ifdef NOT_USED_YET
case RsGxsNotify::TYPE_RECEIVED_PUBLISHKEY:
{
/* group received */
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsChannelEvent>();
ev->mChannelGroupId = *git;
ev->mChannelEventCode = RsGxsChannelEvent::RECEIVED_PUBLISH_KEY;
rsEvents->sendEvent(ev);
}
}
break;
#endif
}
}
}

View file

@ -606,22 +606,7 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
RsGxsMsgChange *msgChange = dynamic_cast<RsGxsMsgChange *>(changes[i]);
if (msgChange && !msgChange->metaChange())
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::notifyChanges() Found Message Change Notification";
std::cerr << std::endl;
#endif
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
for(auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::notifyChanges() Msgs for Group: " << mit->first;
std::cerr << std::endl;
#endif
}
}
RsWarn() << __PRETTY_FUNCTION__ << " Found a Msg data change in p3IdService. This is quite unexpected." << std::endl;
RsGxsGroupChange *groupChange = dynamic_cast<RsGxsGroupChange *>(changes[i]);
@ -631,16 +616,13 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
std::cerr << "p3IdService::notifyChanges() Found Group Change Notification";
std::cerr << std::endl;
#endif
std::list<RsGxsGroupId> &groupList = groupChange->mGrpIdList;
for(auto git = groupList.begin(); git != groupList.end();++git)
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::notifyChanges() Auto Subscribe to Incoming Groups: " << *git;
std::cerr << std::endl;
#endif
const RsGxsGroupId& gid(groupChange->mGroupId);
if(!rsReputations->isIdentityBanned(RsGxsId(*git)))
if(!rsReputations->isIdentityBanned(RsGxsId(gid)))
{
// notify that a new identity is received, if needed
@ -654,12 +636,12 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
case RsGxsNotify::TYPE_PUBLISHED:
{
auto ev = std::make_shared<RsGxsIdentityEvent>();
ev->mIdentityId = *git;
ev->mIdentityId = gid;
ev->mIdentityEventCode = RsGxsIdentityEventCode::UPDATED_IDENTITY;
rsEvents->postEvent(ev);
// also time_stamp the key that this group represents
timeStampKey(RsGxsId(*git),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ;
timeStampKey(RsGxsId(gid),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ;
should_subscribe = true;
}
break;
@ -667,12 +649,12 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
case RsGxsNotify::TYPE_RECEIVED_NEW:
{
auto ev = std::make_shared<RsGxsIdentityEvent>();
ev->mIdentityId = *git;
ev->mIdentityId = gid;
ev->mIdentityEventCode = RsGxsIdentityEventCode::NEW_IDENTITY;
rsEvents->postEvent(ev);
// also time_stamp the key that this group represents
timeStampKey(RsGxsId(*git),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ;
timeStampKey(RsGxsId(gid),RsIdentityUsage(serviceType(),RsIdentityUsage::IDENTITY_DATA_UPDATE)) ;
should_subscribe = true;
}
break;
@ -684,11 +666,10 @@ void p3IdService::notifyChanges(std::vector<RsGxsNotify *> &changes)
if(should_subscribe)
{
uint32_t token;
RsGenExchange::subscribeToGroup(token, *git, true);
RsGenExchange::subscribeToGroup(token, gid, true);
}
}
}
}
delete changes[i];

View file

@ -98,27 +98,22 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
std::cerr << std::endl;
#endif
std::map<RsGxsGroupId, std::set<RsGxsMessageId> > &msgChangeMap = msgChange->msgChangeMap;
for(auto mit = msgChangeMap.begin(); mit != msgChangeMap.end(); ++mit)
{
#ifdef POSTBASE_DEBUG
std::cerr << "p3PostBase::notifyChanges() Msgs for Group: " << mit->first;
std::cerr << std::endl;
std::cerr << "p3PostBase::notifyChanges() Msgs for Group: " << mit->first;
std::cerr << std::endl;
#endif
// To start with we are just going to trigger updates on these groups.
// FUTURE OPTIMISATION.
// It could be taken a step further and directly request these msgs for an update.
addGroupForProcessing(mit->first);
// To start with we are just going to trigger updates on these groups.
// FUTURE OPTIMISATION.
// It could be taken a step further and directly request these msgs for an update.
addGroupForProcessing(msgChange->mGroupId);
if (rsEvents && (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW || msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED))
for (auto mit1 = mit->second.begin(); mit1 != mit->second.end(); ++mit1)
{
auto ev = std::make_shared<RsGxsPostedEvent>();
ev->mPostedMsgId = *mit1;
ev->mPostedGroupId = mit->first;
ev->mPostedEventCode = RsPostedEventCode::NEW_MESSAGE;
rsEvents->postEvent(ev);
}
if (rsEvents && (msgChange->getType() == RsGxsNotify::TYPE_RECEIVED_NEW || msgChange->getType() == RsGxsNotify::TYPE_PUBLISHED))
{
auto ev = std::make_shared<RsGxsPostedEvent>();
ev->mPostedMsgId = msgChange->mMsgId;
ev->mPostedGroupId = msgChange->mGroupId;
ev->mPostedEventCode = RsPostedEventCode::NEW_MESSAGE;
rsEvents->postEvent(ev);
}
}
@ -131,36 +126,25 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
std::cerr << "p3PostBase::notifyChanges() Found Group Change Notification";
std::cerr << std::endl;
#endif
const RsGxsGroupId& group_id(grpChange->mGroupId);
switch(grpChange->getType())
{
case RsGxsNotify::TYPE_PROCESSED: // happens when the group is subscribed
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsPostedEvent>();
ev->mPostedGroupId = *git;
ev->mPostedEventCode = RsPostedEventCode::SUBSCRIBE_STATUS_CHANGED;
rsEvents->postEvent(ev);
}
auto ev = std::make_shared<RsGxsPostedEvent>();
ev->mPostedGroupId = group_id;
ev->mPostedEventCode = RsPostedEventCode::SUBSCRIBE_STATUS_CHANGED;
rsEvents->postEvent(ev);
}
break;
case RsGxsNotify::TYPE_STATISTICS_CHANGED:
{
std::list<RsGxsGroupId> &grpList = grpChange->mGrpIdList;
std::list<RsGxsGroupId>::iterator git;
for (git = grpList.begin(); git != grpList.end(); ++git)
{
auto ev = std::make_shared<RsGxsPostedEvent>();
ev->mPostedGroupId = *git;
ev->mPostedEventCode = RsPostedEventCode::STATISTICS_CHANGED;
rsEvents->postEvent(ev);
}
auto ev = std::make_shared<RsGxsPostedEvent>();
ev->mPostedGroupId = group_id;
ev->mPostedEventCode = RsPostedEventCode::STATISTICS_CHANGED;
rsEvents->postEvent(ev);
}
break;
@ -168,30 +152,26 @@ void p3PostBase::notifyChanges(std::vector<RsGxsNotify *> &changes)
case RsGxsNotify::TYPE_RECEIVED_NEW:
{
/* group received */
const std::list<RsGxsGroupId>& grpList = grpChange->mGrpIdList;
for (auto git = grpList.begin(); git != grpList.end(); ++git)
if(mKnownPosted.find(group_id) == mKnownPosted.end())
{
if(mKnownPosted.find(*git) == mKnownPosted.end())
{
mKnownPosted.insert(std::make_pair(*git, time(nullptr)));
IndicateConfigChanged();
mKnownPosted.insert(std::make_pair(group_id, time(nullptr)));
IndicateConfigChanged();
auto ev = std::make_shared<RsGxsPostedEvent>();
ev->mPostedGroupId = *git;
ev->mPostedEventCode = RsPostedEventCode::NEW_POSTED_GROUP;
rsEvents->postEvent(ev);
auto ev = std::make_shared<RsGxsPostedEvent>();
ev->mPostedGroupId = group_id;
ev->mPostedEventCode = RsPostedEventCode::NEW_POSTED_GROUP;
rsEvents->postEvent(ev);
#ifdef POSTBASE_DEBUG
std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << *git;
std::cerr << std::endl;
std::cerr << "p3PostBase::notifyChanges() Incoming Group: " << group_id;
std::cerr << std::endl;
#endif
}
else
RsInfo() << __PRETTY_FUNCTION__
<< " Not notifying already known forum "
<< *git << std::endl;
}
else
RsInfo() << __PRETTY_FUNCTION__
<< " Not notifying already known forum "
<< group_id << std::endl;
}
break;
@ -351,11 +331,7 @@ void p3PostBase::addGroupForProcessing(RsGxsGroupId grpId)
{
RsStackMutex stack(mPostBaseMtx); /********** STACK LOCKED MTX ******/
// no point having multiple lookups queued.
if (mBgGroupList.end() == std::find(mBgGroupList.begin(),
mBgGroupList.end(), grpId))
{
mBgGroupList.push_back(grpId);
}
mBgGroupList.insert(grpId);
}
}
@ -388,8 +364,8 @@ void p3PostBase::background_requestUnprocessedGroup()
return;
}
grpId = mBgGroupList.front();
mBgGroupList.pop_front();
grpId = *mBgGroupList.begin();
mBgGroupList.erase(grpId);
mBgProcessing = true;
}
@ -483,8 +459,6 @@ void p3PostBase::background_loadMsgs(const uint32_t &token, bool unprocessed)
// generate vector of changes to push to the GUI.
std::vector<RsGxsNotify *> changes;
RsGxsMsgChange *msgChanges = new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, false);
RsGxsGroupId groupId;
std::map<RsGxsGroupId, std::vector<RsGxsMsgItem*> >::iterator mit;
@ -535,7 +509,7 @@ void p3PostBase::background_loadMsgs(const uint32_t &token, bool unprocessed)
#endif
/* but we need to notify GUI about them */
msgChanges->msgChangeMap[mit->first].insert((*vit)->meta.mMsgId);
changes.push_back(new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, mit->first,(*vit)->meta.mMsgId, false));
}
else if (NULL != (commentItem = dynamic_cast<RsGxsCommentItem *>(*vit)))
{
@ -631,22 +605,7 @@ void p3PostBase::background_loadMsgs(const uint32_t &token, bool unprocessed)
}
/* push updates of new Posts */
if (msgChanges->msgChangeMap.size() > 0)
{
#ifdef POSTBASE_DEBUG
std::cerr << "p3PostBase::background_processNewMessages() -> receiveChanges()";
std::cerr << std::endl;
#endif
changes.push_back(msgChanges);
//receiveHelperChanges(changes);
notifyChanges(changes);
}
else
{
delete(msgChanges);
}
notifyChanges(changes);
/* request the summary info from the parents */
uint32_t token_b;
@ -711,7 +670,6 @@ void p3PostBase::background_updateVoteCounts(const uint32_t &token)
// generate vector of changes to push to the GUI.
std::vector<RsGxsNotify *> changes;
RsGxsMsgChange *msgChanges = new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED, false);
for(mit = parentMsgList.begin(); mit != parentMsgList.end(); ++mit)
{
@ -754,7 +712,8 @@ void p3PostBase::background_updateVoteCounts(const uint32_t &token)
#endif
stats.increment(it->second);
msgChanges->msgChangeMap[mit->first].insert(vit->mMsgId);
changes.push_back(new RsGxsMsgChange(RsGxsNotify::TYPE_PROCESSED,mit->first,vit->mMsgId, false));
}
else
{
@ -786,21 +745,7 @@ void p3PostBase::background_updateVoteCounts(const uint32_t &token)
}
}
if (msgChanges->msgChangeMap.size() > 0)
{
#ifdef POSTBASE_DEBUG
std::cerr << "p3PostBase::background_updateVoteCounts() -> receiveChanges()";
std::cerr << std::endl;
#endif
changes.push_back(msgChanges);
//receiveHelperChanges(changes);
notifyChanges(changes);
}
else
{
delete(msgChanges);
}
notifyChanges(changes);
// DONE!.
background_cleanup();

View file

@ -125,7 +125,7 @@ private:
bool mBgProcessing;
bool mBgIncremental;
std::list<RsGxsGroupId> mBgGroupList;
std::set<RsGxsGroupId> mBgGroupList;
std::map<RsGxsMessageId, PostStats> mBgStatsMap;
std::map<RsGxsGroupId,rstime_t> mKnownPosted;

View file

@ -53,10 +53,12 @@ virtual void notifyChanges(std::vector<RsGxsNotify*>& changes)
public:
#ifdef TO_REMOVE
virtual void receiveHelperChanges(std::vector<RsGxsNotify*>& changes)
{
return RsGxsIfaceHelper::receiveChanges(changes);
}
#endif
bool getBoardsInfo(const std::list<RsGxsGroupId>& boardsIds,
std::vector<RsPostedGroup>& groupsInfo ) override;

View file

@ -60,7 +60,12 @@ public:
bool is_cached(const Key &key) const;
bool fetch(const Key &key, Value &data);
Value &ref(const Key &key); // like map[] installs empty one if non-existent.
// Like map[] installs empty one if non-existent.
Value& ref(const Key &key);
Value& operator[](const Key& key) { return ref(key); }
bool store(const Key &key, const Value &data);
bool erase(const Key &key); // clean up cache.
@ -70,7 +75,8 @@ public:
template<class ClientClass> bool applyToAllCachedEntries(ClientClass& c,bool (ClientClass::*method)(Value&));
uint32_t size() const { return mDataMap.size() ; }
uint32_t size() const { return mDataMap.size() ; }
void printStats(std::ostream& out);
private:
bool update_lrumap(const Key &key, rstime_t old_ts, rstime_t new_ts);
@ -96,7 +102,6 @@ private:
std::string mName;
// some statistics.
void printStats(std::ostream &out);
void clearStats();
mutable uint32_t mStats_inserted;