mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
changed the way RsGxsSyncMsgReqItem are sent for circle-restricted groups, using a hash of the group ID instead of encrypting the whole item, hense saving a lot of bandwidth on msg sync.
This commit is contained in:
parent
248d0c42d3
commit
fa29dd7332
@ -208,6 +208,7 @@
|
||||
#include "retroshare/rsgxsflags.h"
|
||||
#include "retroshare/rsgxscircles.h"
|
||||
#include "pgp/pgpauxutils.h"
|
||||
#include "util/rsdir.h"
|
||||
#include "util/rsmemory.h"
|
||||
#include "util/stacktrace.h"
|
||||
|
||||
@ -604,6 +605,21 @@ public:
|
||||
std::vector<T*>::clear() ;
|
||||
}
|
||||
};
|
||||
|
||||
RsGxsGroupId RsGxsNetService::hashGrpId(const RsGxsGroupId& gid,const RsPeerId& pid)
|
||||
{
|
||||
static const uint32_t SIZE = RsGxsGroupId::SIZE_IN_BYTES + RsPeerId::SIZE_IN_BYTES ;
|
||||
unsigned char tmpmem[SIZE];
|
||||
uint32_t offset = 0 ;
|
||||
|
||||
pid.serialise(tmpmem,SIZE,offset) ;
|
||||
gid.serialise(tmpmem,SIZE,offset) ;
|
||||
|
||||
assert(RsGxsGroupId::SIZE_IN_BYTES <= Sha1CheckSum::SIZE_IN_BYTES) ;
|
||||
|
||||
return RsGxsGroupId( RsDirUtil::sha1sum(tmpmem,SIZE).toByteArray() );
|
||||
}
|
||||
|
||||
void RsGxsNetService::syncWithPeers()
|
||||
{
|
||||
#ifdef NXS_NET_DEBUG_0
|
||||
@ -742,45 +758,24 @@ void RsGxsNetService::syncWithPeers()
|
||||
RsNxsSyncMsgReqItem* msg = new RsNxsSyncMsgReqItem(mServType);
|
||||
msg->clear();
|
||||
msg->PeerId(peerId);
|
||||
msg->grpId = grpId;
|
||||
msg->updateTS = updateTS;
|
||||
|
||||
|
||||
if(encrypt_to_this_circle_id.isNull())
|
||||
{
|
||||
#ifdef NXS_NET_DEBUG_7
|
||||
GXSNETDEBUG_PG(*sit,grpId) << " Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself - in clear " << std::endl;
|
||||
#endif
|
||||
sendItem(msg);
|
||||
}
|
||||
msg->grpId = grpId;
|
||||
else
|
||||
{
|
||||
msg->grpId = hashGrpId(grpId,mNetMgr->getOwnId()) ;
|
||||
msg->flag |= RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID ;
|
||||
}
|
||||
|
||||
#ifdef NXS_NET_DEBUG_7
|
||||
GXSNETDEBUG_PG(*sit,grpId) << " Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself - encrypted for circle " << encrypt_to_this_circle_id << std::endl;
|
||||
GXSNETDEBUG_PG(*sit,grpId) << " Service " << std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself - in clear " << std::endl;
|
||||
#endif
|
||||
RsNxsItem *encrypted_item = NULL ;
|
||||
uint32_t status ;
|
||||
|
||||
if(encryptSingleNxsItem(msg, encrypt_to_this_circle_id, grpId, encrypted_item, status))
|
||||
sendItem(encrypted_item) ;
|
||||
#ifdef NXS_NET_DEBUG_7
|
||||
else
|
||||
GXSNETDEBUG_PG(*sit,grpId) << "(WW) could not encrypt for circle ID " << encrypt_to_this_circle_id << ". Not yet in cache?" << std::endl;
|
||||
#endif
|
||||
|
||||
delete msg ;
|
||||
}
|
||||
sendItem(msg);
|
||||
|
||||
#ifdef NXS_NET_DEBUG_5
|
||||
GXSNETDEBUG_PG(*sit,grpId) << "Service "<< std::hex << ((mServiceInfo.mServiceType >> 8)& 0xffff) << std::dec << " sending global message TS of peer id: " << *sit << " ts=" << nice_time_stamp(time(NULL),updateTS) << " (secs ago) for group " << grpId << " to himself" << std::endl;
|
||||
#endif
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// delete msg ;
|
||||
//#ifdef NXS_NET_DEBUG_0
|
||||
// GXSNETDEBUG_PG(*sit,grpId) << " cancel RsNxsSyncMsg req (last local update TS for group+peer) for grpId=" << grpId << " to peer " << *sit << ": not enough bandwidth." << std::endl;
|
||||
//#endif
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4345,28 +4340,57 @@ bool RsGxsNetService::checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxs
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RsGxsNetService::locked_CanReceiveUpdate(const RsNxsSyncMsgReqItem *item)
|
||||
bool RsGxsNetService::locked_CanReceiveUpdate(RsNxsSyncMsgReqItem *item,bool& grp_is_known,bool& item_was_encrypted)
|
||||
{
|
||||
// Do we have new updates for this peer?
|
||||
// Here we compare times in the same clock: the friend's clock, so it should be fine.
|
||||
|
||||
ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(item->grpId);
|
||||
grp_is_known = false ;
|
||||
|
||||
if(item->flag & RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID)
|
||||
{
|
||||
// Item contains the hashed group ID in order to protect is from friends who don't know it. So we de-hash it using bruteforce over known group IDs for this peer.
|
||||
// We could save the de-hash result. But the cost is quite light, since the number of encrypted groups per service is usually low.
|
||||
//
|
||||
// /!\ item_was_encrypted should only be changed to true when appropriate, but never set to false here, since it can be true already for
|
||||
// backward compatibility (truly encrypted item, instead of hashed grp id)
|
||||
|
||||
for(ServerMsgMap::const_iterator it(mServerMsgUpdateMap.begin());it!=mServerMsgUpdateMap.end();++it)
|
||||
if(item->grpId == hashGrpId(it->first,item->PeerId()))
|
||||
{
|
||||
item->grpId = it->first ;
|
||||
item->flag &= ~RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID;
|
||||
#ifdef NXS_NET_DEBUG_0
|
||||
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << "(II) de-hashed group ID " << it->first << " from hash " << item->grpId << " and peer id " << item->PeerId() << std::endl;
|
||||
#endif
|
||||
grp_is_known = true ;
|
||||
item_was_encrypted = true ;
|
||||
|
||||
return item->updateTS < it->second->msgUpdateTS ;
|
||||
}
|
||||
|
||||
return false ;
|
||||
}
|
||||
|
||||
ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(item->grpId);
|
||||
if(cit != mServerMsgUpdateMap.end())
|
||||
{
|
||||
const RsGxsServerMsgUpdateItem *msui = cit->second;
|
||||
const RsGxsServerMsgUpdateItem *msui = cit->second;
|
||||
|
||||
#ifdef NXS_NET_DEBUG_0
|
||||
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " local time stamp: " << std::dec<< time(NULL) - msui->msgUpdateTS << " secs ago. Update sent: " << (item->updateTS < msui->msgUpdateTS) << std::endl;
|
||||
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " local time stamp: " << std::dec<< time(NULL) - msui->msgUpdateTS << " secs ago. Update sent: " << (item->updateTS < msui->msgUpdateTS) << std::endl;
|
||||
#endif
|
||||
return item->updateTS < msui->msgUpdateTS ;
|
||||
grp_is_known = true ;
|
||||
return item->updateTS < msui->msgUpdateTS ;
|
||||
}
|
||||
|
||||
#ifdef NXS_NET_DEBUG_0
|
||||
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " no local time stamp for this grp. "<< std::endl;
|
||||
#endif
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_was_encrypted)
|
||||
{
|
||||
if (!item)
|
||||
@ -4375,19 +4399,24 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_
|
||||
RS_STACK_MUTEX(mNxsMutex) ;
|
||||
|
||||
const RsPeerId& peer = item->PeerId();
|
||||
bool grp_is_known = false;
|
||||
|
||||
bool peer_can_receive_update = locked_CanReceiveUpdate(item, grp_is_known,item_was_encrypted);
|
||||
|
||||
// Insert the PeerId in suppliers list for this grpId
|
||||
#ifdef NXS_NET_DEBUG_6
|
||||
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << "RsGxsNetService::handleRecvSyncMessage(): Inserting PeerId " << item->PeerId() << " in suppliers list for group " << item->grpId << std::endl;
|
||||
#endif
|
||||
RsGroupNetworkStatsRecord& rec(mGroupNetworkStats[item->grpId]) ; // this creates it if needed
|
||||
rec.suppliers.insert(peer) ;
|
||||
|
||||
#ifdef NXS_NET_DEBUG_0
|
||||
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << "handleRecvSyncMsg(): Received last update TS of group " << item->grpId << ", for peer " << peer << ", TS = " << time(NULL) - item->updateTS << " secs ago." ;
|
||||
#endif
|
||||
|
||||
if(!locked_CanReceiveUpdate(item))
|
||||
|
||||
if(grp_is_known)
|
||||
{
|
||||
RsGroupNetworkStatsRecord& rec(mGroupNetworkStats[item->grpId]) ; // this creates it if needed. When the grp is unknown (and hashed) this will would create a unused entry
|
||||
rec.suppliers.insert(peer) ;
|
||||
}
|
||||
if(!peer_can_receive_update)
|
||||
{
|
||||
#ifdef NXS_NET_DEBUG_0
|
||||
GXSNETDEBUG_PG(item->PeerId(),item->grpId) << " no update will be sent." << std::endl;
|
||||
|
@ -384,8 +384,10 @@ private:
|
||||
#endif
|
||||
|
||||
bool locked_CanReceiveUpdate(const RsNxsSyncGrpReqItem *item);
|
||||
bool locked_CanReceiveUpdate(const RsNxsSyncMsgReqItem* item);
|
||||
bool locked_CanReceiveUpdate(RsNxsSyncMsgReqItem *item, bool &grp_is_known, bool &item_was_encrypted);
|
||||
|
||||
static RsGxsGroupId hashGrpId(const RsGxsGroupId& gid,const RsPeerId& pid) ;
|
||||
|
||||
private:
|
||||
|
||||
typedef std::vector<RsNxsGrp*> GrpFragments;
|
||||
|
@ -13,8 +13,10 @@ const uint8_t RsNxsSyncGrpItem::FLAG_RESPONSE = 0x002;
|
||||
const uint8_t RsNxsSyncMsgItem::FLAG_REQUEST = 0x001;
|
||||
const uint8_t RsNxsSyncMsgItem::FLAG_RESPONSE = 0x002;
|
||||
|
||||
const uint8_t RsNxsSyncGrpItem::FLAG_USE_SYNC_HASH = 0x001;
|
||||
const uint8_t RsNxsSyncMsgItem::FLAG_USE_SYNC_HASH = 0x001;
|
||||
const uint8_t RsNxsSyncGrpItem::FLAG_USE_SYNC_HASH = 0x0001;
|
||||
const uint8_t RsNxsSyncMsgItem::FLAG_USE_SYNC_HASH = 0x0001;
|
||||
|
||||
const uint8_t RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID = 0x02;
|
||||
|
||||
/** transaction state **/
|
||||
const uint16_t RsNxsTransacItem::FLAG_BEGIN_P1 = 0x0001;
|
||||
|
@ -348,12 +348,12 @@ public:
|
||||
#ifdef UNUSED_CODE
|
||||
static const uint8_t FLAG_USE_SYNC_HASH;
|
||||
#endif
|
||||
static const uint8_t FLAG_USE_HASHED_GROUP_ID;
|
||||
|
||||
RsNxsSyncMsgReqItem(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_SYNC_MSG_REQ_ITEM) { clear(); return; }
|
||||
|
||||
virtual bool serialise(void *data,uint32_t& size) const;
|
||||
virtual uint32_t serial_size() const;
|
||||
|
||||
virtual bool serialise(void *data,uint32_t& size) const;
|
||||
virtual uint32_t serial_size() const;
|
||||
|
||||
virtual void clear();
|
||||
virtual std::ostream &print(std::ostream &out, uint16_t indent);
|
||||
|
Loading…
Reference in New Issue
Block a user