shared virtual peers across services

This commit is contained in:
csoler 2018-03-29 16:26:36 +02:00
parent 73b04f3109
commit f0f69b8dd9
No known key found for this signature in database
GPG Key ID: 7BCA522266C0804C
3 changed files with 170 additions and 154 deletions

View File

@ -565,6 +565,20 @@ void RsGxsNetService::syncWithPeers()
std::set<RsPeerId> peers;
mNetMgr->getOnlineList(mServiceInfo.mServiceType, peers);
#ifdef TODO
if(mAllowDistSync)
{
// Grab all online virtual peers of distant tunnels for the current service.
std::list<RsGxsNetTunnelVirtualPeerId> vpids ;
mGxsNetTunnel->getVirtualPeers(mServType,vpids);
for(auto it(vpids.begin());it!=vpids.end();++it)
peers.push_back(RsPeerId(*it)) ;
}
#endif
if (peers.empty()) {
// nothing to do
return;

View File

@ -43,11 +43,9 @@ RsGxsNetTunnelService::RsGxsNetTunnelService(): mGxsNetTunnelMtx("GxsNetTunnel")
RsGxsNetTunnelVirtualPeerInfo::~RsGxsNetTunnelVirtualPeerInfo()
{
for(auto it(outgoing_items.begin());it!=outgoing_items.end();++it)
delete *it ;
for(auto it(incoming_data.begin());it!=incoming_data.end();++it)
delete *it ;
for(auto it(providing_set.begin());it!=providing_set.end();++it)
for(auto it2(it->second.incoming_data.begin());it2!=it->second.incoming_data.end();++it2)
delete *it2 ;
}
//===========================================================================================================================================//
@ -131,8 +129,21 @@ public:
unsigned char *& mData;
};
RsGxsNetTunnelService::~RsGxsNetTunnelService()
{
RS_STACK_MUTEX(mGxsNetTunnelMtx);
// This is needed because we need to clear these structure in a mutex protected environment
// Also this calls the destructor of the objects which calls the freeing of memory e.g. allocated in the incoming data list.
mGroups.clear();
mHandledHashes.clear();
mVirtualPeers.clear();
}
bool RsGxsNetTunnelService::sendData(unsigned char *& data,uint32_t data_len,const RsGxsNetTunnelVirtualPeerId& virtual_peer)
{
RS_STACK_MUTEX(mGxsNetTunnelMtx);
// The item is serialized and encrypted using chacha20+SHA256, using the generic turtle encryption, and then sent to the turtle router.
DataAutoDelete iad(data) ; // This ensures the item is deleted whatsoever when leaving
@ -147,25 +158,9 @@ bool RsGxsNetTunnelService::sendData(unsigned char *& data,uint32_t data_len,con
return false ;
}
auto it2 = mGroups.find(it->second.first);
if(it2 == mGroups.end())
if(it->second.vpid_status != RsGxsNetTunnelVirtualPeerInfo::RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE)
{
GXS_NET_TUNNEL_ERROR() << "cannot find virtual peer " << virtual_peer << ". Data is dropped." << std::endl;
return false ;
}
auto it3 = it2->second.virtual_peers.find(it->second.second);
if(it3 == it2->second.virtual_peers.end())
{
std::cerr << "cannot find turtle virtual peer " << it->second.second << ". Data is dropped." << std::endl;
return false ;
}
if(it3->second.vpid_status != RsGxsNetTunnelVirtualPeerInfo::RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE)
{
GXS_NET_TUNNEL_ERROR() << "virtual peer " << it->second.second << " is not active. Data is dropped." << std::endl;
GXS_NET_TUNNEL_ERROR() << "virtual peer " << virtual_peer << " is not active. Data is dropped." << std::endl;
return false ;
}
@ -173,18 +168,18 @@ bool RsGxsNetTunnelService::sendData(unsigned char *& data,uint32_t data_len,con
RsTurtleGenericDataItem *encrypted_turtle_item = NULL ;
if(!p3turtle::encryptData(data,data_len,it3->second.encryption_master_key,encrypted_turtle_item))
if(!p3turtle::encryptData(data,data_len,it->second.encryption_master_key,encrypted_turtle_item))
{
GXS_NET_TUNNEL_ERROR() << "cannot encrypt. Something's wrong. Data is dropped." << std::endl;
return false ;
}
mTurtle->sendTurtleData(it->second.second,encrypted_turtle_item) ;
mTurtle->sendTurtleData(it->second.turtle_virtual_peer_id,encrypted_turtle_item) ;
return true ;
}
bool RsGxsNetTunnelService::getVirtualPeers(const RsGxsGroupId& group_id, std::list<RsGxsNetTunnelVirtualPeerId>& peers)
bool RsGxsNetTunnelService::getVirtualPeers(uint16_t service_id, std::list<RsGxsNetTunnelVirtualPeerId>& peers)
{
// This function has two effects:
// - return the virtual peers for this group
@ -194,21 +189,12 @@ bool RsGxsNetTunnelService::getVirtualPeers(const RsGxsGroupId& group_id, std::l
// update the hash entry if needed
RsFileHash hash = calculateGroupHash(group_id);
mHandledHashes[hash] = group_id ;
// Create the group entry, if needed, with passive mode.
RsGxsNetTunnelGroupInfo& ginfo( mGroups[group_id] ) ;
ginfo.hash = hash ;
for(auto it2 = ginfo.virtual_peers.begin();it2 != ginfo.virtual_peers.end();++it2)
if(it2->second.vpid_status == RsGxsNetTunnelVirtualPeerInfo::RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE)
peers.push_back(it2->second.net_service_virtual_peer) ;
for(auto it(mVirtualPeers.begin());it!=mVirtualPeers.end();++it)
if(it->second.providing_set.find(service_id) != it->second.providing_set.end())
peers.push_back(it->first) ;
#ifdef DEBUG_GXS_TUNNEL
GXS_NET_TUNNEL_DEBUG() << "returning " << peers.size() << " peers." << std::endl;
GXS_NET_TUNNEL_DEBUG() << " service " << std::hex << service_id << std::dec << " returning " << peers.size() << " peers." << std::endl;
#endif
return true ;
@ -243,19 +229,19 @@ bool RsGxsNetTunnelService::releasePeers(const RsGxsGroupId& group_id)
return true;
}
RsGxsNetTunnelVirtualPeerId RsGxsNetTunnelService::makeServerVirtualPeerIdForGroup(const RsGxsGroupId& group_id) const
RsGxsNetTunnelVirtualPeerId RsGxsNetTunnelService::locked_makeVirtualPeerId() const
{
assert(RsPeerId::SIZE_IN_BYTES <= Sha1CheckSum::SIZE_IN_BYTES) ;
// We compute sha1( SSL_id | group_id | mRandomBias ) and trunk it to 16 bytes in order to compute a RsPeerId
// We compute sha1( SSL_id | mRandomBias ) and trunk it to 16 bytes in order to compute a RsPeerId
RsPeerId ssl_id = rsPeers->getOwnId() ;
unsigned char mem[RsPeerId::SIZE_IN_BYTES + RsGxsGroupId::SIZE_IN_BYTES + RS_GXS_TUNNEL_CONST_RANDOM_BIAS_SIZE];
unsigned char mem[RsPeerId::SIZE_IN_BYTES /*+ RsGxsGroupId::SIZE_IN_BYTES */ + RS_GXS_TUNNEL_CONST_RANDOM_BIAS_SIZE];
memcpy(mem ,ssl_id.toByteArray() ,RsPeerId::SIZE_IN_BYTES) ;
memcpy(mem+RsPeerId::SIZE_IN_BYTES ,group_id.toByteArray(),RsGxsGroupId::SIZE_IN_BYTES) ;
memcpy(mem+RsPeerId::SIZE_IN_BYTES+RsGxsGroupId::SIZE_IN_BYTES,mRandomBias ,RS_GXS_TUNNEL_CONST_RANDOM_BIAS_SIZE) ;
//memcpy(mem+RsPeerId::SIZE_IN_BYTES ,group_id.toByteArray(),RsGxsGroupId::SIZE_IN_BYTES) ;
memcpy(mem+RsPeerId::SIZE_IN_BYTES /*+RsGxsGroupId::SIZE_IN_BYTES*/,mRandomBias ,RS_GXS_TUNNEL_CONST_RANDOM_BIAS_SIZE) ;
return RsGxsNetTunnelVirtualPeerId(RsDirUtil::sha1sum(mem,RsPeerId::SIZE_IN_BYTES+RsGxsGroupId::SIZE_IN_BYTES+RS_GXS_TUNNEL_CONST_RANDOM_BIAS_SIZE).toByteArray());
}
@ -264,12 +250,18 @@ void RsGxsNetTunnelService::dump() const
{
RS_STACK_MUTEX(mGxsNetTunnelMtx);
static std::string group_status_str[3] = {
static std::string group_status_str[4] = {
std::string("[RS_GXS_NET_TUNNEL_GRP_STATUS_UNKNOWN ]"),
std::string("[RS_GXS_NET_TUNNEL_GRP_STATUS_IDLE ]"),
std::string("[RS_GXS_NET_TUNNEL_GRP_STATUS_TUNNELS_REQUESTED]"),
std::string("[RS_GXS_NET_TUNNEL_GRP_STATUS_VPIDS_AVAILABLE ]")
};
static std::string group_policy_str[3] = {
std::string("[RS_GXS_NET_TUNNEL_POLICY_UNKNOWN]"),
std::string("[RS_GXS_NET_TUNNEL_POLICY_PASSIVE]"),
std::string("[RS_GXS_NET_TUNNEL_POLICY_ACTIVE ]"),
};
static std::string vpid_status_str[3] = {
std::string("[RS_GXS_NET_TUNNEL_VP_STATUS_UNKNOWN ]"),
std::string("[RS_GXS_NET_TUNNEL_VP_STATUS_TUNNEL_OK ]"),
@ -281,18 +273,23 @@ void RsGxsNetTunnelService::dump() const
for(auto it(mGroups.begin());it!=mGroups.end();++it)
{
std::cerr << " " << it->first << " hash: " << it->second.hash << " status: " << group_status_str[it->second.group_status] << "] Last contact: " << time(NULL) - it->second.last_contact << " secs ago" << std::endl;
std::cerr << " " << it->first << " hash: " << it->second.hash << " policy: " << group_policy_str[it->second.group_policy] << " status: " << group_status_str[it->second.group_status] << "] Last contact: " << time(NULL) - it->second.last_contact << " secs ago" << std::endl;
std::cerr << " virtual peers:" << std::endl;
for(auto it2(it->second.virtual_peers.begin());it2!=it->second.virtual_peers.end();++it2)
std::cerr << " turtle:" << it2->first << " status: " << vpid_status_str[it2->second.vpid_status] << " s: "
<< (int)it2->second.side << " last seen " << time(NULL)-it2->second.last_contact
<< " ekey: " << RsUtil::BinToHex(it2->second.encryption_master_key,RS_GXS_TUNNEL_CONST_EKEY_SIZE)
<< " pending (" << it2->second.incoming_data.size() << "," << it2->second.outgoing_items.size() << ")" << std::endl;
std::cerr << " " << *it2 << std::endl;
}
std::cerr << "Virtual peers: " << std::endl;
for(auto it(mVirtualPeers.begin());it!=mVirtualPeers.end();++it)
std::cerr << " GXS Peer:" << it->first << " group_id: " << it->second.first << " Turtle:" << it->second.second << std::endl;
{
std::cerr << " GXS Peer:" << it->first << " Turtle:" << it->second.turtle_virtual_peer_id
<< " status: " << vpid_status_str[it->second.vpid_status] << " s: "
<< (int)it->second.side << " last seen " << time(NULL)-it->second.last_contact
<< " ekey: " << RsUtil::BinToHex(it->second.encryption_master_key,RS_GXS_TUNNEL_CONST_EKEY_SIZE) ;
for(auto it2(it->second.providing_set.begin());it2!=it->second.providing_set.end();++it2)
std::cerr << " service " << std::hex << it2->first << std::dec << " " << it2->second.provided_groups.size() << " groups, " << it2->second.incoming_data.size() << " data" << std::endl;
}
std::cerr << "Hashes: " << std::endl;
for(auto it(mHandledHashes.begin());it!=mHandledHashes.end();++it)
@ -311,15 +308,18 @@ void RsGxsNetTunnelService::connectToTurtleRouter(p3turtle *tr)
bool RsGxsNetTunnelService::handleTunnelRequest(const RsFileHash &hash,const RsPeerId& peer_id)
{
RS_STACK_MUTEX(mGxsNetTunnelMtx);
// We simply check for wether a managed group has a hash that corresponds to the given hash.
return mHandledHashes.find(hash) != mHandledHashes.end();
}
void RsGxsNetTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *item,const RsFileHash& hash,const RsPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction)
void RsGxsNetTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *item,const RsFileHash& hash,const RsPeerId& turtle_virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction)
{
RS_STACK_MUTEX(mGxsNetTunnelMtx);
#ifdef DEBUG_RSGXSNETTUNNEL
GXS_NET_TUNNEL_DEBUG() << " received turtle data for vpid " << virtual_peer_id << " for hash " << hash << " in direction " << (int)direction << std::endl;
GXS_NET_TUNNEL_DEBUG() << " received turtle data for vpid " << turtle_virtual_peer_id << " for hash " << hash << " in direction " << (int)direction << std::endl;
#endif
if(item->PacketSubType() != RS_TURTLE_SUBTYPE_GENERIC_DATA)
@ -327,45 +327,29 @@ void RsGxsNetTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *item,co
GXS_NET_TUNNEL_ERROR() << "item with type " << std::hex << item->PacketSubType() << std::dec << " received by GxsNetTunnel, but is not handled!" << std::endl;
return;
}
// (cyril) this is a bit complicated. We should store pointers to the encryption keys in another structure and access it directly.
// find the group id
auto it = mHandledHashes.find(hash) ;
if(it == mHandledHashes.end())
{
GXS_NET_TUNNEL_ERROR() << "item received by GxsNetTunnel for hash " << hash << " but this hash is unknown!" << std::endl;
GXS_NET_TUNNEL_ERROR() << "Cannot find hash " << hash << " to be handled by GxsNetTunnel" << std::endl;
return;
}
RsGxsGroupId group_id = it->second;
auto it2 = mGroups.find(group_id) ;
if(it2 == mGroups.end())
{
GXS_NET_TUNNEL_ERROR() << "item received by GxsNetTunnel for hash " << hash << " and group " << group_id << " but this group id is unknown!" << std::endl;
return;
}
RsGxsNetTunnelGroupInfo& g_info(it2->second) ;
g_info.last_contact = time(NULL) ;
auto it3 = g_info.virtual_peers.find(virtual_peer_id) ;
if(it3 == g_info.virtual_peers.end())
{
GXS_NET_TUNNEL_ERROR() << "item received by GxsNetTunnel for hash " << hash << ", group " << group_id << " but the virtual peer id is missing!" << std::endl;
return;
}
RsGxsNetTunnelVirtualPeerInfo& vp_info(it3->second) ;
// Now check if we got an item to advertise a virtual peer
unsigned char *data = NULL ;
uint32_t data_size = 0 ;
if(!p3turtle::decryptItem(static_cast<RsTurtleGenericDataItem*>(item),vp_info.encryption_master_key,data,data_size))
// generate the decryption key based on virtual peer id and group id
uint8_t encryption_master_key[RS_GXS_TUNNEL_CONST_EKEY_SIZE] ;
generateEncryptionKey(group_id,turtle_virtual_peer_id,encryption_master_key);
if(!p3turtle::decryptItem(static_cast<RsTurtleGenericDataItem*>(item),encryption_master_key,data,data_size))
{
GXS_NET_TUNNEL_ERROR() << "Cannot decrypt data!" << std::endl;
@ -375,28 +359,45 @@ void RsGxsNetTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *item,co
return ;
}
// Now we might get 2 kinds of items: GxsNetTunnel items, to be handled here, and Gxs data items, to be handled by the client service
RsItem *decrypted_item = RsGxsNetTunnelSerializer().deserialise(data,&data_size);
RsGxsNetTunnelVirtualPeerItem *pid_item = dynamic_cast<RsGxsNetTunnelVirtualPeerItem*>(decrypted_item) ;
if(pid_item)
{
if(direction == RsTurtleGenericTunnelItem::DIRECTION_SERVER)
{
#ifdef DEBUG_RSGXSNETTUNNEL
GXS_NET_TUNNEL_DEBUG() << " item is a virtual peer id item with vpid = "<< pid_item->virtual_peer_id << ". Setting virtual peer." << std::endl;
GXS_NET_TUNNEL_DEBUG() << " item is a virtual peer id item with vpid = "<< pid_item->virtual_peer_id << ". Setting virtual peer." << std::endl;
#endif
#ifdef TODO
vp_info.net_service_virtual_peer = pid_item->virtual_peer_id;
vp_info.vpid_status = RsGxsNetTunnelVirtualPeerInfo::RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE ;
#endif
vp_info.net_service_virtual_peer = pid_item->virtual_peer_id;
vp_info.vpid_status = RsGxsNetTunnelVirtualPeerInfo::RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE ;
}
else
GXS_NET_TUNNEL_ERROR() << "Cannot decrypt data!" << std::endl;
free(data);
return ;
}
#ifdef TODO
auto it = mTurtle2GxsPeer.find(turtle_virtual_peer_id) ;
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;
return;
}
RsGxsNetTunnelVirtualPeerId gxs_vpid = it->second ;
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;
return;
}
RsGxsNetTunnelVirtualPeerInfo& vp_info(it2->second) ;
else
{
#ifdef DEBUG_RSGXSNETTUNNEL
@ -411,10 +412,13 @@ void RsGxsNetTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *item,co
vp_info.incoming_data.push_back(bind) ;
}
#endif
}
void RsGxsNetTunnelService::addVirtualPeer(const TurtleFileHash& hash, const TurtleVirtualPeerId& vpid,RsTurtleGenericTunnelItem::Direction dir)
{
RS_STACK_MUTEX(mGxsNetTunnelMtx);
auto it = mHandledHashes.find(hash) ;
if(it == mHandledHashes.end())
@ -431,23 +435,19 @@ void RsGxsNetTunnelService::addVirtualPeer(const TurtleFileHash& hash, const Tur
RsGxsNetTunnelGroupInfo& ginfo( mGroups[group_id] ) ;
ginfo.group_status = RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_STATUS_VPIDS_AVAILABLE ;
RsGxsNetTunnelVirtualPeerInfo& vpinfo( ginfo.virtual_peers[vpid] ) ;
uint8_t encryption_master_key[RS_GXS_TUNNEL_CONST_EKEY_SIZE];
vpinfo.vpid_status = RsGxsNetTunnelVirtualPeerInfo::RS_GXS_NET_TUNNEL_VP_STATUS_TUNNEL_OK ;
vpinfo.side = dir ;
vpinfo.last_contact = time(NULL) ;
generateEncryptionKey(group_id,vpid,vpinfo.encryption_master_key );
generateEncryptionKey(group_id,vpid,encryption_master_key );
// We need to send our own virtual peer id to the other end of the tunnel
vpinfo.net_service_virtual_peer = makeServerVirtualPeerIdForGroup(group_id);
RsGxsNetTunnelVirtualPeerId net_service_virtual_peer = locked_makeVirtualPeerId();
#ifdef DEBUG_RSGXSNETTUNNEL
GXS_NET_TUNNEL_DEBUG() << " sending back virtual peer name " << vpinfo.net_service_virtual_peer << " to end of tunnel" << std::endl;
GXS_NET_TUNNEL_DEBUG() << " sending back virtual peer name " << net_service_virtual_peer << " to end of tunnel" << std::endl;
#endif
RsGxsNetTunnelVirtualPeerItem pitem ;
pitem.virtual_peer_id = vpinfo.net_service_virtual_peer ;
pitem.virtual_peer_id = net_service_virtual_peer ;
RsTemporaryMemory tmpmem( RsGxsNetTunnelSerializer().size(&pitem) ) ;
uint32_t len = tmpmem.size();
@ -456,7 +456,7 @@ void RsGxsNetTunnelService::addVirtualPeer(const TurtleFileHash& hash, const Tur
RsTurtleGenericDataItem *encrypted_turtle_item = NULL ;
if(p3turtle::encryptData(tmpmem,len,vpinfo.encryption_master_key,encrypted_turtle_item))
if(p3turtle::encryptData(tmpmem,len,encryption_master_key,encrypted_turtle_item))
mTurtle->sendTurtleData(vpid,encrypted_turtle_item) ;
else
GXS_NET_TUNNEL_ERROR() << "cannot encrypt. Something's wrong. Data is dropped." << std::endl;
@ -464,6 +464,8 @@ void RsGxsNetTunnelService::addVirtualPeer(const TurtleFileHash& hash, const Tur
void RsGxsNetTunnelService::removeVirtualPeer(const TurtleFileHash& hash, const TurtleVirtualPeerId& vpid)
{
RS_STACK_MUTEX(mGxsNetTunnelMtx);
#ifdef DEBUG_RSGXSNETTUNNEL
GXS_NET_TUNNEL_DEBUG() << " removing virtual peer " << vpid << " for hash " << hash << std::endl;
#endif
@ -496,7 +498,7 @@ RsFileHash RsGxsNetTunnelService::calculateGroupHash(const RsGxsGroupId& group_i
return RsDirUtil::sha1sum(group_id.toByteArray(),RsGxsGroupId::SIZE_IN_BYTES) ;
}
void RsGxsNetTunnelService::generateEncryptionKey(const RsGxsGroupId& group_id,const TurtleVirtualPeerId& vpid,unsigned char key[RS_GXS_TUNNEL_CONST_EKEY_SIZE]) const
void RsGxsNetTunnelService::generateEncryptionKey(const RsGxsGroupId& group_id,const TurtleVirtualPeerId& vpid,unsigned char key[RS_GXS_TUNNEL_CONST_EKEY_SIZE])
{
// The key is generated as H(group_id | vpid)
// Because group_id is not known it shouldn't be possible to recover the key by observing the traffic.
@ -519,12 +521,19 @@ void RsGxsNetTunnelService::data_tick()
{
GXS_NET_TUNNEL_DEBUG() << std::endl;
time_t now = time(NULL);
// cleanup
autowash();
static time_t last_autowash = time(NULL);
if(last_autowash + 5 > now)
{
autowash();
last_autowash = now;
}
static time_t last_dump = time(NULL);
time_t now = time(NULL);
if(last_dump + 10 > now)
{
@ -535,44 +544,24 @@ void RsGxsNetTunnelService::data_tick()
void RsGxsNetTunnelService::autowash()
{
RS_STACK_MUTEX(mGxsNetTunnelMtx);
for(auto it(mGroups.begin());it!=mGroups.end();++it)
{
// check if the group is in active or passive mode, in which case make sure that turtle manages tunnels or not.
// if active, then we check wether they are tunnels are not. If not, we ask turtle to monitor.
RsGxsNetTunnelGroupInfo& ginfo(it->second) ;
if(ginfo.group_policy == RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_ACTIVE && ginfo.virtual_peers.empty())
{
mTurtle->monitorTunnels(ginfo.hash,this,false) ;
ginfo.group_status = RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_STATUS_TUNNELS_REQUESTED;
}
if(ginfo.group_policy == RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_PASSIVE)
mTurtle->stopMonitoringTunnels(ginfo.hash);
}
}
// info.group_status = RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_STATUS_TUNNELS_REQUESTED;
//
// mTurtle->monitorTunnels(hash,this,false) ;
// info.group_status = RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_STATUS_TUNNELS_REQUESTED;
// void RsGxsNetTunnelService::handleIncoming(const RsGxsTunnelId& tunnel_id,RsGxsTunnelItem *item)
// {
// #ifdef DEBUG_RSGXSNETTUNNEL
// GXS_NET_TUNNEL_DEBUG() << " received turtle data for vpid " << virtual_peer_id << " for hash " << hash << " in direction " << dir << std::endl;
// #endif
// if(item == NULL)
// return ;
//
// // We have 3 things to do:
// //
// // 1 - if it's a data item, send an ACK
// // 2 - if it's an ack item, mark the item as properly received, and remove it from the queue
// // 3 - if it's a status item, act accordingly.
//
// switch(item->PacketSubType())
// {
//
// case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA: handleRecvTunnelDataItem(tunnel_id,dynamic_cast<RsGxsTunnelDataItem*>(item)) ;
// break ;
//
// case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK: handleRecvTunnelDataAckItem(tunnel_id,dynamic_cast<RsGxsTunnelDataAckItem*>(item)) ;
// break ;
//
// case RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS: handleRecvStatusItem(tunnel_id,dynamic_cast<RsGxsTunnelStatusItem*>(item)) ;
// break ;
//
// default:
// std::cerr << "(EE) impossible situation. DH items should be handled at the service level" << std::endl;
// }
//
// delete item ;
// }

View File

@ -82,11 +82,22 @@
// However, a call should be made to set a particular group policy to "ACTIVE" for group that do not have peers and need some.
//
// * services also need to retrieve GXS data items that come out of tunnels. These will be available as (data,len) type, since they are not de-serialized.
//
// * GxsNetService stores data information (such as update maps) per peerId, so it makes sense to use the same PeerId for all groups of a given service
// Therefore, virtual peers are stored separately from groups, because each one can sync multiple groups.
//
// * virtual peers are also shared among services. This reduces the required amount of tunnels and tunnel requests to send.
typedef RsPeerId RsGxsNetTunnelVirtualPeerId ;
class RsGxsNetTunnelItem ;
struct RsGxsNetTunnelVirtualPeerProvidingSet
{
std::set<RsGxsGroupId> provided_groups ;
std::list<RsTlvBinaryData*> incoming_data ;
};
struct RsGxsNetTunnelVirtualPeerInfo
{
enum { RS_GXS_NET_TUNNEL_VP_STATUS_UNKNOWN = 0x00, // unknown status.
@ -102,11 +113,10 @@ struct RsGxsNetTunnelVirtualPeerInfo
uint8_t encryption_master_key[32] ; // key from which the encryption key is derived for each virtual peer (using H(master_key | random IV))
time_t last_contact ; // last time some data was sent/recvd
RsGxsNetTunnelVirtualPeerId net_service_virtual_peer ; // anonymised peer that is used to communicate with client services
RsGxsGroupId group_id ; // group id
TurtleVirtualPeerId turtle_virtual_peer_id ; // turtle peer to use when sending data to this vpid.
RsGxsGroupId group_id ; // group id
std::list<RsTlvBinaryData*> incoming_data ;
std::list<RsItem*> outgoing_items ;
std::map<uint16_t,RsGxsNetTunnelVirtualPeerProvidingSet> providing_set; // partial list of groups provided by this virtual peer id, based on tunnel results, for each service
};
struct RsGxsNetTunnelGroupInfo
@ -124,20 +134,22 @@ struct RsGxsNetTunnelGroupInfo
RS_GXS_NET_TUNNEL_GRP_POLICY_ACTIVE = 0x02, // group explicitely request tunnels, if none available
};
RsGxsNetTunnelGroupInfo() : group_policy(RS_GXS_NET_TUNNEL_GRP_POLICY_PASSIVE),group_status(RS_GXS_NET_TUNNEL_GRP_STATUS_IDLE),last_contact(0) {}
RsGxsNetTunnelGroupInfo() : group_policy(RS_GXS_NET_TUNNEL_GRP_POLICY_PASSIVE),group_status(RS_GXS_NET_TUNNEL_GRP_STATUS_IDLE),last_contact(0),service_id(0) {}
GroupPolicy group_policy ;
GroupStatus group_status ;
time_t last_contact ;
TurtleFileHash hash ;
uint16_t service_id ;
std::map<TurtleVirtualPeerId, RsGxsNetTunnelVirtualPeerInfo> virtual_peers ;
std::set<RsGxsNetTunnelVirtualPeerId> virtual_peers ; // list of which virtual peers provide this group. Can me more than 1.
};
class RsGxsNetTunnelService: public RsTurtleClientService, public RsTickingThread
{
public:
RsGxsNetTunnelService() ;
virtual ~RsGxsNetTunnelService() ;
/*!
* \brief Manage tunnels for this group
@ -155,7 +167,7 @@ public:
* \brief Get the list of active virtual peers for a given group. This implies that a tunnel is up and
* alive. This function also "registers" the group which allows to handle tunnel requests in the server side.
*/
bool getVirtualPeers(const RsGxsGroupId& group_id, std::list<RsGxsNetTunnelVirtualPeerId>& peers) ; // returns the virtual peers for this group
bool getVirtualPeers(uint16_t service_id, std::list<RsGxsNetTunnelVirtualPeerId>& peers) ; // returns the virtual peers for this group
/*!
* \brief sendData
@ -204,13 +216,14 @@ private:
void autowash() ;
void handleIncoming(RsGxsNetTunnelItem *item) ;
static const uint32_t RS_GXS_TUNNEL_CONST_RANDOM_BIAS_SIZE = 16 ;
static const uint32_t RS_GXS_TUNNEL_CONST_RANDOM_BIAS_SIZE = 20 ;
static const uint32_t RS_GXS_TUNNEL_CONST_EKEY_SIZE = 32 ;
std::map<RsGxsGroupId,RsGxsNetTunnelGroupInfo> mGroups ; // groups on the client and server side
std::map<RsGxsNetTunnelVirtualPeerId, std::pair<RsGxsGroupId,TurtleVirtualPeerId> > mVirtualPeers ; // current virtual peers,
std::map<RsFileHash, RsGxsGroupId> mHandledHashes ; // hashes asked to turtle
std::map<RsGxsNetTunnelVirtualPeerId, RsGxsNetTunnelVirtualPeerInfo> mVirtualPeers ; // current virtual peers, which group they provide, and how to talk to them through turtle
std::map<RsFileHash, RsGxsGroupId> mHandledHashes ; // hashes asked to turtle. Used to answer tunnel requests
std::map<TurtleVirtualPeerId, RsGxsNetTunnelVirtualPeerId> mTurtle2GxsPeer ; // convertion table to find GXS peer id from turtle
/*!
* \brief Generates the hash to request tunnels for this group. This hash is only used by turtle, and is used to
@ -224,9 +237,9 @@ private:
* tunnel ID and turtle virtual peer id. This allows RsGxsNetService to keep sync-ing the data consistently.
*/
RsGxsNetTunnelVirtualPeerId makeServerVirtualPeerIdForGroup(const RsGxsGroupId&group_id) const ;
RsGxsNetTunnelVirtualPeerId locked_makeVirtualPeerId() const ;
void generateEncryptionKey(const RsGxsGroupId& group_id,const TurtleVirtualPeerId& vpid,unsigned char key[RS_GXS_TUNNEL_CONST_EKEY_SIZE]) const ;
static void generateEncryptionKey(const RsGxsGroupId& group_id,const TurtleVirtualPeerId& vpid,unsigned char key[RS_GXS_TUNNEL_CONST_EKEY_SIZE]) ;
uint8_t mRandomBias[RS_GXS_TUNNEL_CONST_RANDOM_BIAS_SIZE] ; // constant accross reboots. Allows to disguise the real SSL id while providing a consistent value accross time.