mirror of
https://github.com/RetroShare/libretroshare.git
synced 2026-09-14 11:05:45 +05:00
Merge pull request #74 from csoler/v0.6-BugFixing_22
added auto-delete and not syncing of previous versions of group messa…
This commit is contained in:
commit
74cd958cf8
@ -96,8 +96,7 @@ typedef std::map<RsGxsGrpMsgIdPair, std::vector<RsGxsMsgItem*> > GxsMsgRelatedDa
|
||||
|
||||
class RsGixs;
|
||||
|
||||
class RsGenExchange : public RsNxsObserver, public RsTickingThread,
|
||||
public RsGxsIface
|
||||
class RsGenExchange : public RsNxsObserver, public RsTickingThread, public RsGxsIface
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
@ -367,7 +367,7 @@ RsGxsNetService::RsGxsNetService(uint16_t servType, RsGeneralDataService *gds,
|
||||
RsNxsNetMgr *netMgr, RsNxsObserver *nxsObs,
|
||||
const RsServiceInfo serviceInfo,
|
||||
RsGixsReputation* reputations, RsGcxs* circles, RsGixs *gixs,
|
||||
PgpAuxUtils *pgpUtils, RsGxsNetTunnelService *mGxsNT,
|
||||
PgpAuxUtils *pgpUtils, RsGxsNetTunnelService *mGxsNT, bool syncOldMsgVersions,
|
||||
bool grpAutoSync, bool msgAutoSync, bool distSync, uint32_t default_store_period, uint32_t default_sync_period)
|
||||
: p3ThreadedService(), p3Config(), mTransactionN(0),
|
||||
mObserver(nxsObs), mDataStore(gds),
|
||||
@ -377,6 +377,7 @@ RsGxsNetService::RsGxsNetService(uint16_t servType, RsGeneralDataService *gds,
|
||||
mLastCleanRejectedMessages(0), mSYNC_PERIOD(SYNC_PERIOD),
|
||||
mCircles(circles), mGixs(gixs),
|
||||
mReputations(reputations), mPgpUtils(pgpUtils), mGxsNetTunnel(mGxsNT),
|
||||
mSyncOldMsgVersions(syncOldMsgVersions),
|
||||
mGrpAutoSync(grpAutoSync), mAllowMsgSync(msgAutoSync),mAllowDistSync(distSync),
|
||||
mServiceInfo(serviceInfo), mDefaultMsgStorePeriod(default_store_period),
|
||||
mDefaultMsgSyncPeriod(default_sync_period)
|
||||
@ -961,12 +962,28 @@ void RsGxsNetService::handleRecvSyncGrpStatistics(RsNxsSyncGrpStatsItem *grs)
|
||||
#endif
|
||||
mDataStore->retrieveGxsMsgMetaData(reqIds, result);
|
||||
|
||||
const auto& vec(result[grs->grpId]) ;
|
||||
auto& vec(result[grs->grpId]) ;
|
||||
|
||||
if(vec.empty()) // that means we don't have any, or there isn't any, but since the default is always 0, no need to send.
|
||||
return ;
|
||||
|
||||
RsNxsSyncGrpStatsItem *grs_resp = new RsNxsSyncGrpStatsItem(mServType) ;
|
||||
if(!mSyncOldMsgVersions) // if the service doesn't sync old msg versions, get rid of them asap
|
||||
{
|
||||
std::set<RsGxsMessageId> old_versions;
|
||||
for(auto msgMeta:vec)
|
||||
if(!msgMeta->mOrigMsgId.isNull() && msgMeta->mMsgId != msgMeta->mOrigMsgId)
|
||||
old_versions.insert(msgMeta->mOrigMsgId);
|
||||
|
||||
for(uint32_t i=0;i<vec.size();)
|
||||
if(old_versions.find(vec[i]->mMsgId)!= old_versions.end())
|
||||
{
|
||||
vec[i] = vec[vec.size()-1];
|
||||
vec.pop_back();
|
||||
}
|
||||
else
|
||||
++i;
|
||||
}
|
||||
RsNxsSyncGrpStatsItem *grs_resp = new RsNxsSyncGrpStatsItem(mServType) ;
|
||||
grs_resp->request_type = RsNxsSyncGrpStatsItem::GROUP_INFO_TYPE_RESPONSE ;
|
||||
grs_resp->number_of_posts = vec.size();
|
||||
grs_resp->grpId = grs->grpId;
|
||||
@ -4450,6 +4467,8 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_
|
||||
uint32_t max_send_delay = locked_getGrpConfig(item->grpId).msg_req_delay; // we should use "sync" but there's only one variable used in the GUI: the req one.
|
||||
#endif
|
||||
|
||||
// First, filter out some messages we may not want to send.
|
||||
|
||||
if(canSendMsgIds(msgMetas, *grpMeta, peer, should_encrypt_to_this_circle_id))
|
||||
{
|
||||
for(auto vit = msgMetas.begin();vit != msgMetas.end(); ++vit)
|
||||
@ -4615,87 +4634,108 @@ bool RsGxsNetService::canSendMsgIds(std::vector<std::shared_ptr<RsGxsMsgMetaData
|
||||
return false ;
|
||||
}
|
||||
|
||||
// first do the simple checks
|
||||
uint8_t circleType = grpMeta.mCircleType;
|
||||
// If the service prevents sending old versions of messages, remove them from the list
|
||||
std::set<RsGxsMessageId> messages_old_versions;
|
||||
|
||||
if(circleType == GXS_CIRCLE_TYPE_LOCAL)
|
||||
if(!mSyncOldMsgVersions)
|
||||
{
|
||||
#ifdef NXS_NET_DEBUG_4
|
||||
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: LOCAL => returning false" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
else if(circleType == GXS_CIRCLE_TYPE_PUBLIC || circleType == GXS_CIRCLE_TYPE_UNKNOWN) // this complies with the fact that p3IdService does not initialise the circle type.
|
||||
{
|
||||
#ifdef NXS_NET_DEBUG_4
|
||||
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: PUBLIC => returning true" << std::endl;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
else if(circleType == GXS_CIRCLE_TYPE_EXTERNAL)
|
||||
{
|
||||
const RsGxsCircleId& circleId = grpMeta.mCircleId;
|
||||
#ifdef NXS_NET_DEBUG_4
|
||||
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: EXTERNAL => returning true. Msgs ids list will be encrypted." << std::endl;
|
||||
#endif
|
||||
should_encrypt_id = circleId ;
|
||||
|
||||
// For each message ID, check that the author is in the circle. If not, do not send the message, which means, remove it from the list.
|
||||
// Unsigned messages are still transmitted. This is because in some groups (channels) the posts are not signed. Whether an unsigned post
|
||||
// is allowed at this point is anyway already vetted by the RsGxsGenExchange service.
|
||||
|
||||
// Messages that stay in the list will be sent. As a consequence true is always returned.
|
||||
// Messages put in vetting list will be dealt with later
|
||||
|
||||
std::vector<MsgIdCircleVet> toVet;
|
||||
for(const auto& pmsg:msgMetas)
|
||||
if(!pmsg->mOrigMsgId.isNull() && pmsg->mOrigMsgId != pmsg->mMsgId)
|
||||
messages_old_versions.insert(pmsg->mOrigMsgId);
|
||||
|
||||
for(uint32_t i=0;i<msgMetas.size();)
|
||||
if( msgMetas[i]->mAuthorId.isNull() ) // keep the message in this case
|
||||
++i ;
|
||||
else
|
||||
if(messages_old_versions.find(msgMetas[i]->mMsgId) != messages_old_versions.end())
|
||||
{
|
||||
if(mCircles->isLoaded(circleId) && mCircles->isRecipient(circleId, grpMeta.mGroupId, msgMetas[i]->mAuthorId))
|
||||
{
|
||||
std::cerr << " Not sending msg id " << msgMetas[i]->mMsgId << " because it is an old version." << std::endl;
|
||||
msgMetas[i] = msgMetas[msgMetas.size()-1];
|
||||
msgMetas.pop_back();
|
||||
}
|
||||
else
|
||||
++i;
|
||||
}
|
||||
|
||||
|
||||
// first do the simple checks
|
||||
uint8_t circleType = grpMeta.mCircleType;
|
||||
|
||||
if(circleType == GXS_CIRCLE_TYPE_LOCAL)
|
||||
{
|
||||
#ifdef NXS_NET_DEBUG_4
|
||||
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: LOCAL => returning false" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
else if(circleType == GXS_CIRCLE_TYPE_PUBLIC || circleType == GXS_CIRCLE_TYPE_UNKNOWN) // this complies with the fact that p3IdService does not initialise the circle type.
|
||||
{
|
||||
#ifdef NXS_NET_DEBUG_4
|
||||
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: PUBLIC => returning true" << std::endl;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
else if(circleType == GXS_CIRCLE_TYPE_EXTERNAL)
|
||||
{
|
||||
const RsGxsCircleId& circleId = grpMeta.mCircleId;
|
||||
#ifdef NXS_NET_DEBUG_4
|
||||
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle type: EXTERNAL => returning true. Msgs ids list will be encrypted." << std::endl;
|
||||
#endif
|
||||
should_encrypt_id = circleId ;
|
||||
|
||||
// For each message ID, check that the author is in the circle. If not, do not send the message, which means, remove it from the list.
|
||||
// Unsigned messages are still transmitted. This is because in some groups (channels) the posts are not signed. Whether an unsigned post
|
||||
// is allowed at this point is anyway already vetted by the RsGxsGenExchange service.
|
||||
|
||||
// Messages that stay in the list will be sent. As a consequence true is always returned.
|
||||
// Messages put in vetting list will be dealt with later
|
||||
|
||||
std::vector<MsgIdCircleVet> toVet;
|
||||
|
||||
for(uint32_t i=0;i<msgMetas.size();)
|
||||
if( msgMetas[i]->mAuthorId.isNull() ) // keep the message in this case
|
||||
++i ;
|
||||
continue ;
|
||||
else
|
||||
{
|
||||
if(mCircles->isLoaded(circleId) && mCircles->isRecipient(circleId, grpMeta.mGroupId, msgMetas[i]->mAuthorId))
|
||||
{
|
||||
++i ;
|
||||
continue ;
|
||||
}
|
||||
|
||||
MsgIdCircleVet mic(msgMetas[i]->mMsgId, msgMetas[i]->mAuthorId);
|
||||
toVet.push_back(mic);
|
||||
#ifdef NXS_NET_DEBUG_4
|
||||
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " deleting MsgMeta entry for msg ID " << msgMetas[i]->mMsgId << " signed by " << msgMetas[i]->mAuthorId << " who is not in group circle " << circleId << std::endl;
|
||||
#endif
|
||||
|
||||
//delete msgMetas[i] ;
|
||||
msgMetas[i] = msgMetas[msgMetas.size()-1] ;
|
||||
msgMetas.pop_back() ;
|
||||
}
|
||||
|
||||
MsgIdCircleVet mic(msgMetas[i]->mMsgId, msgMetas[i]->mAuthorId);
|
||||
toVet.push_back(mic);
|
||||
#ifdef NXS_NET_DEBUG_4
|
||||
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " deleting MsgMeta entry for msg ID " << msgMetas[i]->mMsgId << " signed by " << msgMetas[i]->mAuthorId << " who is not in group circle " << circleId << std::endl;
|
||||
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle info not loaded. Putting in vetting list and returning false." << std::endl;
|
||||
#endif
|
||||
if(!toVet.empty())
|
||||
mPendingCircleVets.push_back(new MsgCircleIdsRequestVetting(mCircles, mPgpUtils, toVet, grpMeta.mGroupId, sslId, grpMeta.mCircleId));
|
||||
|
||||
//delete msgMetas[i] ;
|
||||
msgMetas[i] = msgMetas[msgMetas.size()-1] ;
|
||||
msgMetas.pop_back() ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
else if(circleType == GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY)
|
||||
{
|
||||
#ifdef NXS_NET_DEBUG_4
|
||||
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Circle info not loaded. Putting in vetting list and returning false." << std::endl;
|
||||
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " YOUREYESONLY, checking further" << std::endl;
|
||||
#endif
|
||||
if(!toVet.empty())
|
||||
mPendingCircleVets.push_back(new MsgCircleIdsRequestVetting(mCircles, mPgpUtils, toVet, grpMeta.mGroupId, sslId, grpMeta.mCircleId));
|
||||
|
||||
return true ;
|
||||
}
|
||||
else if(circleType == GXS_CIRCLE_TYPE_YOUR_FRIENDS_ONLY)
|
||||
{
|
||||
bool res = checkPermissionsForFriendGroup(sslId,grpMeta) ;
|
||||
#ifdef NXS_NET_DEBUG_4
|
||||
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " YOUREYESONLY, checking further" << std::endl;
|
||||
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Final answer: " << res << std::endl;
|
||||
#endif
|
||||
bool res = checkPermissionsForFriendGroup(sslId,grpMeta) ;
|
||||
#ifdef NXS_NET_DEBUG_4
|
||||
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Final answer: " << res << std::endl;
|
||||
#endif
|
||||
return res ;
|
||||
return res ;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "(EE) unknown value found in circle type for group " << grpMeta.mGroupId << ": " << (int)circleType << ": this is probably a bug in the design of the group creation." << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "(EE) unknown value found in circle type for group " << grpMeta.mGroupId << ": " << (int)circleType << ": this is probably a bug in the design of the group creation." << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** inherited methods **/
|
||||
|
||||
|
||||
@ -97,6 +97,7 @@ public:
|
||||
const RsServiceInfo serviceInfo,
|
||||
RsGixsReputation* reputations = NULL, RsGcxs* circles = NULL, RsGixs *gixs=NULL,
|
||||
PgpAuxUtils *pgpUtils = NULL, RsGxsNetTunnelService *mGxsNT = NULL,
|
||||
bool sendOldMsgVersions = true,
|
||||
bool grpAutoSync = true, bool msgAutoSync = true,bool distSync=false,
|
||||
uint32_t default_store_period = RS_GXS_DEFAULT_MSG_STORE_PERIOD,
|
||||
uint32_t default_sync_period = RS_GXS_DEFAULT_MSG_REQ_PERIOD);
|
||||
@ -626,6 +627,7 @@ private:
|
||||
PgpAuxUtils *mPgpUtils;
|
||||
RsGxsNetTunnelService *mGxsNetTunnel;
|
||||
|
||||
bool mSyncOldMsgVersions;
|
||||
bool mGrpAutoSync;
|
||||
bool mAllowMsgSync;
|
||||
bool mAllowDistSync;
|
||||
|
||||
@ -99,7 +99,7 @@ bool RsGxsCleanUp::clean(RsGxsGroupId& next_group_to_check,std::vector<RsGxsGrou
|
||||
GxsMsgMetaResult::iterator mit = result.begin();
|
||||
|
||||
#ifdef DEBUG_GXSUTIL
|
||||
GXSUTIL_DEBUG() << " Cleaning up group message for group ID " << grpId << std::endl;
|
||||
GXSUTIL_DEBUG() << " Cleaning up messages for group ID " << grpId << std::endl;
|
||||
#endif
|
||||
uint32_t store_period = mGenExchangeClient->getStoragePeriod(grpId) ;
|
||||
|
||||
@ -112,24 +112,29 @@ bool RsGxsCleanUp::clean(RsGxsGroupId& next_group_to_check,std::vector<RsGxsGrou
|
||||
// end the message tree will be deleted slice after slice, which should still be reasonnably fast.
|
||||
//
|
||||
std::set<RsGxsMessageId> messages_with_kids ;
|
||||
std::set<RsGxsMessageId> messages_old_versions ;
|
||||
|
||||
for( uint32_t i=0;i<metaV.size();++i)
|
||||
if(!metaV[i]->mParentId.isNull())
|
||||
messages_with_kids.insert(metaV[i]->mParentId) ;
|
||||
|
||||
for( uint32_t i=0;i<metaV.size();++i)
|
||||
if(!metaV[i]->mOrigMsgId.isNull() && metaV[i]->mOrigMsgId != metaV[i]->mMsgId) // in some situations, mOrigMsgId is initialized, but equal to the sgId itself
|
||||
messages_old_versions.insert(metaV[i]->mOrigMsgId) ;
|
||||
|
||||
for( uint32_t i=0;i<metaV.size();++i)
|
||||
{
|
||||
const auto& meta = metaV[i];
|
||||
|
||||
bool have_kids = (messages_with_kids.find(meta->mMsgId)!=messages_with_kids.end());
|
||||
|
||||
// check if expired
|
||||
// Check if expired
|
||||
bool remove = store_period > 0 && ((meta->mPublishTs + store_period) < now) && !have_kids;
|
||||
|
||||
// check client does not want the message kept regardless of age
|
||||
remove &= !(meta->mMsgStatus & GXS_SERV::GXS_MSG_STATUS_KEEP_FOREVER);
|
||||
// Check client does not want the message kept regardless of age
|
||||
remove = remove && !(meta->mMsgStatus & GXS_SERV::GXS_MSG_STATUS_KEEP_FOREVER);
|
||||
|
||||
// if not subscribed remove messages (can optimise this really)
|
||||
// If not subscribed remove messages (can optimise this really)
|
||||
remove = remove || (grpMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED);
|
||||
remove = remove || !(grpMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED);
|
||||
|
||||
@ -138,6 +143,10 @@ bool RsGxsCleanUp::clean(RsGxsGroupId& next_group_to_check,std::vector<RsGxsGrou
|
||||
<< " subscribed: " << bool(grpMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED) << " store_period: " << store_period
|
||||
<< " kids: " << have_kids << " now - meta->mPublishTs: " << now - meta->mPublishTs ;
|
||||
#endif
|
||||
// Only keep old messages if the client service asks for it.
|
||||
|
||||
if(!mGenExchangeClient->keepOldMsgVersions() && messages_old_versions.find(meta->mMsgId)!=messages_old_versions.end())
|
||||
remove = true;
|
||||
|
||||
if( remove )
|
||||
{
|
||||
@ -150,7 +159,6 @@ bool RsGxsCleanUp::clean(RsGxsGroupId& next_group_to_check,std::vector<RsGxsGrou
|
||||
else
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
//delete meta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -344,6 +344,15 @@ struct RsGxsIface
|
||||
virtual uint32_t getStoragePeriod(const RsGxsGroupId& grpId) = 0;
|
||||
virtual void setStoragePeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) = 0;
|
||||
|
||||
/*!
|
||||
* \brief keepOldMsgVersions
|
||||
* Overload this in order to force the deletion of old versions of messages.
|
||||
* \return
|
||||
* true = keep old message versions (e.g. forums)
|
||||
* false = delete old message versions (e.g. channels)
|
||||
*/
|
||||
virtual bool keepOldMsgVersions() const { return true ; }
|
||||
|
||||
virtual uint32_t getDefaultSyncPeriod() = 0;
|
||||
virtual uint32_t getSyncPeriod(const RsGxsGroupId& grpId) = 0;
|
||||
virtual void setSyncPeriod(const RsGxsGroupId& grpId,uint32_t age_in_secs) = 0;
|
||||
|
||||
@ -1295,7 +1295,8 @@ int RsServer::StartupRetroShare()
|
||||
RS_SERVICE_GXS_TYPE_GXSID, gxsid_ds, nxsMgr,
|
||||
mGxsIdService, mGxsIdService->getServiceInfo(),
|
||||
mReputations, mGxsCircles,mGxsIdService,
|
||||
pgpAuxUtils,mGxsNetTunnel,
|
||||
pgpAuxUtils,mGxsNetTunnel,
|
||||
true, // sync old versions of msgs. Not really useful here because msgs are not sync-ed anyway, but this is the default.
|
||||
false,false,true); // don't synchronise group automatic (need explicit group request)
|
||||
// don't sync messages at all.
|
||||
// allow distsync, so that we can grab GXS id requests for other services
|
||||
@ -1386,7 +1387,11 @@ int RsServer::StartupRetroShare()
|
||||
RS_SERVICE_GXS_TYPE_CHANNELS, gxschannels_ds, nxsMgr,
|
||||
mGxsChannels, mGxsChannels->getServiceInfo(),
|
||||
mReputations, mGxsCircles,mGxsIdService,
|
||||
pgpAuxUtils,mGxsNetTunnel,true,true,true);
|
||||
pgpAuxUtils,mGxsNetTunnel,
|
||||
false, // don't sync old versions of messages
|
||||
true, // auto-sync groups
|
||||
true, // auto-sync messages
|
||||
true); // distant sync (default=false)
|
||||
|
||||
mGxsChannels->setNetworkExchangeService(gxschannels_ns) ;
|
||||
|
||||
@ -1449,7 +1454,7 @@ int RsServer::StartupRetroShare()
|
||||
RsGxsNetService* gxstrans_ns = new RsGxsNetService(
|
||||
RS_SERVICE_TYPE_GXS_TRANS, gxstrans_ds, nxsMgr, mGxsTrans,
|
||||
mGxsTrans->getServiceInfo(), mReputations, mGxsCircles,
|
||||
mGxsIdService, pgpAuxUtils,NULL,true,true,false,p3GxsTrans::GXS_STORAGE_PERIOD,p3GxsTrans::GXS_SYNC_PERIOD);
|
||||
mGxsIdService, pgpAuxUtils,NULL,true,true,true,false,p3GxsTrans::GXS_STORAGE_PERIOD,p3GxsTrans::GXS_SYNC_PERIOD);
|
||||
|
||||
mGxsTrans->setNetworkExchangeService(gxstrans_ns);
|
||||
pqih->addService(gxstrans_ns, true);
|
||||
|
||||
@ -79,6 +79,7 @@ protected:
|
||||
virtual RsGenExchange::ServiceCreate_Return service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet) override;
|
||||
|
||||
virtual void notifyChanges(std::vector<RsGxsNotify*>& changes) override;
|
||||
virtual bool keepOldMsgVersions() const override { return false ; }
|
||||
|
||||
// Overloaded from RsTickEvent.
|
||||
virtual void handle_event(uint32_t event_type, const std::string &elabel) override;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user