mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
added proper synchronization of GxsIds through tunnels of another service
This commit is contained in:
parent
4d6fed643a
commit
8d5c013a17
@ -766,7 +766,7 @@ void RsGxsNetService::generic_sendItem(RsNxsItem *si)
|
||||
|
||||
void RsGxsNetService::checkDistantSyncState()
|
||||
{
|
||||
if(!mAllowDistSync || mGxsNetTunnel==NULL)
|
||||
if(!mAllowDistSync || mGxsNetTunnel==NULL || !mGrpAutoSync)
|
||||
return ;
|
||||
|
||||
RsGxsGrpMetaTemporaryMap grpMeta;
|
||||
@ -835,6 +835,17 @@ void RsGxsNetService::syncGrpStatistics()
|
||||
std::set<RsPeerId> online_peers;
|
||||
mNetMgr->getOnlineList(mServiceInfo.mServiceType, online_peers);
|
||||
|
||||
if(mAllowDistSync && mGxsNetTunnel != NULL)
|
||||
{
|
||||
// Grab all online virtual peers of distant tunnels for the current service.
|
||||
|
||||
std::list<RsGxsNetTunnelVirtualPeerId> vpids ;
|
||||
mGxsNetTunnel->getVirtualPeers(vpids);
|
||||
|
||||
for(auto it(vpids.begin());it!=vpids.end();++it)
|
||||
online_peers.insert(RsPeerId(*it)) ;
|
||||
}
|
||||
|
||||
// Go through group statistics and groups without information are re-requested to random peers selected
|
||||
// among the ones who provided the group info.
|
||||
|
||||
@ -4168,7 +4179,7 @@ bool RsGxsNetService::checkCanRecvMsgFromPeer(const RsPeerId& sslId, const RsGxs
|
||||
// check if that peer is a virtual peer id, in which case we only send/recv data to/from it items for the group it's requested for
|
||||
|
||||
RsGxsGroupId peer_grp ;
|
||||
if(mGxsNetTunnel->isDistantPeer(RsGxsNetTunnelVirtualPeerId(sslId),peer_grp) && peer_grp != grpMeta.mGroupId)
|
||||
if(mAllowDistSync && mGxsNetTunnel != NULL && mGxsNetTunnel->isDistantPeer(RsGxsNetTunnelVirtualPeerId(sslId),peer_grp) && peer_grp != grpMeta.mGroupId)
|
||||
{
|
||||
#ifdef NXS_NET_DEBUG_4
|
||||
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Distant peer designed for group " << peer_grp << ": cannot request sync for different group." << std::endl;
|
||||
@ -4522,7 +4533,7 @@ bool RsGxsNetService::canSendMsgIds(std::vector<RsGxsMsgMetaData*>& msgMetas, co
|
||||
// check if that peer is a virtual peer id, in which case we only send/recv data to/from it items for the group it's requested for
|
||||
|
||||
RsGxsGroupId peer_grp ;
|
||||
if(mGxsNetTunnel->isDistantPeer(RsGxsNetTunnelVirtualPeerId(sslId),peer_grp) && peer_grp != grpMeta.mGroupId)
|
||||
if(mAllowDistSync && mGxsNetTunnel != NULL && mGxsNetTunnel->isDistantPeer(RsGxsNetTunnelVirtualPeerId(sslId),peer_grp) && peer_grp != grpMeta.mGroupId)
|
||||
{
|
||||
#ifdef NXS_NET_DEBUG_4
|
||||
GXSNETDEBUG_PG(sslId,grpMeta.mGroupId) << " Distant peer designed for group " << peer_grp << ": cannot request sync for different group." << std::endl;
|
||||
@ -5064,6 +5075,18 @@ bool RsGxsNetService::removeGroups(const std::list<RsGxsGroupId>& groups)
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool RsGxsNetService::isDistantPeer(const RsPeerId& pid)
|
||||
{
|
||||
RS_STACK_MUTEX(mNxsMutex) ;
|
||||
|
||||
if(!mAllowDistSync || mGxsNetTunnel == NULL)
|
||||
return false ;
|
||||
|
||||
RsGxsGroupId group_id ;
|
||||
|
||||
return mGxsNetTunnel->isDistantPeer(RsGxsNetTunnelVirtualPeerId(pid),group_id);
|
||||
}
|
||||
|
||||
bool RsGxsNetService::stampMsgServerUpdateTS(const RsGxsGroupId& gid)
|
||||
{
|
||||
RS_STACK_MUTEX(mNxsMutex) ;
|
||||
|
@ -170,6 +170,7 @@ public:
|
||||
virtual bool getGroupServerUpdateTS(const RsGxsGroupId& gid,time_t& grp_server_update_TS,time_t& msg_server_update_TS) ;
|
||||
virtual bool stampMsgServerUpdateTS(const RsGxsGroupId& gid) ;
|
||||
virtual bool removeGroups(const std::list<RsGxsGroupId>& groups);
|
||||
virtual bool isDistantPeer(const RsPeerId& pid);
|
||||
|
||||
/* p3Config methods */
|
||||
public:
|
||||
|
@ -275,6 +275,7 @@ bool RsGxsNetTunnelService::requestDistantPeers(uint16_t service_id, const RsGxs
|
||||
ginfo.group_policy = RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_ACTIVE;
|
||||
|
||||
ginfo.hash = calculateGroupHash(group_id) ;
|
||||
ginfo.service_id = service_id;
|
||||
|
||||
mHandledHashes[ginfo.hash] = group_id ;
|
||||
|
||||
@ -307,39 +308,6 @@ bool RsGxsNetTunnelService::releaseDistantPeers(uint16_t service_id,const RsGxsG
|
||||
return true;
|
||||
}
|
||||
|
||||
const Bias20Bytes& RsGxsNetTunnelService::locked_randomBias()
|
||||
{
|
||||
if(mRandomBias.isNull())
|
||||
{
|
||||
#ifdef DEBUG_RSGXSNETTUNNEL
|
||||
#warning /!\ this is for testing only! Remove this when done! Can not be done at initialization when rsPeer is not started.
|
||||
RsPeerId ssl_id = rsPeers->getOwnId() ;
|
||||
mRandomBias = Bias20Bytes(RsDirUtil::sha1sum(ssl_id.toByteArray(),ssl_id.SIZE_IN_BYTES)) ;
|
||||
#else
|
||||
mRandomBias = Bias20Bytes::random();
|
||||
#endif
|
||||
IndicateConfigChanged();
|
||||
}
|
||||
|
||||
return mRandomBias ;
|
||||
}
|
||||
|
||||
RsGxsNetTunnelVirtualPeerId RsGxsNetTunnelService::locked_makeVirtualPeerId(const RsGxsGroupId& group_id)
|
||||
{
|
||||
assert(RsPeerId::SIZE_IN_BYTES <= Sha1CheckSum::SIZE_IN_BYTES) ;// so that we can build the virtual PeerId from a SHA1 sum.
|
||||
|
||||
// We compute sha1( SSL_id | mRandomBias ) and trunk it to 16 bytes in order to compute a RsPeerId
|
||||
|
||||
Bias20Bytes rb(locked_randomBias());
|
||||
|
||||
unsigned char mem[group_id.SIZE_IN_BYTES + rb.SIZE_IN_BYTES];
|
||||
|
||||
memcpy(mem ,group_id.toByteArray(),group_id.SIZE_IN_BYTES) ;
|
||||
memcpy(mem+group_id.SIZE_IN_BYTES,rb.toByteArray(),rb.SIZE_IN_BYTES) ;
|
||||
|
||||
return RsGxsNetTunnelVirtualPeerId(RsDirUtil::sha1sum(mem,group_id.SIZE_IN_BYTES+rb.SIZE_IN_BYTES).toByteArray());
|
||||
}
|
||||
|
||||
void RsGxsNetTunnelService::dump() const
|
||||
{
|
||||
RS_STACK_MUTEX(mGxsNetTunnelMtx);
|
||||
@ -379,7 +347,7 @@ void RsGxsNetTunnelService::dump() const
|
||||
std::cerr << " Virtual peers: " << std::endl;
|
||||
for(auto it(mVirtualPeers.begin());it!=mVirtualPeers.end();++it)
|
||||
std::cerr << " GXS Peer:" << it->first << " Turtle:" << it->second.turtle_virtual_peer_id
|
||||
<< " status: " << vpid_status_str[it->second.vpid_status] << " direction: "
|
||||
<< " status: " << vpid_status_str[it->second.vpid_status]
|
||||
<< " group_id: " << it->second.group_id
|
||||
<< " direction: " << (int)it->second.side
|
||||
<< " last seen " << time(NULL)-it->second.last_contact << " secs ago"
|
||||
@ -466,7 +434,9 @@ void RsGxsNetTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *item,co
|
||||
return ;
|
||||
}
|
||||
|
||||
if(getRsItemService(getRsItemId(data)) == RS_SERVICE_TYPE_GXS_NET_TUNNEL)
|
||||
uint16_t service_id = getRsItemService(getRsItemId(data));
|
||||
|
||||
if(service_id == RS_SERVICE_TYPE_GXS_NET_TUNNEL)
|
||||
{
|
||||
RsItem *decrypted_item = RsGxsNetTunnelSerializer().deserialise(data,&data_size);
|
||||
RsGxsNetTunnelVirtualPeerItem *pid_item = dynamic_cast<RsGxsNetTunnelVirtualPeerItem*>(decrypted_item) ;
|
||||
@ -491,52 +461,61 @@ void RsGxsNetTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *item,co
|
||||
vp_info.side = direction; // client/server
|
||||
vp_info.last_contact = time(NULL); // last time some data was sent/recvd
|
||||
vp_info.group_id = group_id;
|
||||
vp_info.service_id = mGroups[group_id].service_id ;
|
||||
|
||||
memcpy(vp_info.encryption_master_key,encryption_master_key,RS_GXS_TUNNEL_CONST_EKEY_SIZE);
|
||||
|
||||
vp_info.turtle_virtual_peer_id = turtle_virtual_peer_id; // turtle peer to use when sending data to this vpid.
|
||||
|
||||
free(data);
|
||||
|
||||
return ;
|
||||
}
|
||||
else
|
||||
|
||||
|
||||
// item is a generic data item for the client. Let's store the data in the appropriate incoming data queue.
|
||||
|
||||
auto it = mTurtle2GxsPeer.find(turtle_virtual_peer_id) ;
|
||||
|
||||
if(it == mTurtle2GxsPeer.end())
|
||||
{
|
||||
// item is a generic data item for the client. Let's store the data in the appropriate incoming data queue.
|
||||
GXS_NET_TUNNEL_ERROR() << "item received by GxsNetTunnel for vpid " << turtle_virtual_peer_id << " but this vpid is unknown!" << std::endl;
|
||||
free(data);
|
||||
return;
|
||||
}
|
||||
|
||||
auto it = mTurtle2GxsPeer.find(turtle_virtual_peer_id) ;
|
||||
RsGxsNetTunnelVirtualPeerId gxs_vpid = it->second ;
|
||||
|
||||
if(it == mTurtle2GxsPeer.end())
|
||||
{
|
||||
GXS_NET_TUNNEL_ERROR() << "item received by GxsNetTunnel for vpid " << turtle_virtual_peer_id << " but this vpid is unknown!" << std::endl;
|
||||
free(data);
|
||||
return;
|
||||
}
|
||||
auto it2 = mVirtualPeers.find(gxs_vpid) ;
|
||||
|
||||
RsGxsNetTunnelVirtualPeerId gxs_vpid = it->second ;
|
||||
if(it2 == mVirtualPeers.end())
|
||||
{
|
||||
GXS_NET_TUNNEL_ERROR() << "item received by GxsNetTunnel for GXS vpid " << gxs_vpid << " but the virtual peer id is missing!" << std::endl;
|
||||
free(data);
|
||||
return;
|
||||
}
|
||||
it2->second.vpid_status = RsGxsNetTunnelVirtualPeerInfo::RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE ; // status of the peer
|
||||
it2->second.last_contact = time(NULL); // last time some data was sent/recvd
|
||||
|
||||
auto it2 = mVirtualPeers.find(gxs_vpid) ;
|
||||
|
||||
if(it2 == mVirtualPeers.end())
|
||||
{
|
||||
GXS_NET_TUNNEL_ERROR() << "item received by GxsNetTunnel for GXS vpid " << gxs_vpid << " but the virtual peer id is missing!" << std::endl;
|
||||
free(data);
|
||||
return;
|
||||
}
|
||||
it2->second.vpid_status = RsGxsNetTunnelVirtualPeerInfo::RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE ; // status of the peer
|
||||
it2->second.last_contact = time(NULL); // last time some data was sent/recvd
|
||||
if(service_id != it2->second.service_id && service_id != RS_SERVICE_GXS_TYPE_GXSID)
|
||||
{
|
||||
GXS_NET_TUNNEL_ERROR() << " received an item for VPID " << gxs_vpid << " openned for service " << it2->second.service_id << " that is not for that service nor for GXS Id service (service=" << std::hex << service_id << std::dec << ". Rejecting!" << std::endl;
|
||||
free(data);
|
||||
return ;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_RSGXSNETTUNNEL
|
||||
GXS_NET_TUNNEL_DEBUG() << "item contains generic data for VPID " << gxs_vpid << ". Storing in incoming list" << std::endl;
|
||||
GXS_NET_TUNNEL_DEBUG() << "item contains generic data for VPID " << gxs_vpid << ". service_id = " << std::hex << service_id << std::dec << ". Storing in incoming list" << std::endl;
|
||||
#endif
|
||||
|
||||
// push the data into the incoming data list
|
||||
// push the data into the incoming data list
|
||||
|
||||
RsTlvBinaryData *bind = new RsTlvBinaryData;
|
||||
bind->tlvtype = 0;
|
||||
bind->bin_len = data_size;
|
||||
bind->bin_data = data;
|
||||
RsTlvBinaryData *bind = new RsTlvBinaryData;
|
||||
bind->tlvtype = 0;
|
||||
bind->bin_len = data_size;
|
||||
bind->bin_data = data;
|
||||
|
||||
mIncomingData.push_back(std::make_pair(gxs_vpid,bind)) ;
|
||||
}
|
||||
mIncomingData[service_id].push_back(std::make_pair(gxs_vpid,bind)) ;
|
||||
}
|
||||
|
||||
void RsGxsNetTunnelService::addVirtualPeer(const TurtleFileHash& hash, const TurtleVirtualPeerId& vpid,RsTurtleGenericTunnelItem::Direction dir)
|
||||
@ -679,6 +658,40 @@ void RsGxsNetTunnelService::data_tick()
|
||||
rstime::rs_usleep(1*1000*1000) ; // 1 sec
|
||||
}
|
||||
|
||||
const Bias20Bytes& RsGxsNetTunnelService::locked_randomBias()
|
||||
{
|
||||
if(mRandomBias.isNull())
|
||||
{
|
||||
#ifdef DEBUG_RSGXSNETTUNNEL
|
||||
#warning /!\ this is for testing only! Remove this when done! Can not be done at initialization when rsPeer is not started.
|
||||
RsPeerId ssl_id = rsPeers->getOwnId() ;
|
||||
mRandomBias = Bias20Bytes(RsDirUtil::sha1sum(ssl_id.toByteArray(),ssl_id.SIZE_IN_BYTES)) ;
|
||||
#else
|
||||
mRandomBias = Bias20Bytes::random();
|
||||
#endif
|
||||
IndicateConfigChanged();
|
||||
}
|
||||
|
||||
return mRandomBias ;
|
||||
}
|
||||
|
||||
RsGxsNetTunnelVirtualPeerId RsGxsNetTunnelService::locked_makeVirtualPeerId(const RsGxsGroupId& group_id)
|
||||
{
|
||||
assert(RsPeerId::SIZE_IN_BYTES <= Sha1CheckSum::SIZE_IN_BYTES) ;// so that we can build the virtual PeerId from a SHA1 sum.
|
||||
|
||||
// We compute sha1( SSL_id | mRandomBias ) and trunk it to 16 bytes in order to compute a RsPeerId
|
||||
|
||||
Bias20Bytes rb(locked_randomBias());
|
||||
|
||||
unsigned char mem[group_id.SIZE_IN_BYTES + rb.SIZE_IN_BYTES];
|
||||
|
||||
memcpy(mem ,group_id.toByteArray(),group_id.SIZE_IN_BYTES) ;
|
||||
memcpy(mem+group_id.SIZE_IN_BYTES,rb.toByteArray(),rb.SIZE_IN_BYTES) ;
|
||||
|
||||
return RsGxsNetTunnelVirtualPeerId(RsDirUtil::sha1sum(mem,group_id.SIZE_IN_BYTES+rb.SIZE_IN_BYTES).toByteArray());
|
||||
}
|
||||
|
||||
|
||||
void RsGxsNetTunnelService::sendKeepAlivePackets()
|
||||
{
|
||||
RS_STACK_MUTEX(mGxsNetTunnelMtx);
|
||||
@ -834,14 +847,8 @@ bool RsGxsNetTunnelService::loadList(std::list<RsItem *> &load)
|
||||
|
||||
RsSerialiser *RsGxsNetTunnelService::setupSerialiser()
|
||||
{
|
||||
RS_STACK_MUTEX(mGxsNetTunnelMtx);
|
||||
static RsSerialiser *ser = NULL ; // this is not so nice, but this method is only called from p3Config, so there's no really need of a data race
|
||||
|
||||
if(!ser)
|
||||
{
|
||||
ser = new RsSerialiser ;
|
||||
ser->addSerialType(new RsGxsNetTunnelSerializer) ;
|
||||
}
|
||||
RsSerialiser *ser = new RsSerialiser ;
|
||||
ser->addSerialType(new RsGxsNetTunnelSerializer) ;
|
||||
|
||||
return ser ;
|
||||
}
|
||||
|
@ -120,6 +120,7 @@ struct RsGxsNetTunnelVirtualPeerInfo
|
||||
TurtleVirtualPeerId turtle_virtual_peer_id ; // turtle peer to use when sending data to this vpid.
|
||||
|
||||
RsGxsGroupId group_id ; // group that virtual peer is providing
|
||||
uint16_t service_id ; // this is used for checkng consistency of the incoming data
|
||||
};
|
||||
|
||||
struct RsGxsNetTunnelGroupInfo
|
||||
@ -144,6 +145,7 @@ struct RsGxsNetTunnelGroupInfo
|
||||
GroupStatus group_status ;
|
||||
time_t last_contact ;
|
||||
TurtleFileHash hash ;
|
||||
uint16_t service_id ;
|
||||
|
||||
std::set<TurtleVirtualPeerId> virtual_peers ; // list of which virtual peers provide this group. Can me more than 1.
|
||||
};
|
||||
|
@ -166,6 +166,14 @@ public:
|
||||
*/
|
||||
virtual bool stampMsgServerUpdateTS(const RsGxsGroupId& gid) =0;
|
||||
|
||||
/*!
|
||||
* \brief isDistantPeer
|
||||
* \param pid peer that is a virtual peer provided by GxsNetTunnel
|
||||
* \return
|
||||
* true if the peer exists (adn therefore is online)
|
||||
*/
|
||||
virtual bool isDistantPeer(const RsPeerId& pid)=0;
|
||||
|
||||
/*!
|
||||
* \brief removeGroups
|
||||
* Removes time stamp information from the list of groups. This allows to re-sync them if suppliers are present.
|
||||
|
@ -1279,6 +1279,14 @@ int RsServer::StartupRetroShare()
|
||||
|
||||
RsNxsNetMgr* nxsMgr = new RsNxsNetMgrImpl(serviceCtrl);
|
||||
|
||||
/**** GXS Dist sync service ****/
|
||||
|
||||
#ifdef RS_USE_GXS_DISTANT_SYNC
|
||||
RsGxsNetTunnelService *mGxsNetTunnel = new RsGxsNetTunnelService ;
|
||||
#else
|
||||
RsGxsNetTunnelService *mGxsNetTunnel = NULL ;
|
||||
#endif
|
||||
|
||||
/**** Identity service ****/
|
||||
|
||||
RsGeneralDataService* gxsid_ds = new RsDataService(currGxsDir + "/", "gxsid_db",
|
||||
@ -1300,9 +1308,10 @@ int RsServer::StartupRetroShare()
|
||||
RS_SERVICE_GXS_TYPE_GXSID, gxsid_ds, nxsMgr,
|
||||
mGxsIdService, mGxsIdService->getServiceInfo(),
|
||||
mReputations, mGxsCircles,mGxsIdService,
|
||||
pgpAuxUtils,NULL,
|
||||
false,false); // don't synchronise group automatic (need explicit group request)
|
||||
pgpAuxUtils,mGxsNetTunnel,
|
||||
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
|
||||
|
||||
// Normally we wouldn't need this (we do in other service):
|
||||
// mGxsIdService->setNetworkExchangeService(gxsid_ns) ;
|
||||
@ -1358,14 +1367,6 @@ int RsServer::StartupRetroShare()
|
||||
mWiki->setNetworkExchangeService(wiki_ns) ;
|
||||
#endif
|
||||
|
||||
/**** GXS Dist sync service ****/
|
||||
|
||||
#ifdef RS_USE_GXS_DISTANT_SYNC
|
||||
RsGxsNetTunnelService *mGxsNetTunnel = new RsGxsNetTunnelService ;
|
||||
#else
|
||||
RsGxsNetTunnelService *mGxsNetTunnel = NULL ;
|
||||
#endif
|
||||
|
||||
/**** Forum GXS service ****/
|
||||
|
||||
RsGeneralDataService* gxsforums_ds = new RsDataService(currGxsDir + "/", "gxsforums_db",
|
||||
|
@ -2700,7 +2700,7 @@ void p3IdService::requestIdsFromNet()
|
||||
bool request_can_proceed = false ;
|
||||
|
||||
for(cit2 = peers.begin(); cit2 != peers.end(); ++cit2)
|
||||
if(rsPeers->isOnline(*cit2)) // make sure that the peer in online, so that we know that the request has some chance to succeed.
|
||||
if(rsPeers->isOnline(*cit2) || mNes->isDistantPeer(*cit2)) // make sure that the peer in online, so that we know that the request has some chance to succeed.
|
||||
{
|
||||
requests[*cit2].push_back(cit->first);
|
||||
request_can_proceed = true ;
|
||||
|
Loading…
Reference in New Issue
Block a user