mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
finished implementation of GxsNetTunnel service
This commit is contained in:
parent
b488760d7d
commit
73b04f3109
@ -359,7 +359,7 @@ RsGxsNetService::RsGxsNetService(uint16_t servType, RsGeneralDataService *gds,
|
|||||||
RsNxsNetMgr *netMgr, RsNxsObserver *nxsObs,
|
RsNxsNetMgr *netMgr, RsNxsObserver *nxsObs,
|
||||||
const RsServiceInfo serviceInfo,
|
const RsServiceInfo serviceInfo,
|
||||||
RsGixsReputation* reputations, RsGcxs* circles, RsGixs *gixs,
|
RsGixsReputation* reputations, RsGcxs* circles, RsGixs *gixs,
|
||||||
PgpAuxUtils *pgpUtils, bool grpAutoSync, bool msgAutoSync, uint32_t default_store_period, uint32_t default_sync_period)
|
PgpAuxUtils *pgpUtils, bool grpAutoSync, bool msgAutoSync, bool distSync, uint32_t default_store_period, uint32_t default_sync_period)
|
||||||
: p3ThreadedService(), p3Config(), mTransactionN(0),
|
: p3ThreadedService(), p3Config(), mTransactionN(0),
|
||||||
mObserver(nxsObs), mDataStore(gds),
|
mObserver(nxsObs), mDataStore(gds),
|
||||||
mServType(servType), mTransactionTimeOut(TRANSAC_TIMEOUT),
|
mServType(servType), mTransactionTimeOut(TRANSAC_TIMEOUT),
|
||||||
@ -368,7 +368,7 @@ RsGxsNetService::RsGxsNetService(uint16_t servType, RsGeneralDataService *gds,
|
|||||||
mLastCleanRejectedMessages(0), mSYNC_PERIOD(SYNC_PERIOD),
|
mLastCleanRejectedMessages(0), mSYNC_PERIOD(SYNC_PERIOD),
|
||||||
mCircles(circles), mGixs(gixs),
|
mCircles(circles), mGixs(gixs),
|
||||||
mReputations(reputations), mPgpUtils(pgpUtils),
|
mReputations(reputations), mPgpUtils(pgpUtils),
|
||||||
mGrpAutoSync(grpAutoSync), mAllowMsgSync(msgAutoSync),
|
mGrpAutoSync(grpAutoSync), mAllowMsgSync(msgAutoSync),mAllowDistSync(distSync),
|
||||||
mServiceInfo(serviceInfo), mDefaultMsgStorePeriod(default_store_period),
|
mServiceInfo(serviceInfo), mDefaultMsgStorePeriod(default_store_period),
|
||||||
mDefaultMsgSyncPeriod(default_sync_period)
|
mDefaultMsgSyncPeriod(default_sync_period)
|
||||||
{
|
{
|
||||||
|
@ -90,7 +90,7 @@ public:
|
|||||||
const RsServiceInfo serviceInfo,
|
const RsServiceInfo serviceInfo,
|
||||||
RsGixsReputation* reputations = NULL, RsGcxs* circles = NULL, RsGixs *gixs=NULL,
|
RsGixsReputation* reputations = NULL, RsGcxs* circles = NULL, RsGixs *gixs=NULL,
|
||||||
PgpAuxUtils *pgpUtils = NULL,
|
PgpAuxUtils *pgpUtils = NULL,
|
||||||
bool grpAutoSync = true, bool msgAutoSync = true,
|
bool grpAutoSync = true, bool msgAutoSync = true,bool distSync=false,
|
||||||
uint32_t default_store_period = RS_GXS_DEFAULT_MSG_STORE_PERIOD,
|
uint32_t default_store_period = RS_GXS_DEFAULT_MSG_STORE_PERIOD,
|
||||||
uint32_t default_sync_period = RS_GXS_DEFAULT_MSG_REQ_PERIOD);
|
uint32_t default_sync_period = RS_GXS_DEFAULT_MSG_REQ_PERIOD);
|
||||||
|
|
||||||
@ -543,6 +543,7 @@ private:
|
|||||||
PgpAuxUtils *mPgpUtils;
|
PgpAuxUtils *mPgpUtils;
|
||||||
bool mGrpAutoSync;
|
bool mGrpAutoSync;
|
||||||
bool mAllowMsgSync;
|
bool mAllowMsgSync;
|
||||||
|
bool mAllowDistSync;
|
||||||
|
|
||||||
// need to be verfied
|
// need to be verfied
|
||||||
std::vector<AuthorPending*> mPendingResp;
|
std::vector<AuthorPending*> mPendingResp;
|
||||||
|
@ -57,6 +57,7 @@ RsGxsNetTunnelVirtualPeerInfo::~RsGxsNetTunnelVirtualPeerInfo()
|
|||||||
const uint16_t RS_SERVICE_TYPE_GXS_NET_TUNNEL = 0x2233 ;
|
const uint16_t RS_SERVICE_TYPE_GXS_NET_TUNNEL = 0x2233 ;
|
||||||
|
|
||||||
const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_VIRTUAL_PEER = 0x01 ;
|
const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_VIRTUAL_PEER = 0x01 ;
|
||||||
|
const uint8_t RS_PKT_SUBTYPE_GXS_NET_TUNNEL_KEEP_ALIVE = 0x02 ;
|
||||||
|
|
||||||
class RsGxsNetTunnelItem: public RsItem
|
class RsGxsNetTunnelItem: public RsItem
|
||||||
{
|
{
|
||||||
@ -74,7 +75,6 @@ class RsGxsNetTunnelVirtualPeerItem: public RsGxsNetTunnelItem
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RsGxsNetTunnelVirtualPeerItem() :RsGxsNetTunnelItem(RS_PKT_SUBTYPE_GXS_NET_TUNNEL_VIRTUAL_PEER) {}
|
RsGxsNetTunnelVirtualPeerItem() :RsGxsNetTunnelItem(RS_PKT_SUBTYPE_GXS_NET_TUNNEL_VIRTUAL_PEER) {}
|
||||||
explicit RsGxsNetTunnelVirtualPeerItem(uint8_t subtype) :RsGxsNetTunnelItem(subtype) {}
|
|
||||||
|
|
||||||
virtual ~RsGxsNetTunnelVirtualPeerItem() {}
|
virtual ~RsGxsNetTunnelVirtualPeerItem() {}
|
||||||
|
|
||||||
@ -86,6 +86,15 @@ public:
|
|||||||
RsPeerId virtual_peer_id ;
|
RsPeerId virtual_peer_id ;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RsGxsNetTunnelKeepAliveItem: public RsGxsNetTunnelItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RsGxsNetTunnelKeepAliveItem() :RsGxsNetTunnelItem(RS_PKT_SUBTYPE_GXS_NET_TUNNEL_KEEP_ALIVE) {}
|
||||||
|
|
||||||
|
virtual ~RsGxsNetTunnelKeepAliveItem() {}
|
||||||
|
virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx) {}
|
||||||
|
};
|
||||||
|
|
||||||
class RsGxsNetTunnelSerializer: public RsServiceSerializer
|
class RsGxsNetTunnelSerializer: public RsServiceSerializer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -102,6 +111,7 @@ public:
|
|||||||
switch(item_subtype)
|
switch(item_subtype)
|
||||||
{
|
{
|
||||||
case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_VIRTUAL_PEER: return new RsGxsNetTunnelVirtualPeerItem ;
|
case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_VIRTUAL_PEER: return new RsGxsNetTunnelVirtualPeerItem ;
|
||||||
|
case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_KEEP_ALIVE : return new RsGxsNetTunnelKeepAliveItem ;
|
||||||
default:
|
default:
|
||||||
GXS_NET_TUNNEL_ERROR() << "type ID " << std::hex << item_subtype << std::dec << " is not handled!" << std::endl;
|
GXS_NET_TUNNEL_ERROR() << "type ID " << std::hex << item_subtype << std::dec << " is not handled!" << std::endl;
|
||||||
return NULL ;
|
return NULL ;
|
||||||
@ -113,71 +123,19 @@ public:
|
|||||||
// Interface with rest of the software //
|
// Interface with rest of the software //
|
||||||
//===========================================================================================================================================//
|
//===========================================================================================================================================//
|
||||||
|
|
||||||
bool RsGxsNetTunnelService::manage(const RsGxsGroupId& group_id)
|
class DataAutoDelete
|
||||||
{
|
|
||||||
RsFileHash hash = calculateGroupHash(group_id) ;
|
|
||||||
|
|
||||||
RsStackMutex stack(mGxsNetTunnelMtx); /********** STACK LOCKED MTX ******/
|
|
||||||
|
|
||||||
RsGxsNetTunnelGroupInfo& info(mGroups[group_id]) ;
|
|
||||||
|
|
||||||
time_t now = time(NULL) ;
|
|
||||||
|
|
||||||
if(info.group_status == RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_STATUS_VPIDS_AVAILABLE)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
info.hash = hash ;
|
|
||||||
info.last_contact = now ;
|
|
||||||
info.group_status = RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_STATUS_TUNNELS_REQUESTED;
|
|
||||||
|
|
||||||
mHandledHashes[hash] = group_id ;
|
|
||||||
|
|
||||||
#ifdef DEBUG_GXS_TUNNEL
|
|
||||||
GXS_NET_TUNNEL_DEBUG() << "Asking turtle router to monitor tunnels for hash " << hash << std::endl;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Now ask the turtle router to manage a tunnel for that hash.
|
|
||||||
|
|
||||||
mTurtle->monitorTunnels(hash,this,false) ;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RsGxsNetTunnelService::release(const RsGxsGroupId& group_id)
|
|
||||||
{
|
|
||||||
RsStackMutex stack(mGxsNetTunnelMtx); /********** STACK LOCKED MTX ******/
|
|
||||||
|
|
||||||
// Here we need to clean the stuff that was created by this group id.
|
|
||||||
|
|
||||||
auto it = mGroups.find(group_id) ;
|
|
||||||
|
|
||||||
if(it == mGroups.end())
|
|
||||||
{
|
|
||||||
GXS_NET_TUNNEL_ERROR() << "RsGxsNetTunnelService::release(): Weird. Cannot release client group " << group_id << " that is not known." << std::endl;
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
mGroups.erase(it) ;
|
|
||||||
|
|
||||||
RsFileHash hash = calculateGroupHash(group_id) ;
|
|
||||||
|
|
||||||
mHandledHashes.erase(hash) ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
class ItemAutoDelete
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ItemAutoDelete(RsItem *& item) : mItem(item) {}
|
DataAutoDelete(unsigned char *& data) : mData(data) {}
|
||||||
~ItemAutoDelete() { delete mItem; mItem=NULL ; }
|
~DataAutoDelete() { free(mData); mData=NULL ; }
|
||||||
RsItem *& mItem;
|
unsigned char *& mData;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool RsGxsNetTunnelService::sendItem(RsItem *& item,const RsGxsNetTunnelVirtualPeerId& virtual_peer)
|
bool RsGxsNetTunnelService::sendData(unsigned char *& data,uint32_t data_len,const RsGxsNetTunnelVirtualPeerId& virtual_peer)
|
||||||
{
|
{
|
||||||
// The item is serialized and encrypted using chacha20+SHA256, using the generic turtle encryption, and then sent to the turtle router.
|
// The item is serialized and encrypted using chacha20+SHA256, using the generic turtle encryption, and then sent to the turtle router.
|
||||||
|
|
||||||
ItemAutoDelete iad(item) ; // This ensures the item is deleted whatsoever when leaving
|
DataAutoDelete iad(data) ; // This ensures the item is deleted whatsoever when leaving
|
||||||
|
|
||||||
// 1 - find the virtual peer and the proper master key to encrypt with, and check that all the info is known
|
// 1 - find the virtual peer and the proper master key to encrypt with, and check that all the info is known
|
||||||
|
|
||||||
@ -215,10 +173,7 @@ bool RsGxsNetTunnelService::sendItem(RsItem *& item,const RsGxsNetTunnelVirtualP
|
|||||||
|
|
||||||
RsTurtleGenericDataItem *encrypted_turtle_item = NULL ;
|
RsTurtleGenericDataItem *encrypted_turtle_item = NULL ;
|
||||||
|
|
||||||
uint32_t serialized_size = 0; // TODO
|
if(!p3turtle::encryptData(data,data_len,it3->second.encryption_master_key,encrypted_turtle_item))
|
||||||
RsTemporaryMemory data(serialized_size) ;
|
|
||||||
|
|
||||||
if(!p3turtle::encryptData(data,serialized_size,it3->second.encryption_master_key,encrypted_turtle_item))
|
|
||||||
{
|
{
|
||||||
GXS_NET_TUNNEL_ERROR() << "cannot encrypt. Something's wrong. Data is dropped." << std::endl;
|
GXS_NET_TUNNEL_ERROR() << "cannot encrypt. Something's wrong. Data is dropped." << std::endl;
|
||||||
return false ;
|
return false ;
|
||||||
@ -229,11 +184,63 @@ bool RsGxsNetTunnelService::sendItem(RsItem *& item,const RsGxsNetTunnelVirtualP
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RsGxsNetTunnelService::getVirtualPeers(const RsGxsGroupId&, std::list<RsPeerId>& peers)
|
bool RsGxsNetTunnelService::getVirtualPeers(const RsGxsGroupId& group_id, std::list<RsGxsNetTunnelVirtualPeerId>& peers)
|
||||||
{
|
{
|
||||||
// returns the virtual peers for this group
|
// This function has two effects:
|
||||||
GXS_NET_TUNNEL_NOT_IMPLEMENTED();
|
// - return the virtual peers for this group
|
||||||
return false ;
|
// - passively set the group as "managed", so that it we answer tunnel requests.
|
||||||
|
|
||||||
|
RS_STACK_MUTEX(mGxsNetTunnelMtx);
|
||||||
|
|
||||||
|
// 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) ;
|
||||||
|
|
||||||
|
#ifdef DEBUG_GXS_TUNNEL
|
||||||
|
GXS_NET_TUNNEL_DEBUG() << "returning " << peers.size() << " peers." << std::endl;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RsGxsNetTunnelService::requestPeers(const RsGxsGroupId& group_id)
|
||||||
|
{
|
||||||
|
RS_STACK_MUTEX(mGxsNetTunnelMtx);
|
||||||
|
|
||||||
|
// Now ask the turtle router to manage a tunnel for that hash.
|
||||||
|
|
||||||
|
RsGxsNetTunnelGroupInfo& ginfo( mGroups[group_id] ) ;
|
||||||
|
|
||||||
|
ginfo.group_policy = RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_ACTIVE;
|
||||||
|
|
||||||
|
// we dont set the group policy here. It will only be set if no peers, or too few peers are available.
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RsGxsNetTunnelService::releasePeers(const RsGxsGroupId& group_id)
|
||||||
|
{
|
||||||
|
RS_STACK_MUTEX(mGxsNetTunnelMtx);
|
||||||
|
|
||||||
|
// Ask turtle router to stop requesting tunnels for that hash.
|
||||||
|
|
||||||
|
RsGxsNetTunnelGroupInfo& ginfo( mGroups[group_id] ) ;
|
||||||
|
|
||||||
|
ginfo.group_policy = RsGxsNetTunnelGroupInfo::RS_GXS_NET_TUNNEL_GRP_POLICY_PASSIVE;
|
||||||
|
mTurtle->stopMonitoringTunnels(ginfo.hash) ;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RsGxsNetTunnelVirtualPeerId RsGxsNetTunnelService::makeServerVirtualPeerIdForGroup(const RsGxsGroupId& group_id) const
|
RsGxsNetTunnelVirtualPeerId RsGxsNetTunnelService::makeServerVirtualPeerIdForGroup(const RsGxsGroupId& group_id) const
|
||||||
@ -304,14 +311,9 @@ void RsGxsNetTunnelService::connectToTurtleRouter(p3turtle *tr)
|
|||||||
|
|
||||||
bool RsGxsNetTunnelService::handleTunnelRequest(const RsFileHash &hash,const RsPeerId& peer_id)
|
bool RsGxsNetTunnelService::handleTunnelRequest(const RsFileHash &hash,const RsPeerId& peer_id)
|
||||||
{
|
{
|
||||||
GXS_NET_TUNNEL_NOT_IMPLEMENTED();
|
// We simply check for wether a managed group has a hash that corresponds to the given hash.
|
||||||
|
|
||||||
// at this point we need to talk to the client services
|
return mHandledHashes.find(hash) != mHandledHashes.end();
|
||||||
// There's 2 ways to do that:
|
|
||||||
// 1 - client services "register" and we ask them one by one.
|
|
||||||
// 2 - client service derives from RsGxsNetTunnelService and the client is interrogated using an overloaded virtual method
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction)
|
||||||
@ -437,23 +439,27 @@ void RsGxsNetTunnelService::addVirtualPeer(const TurtleFileHash& hash, const Tur
|
|||||||
|
|
||||||
generateEncryptionKey(group_id,vpid,vpinfo.encryption_master_key );
|
generateEncryptionKey(group_id,vpid,vpinfo.encryption_master_key );
|
||||||
|
|
||||||
// If we're a server, we need to send our own virtual peer id to the client
|
// We need to send our own virtual peer id to the other end of the tunnel
|
||||||
|
|
||||||
if(dir == RsTurtleGenericTunnelItem::DIRECTION_CLIENT)
|
|
||||||
{
|
|
||||||
vpinfo.net_service_virtual_peer = makeServerVirtualPeerIdForGroup(group_id);
|
vpinfo.net_service_virtual_peer = makeServerVirtualPeerIdForGroup(group_id);
|
||||||
|
|
||||||
#ifdef DEBUG_RSGXSNETTUNNEL
|
#ifdef DEBUG_RSGXSNETTUNNEL
|
||||||
GXS_NET_TUNNEL_DEBUG() << " peer is server side: sending back virtual peer name " << vpinfo.net_service_virtual_peer << std::endl;
|
GXS_NET_TUNNEL_DEBUG() << " sending back virtual peer name " << vpinfo.net_service_virtual_peer << " to end of tunnel" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
RsGxsNetTunnelVirtualPeerItem *pitem = new RsGxsNetTunnelVirtualPeerItem ;
|
RsGxsNetTunnelVirtualPeerItem pitem ;
|
||||||
|
pitem.virtual_peer_id = vpinfo.net_service_virtual_peer ;
|
||||||
|
|
||||||
pitem->virtual_peer_id = vpinfo.net_service_virtual_peer ;
|
RsTemporaryMemory tmpmem( RsGxsNetTunnelSerializer().size(&pitem) ) ;
|
||||||
|
uint32_t len = tmpmem.size();
|
||||||
|
|
||||||
vpinfo.outgoing_items.push_back(pitem) ;
|
RsGxsNetTunnelSerializer().serialise(&pitem,tmpmem,&len);
|
||||||
}
|
|
||||||
|
RsTurtleGenericDataItem *encrypted_turtle_item = NULL ;
|
||||||
|
|
||||||
|
if(p3turtle::encryptData(tmpmem,len,vpinfo.encryption_master_key,encrypted_turtle_item))
|
||||||
|
mTurtle->sendTurtleData(vpid,encrypted_turtle_item) ;
|
||||||
else
|
else
|
||||||
vpinfo.net_service_virtual_peer.clear();
|
GXS_NET_TUNNEL_ERROR() << "cannot encrypt. Something's wrong. Data is dropped." << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RsGxsNetTunnelService::removeVirtualPeer(const TurtleFileHash& hash, const TurtleVirtualPeerId& vpid)
|
void RsGxsNetTunnelService::removeVirtualPeer(const TurtleFileHash& hash, const TurtleVirtualPeerId& vpid)
|
||||||
@ -531,6 +537,12 @@ void RsGxsNetTunnelService::autowash()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
// void RsGxsNetTunnelService::handleIncoming(const RsGxsTunnelId& tunnel_id,RsGxsTunnelItem *item)
|
||||||
// {
|
// {
|
||||||
// #ifdef DEBUG_RSGXSNETTUNNEL
|
// #ifdef DEBUG_RSGXSNETTUNNEL
|
||||||
|
@ -34,6 +34,10 @@
|
|||||||
*
|
*
|
||||||
* It is the responsibility of RsGxsNetService to activate/desactivate tunnels for each particular group, depending on wether the group
|
* It is the responsibility of RsGxsNetService to activate/desactivate tunnels for each particular group, depending on wether the group
|
||||||
* is already available at friends or not.
|
* is already available at friends or not.
|
||||||
|
*
|
||||||
|
* Tunnel management is done at the level of groups rather than services, because we would like to keep the possibility to not
|
||||||
|
* request tunnels for some groups which do not need it, and only request tunnels for specific groups that cannot be provided
|
||||||
|
* by direct connections.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Protocol:
|
// Protocol:
|
||||||
@ -61,8 +65,23 @@
|
|||||||
// Client <------------------- GXS Data ------------------> Server |
|
// Client <------------------- GXS Data ------------------> Server |
|
||||||
// -
|
// -
|
||||||
// Notes:
|
// Notes:
|
||||||
// * tunnels are only used one-way. If a distant peers wants to sync the same group, he'll have to open his own tunnel, with a different ID.
|
// * tunnels are established symetrically. If a distant peers wants to sync the same group, they'll have to open a single tunnel, with a different ID.
|
||||||
// * each group will produced multiple tunnels, but each tunnel with have exactly one virtual peer ID
|
// Groups therefore have two states:
|
||||||
|
// - managed : the group can be used to answer tunnel requests. If server tunnels are established, the group will be synced with these peers
|
||||||
|
// - tunneled: the group will actively request tunnels. If tunnels are established both ways, the same virtual peers will be used so the tunnels are "merged".
|
||||||
|
// * In practice, that means one of the two tunnels will not be used and therefore die.
|
||||||
|
// * If a tunneled group already has enough virtual peers, it will not request for tunnels itself.
|
||||||
|
//
|
||||||
|
// Group policy | Request tunnels | SyncWithPeers | Item receipt
|
||||||
|
// --------------------+-------------------+-----------------------+----------------
|
||||||
|
// Passive | no | If peers present | If peers present
|
||||||
|
// Active | yes, if no peers | If peers present | If peers present
|
||||||
|
// | | |
|
||||||
|
//
|
||||||
|
// * when a service has the DistSync flag set, groups to sync are communicated passively to the GxsNetTunnel service when requesting distant peers.
|
||||||
|
// 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.
|
||||||
|
|
||||||
typedef RsPeerId RsGxsNetTunnelVirtualPeerId ;
|
typedef RsPeerId RsGxsNetTunnelVirtualPeerId ;
|
||||||
|
|
||||||
@ -75,7 +94,7 @@ struct RsGxsNetTunnelVirtualPeerInfo
|
|||||||
RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE = 0x02 // virtual peer id is known. Data can transfer.
|
RS_GXS_NET_TUNNEL_VP_STATUS_ACTIVE = 0x02 // virtual peer id is known. Data can transfer.
|
||||||
};
|
};
|
||||||
|
|
||||||
RsGxsNetTunnelVirtualPeerInfo() : vpid_status(RS_GXS_NET_TUNNEL_VP_STATUS_UNKNOWN) { memset(encryption_master_key,0,16) ; }
|
RsGxsNetTunnelVirtualPeerInfo() : vpid_status(RS_GXS_NET_TUNNEL_VP_STATUS_UNKNOWN) { memset(encryption_master_key,0,32) ; }
|
||||||
~RsGxsNetTunnelVirtualPeerInfo() ;
|
~RsGxsNetTunnelVirtualPeerInfo() ;
|
||||||
|
|
||||||
uint8_t vpid_status ; // status of the peer
|
uint8_t vpid_status ; // status of the peer
|
||||||
@ -92,14 +111,23 @@ struct RsGxsNetTunnelVirtualPeerInfo
|
|||||||
|
|
||||||
struct RsGxsNetTunnelGroupInfo
|
struct RsGxsNetTunnelGroupInfo
|
||||||
{
|
{
|
||||||
enum { RS_GXS_NET_TUNNEL_GRP_STATUS_UNKNOWN = 0x00, // unknown status
|
enum GroupStatus {
|
||||||
RS_GXS_NET_TUNNEL_GRP_STATUS_TUNNELS_REQUESTED = 0x01, // waiting for turtle to send some virtual peers.
|
RS_GXS_NET_TUNNEL_GRP_STATUS_UNKNOWN = 0x00, // unknown status
|
||||||
RS_GXS_NET_TUNNEL_GRP_STATUS_VPIDS_AVAILABLE = 0x02 // some virtual peers are available
|
RS_GXS_NET_TUNNEL_GRP_STATUS_IDLE = 0x01, // no virtual peers requested, just waiting
|
||||||
|
RS_GXS_NET_TUNNEL_GRP_STATUS_TUNNELS_REQUESTED = 0x02, // virtual peers requested, and waiting for turtle to answer
|
||||||
|
RS_GXS_NET_TUNNEL_GRP_STATUS_VPIDS_AVAILABLE = 0x03 // some virtual peers are available. Data can be read/written
|
||||||
};
|
};
|
||||||
|
|
||||||
RsGxsNetTunnelGroupInfo() : group_status(RS_GXS_NET_TUNNEL_GRP_STATUS_UNKNOWN),last_contact(0) {}
|
enum GroupPolicy {
|
||||||
|
RS_GXS_NET_TUNNEL_GRP_POLICY_UNKNOWN = 0x00, // nothing has been set
|
||||||
|
RS_GXS_NET_TUNNEL_GRP_POLICY_PASSIVE = 0x01, // group is available for server side tunnels, but does not explicitely request tunnels
|
||||||
|
RS_GXS_NET_TUNNEL_GRP_POLICY_ACTIVE = 0x02, // group explicitely request tunnels, if none available
|
||||||
|
};
|
||||||
|
|
||||||
uint8_t group_status ;
|
RsGxsNetTunnelGroupInfo() : group_policy(RS_GXS_NET_TUNNEL_GRP_POLICY_PASSIVE),group_status(RS_GXS_NET_TUNNEL_GRP_STATUS_IDLE),last_contact(0) {}
|
||||||
|
|
||||||
|
GroupPolicy group_policy ;
|
||||||
|
GroupStatus group_status ;
|
||||||
time_t last_contact ;
|
time_t last_contact ;
|
||||||
TurtleFileHash hash ;
|
TurtleFileHash hash ;
|
||||||
|
|
||||||
@ -112,27 +140,32 @@ public:
|
|||||||
RsGxsNetTunnelService() ;
|
RsGxsNetTunnelService() ;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief start managing tunnels for this group
|
* \brief Manage tunnels for this group
|
||||||
* @param group_id group for which tunnels should be requested
|
* @param group_id group for which tunnels should be released
|
||||||
*/
|
*/
|
||||||
bool manage(const RsGxsGroupId& group_id) ;
|
bool requestPeers(const RsGxsGroupId&group_id) ;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Stop managing tunnels for this group
|
* \brief Stop managing tunnels for this group
|
||||||
* @param group_id group for which tunnels should be released
|
* @param group_id group for which tunnels should be released
|
||||||
*/
|
*/
|
||||||
bool release(const RsGxsGroupId&group_id) ;
|
bool releasePeers(const RsGxsGroupId&group_id) ;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief sendItem
|
* \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
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief sendData
|
||||||
* send data to this virtual peer, and takes memory ownership (deletes the item)
|
* send data to this virtual peer, and takes memory ownership (deletes the item)
|
||||||
* \param item item to send
|
* \param item item to send
|
||||||
* \param virtual_peer destination virtual peer
|
* \param virtual_peer destination virtual peer
|
||||||
* \return
|
* \return
|
||||||
* true if succeeded.
|
* true if succeeded.
|
||||||
*/
|
*/
|
||||||
bool sendItem(RsItem *& item, const RsGxsNetTunnelVirtualPeerId& virtual_peer) ;
|
bool sendData(unsigned char *& data, uint32_t data_len, const RsGxsNetTunnelVirtualPeerId& virtual_peer) ;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief receivedItem
|
* \brief receivedItem
|
||||||
@ -142,12 +175,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
RsItem *receivedItem(const RsGxsNetTunnelVirtualPeerId& virtual_peer) ;
|
RsItem *receivedItem(const RsGxsNetTunnelVirtualPeerId& virtual_peer) ;
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Get the list of active virtual peers for a given group. This implies that the tunnel is up and
|
|
||||||
* alive.
|
|
||||||
*/
|
|
||||||
bool getVirtualPeers(const RsGxsGroupId&, std::list<RsPeerId>& peers) ; // returns the virtual peers for this group
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief dumps all information about monitored groups.
|
* \brief dumps all information about monitored groups.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user