From 0cf889d556c2d094299a245af57549fe74ca66c9 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 7 Nov 2021 22:39:24 +0100 Subject: [PATCH] fixed a few bugs in peer management --- retroshare-friendserver/src/friendserver.cc | 81 +++++++++++++-------- retroshare-friendserver/src/friendserver.h | 2 +- 2 files changed, 52 insertions(+), 31 deletions(-) diff --git a/retroshare-friendserver/src/friendserver.cc b/retroshare-friendserver/src/friendserver.cc index be445540d..ac75f4464 100644 --- a/retroshare-friendserver/src/friendserver.cc +++ b/retroshare-friendserver/src/friendserver.cc @@ -82,15 +82,19 @@ void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *it RsFriendServerServerResponseItem *sr_item = new RsFriendServerServerResponseItem; + std::map friends; sr_item->nonce = pi->second.last_nonce; - sr_item->friend_invites = computeListOfFriendInvites(item->n_requested_friends,pi->first,pi->second.pgp_fingerprint); + sr_item->friend_invites = computeListOfFriendInvites(item->n_requested_friends,pi->first,friends); sr_item->PeerId(item->PeerId()); // Update the have_added_as_friend for the list of each peer. We do that before sending because sending destroys // the item. - for(auto& it:mCurrentClientPeers) - it.second.have_added_this_peer[computePeerDistance(it.second.pgp_fingerprint,pi->second.pgp_fingerprint)] = pi->first; + for(const auto& pid:friends) + { + auto& p(mCurrentClientPeers[pid.first]); + p.have_added_this_peer[computePeerDistance(p.pgp_fingerprint, pi->second.pgp_fingerprint)] = pi->first; + } // Send the item. mni->SendItem(sr_item); @@ -111,23 +115,8 @@ void FriendServer::handleClientPublish(const RsFriendServerClientPublishItem *it } } -std::map FriendServer::computeListOfFriendInvites(uint32_t nb_reqs_invites, const RsPeerId &pid, const RsPgpFingerprint &fpr) +std::map FriendServer::computeListOfFriendInvites(uint32_t nb_reqs_invites, const RsPeerId &pid, std::map& friends) { - // For now, returns the first nb_reqs_invites from the currently known peer, that would not be the peer who's asking - - std::map res; - - for(auto it:mCurrentClientPeers) - { - if(it.first == pid) - continue; - - res.insert(std::make_pair(it.second.short_certificate,false)); // for now we say that peers havn't been warned already - - if(res.size() >= nb_reqs_invites) - break; - } - // Strategy: we want to return the same set of friends for a given PGP profile key. // Still, using some closest distance strategy, the n-closest peers for profile A is not the // same set than the n-closest peers for profile B. We have multiple options: @@ -148,9 +137,32 @@ std::map FriendServer::computeListOfFriendInvites(uint32_t nb // When a peer asks for k friends, read from (2) first, then (1), until the number of collected peers // reaches the requested value. // - // Drawbacks: it's not clear which list of friends you're going to get eventually, but in the end the peers that will be - // sent that are not in the n-closest list will need to be checked, so they will be known whatsoever. - // + // So we choose Option 2. + + std::map res; + + auto add_from = [&res,&friends,nb_reqs_invites,this](bool added,const std::map& lst) -> bool + { + for(const auto& pid:lst) + { + const auto p = mCurrentClientPeers.find(pid.second); + res.insert(std::make_pair(p->second.short_certificate,added)); + friends.insert(std::make_pair(p->first,p->second.pgp_fingerprint)); + + if(res.size() >= nb_reqs_invites) + return true; + } + return false; + }; + + const auto& pinfo(mCurrentClientPeers[pid]); + + // First add from peers who already added the current peer as friend, and leave if we already have enough + + if(add_from(true,pinfo.have_added_this_peer)) + return res; + + add_from(false,pinfo.closest_peers); return res; } @@ -207,6 +219,7 @@ std::map::iterator FriendServer::handleIncomingClientData(con pi.short_certificate = short_invite_b64; pi.last_connection_TS = time(nullptr); + pi.pgp_fingerprint = fpr_test; while(pi.last_nonce == 0) // reuse the same identifier (so it's not really a nonce, but it's kept secret whatsoever). pi.last_nonce = RsRandom::random_u64(); @@ -282,6 +295,7 @@ void FriendServer::removePeer(const RsPeerId& peer_id) PeerInfo::PeerDistance FriendServer::computePeerDistance(const RsPgpFingerprint& p1,const RsPgpFingerprint& p2) { + std::cerr << "Computing peer distance: p1=" << p1 << " p2=" << p2 << " p1^p2=" << (p1^p2) << " distance=" << ((p1^p2)^mRandomPeerBias) << std::endl; return (p1 ^ p2)^mRandomPeerBias; } FriendServer::FriendServer(const std::string& base_dir) @@ -337,14 +351,15 @@ void FriendServer::autoWash() void FriendServer::updateClosestPeers(const RsPeerId& pid,const RsPgpFingerprint& fpr) { for(auto& it:mCurrentClientPeers) - { - PeerInfo::PeerDistance d = computePeerDistance(fpr,it.second.pgp_fingerprint); + if(it.first != pid) + { + PeerInfo::PeerDistance d = computePeerDistance(fpr,it.second.pgp_fingerprint); - it.second.closest_peers.insert(std::make_pair(d,pid)); + it.second.closest_peers.insert(std::make_pair(d,pid)); - if(it.second.closest_peers.size() > MAXIMUM_PEERS_TO_REQUEST) - it.second.closest_peers.erase(std::prev(it.second.closest_peers.end())); - } + if(it.second.closest_peers.size() > MAXIMUM_PEERS_TO_REQUEST) + it.second.closest_peers.erase(std::prev(it.second.closest_peers.end())); + } } void FriendServer::debugPrint() @@ -360,10 +375,16 @@ void FriendServer::debugPrint() for(const auto& it:mCurrentClientPeers) { - RsDbg() << " " << it.first << ": nonce=" << std::hex << it.second.last_nonce << std::dec << ", last contact: " << now - it.second.last_connection_TS << " secs ago."; + RsDbg() << " " << it.first << ": nonce=" << std::hex << it.second.last_nonce << std::dec << " fpr: " << it.second.pgp_fingerprint << ", last contact: " << now - it.second.last_connection_TS << " secs ago."; + RsDbg() << " Closest peers:" ; for(const auto& pit:it.second.closest_peers) - RsDbg() << " " << pit.second << " distance=" << pit.first ; + RsDbg() << " " << pit.second << " distance=" << pit.first ; + + RsDbg() << " Have added this peer:" ; + + for(const auto& pit:it.second.have_added_this_peer) + RsDbg() << " " << pit.second << " distance=" << pit.first ; } RsDbg() << "==============================================="; diff --git a/retroshare-friendserver/src/friendserver.h b/retroshare-friendserver/src/friendserver.h index 18cef0287..edf2a38cb 100644 --- a/retroshare-friendserver/src/friendserver.h +++ b/retroshare-friendserver/src/friendserver.h @@ -69,7 +69,7 @@ private: std::map::iterator handleIncomingClientData(const std::string& pgp_public_key_b64,const std::string& short_invite_b64); // Computes the appropriate list of short invites to send to a given peer. - std::map computeListOfFriendInvites(uint32_t nb_reqs_invites,const RsPeerId& pid,const RsPgpFingerprint& fpr); + std::map computeListOfFriendInvites(uint32_t nb_reqs_invites, const RsPeerId &pid, std::map& friends); // Compute the distance between peers using the random bias (It's not really a distance though. I'm not sure about the triangular inequality). PeerInfo::PeerDistance computePeerDistance(const RsPgpFingerprint &p1, const RsPgpFingerprint &p2);