mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
basic structure of GxsNetTunnelService
This commit is contained in:
parent
04dc764339
commit
076309133b
@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
* libretroshare/src/gxs: rsgxsnettunnel.cc
|
||||||
|
*
|
||||||
|
* General Data service, interface for RetroShare.
|
||||||
|
*
|
||||||
|
* Copyright 2018-2018 by Cyril Soler
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License Version 2 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||||
|
* USA.
|
||||||
|
*
|
||||||
|
* Please report all bugs and problems to "retroshare.project@gmail.com"
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rsgxsnettunnel.h"
|
||||||
|
|
||||||
|
#define DEBUG_RSGXSNETTUNNEL 1
|
||||||
|
|
||||||
|
#define NOT_IMPLEMENTED() { std::cerr << __PRETTY_FUNCTION__ << ": not yet implemented." << std::endl; }
|
||||||
|
|
||||||
|
RsGxsNetTunnelService::RsGxsNetTunnelService(): mGxsNetTunnelMtx("GxsNetTunnel") {}
|
||||||
|
|
||||||
|
bool RsGxsNetTunnelService::manage(const RsGxsGroupId& group_id)
|
||||||
|
{
|
||||||
|
RsFileHash hash = calculateGroupHash(group_id) ;
|
||||||
|
|
||||||
|
RsStackMutex stack(mGxsNetTunnelMtx); /********** STACK LOCKED MTX ******/
|
||||||
|
|
||||||
|
RsGxsNetTunnelGroupInfo& info(mClientGroups[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;
|
||||||
|
|
||||||
|
#ifdef DEBUG_GXS_TUNNEL
|
||||||
|
std::cerr << "Starting distant chat to " << to_gxs_id << ", hash = " << hash << ", from " << from_gxs_id << std::endl;
|
||||||
|
std::cerr << "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 = mClientGroups.find(group_id) ;
|
||||||
|
|
||||||
|
if(it == mClientGroups.end())
|
||||||
|
{
|
||||||
|
std::cerr << "RsGxsNetTunnelService::release(): Weird. Cannot release client group " << group_id << " that is not known." << std::endl;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
mClientGroups.erase(it) ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RsGxsNetTunnelService::sendData(const unsigned char *data,uint32_t size,const RsGxsNetTunnelVirtualPeerId& virtual_peer)
|
||||||
|
{
|
||||||
|
// The data is encrypted using chacha20+SHA256 and sent to the turtle router.
|
||||||
|
|
||||||
|
NOT_IMPLEMENTED();
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RsGxsNetTunnelService::getVirtualPeers(const RsGxsGroupId&, std::list<RsPeerId>& peers)
|
||||||
|
{
|
||||||
|
// returns the virtual peers for this group
|
||||||
|
NOT_IMPLEMENTED();
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
RsGxsNetTunnelVirtualPeerInfo RsGxsNetTunnelService::makeVirtualPeerIdForGroup(const RsGxsGroupId&) const
|
||||||
|
{
|
||||||
|
NOT_IMPLEMENTED();
|
||||||
|
return RsGxsNetTunnelVirtualPeerInfo();
|
||||||
|
}
|
||||||
|
void RsGxsNetTunnelService::dump() const
|
||||||
|
{
|
||||||
|
NOT_IMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================================================================================//
|
||||||
|
// Interaction with Turtle Router //
|
||||||
|
//===========================================================================================================================================//
|
||||||
|
|
||||||
|
void RsGxsNetTunnelService::connectToTurtleRouter(p3turtle *tr)
|
||||||
|
{
|
||||||
|
mTurtle = tr ;
|
||||||
|
mTurtle->registerTunnelService(this) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RsGxsNetTunnelService::handleTunnelRequest(const RsFileHash &hash,const RsPeerId& peer_id)
|
||||||
|
{
|
||||||
|
NOT_IMPLEMENTED();
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
void RsGxsNetTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *item,const RsFileHash& hash,const RsPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction)
|
||||||
|
{
|
||||||
|
NOT_IMPLEMENTED();
|
||||||
|
}
|
||||||
|
void RsGxsNetTunnelService::addVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&,RsTurtleGenericTunnelItem::Direction dir)
|
||||||
|
{
|
||||||
|
NOT_IMPLEMENTED();
|
||||||
|
}
|
||||||
|
void RsGxsNetTunnelService::removeVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&)
|
||||||
|
{
|
||||||
|
NOT_IMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
RsFileHash RsGxsNetTunnelService::calculateGroupHash(const RsGxsGroupId&) const
|
||||||
|
{
|
||||||
|
NOT_IMPLEMENTED();
|
||||||
|
return RsFileHash() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================================================================================//
|
||||||
|
// Service parts //
|
||||||
|
//===========================================================================================================================================//
|
||||||
|
|
||||||
|
#ifdef TODO
|
||||||
|
void RsGxsNetTunnelService::handleIncomingItem(const RsGxsTunnelId& tunnel_id,RsGxsTunnelItem *item)
|
||||||
|
{
|
||||||
|
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 ;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* General Data service, interface for RetroShare.
|
* General Data service, interface for RetroShare.
|
||||||
*
|
*
|
||||||
* Copyright 2011-2011 by Robert Fernie, Evi-Parker Christopher
|
* Copyright 2018-2018 by Cyril Soler
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Library General Public
|
* modify it under the terms of the GNU Library General Public
|
||||||
@ -29,34 +29,40 @@
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief The RsGxsNetTunnelService class takes care of requesting tunnels to the turtle router, through which it is possible to sync
|
* \brief The RsGxsNetTunnelService class takes care of requesting tunnels to the turtle router, through which it is possible to sync
|
||||||
* a particular GXS group. For each group, a set of virtual peers, corresponding to active tunnels will be made available
|
* a particular GXS group. For each group, a set of virtual peers, corresponding to active tunnels will be made available
|
||||||
* to RsGxsNetService.
|
* to RsGxsNetService.
|
||||||
*
|
*
|
||||||
* 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.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Proposed protocol:
|
// Protocol:
|
||||||
// * request tunnels based on H(GroupId)
|
// * request tunnels based on H(GroupId)
|
||||||
// * encrypt tunnel data using chacha20+HMAC-SHA256 using AEAD( GroupId, 96bits IV, tunnel ID ) (similar to what FT does)
|
// * encrypt tunnel data using chacha20+HMAC-SHA256 using AEAD( GroupId, 96bits IV, tunnel ID ) (similar to what FT does)
|
||||||
// * when tunnel is established, exchange virtual peer names: vpid = H( GroupID | Random bias )
|
// * when tunnel is established, exchange virtual peer names: vpid = H( GroupID | Random bias )
|
||||||
// * when vpid is known, notify the client (GXS net service) which can use the virtual peer to sync
|
// * when vpid is known, notify the client (GXS net service) which can use the virtual peer to sync
|
||||||
//
|
//
|
||||||
// * only use a single tunnel per virtual peer ID
|
// * only use a single tunnel per virtual peer ID
|
||||||
//
|
// -
|
||||||
// Client ------------------ TR(H(GroupId)) --------------> Server
|
// Client ------------------ TR(H(GroupId)) --------------> Server |
|
||||||
//
|
// | Turtle
|
||||||
// Client <-------------------- T OK ---------------------- Server
|
// Client <-------------------- T OK ---------------------- Server |
|
||||||
//
|
// -
|
||||||
// Here, a turtle vpid is known
|
// Here, a turtle vpid is known | [ addVirtualPeer() called by turtle ]
|
||||||
//
|
// -
|
||||||
// [Encrypted traffic using H(GroupId, 96bits IV, tunnel ID)]
|
// [Encrypted traffic using H(GroupId | Tunnel ID, 96bits IV)] |
|
||||||
//
|
// |
|
||||||
// Client <--------- VPID = H( Random IV | GroupId ) ------ Server
|
// Client <--------- VPID = H( Random IV | GroupId ) ------ Server |
|
||||||
// | |
|
// | | |
|
||||||
// +--------------> Mark the virtual peer active <-----------+
|
// +--------------> Mark the virtual peer active <-----------+ | Encrypted traffic decoded locally and sorted
|
||||||
//
|
// |
|
||||||
// Here, a consistent virtual peer ID is known
|
// Here, a consistent virtual peer ID is known |
|
||||||
|
// |
|
||||||
|
// Client <------------------- GXS Data ------------------> Server |
|
||||||
|
// -
|
||||||
|
// 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.
|
||||||
|
// * each group will produced multiple tunnels, but each tunnel with have exactly one virtual peer ID
|
||||||
|
|
||||||
typedef RsPeerId RsGxsNetTunnelVirtualPeerId ;
|
typedef RsPeerId RsGxsNetTunnelVirtualPeerId ;
|
||||||
|
|
||||||
@ -67,40 +73,47 @@ 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) ; }
|
||||||
|
|
||||||
uint8_t vpid_status ;
|
uint8_t vpid_status ;
|
||||||
RsGxsNetTunnelVirtualPeerId net_service_virtual_peer ;
|
RsGxsNetTunnelVirtualPeerId net_service_virtual_peer ;
|
||||||
uint8_t side ; // client/server
|
uint8_t side ; // client/server
|
||||||
|
uint8_t encryption_master_key[16] ; // 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
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RsGxsNetTunnelInfo
|
struct RsGxsNetTunnelGroupInfo
|
||||||
{
|
{
|
||||||
enum { RS_GXS_NET_TUNNEL_GRP_STATUS_UNKNOWN = 0x00, // unknown status
|
enum { RS_GXS_NET_TUNNEL_GRP_STATUS_UNKNOWN = 0x00, // unknown status
|
||||||
RS_GXS_NET_TUNNEL_GRP_STATUS_TUNNELS_REQUESTED = 0x01, // waiting for turtle to send some virtual peers.
|
RS_GXS_NET_TUNNEL_GRP_STATUS_TUNNELS_REQUESTED = 0x01, // waiting for turtle to send some virtual peers.
|
||||||
RS_GXS_NET_TUNNEL_GRP_STATUS_VPIDS_AVAILABLE = 0x02 // some virtual peers are available
|
RS_GXS_NET_TUNNEL_GRP_STATUS_VPIDS_AVAILABLE = 0x02 // some virtual peers are available
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t group_status ;
|
RsGxsNetTunnelGroupInfo() : group_status(RS_GXS_NET_TUNNEL_GRP_STATUS_UNKNOWN),last_contact(0) {}
|
||||||
uint8_t encryption_master_key[16] ; // key from which the encryption key is derived for each virtual peer (using H(master_key | random IV))
|
|
||||||
|
uint8_t group_status ;
|
||||||
|
time_t last_contact ;
|
||||||
|
TurtleFileHash hash ;
|
||||||
|
|
||||||
std::map<TurtleVirtualPeerId, RsGxsNetTunnelVirtualPeerInfo> virtual_peers ;
|
std::map<TurtleVirtualPeerId, RsGxsNetTunnelVirtualPeerInfo> virtual_peers ;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RsGxsNetTunnelService
|
class RsGxsNetTunnelService: public RsTurtleClientService
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RsGxsNetTunnelService() {}
|
RsGxsNetTunnelService() ;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief start managing tunnels for this group
|
* \brief start managing tunnels for this group
|
||||||
* @param group_id group for which tunnels should be requested
|
* @param group_id group for which tunnels should be requested
|
||||||
*/
|
*/
|
||||||
bool manageTunnels(const RsGxsGroupId&) ;
|
bool manage(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 releaseTunnels(const RsGxsGroupId&) ;
|
bool release(const RsGxsGroupId&group_id) ;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* sends data to this virtual peer ID
|
* sends data to this virtual peer ID
|
||||||
@ -123,9 +136,19 @@ public:
|
|||||||
// - method to respond to tunnel requests, probably using RsGxsNetService
|
// - method to respond to tunnel requests, probably using RsGxsNetService
|
||||||
// - method to encrypt/decrypt data and send/receive to/from turtle.
|
// - method to encrypt/decrypt data and send/receive to/from turtle.
|
||||||
|
|
||||||
|
virtual void connectToTurtleRouter(p3turtle *tr) ;
|
||||||
|
protected:
|
||||||
|
// interaction with turtle router
|
||||||
|
|
||||||
|
virtual bool handleTunnelRequest(const RsFileHash &hash,const RsPeerId& peer_id) ;
|
||||||
|
virtual void receiveTurtleData(RsTurtleGenericTunnelItem *item,const RsFileHash& hash,const RsPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction) ;
|
||||||
|
void addVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&,RsTurtleGenericTunnelItem::Direction dir) ;
|
||||||
|
void removeVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&) ;
|
||||||
|
|
||||||
|
p3turtle *mTurtle ;
|
||||||
private:
|
private:
|
||||||
std::map<RsGxsGroupId,RsGxsNetTunnelInfo> mClientGroups ; // groups on the client side
|
std::map<RsGxsGroupId,RsGxsNetTunnelGroupInfo> mClientGroups ; // groups on the client side
|
||||||
std::map<RsGxsGroupId,RsGxsNetTunnelInfo> mServerGroups ; // groups on the server side
|
std::map<RsGxsGroupId,RsGxsNetTunnelGroupInfo> mServerGroups ; // groups on the server side
|
||||||
|
|
||||||
std::map<RsGxsNetTunnelVirtualPeerId, std::pair<RsGxsGroupId,TurtleVirtualPeerId> > mVirtualPeers ;
|
std::map<RsGxsNetTunnelVirtualPeerId, std::pair<RsGxsGroupId,TurtleVirtualPeerId> > mVirtualPeers ;
|
||||||
|
|
||||||
@ -134,7 +157,7 @@ private:
|
|||||||
* hide the real group id.
|
* hide the real group id.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
RsFileHash makeRequestHash(const RsGxsGroupId&) const ;
|
RsFileHash calculateGroupHash(const RsGxsGroupId&) const ;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief makeVirtualPeerIdForGroup creates a virtual peer id that can be used and that will be constant accross time, whatever the
|
* \brief makeVirtualPeerIdForGroup creates a virtual peer id that can be used and that will be constant accross time, whatever the
|
||||||
@ -144,5 +167,7 @@ private:
|
|||||||
RsGxsNetTunnelVirtualPeerInfo makeVirtualPeerIdForGroup(const RsGxsGroupId&) const ;
|
RsGxsNetTunnelVirtualPeerInfo makeVirtualPeerIdForGroup(const RsGxsGroupId&) const ;
|
||||||
|
|
||||||
uint8_t mRandomBias[16] ; // constant accross reboots. Allows to disguise the real SSL id while providing a consistent value accross time.
|
uint8_t mRandomBias[16] ; // constant accross reboots. Allows to disguise the real SSL id while providing a consistent value accross time.
|
||||||
|
|
||||||
|
RsMutex mGxsNetTunnelMtx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@
|
|||||||
// by a mix between our own GXS id and the GXS id we're talking to. That is what the TunnelVirtualPeer is.
|
// by a mix between our own GXS id and the GXS id we're talking to. That is what the TunnelVirtualPeer is.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// RequestTunnel(source_own_id,destination_id) -
|
// RequestTunnel(source_own_id,destination_id) -
|
||||||
// | |
|
// | |
|
||||||
// +---------------------------> p3Turtle::monitorTunnels( hash(destination_id) ) |
|
// +---------------------------> p3Turtle::monitorTunnels( hash(destination_id) ) |
|
||||||
// | |
|
// | |
|
||||||
|
Loading…
Reference in New Issue
Block a user