From fa29dd73329d1a011712ca03a78ed32eca4bcc26 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 12 Jun 2016 21:41:09 -0400 Subject: [PATCH 1/3] 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. --- libretroshare/src/gxs/rsgxsnetservice.cc | 109 +++++++++++++-------- libretroshare/src/gxs/rsgxsnetservice.h | 4 +- libretroshare/src/serialiser/rsnxsitems.cc | 6 +- libretroshare/src/serialiser/rsnxsitems.h | 6 +- 4 files changed, 79 insertions(+), 46 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 67014e179..3af34b166 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -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::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; diff --git a/libretroshare/src/gxs/rsgxsnetservice.h b/libretroshare/src/gxs/rsgxsnetservice.h index e9556701c..5875617dd 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.h +++ b/libretroshare/src/gxs/rsgxsnetservice.h @@ -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 GrpFragments; diff --git a/libretroshare/src/serialiser/rsnxsitems.cc b/libretroshare/src/serialiser/rsnxsitems.cc index 1a7cf45b4..5f4770efc 100644 --- a/libretroshare/src/serialiser/rsnxsitems.cc +++ b/libretroshare/src/serialiser/rsnxsitems.cc @@ -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; diff --git a/libretroshare/src/serialiser/rsnxsitems.h b/libretroshare/src/serialiser/rsnxsitems.h index 6be81ecbe..7f5ff2438 100644 --- a/libretroshare/src/serialiser/rsnxsitems.h +++ b/libretroshare/src/serialiser/rsnxsitems.h @@ -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); From 600607d8798b2186d92c64083461258ef15bd5c2 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 13 Jun 2016 22:14:09 -0400 Subject: [PATCH 2/3] added warning for old peers in circles --- libretroshare/src/gxs/rsgxsnetservice.cc | 16 ++++++++-------- libretroshare/src/gxs/rsgxsnetservice.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 3af34b166..893d8ec6b 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -4340,7 +4340,7 @@ bool RsGxsNetService::checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxs return true; } -bool RsGxsNetService::locked_CanReceiveUpdate(RsNxsSyncMsgReqItem *item,bool& grp_is_known,bool& item_was_encrypted) +bool RsGxsNetService::locked_CanReceiveUpdate(RsNxsSyncMsgReqItem *item,bool& grp_is_known) { // 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. @@ -4351,9 +4351,6 @@ bool RsGxsNetService::locked_CanReceiveUpdate(RsNxsSyncMsgReqItem *item,bool& gr { // 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())) @@ -4364,7 +4361,6 @@ bool RsGxsNetService::locked_CanReceiveUpdate(RsNxsSyncMsgReqItem *item,bool& gr 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 ; } @@ -4400,9 +4396,13 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_ const RsPeerId& peer = item->PeerId(); bool grp_is_known = false; + bool was_circle_protected = item_was_encrypted || bool(item->flag & RsNxsSyncMsgReqItem::FLAG_USE_HASHED_GROUP_ID); - bool peer_can_receive_update = locked_CanReceiveUpdate(item, grp_is_known,item_was_encrypted); + bool peer_can_receive_update = locked_CanReceiveUpdate(item, grp_is_known); + if(item_was_encrypted) + std::cerr << "(WW) received an encrypted msg sync request from peer " << item->PeerId() << ". This is outdated, but still supported (Tell your friend to upgrade his RS!)" << std::endl; + // 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; @@ -4445,10 +4445,10 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_ return ; } - if( (grpMeta->mCircleType == GXS_CIRCLE_TYPE_EXTERNAL) != item_was_encrypted ) + if( (grpMeta->mCircleType == GXS_CIRCLE_TYPE_EXTERNAL) != was_circle_protected ) { std::cerr << "(EE) received a sync Msg request for group " << item->grpId << " from peer " << item->PeerId() ; - if(!item_was_encrypted) + if(!was_circle_protected) std::cerr << ". The group is tied to an external circle (ID=" << grpMeta->mCircleId << ") but the request wasn't encrypted." << std::endl; else std::cerr << ". The group is not tied to an external circle (ID=" << grpMeta->mCircleId << ") but the request was encrypted." << std::endl; diff --git a/libretroshare/src/gxs/rsgxsnetservice.h b/libretroshare/src/gxs/rsgxsnetservice.h index 5875617dd..b6d407a84 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.h +++ b/libretroshare/src/gxs/rsgxsnetservice.h @@ -384,7 +384,7 @@ private: #endif bool locked_CanReceiveUpdate(const RsNxsSyncGrpReqItem *item); - bool locked_CanReceiveUpdate(RsNxsSyncMsgReqItem *item, bool &grp_is_known, bool &item_was_encrypted); + bool locked_CanReceiveUpdate(RsNxsSyncMsgReqItem *item, bool &grp_is_known); static RsGxsGroupId hashGrpId(const RsGxsGroupId& gid,const RsPeerId& pid) ; From e03c5dfe5682c3a008f07464cd25935c82ff055e Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 13 Jun 2016 22:38:51 -0400 Subject: [PATCH 3/3] improved GUI layout in circle creation box. Added tooltips --- libretroshare/src/gxs/rsgxsnetservice.cc | 2 +- .../src/gui/Circles/CreateCircleDialog.cpp | 2 + .../src/gui/Circles/CreateCircleDialog.ui | 111 ++++++++---------- 3 files changed, 53 insertions(+), 62 deletions(-) diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 893d8ec6b..580b11485 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -4401,7 +4401,7 @@ void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsgReqItem *item,bool item_ bool peer_can_receive_update = locked_CanReceiveUpdate(item, grp_is_known); if(item_was_encrypted) - std::cerr << "(WW) received an encrypted msg sync request from peer " << item->PeerId() << ". This is outdated, but still supported (Tell your friend to upgrade his RS!)" << std::endl; + std::cerr << "(WW) got an encrypted msg sync req. from " << item->PeerId() << ". This will not send messages updates for group " << item->grpId << std::endl; // Insert the PeerId in suppliers list for this grpId #ifdef NXS_NET_DEBUG_6 diff --git a/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp b/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp index 9e8f96075..47ca337ec 100644 --- a/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp +++ b/retroshare-gui/src/gui/Circles/CreateCircleDialog.cpp @@ -138,6 +138,7 @@ void CreateCircleDialog::editExistingId(const RsGxsGroupId &circleId, const bool else { ui.circleAdminLabel->setVisible(false) ; + ui.circleAdminLabel->hide(); ui.idChooser->setVisible(true) ; } @@ -634,6 +635,7 @@ void CreateCircleDialog::updateCircleGUI() //ui.idChooser->setIdConstraintSet(ids) ; ui.idChooser->setFlags(IDCHOOSER_NO_CREATE) ; ui.circleAdminLabel->setVisible(false) ; + ui.circleAdminLabel->hide(); } } diff --git a/retroshare-gui/src/gui/Circles/CreateCircleDialog.ui b/retroshare-gui/src/gui/Circles/CreateCircleDialog.ui index ba8508462..fdfecb434 100644 --- a/retroshare-gui/src/gui/Circles/CreateCircleDialog.ui +++ b/retroshare-gui/src/gui/Circles/CreateCircleDialog.ui @@ -6,7 +6,7 @@ 0 0 - 924 + 951 578 @@ -14,16 +14,7 @@ - - 0 - - - 0 - - - 0 - - + 0 @@ -61,6 +52,9 @@ Qt::CustomContextMenu + + <html><head/><body><p>Members of this list will be automatically proposed to join the circle (by accepting membership). They will</p><p>not receive data that is restricted to this circle until they do so.</p></body></html> + true @@ -143,6 +137,31 @@ Known People + + + + Qt::CustomContextMenu + + + true + + + + Nickname + + + + + ID + + + + + Type + + + + @@ -155,16 +174,7 @@ 0 - - 0 - - - 0 - - - 0 - - + 0 @@ -205,31 +215,6 @@ - - - - Qt::CustomContextMenu - - - true - - - - Nickname - - - - - ID - - - - - Type - - - - @@ -258,13 +243,23 @@ true + + Qt::LeftToRight + - Name + Name: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + + + <html><head/><body><p>The circle name, contact author and invted member list will be visible to all invited members. If the circle is not private, it will also be visible to neighbor nodes of the nodes who host the invited members.</p></body></html> + + @@ -275,7 +270,7 @@ - Creator: + Contact author: @@ -288,7 +283,7 @@ - <html><head/><body><p>The creator of a circle does not need to be known. It is however useful for public circles so that people know to whom to send a request for membership.</p></body></html> + <html><head/><body><p>The creator of a circle ia purely optional. It is however useful for public circles so that people know with whom to discuss membership aspects.</p></body></html> @@ -324,7 +319,10 @@ - Distribution + Distribution: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -337,16 +335,7 @@ QFrame::Raised - - 2 - - - 2 - - - 2 - - + 2