mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-01-30 17:23:23 -05:00
added service part and item queues to GXS tunnel service
This commit is contained in:
parent
19f1a82bd8
commit
b552408aab
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include "util/rsaes.h"
|
#include "util/rsaes.h"
|
||||||
#include "util/rsprint.h"
|
#include "util/rsprint.h"
|
||||||
|
#include "util/rsmemory.h"
|
||||||
|
|
||||||
#include <retroshare/rsidentity.h>
|
#include <retroshare/rsidentity.h>
|
||||||
#include <retroshare/rsiface.h>
|
#include <retroshare/rsiface.h>
|
||||||
@ -57,9 +58,20 @@ static const uint32_t RS_GXS_TUNNEL_STATUS_CAN_TALK = 0x01 ;
|
|||||||
static const uint32_t RS_GXS_TUNNEL_STATUS_TUNNEL_DN = 0x02 ;
|
static const uint32_t RS_GXS_TUNNEL_STATUS_TUNNEL_DN = 0x02 ;
|
||||||
static const uint32_t RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED = 0x03 ;
|
static const uint32_t RS_GXS_TUNNEL_STATUS_REMOTELY_CLOSED = 0x03 ;
|
||||||
|
|
||||||
|
static const uint32_t RS_GXS_TUNNEL_DELAY_BETWEEN_RESEND = 10 ; // re-send every 10 secs.
|
||||||
|
|
||||||
static const uint32_t GXS_TUNNEL_ENCRYPTION_HMAC_SIZE = SHA_DIGEST_LENGTH ;
|
static const uint32_t GXS_TUNNEL_ENCRYPTION_HMAC_SIZE = SHA_DIGEST_LENGTH ;
|
||||||
static const uint32_t GXS_TUNNEL_ENCRYPTION_IV_SIZE = 8 ;
|
static const uint32_t GXS_TUNNEL_ENCRYPTION_IV_SIZE = 8 ;
|
||||||
|
|
||||||
|
p3GxsTunnelService::p3GxsTunnelService(RsGixs *pids)
|
||||||
|
: mGixs(pids), mGxsTunnelMtx("GXS tunnel")
|
||||||
|
{
|
||||||
|
mTurtle = NULL ;
|
||||||
|
|
||||||
|
// any value is fine here, even 0, since items in different RS sessions will use different AES keys.
|
||||||
|
global_item_counter = 0;//RSRandom::random_u64() ;
|
||||||
|
}
|
||||||
|
|
||||||
void p3GxsTunnelService::connectToTurtleRouter(p3turtle *tr)
|
void p3GxsTunnelService::connectToTurtleRouter(p3turtle *tr)
|
||||||
{
|
{
|
||||||
mTurtle = tr ;
|
mTurtle = tr ;
|
||||||
@ -68,12 +80,47 @@ void p3GxsTunnelService::connectToTurtleRouter(p3turtle *tr)
|
|||||||
|
|
||||||
void p3GxsTunnelService::flush()
|
void p3GxsTunnelService::flush()
|
||||||
{
|
{
|
||||||
|
// Flush pending DH items. This is a higher priority, so we deal with them first.
|
||||||
|
|
||||||
|
std::cerr << "p3GxsTunnelService::flush() flushing pending items." << std::endl;
|
||||||
|
{
|
||||||
|
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
|
||||||
|
|
||||||
|
while(!pendingDHItems.empty())
|
||||||
|
if(locked_sendClearTunnelData(pendingDHItems.front()) )
|
||||||
|
pendingDHItems.pop_front() ;
|
||||||
|
}
|
||||||
|
|
||||||
// Flush items that could not be sent, probably because of a Mutex protected zone.
|
// Flush items that could not be sent, probably because of a Mutex protected zone.
|
||||||
//
|
//
|
||||||
while(!pendingGxsTunnelItems.empty())
|
|
||||||
{
|
{
|
||||||
sendTurtleData(pendingGxsTunnelItems.front() ) ;
|
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
|
||||||
|
|
||||||
|
while(!pendingGxsTunnelItems.empty())
|
||||||
|
if(locked_sendEncryptedTunnelData(pendingGxsTunnelItems.front()))
|
||||||
pendingGxsTunnelItems.pop_front() ;
|
pendingGxsTunnelItems.pop_front() ;
|
||||||
|
else
|
||||||
|
std::cerr << "Cannot send encrypted data item to tunnel " << pendingGxsTunnelItems.front()->PeerId() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look at pending data item, and re-send them if necessary.
|
||||||
|
|
||||||
|
{
|
||||||
|
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
|
||||||
|
|
||||||
|
time_t now = time(NULL) ;
|
||||||
|
|
||||||
|
for(std::map<uint64_t, GxsTunnelData>::iterator it = pendingGxsTunnelDataItems.begin();it != pendingGxsTunnelDataItems.end();++it)
|
||||||
|
if(now > RS_GXS_TUNNEL_DELAY_BETWEEN_RESEND + it->second.last_sending_attempt)
|
||||||
|
{
|
||||||
|
if(locked_sendEncryptedTunnelData(it->second.data_item))
|
||||||
|
{
|
||||||
|
std::cerr << " sending data item #" << std::hex << it->first << std::dec << std::endl;
|
||||||
|
it->second.last_sending_attempt = now ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
std::cerr << " Cannot send item " << std::hex << it->first << std::dec << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: also sweep GXS id map and disable any ID with no virtual peer id in the list.
|
// TODO: also sweep GXS id map and disable any ID with no virtual peer id in the list.
|
||||||
@ -121,80 +168,108 @@ void p3GxsTunnelService::flush()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3GxsTunnelService::handleIncomingItem(RsGxsTunnelItem *item)
|
// In this function the PeerId is the GXS tunnel ID.
|
||||||
|
|
||||||
|
void p3GxsTunnelService::handleIncomingItem(const RsGxsTunnelId& tunnel_id,RsGxsTunnelItem *item)
|
||||||
{
|
{
|
||||||
if(item == NULL)
|
if(item == NULL)
|
||||||
return false ;
|
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())
|
switch(item->PacketSubType())
|
||||||
{
|
{
|
||||||
case RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY: handleRecvDHPublicKey(dynamic_cast<RsGxsTunnelDHPublicKeyItem*>(item)) ; break ;
|
|
||||||
return true ;
|
|
||||||
|
|
||||||
#warning need to implement tunnel data handling here
|
case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA: handleRecvTunnelDataItem(tunnel_id,dynamic_cast<RsGxsTunnelDataItem*>(item)) ;
|
||||||
case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA:
|
break ;
|
||||||
return true ;
|
|
||||||
|
|
||||||
#warning need to implement tunnel data ACK handling here
|
case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK: handleRecvTunnelDataAckItem(tunnel_id,dynamic_cast<RsGxsTunnelDataAckItem*>(item)) ;
|
||||||
case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK:
|
break ;
|
||||||
return true ;
|
|
||||||
|
|
||||||
case RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS: handleRecvStatusItem(dynamic_cast<RsGxsTunnelStatusItem*>(item)) ;
|
case RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS: handleRecvStatusItem(tunnel_id,dynamic_cast<RsGxsTunnelStatusItem*>(item)) ;
|
||||||
return true ;
|
break ;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false ;
|
std::cerr << "(EE) impossible situation. DH items should be handled at the service level" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false ;
|
delete item ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//#warning is this function still used??
|
void p3GxsTunnelService::handleRecvTunnelDataAckItem(const RsGxsTunnelId& id,RsGxsTunnelDataAckItem *item)
|
||||||
//bool p3GxsTunnelService::handleOutgoingItem(RsGxsTunnelItem *item)
|
|
||||||
//{
|
|
||||||
// {
|
|
||||||
// RS_STACK_MUTEX(mGxsTunnelMtx) ;
|
|
||||||
//
|
|
||||||
// std::map<RsGxsId,GxsTunnelPeerInfo>::const_iterator it=_gxs_tunnel_contacts.find(RsGxsId(item->PeerId()));
|
|
||||||
//
|
|
||||||
// if(it == _gxs_tunnel_contacts.end())
|
|
||||||
// return false ;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//#ifdef CHAT_DEBUG
|
|
||||||
// std::cerr << "p3GxsTunnelService::handleOutgoingItem(): sending to " << item->PeerId() << ": interpreted as a distant chat virtual peer id." << std::endl;
|
|
||||||
//#endif
|
|
||||||
// sendTurtleData(item) ;
|
|
||||||
// return true;
|
|
||||||
//}
|
|
||||||
|
|
||||||
void p3GxsTunnelService::handleRecvStatusItem(RsGxsTunnelStatusItem *cs)
|
|
||||||
{
|
{
|
||||||
if(cs->flags & RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION)
|
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
|
||||||
|
|
||||||
|
std::cerr << "p3GxsTunnelService::handling RecvTunnelDataAckItem()" << std::endl;
|
||||||
|
std::cerr << " item counter = " << std::hex << item->unique_item_counter << std::dec << std::endl;
|
||||||
|
|
||||||
|
// remove it from the queue.
|
||||||
|
|
||||||
|
std::map<uint64_t,GxsTunnelData>::iterator it = pendingGxsTunnelDataItems.find(item->unique_item_counter) ;
|
||||||
|
|
||||||
|
if(it == pendingGxsTunnelDataItems.end())
|
||||||
{
|
{
|
||||||
RsGxsTunnelId tunnel_id ;
|
std::cerr << " (EE) item number " << std::hex << item->unique_item_counter << " is unknown. This is unexpected." << std::endl;
|
||||||
TurtleVirtualPeerId vpid = cs->PeerId() ;
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete it->second.data_item ;
|
||||||
|
pendingGxsTunnelDataItems.erase(it) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void p3GxsTunnelService::handleRecvTunnelDataItem(const RsGxsTunnelId& tunnel_id,RsGxsTunnelDataItem *item)
|
||||||
|
{
|
||||||
|
// imediately send an ACK for this item
|
||||||
|
|
||||||
|
RsGxsTunnelDataAckItem *ackitem = new RsGxsTunnelDataAckItem ;
|
||||||
|
|
||||||
|
ackitem->unique_item_counter = item->unique_item_counter ;
|
||||||
|
ackitem->PeerId(item->PeerId());
|
||||||
|
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
|
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
|
||||||
|
pendingGxsTunnelItems.push_back(ackitem) ; // we use the queue that does not need an ACK, in order to avoid an infinite loop ;-)
|
||||||
|
}
|
||||||
|
|
||||||
std::map<RsPeerId,GxsTunnelDHInfo>::iterator it = _gxs_tunnel_virtual_peer_ids.find(vpid) ;
|
// notify the client for the received data
|
||||||
|
|
||||||
if(it == _gxs_tunnel_virtual_peer_ids.end())
|
std::cerr << "p3GxsTunnelService::handleRecvTunnelDataItem()" << std::endl;
|
||||||
|
std::cerr << " data size = " << item->data_size << std::endl;
|
||||||
|
std::cerr << " service id = " << std::hex << item->service_id << std::dec << std::endl;
|
||||||
|
std::cerr << " counter id = " << std::hex << item->unique_item_counter << std::dec << std::endl;
|
||||||
|
|
||||||
|
RsGxsTunnelClientService *service = NULL ;
|
||||||
{
|
{
|
||||||
std::cerr << " (EE) Cannot find hash in gxs_tunnel peer list!!" << std::endl;
|
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
|
||||||
|
std::map<uint32_t,RsGxsTunnelClientService *>::const_iterator it = mRegisteredServices.find(item->service_id) ;
|
||||||
|
|
||||||
|
if(it == mRegisteredServices.end())
|
||||||
|
{
|
||||||
|
std::cerr << " (EE) no registered service with ID " << std::hex << item->service_id << std::dec << ". Rejecting item." << std::endl;
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
tunnel_id = it->second.tunnel_id ;
|
service = it->second ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
service->receiveData(tunnel_id,item->data,item->data_size) ;
|
||||||
|
|
||||||
|
item->data = NULL ; // avoids deletion, since the client has the memory now
|
||||||
|
item->data_size = 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void p3GxsTunnelService::handleRecvStatusItem(const RsGxsTunnelId& tunnel_id, RsGxsTunnelStatusItem *cs)
|
||||||
|
{
|
||||||
|
if(cs->flags & RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION)
|
||||||
markGxsTunnelAsClosed(tunnel_id);
|
markGxsTunnelAsClosed(tunnel_id);
|
||||||
}
|
|
||||||
|
|
||||||
// nothing more to do, because the decryption routing will update the last_contact time when decrypting.
|
// nothing more to do, because the decryption routing will update the last_contact time when decrypting.
|
||||||
|
|
||||||
if(cs->flags & RS_GXS_TUNNEL_FLAG_KEEP_ALIVE)
|
if(cs->flags & RS_GXS_TUNNEL_FLAG_KEEP_ALIVE)
|
||||||
std::cerr << "GxsTunnelService::handleRecvGxsTunnelStatusItem(): received keep alive packet for inactive tunnel! peerId=" << cs->PeerId() << std::endl;
|
std::cerr << "GxsTunnelService::handleRecvGxsTunnelStatusItem(): received keep alive packet for inactive tunnel! peerId=" << cs->PeerId() << " tunnel=" << tunnel_id << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3GxsTunnelService::handleTunnelRequest(const RsFileHash& hash,const RsPeerId& /*peer_id*/)
|
bool p3GxsTunnelService::handleTunnelRequest(const RsFileHash& hash,const RsPeerId& /*peer_id*/)
|
||||||
@ -408,7 +483,6 @@ void p3GxsTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *gitem,cons
|
|||||||
|
|
||||||
// Now try deserialise the decrypted data to make an RsItem out of it.
|
// Now try deserialise the decrypted data to make an RsItem out of it.
|
||||||
//
|
//
|
||||||
#warning needs proper passing of item to client
|
|
||||||
RsItem *citem = RsGxsTunnelSerialiser().deserialise(&((uint8_t*)item->data_bytes)[8],&item->data_size-8) ;
|
RsItem *citem = RsGxsTunnelSerialiser().deserialise(&((uint8_t*)item->data_bytes)[8],&item->data_size-8) ;
|
||||||
|
|
||||||
if(citem == NULL)
|
if(citem == NULL)
|
||||||
@ -419,11 +493,12 @@ void p3GxsTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *gitem,cons
|
|||||||
|
|
||||||
// DH key items are sent even before we know who we speak to, so the virtual peer id is used in this
|
// DH key items are sent even before we know who we speak to, so the virtual peer id is used in this
|
||||||
// case only.
|
// case only.
|
||||||
|
RsGxsTunnelDHPublicKeyItem *dhitem = dynamic_cast<RsGxsTunnelDHPublicKeyItem*>(citem) ;
|
||||||
|
|
||||||
if(dynamic_cast<RsGxsTunnelDHPublicKeyItem*>(citem) != NULL)
|
if(dhitem != NULL)
|
||||||
{
|
{
|
||||||
citem->PeerId(virtual_peer_id) ;
|
dhitem->PeerId(virtual_peer_id) ;
|
||||||
handleIncomingItem(dynamic_cast<RsGxsTunnelItem*>(citem)) ;
|
handleRecvDHPublicKey(dhitem) ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
std::cerr << "(EE) Deserialiased item has unexpected type." << std::endl;
|
std::cerr << "(EE) Deserialiased item has unexpected type." << std::endl;
|
||||||
@ -444,6 +519,7 @@ bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
RsGxsTunnelItem *citem = NULL;
|
RsGxsTunnelItem *citem = NULL;
|
||||||
|
RsGxsTunnelId tunnel_id;
|
||||||
|
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
|
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
|
||||||
@ -462,7 +538,7 @@ bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
RsGxsTunnelId tunnel_id = it->second.tunnel_id ;
|
tunnel_id = it->second.tunnel_id ;
|
||||||
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it2 = _gxs_tunnel_contacts.find(tunnel_id) ;
|
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it2 = _gxs_tunnel_contacts.find(tunnel_id) ;
|
||||||
|
|
||||||
if(it2 == _gxs_tunnel_contacts.end())
|
if(it2 == _gxs_tunnel_contacts.end())
|
||||||
@ -534,7 +610,7 @@ bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t
|
|||||||
#ifdef DEBUG_GXS_TUNNEL
|
#ifdef DEBUG_GXS_TUNNEL
|
||||||
std::cerr << "(II) Setting peer id to " << citem->PeerId() << std::endl;
|
std::cerr << "(II) Setting peer id to " << citem->PeerId() << std::endl;
|
||||||
#endif
|
#endif
|
||||||
handleIncomingItem(citem) ; // Treats the item, and deletes it
|
handleIncomingItem(tunnel_id,citem) ; // Treats the item, and deletes it
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@ -792,7 +868,7 @@ bool p3GxsTunnelService::locked_sendDHPublicKey(const DH *dh,const RsGxsId& own_
|
|||||||
dhitem->print(std::cerr, 2) ;
|
dhitem->print(std::cerr, 2) ;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
pendingGxsTunnelItems.push_back(dhitem) ; // sent off-mutex to avoid deadlocking.
|
pendingDHItems.push_back(dhitem) ; // sent off-mutex to avoid deadlocking.
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@ -841,14 +917,12 @@ bool p3GxsTunnelService::locked_initDHSessionKey(DH *& dh)
|
|||||||
|
|
||||||
// Encrypts and sends the item.
|
// Encrypts and sends the item.
|
||||||
|
|
||||||
void p3GxsTunnelService::sendTurtleData(RsGxsTunnelItem *item)
|
bool p3GxsTunnelService::locked_sendClearTunnelData(RsGxsTunnelDHPublicKeyItem *item)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_GXS_TUNNEL
|
#ifdef DEBUG_GXS_TUNNEL
|
||||||
std::cerr << "GxsTunnelService::sendTurtleData(): try sending item " << (void*)item << " to peer " << item->PeerId() << std::endl;
|
std::cerr << "GxsTunnelService::sendClearTunnelData(): try sending item " << (void*)item << " to peer " << item->PeerId() << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(dynamic_cast<RsGxsTunnelDHPublicKeyItem*>(item) != NULL)
|
|
||||||
{
|
|
||||||
// make a TurtleGenericData item out of it, and send it in clear.
|
// make a TurtleGenericData item out of it, and send it in clear.
|
||||||
//
|
//
|
||||||
RsTurtleGenericDataItem *gitem = new RsTurtleGenericDataItem ;
|
RsTurtleGenericDataItem *gitem = new RsTurtleGenericDataItem ;
|
||||||
@ -865,53 +939,46 @@ void p3GxsTunnelService::sendTurtleData(RsGxsTunnelItem *item)
|
|||||||
{
|
{
|
||||||
std::cerr << "(EE) Could not serialise item!!!" << std::endl;
|
std::cerr << "(EE) Could not serialise item!!!" << std::endl;
|
||||||
delete gitem ;
|
delete gitem ;
|
||||||
delete item ;
|
return false;
|
||||||
return ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_GXS_TUNNEL
|
#ifdef DEBUG_GXS_TUNNEL
|
||||||
std::cerr << " GxsTunnelService::sendTurtleData(): Sending clear data to virtual peer: " << item->PeerId() << std::endl;
|
std::cerr << " GxsTunnelService::sendClearTunnelData(): Sending clear data to virtual peer: " << item->PeerId() << std::endl;
|
||||||
std::cerr << " gitem->data_size = " << gitem->data_size << std::endl;
|
std::cerr << " gitem->data_size = " << gitem->data_size << std::endl;
|
||||||
std::cerr << " data = " << RsUtil::BinToHex((char*)gitem->data_bytes,gitem->data_size) ;
|
std::cerr << " data = " << RsUtil::BinToHex((char*)gitem->data_bytes,gitem->data_size) ;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
mTurtle->sendTurtleData(item->PeerId(),gitem) ;
|
mTurtle->sendTurtleData(item->PeerId(),gitem) ;
|
||||||
}
|
|
||||||
else
|
return true ;
|
||||||
{
|
}
|
||||||
|
|
||||||
|
// Sends this item using secured/authenticated method, thx to the establshed cryptographic channel.
|
||||||
|
|
||||||
|
bool p3GxsTunnelService::locked_sendEncryptedTunnelData(RsGxsTunnelItem *item)
|
||||||
|
{
|
||||||
uint32_t rssize = item->serial_size();
|
uint32_t rssize = item->serial_size();
|
||||||
uint8_t *buff = (uint8_t*)malloc(rssize) ;
|
RsTemporaryMemory buff(rssize) ;
|
||||||
|
|
||||||
if(!item->serialise(buff,rssize))
|
if(!item->serialise(buff,rssize))
|
||||||
{
|
{
|
||||||
std::cerr << "(EE) GxsTunnelService::sendTurtleData(): Could not serialise item!" << std::endl;
|
std::cerr << "(EE) GxsTunnelService::sendEncryptedTunnelData(): Could not serialise item!" << std::endl;
|
||||||
free(buff) ;
|
return false;
|
||||||
delete item ;
|
|
||||||
return ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sendEncryptedTurtleData(buff,rssize,item->PeerId()) ;
|
|
||||||
|
|
||||||
free(buff) ;
|
|
||||||
}
|
|
||||||
delete item ;
|
|
||||||
}
|
|
||||||
|
|
||||||
void p3GxsTunnelService::sendEncryptedTurtleData(const uint8_t *buff,uint32_t rssize,const TurtleVirtualPeerId& vpid)
|
|
||||||
{
|
|
||||||
uint8_t aes_key[GXS_TUNNEL_AES_KEY_SIZE] ;
|
uint8_t aes_key[GXS_TUNNEL_AES_KEY_SIZE] ;
|
||||||
uint64_t IV = 0;
|
uint64_t IV = 0;
|
||||||
|
|
||||||
#ifdef DEBUG_GXS_TUNNEL
|
#ifdef DEBUG_GXS_TUNNEL
|
||||||
std::cerr << "Sending encrypted data to tunnel wuth vpid " << vpid << std::endl;
|
std::cerr << "Sending encrypted data to tunnel wuth vpid " << item->PeerId() << std::endl;
|
||||||
#endif
|
#endif
|
||||||
RsStackMutex stack(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
|
TurtleVirtualPeerId vpid = item->PeerId() ;
|
||||||
|
|
||||||
std::map<TurtleVirtualPeerId,GxsTunnelDHInfo>::const_iterator it2 = _gxs_tunnel_virtual_peer_ids.find(vpid) ;
|
std::map<TurtleVirtualPeerId,GxsTunnelDHInfo>::const_iterator it2 = _gxs_tunnel_virtual_peer_ids.find(vpid) ;
|
||||||
if(it2 == _gxs_tunnel_virtual_peer_ids.end())
|
if(it2 == _gxs_tunnel_virtual_peer_ids.end())
|
||||||
{
|
{
|
||||||
std::cerr << "(EE) no virtual peer " << vpid << ". Something's wrong!" << std::endl;
|
std::cerr << "(EE) no virtual peer " << vpid << ". Something's wrong!" << std::endl;
|
||||||
return ;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it = _gxs_tunnel_contacts.find(it2->second.tunnel_id) ;
|
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::iterator it = _gxs_tunnel_contacts.find(it2->second.tunnel_id) ;
|
||||||
@ -919,12 +986,12 @@ void p3GxsTunnelService::sendEncryptedTurtleData(const uint8_t *buff,uint32_t rs
|
|||||||
if(it == _gxs_tunnel_contacts.end())
|
if(it == _gxs_tunnel_contacts.end())
|
||||||
{
|
{
|
||||||
std::cerr << "(EE) Cannot find contact key info for virtual peer id " << vpid << ". Cannot send message!" << std::endl;
|
std::cerr << "(EE) Cannot find contact key info for virtual peer id " << vpid << ". Cannot send message!" << std::endl;
|
||||||
return ;
|
return false;
|
||||||
}
|
}
|
||||||
if(it->second.status != RS_GXS_TUNNEL_STATUS_CAN_TALK)
|
if(it->second.status != RS_GXS_TUNNEL_STATUS_CAN_TALK)
|
||||||
{
|
{
|
||||||
std::cerr << "(EE) Cannot talk to vpid " << vpid << ". Tunnel status is: " << it->second.status << std::endl;
|
std::cerr << "(EE) Cannot talk to vpid " << vpid << ". Tunnel status is: " << it->second.status << std::endl;
|
||||||
return ;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(aes_key,it->second.aes_key,GXS_TUNNEL_AES_KEY_SIZE) ;
|
memcpy(aes_key,it->second.aes_key,GXS_TUNNEL_AES_KEY_SIZE) ;
|
||||||
@ -933,19 +1000,19 @@ void p3GxsTunnelService::sendEncryptedTurtleData(const uint8_t *buff,uint32_t rs
|
|||||||
while(IV == 0) IV = RSRandom::random_u64() ; // make a random 8 bytes IV, that is not 0
|
while(IV == 0) IV = RSRandom::random_u64() ; // make a random 8 bytes IV, that is not 0
|
||||||
|
|
||||||
#ifdef DEBUG_GXS_TUNNEL
|
#ifdef DEBUG_GXS_TUNNEL
|
||||||
std::cerr << "GxsTunnelService::sendTurtleData(): tunnel found. Encrypting data." << std::endl;
|
std::cerr << "GxsTunnelService::sendEncryptedTunnelData(): tunnel found. Encrypting data." << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Now encrypt this data using AES.
|
// Now encrypt this data using AES.
|
||||||
//
|
//
|
||||||
uint8_t *encrypted_data = new uint8_t[RsAES::get_buffer_size(rssize)];
|
|
||||||
uint32_t encrypted_size = RsAES::get_buffer_size(rssize);
|
uint32_t encrypted_size = RsAES::get_buffer_size(rssize);
|
||||||
|
RsTemporaryMemory encrypted_data(encrypted_size) ;
|
||||||
|
|
||||||
if(!RsAES::aes_crypt_8_16(buff,rssize,aes_key,(uint8_t*)&IV,encrypted_data,encrypted_size))
|
if(!RsAES::aes_crypt_8_16(buff,rssize,aes_key,(uint8_t*)&IV,encrypted_data,encrypted_size))
|
||||||
{
|
{
|
||||||
std::cerr << "(EE) packet encryption failed." << std::endl;
|
std::cerr << "(EE) packet encryption failed." << std::endl;
|
||||||
delete[] encrypted_data ;
|
delete[] encrypted_data ;
|
||||||
return ;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// make a TurtleGenericData item out of it:
|
// make a TurtleGenericData item out of it:
|
||||||
@ -962,21 +1029,21 @@ void p3GxsTunnelService::sendEncryptedTurtleData(const uint8_t *buff,uint32_t rs
|
|||||||
|
|
||||||
memcpy(& (((uint8_t*)gitem->data_bytes)[GXS_TUNNEL_ENCRYPTION_HMAC_SIZE+GXS_TUNNEL_ENCRYPTION_IV_SIZE]),encrypted_data,encrypted_size) ;
|
memcpy(& (((uint8_t*)gitem->data_bytes)[GXS_TUNNEL_ENCRYPTION_HMAC_SIZE+GXS_TUNNEL_ENCRYPTION_IV_SIZE]),encrypted_data,encrypted_size) ;
|
||||||
|
|
||||||
delete[] encrypted_data ;
|
|
||||||
|
|
||||||
#ifdef DEBUG_GXS_TUNNEL
|
#ifdef DEBUG_GXS_TUNNEL
|
||||||
std::cerr << " Using IV: " << std::hex << IV << std::dec << std::endl;
|
std::cerr << " Using IV: " << std::hex << IV << std::dec << std::endl;
|
||||||
std::cerr << " Using Key: " << RsUtil::BinToHex((char*)aes_key,GXS_TUNNEL_AES_KEY_SIZE) ; std::cerr << std::endl;
|
std::cerr << " Using Key: " << RsUtil::BinToHex((char*)aes_key,GXS_TUNNEL_AES_KEY_SIZE) ; std::cerr << std::endl;
|
||||||
std::cerr << " hmac: " << RsUtil::BinToHex((char*)gitem->data_bytes,GXS_TUNNEL_ENCRYPTION_HMAC_SIZE) ;
|
std::cerr << " hmac: " << RsUtil::BinToHex((char*)gitem->data_bytes,GXS_TUNNEL_ENCRYPTION_HMAC_SIZE) ;
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUG_GXS_TUNNEL
|
#ifdef DEBUG_GXS_TUNNEL
|
||||||
std::cerr << "GxsTunnelService::sendTurtleData(): Sending encrypted data to virtual peer: " << virtual_peer_id << std::endl;
|
std::cerr << "GxsTunnelService::sendEncryptedTunnelData(): Sending encrypted data to virtual peer: " << virtual_peer_id << std::endl;
|
||||||
std::cerr << " gitem->data_size = " << gitem->data_size << std::endl;
|
std::cerr << " gitem->data_size = " << gitem->data_size << std::endl;
|
||||||
std::cerr << " serialised data = " << RsUtil::BinToHex((char*)gitem->data_bytes,gitem->data_size) ;
|
std::cerr << " serialised data = " << RsUtil::BinToHex((char*)gitem->data_bytes,gitem->data_size) ;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mTurtle->sendTurtleData(virtual_peer_id,gitem) ;
|
mTurtle->sendTurtleData(virtual_peer_id,gitem) ;
|
||||||
|
|
||||||
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool p3GxsTunnelService::requestSecuredTunnel(const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, RsGxsTunnelId &tunnel_id, uint32_t& error_code)
|
bool p3GxsTunnelService::requestSecuredTunnel(const RsGxsId& to_gxs_id, const RsGxsId& from_gxs_id, RsGxsTunnelId &tunnel_id, uint32_t& error_code)
|
||||||
@ -1009,6 +1076,55 @@ bool p3GxsTunnelService::requestSecuredTunnel(const RsGxsId& to_gxs_id, const Rs
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool p3GxsTunnelService::sendData(const RsGxsTunnelId &tunnel_id, uint32_t service_id, const uint8_t *data, uint32_t size)
|
||||||
|
{
|
||||||
|
// make sure that the tunnel ID is registered.
|
||||||
|
|
||||||
|
std::cerr << "p3GxsTunnelService::sendData()" << std::endl;
|
||||||
|
std::cerr << " tunnel id : " << tunnel_id << std::endl;
|
||||||
|
std::cerr << " data size : " << size << std::endl;
|
||||||
|
std::cerr << " service id: " << std::hex << service_id << std::dec << std::endl;
|
||||||
|
|
||||||
|
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
|
||||||
|
|
||||||
|
std::map<RsGxsTunnelId,GxsTunnelPeerInfo>::const_iterator it = _gxs_tunnel_contacts.find(tunnel_id) ;
|
||||||
|
|
||||||
|
if(it == _gxs_tunnel_contacts.end())
|
||||||
|
{
|
||||||
|
std::cerr << " (EE) no tunnel known with this ID. Sorry!" << std::endl;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure the service is registered.
|
||||||
|
|
||||||
|
if(mRegisteredServices.find(service_id) == mRegisteredServices.end())
|
||||||
|
{
|
||||||
|
std::cerr << " (EE) no service registered with this ID. Please call rsGxsTunnel->registerClientService() at some point." << std::endl;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cerr << " verifications fine! Storing in out queue with:" << std::endl;
|
||||||
|
|
||||||
|
RsGxsTunnelDataItem *item = new RsGxsTunnelDataItem ;
|
||||||
|
|
||||||
|
item->unique_item_counter = global_item_counter++; // this allows to make the item unique
|
||||||
|
item->flags = 0; // not used yet.
|
||||||
|
item->service_id = service_id;
|
||||||
|
item->data_size = size; // encrypted data size
|
||||||
|
item->data = (uint8_t*)malloc(size); // encrypted data
|
||||||
|
memcpy(item->data,data,size) ;
|
||||||
|
|
||||||
|
GxsTunnelData& tdata( pendingGxsTunnelDataItems[item->unique_item_counter] ) ;
|
||||||
|
|
||||||
|
tdata.data_item = item ;
|
||||||
|
tdata.last_sending_attempt = 0 ; // never sent until now
|
||||||
|
|
||||||
|
std::cerr << " counter id : " << std::hex << item->unique_item_counter << std::dec << std::endl;
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void p3GxsTunnelService::startClientGxsTunnelConnection(const RsGxsId& to_gxs_id,const RsGxsId& from_gxs_id,RsGxsTunnelId& tunnel_id)
|
void p3GxsTunnelService::startClientGxsTunnelConnection(const RsGxsId& to_gxs_id,const RsGxsId& from_gxs_id,RsGxsTunnelId& tunnel_id)
|
||||||
{
|
{
|
||||||
// compute a random hash for that pair, and init the DH session for it so that we can recognise it when we get the virtual peer for it.
|
// compute a random hash for that pair, and init the DH session for it so that we can recognise it when we get the virtual peer for it.
|
||||||
@ -1158,7 +1274,7 @@ bool p3GxsTunnelService::closeExistingTunnel(const RsGxsTunnelId& tunnel_id)
|
|||||||
cs->flags = RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION;
|
cs->flags = RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION;
|
||||||
cs->PeerId(vpid) ;
|
cs->PeerId(vpid) ;
|
||||||
|
|
||||||
sendTurtleData(cs) ; // that needs to be done off-mutex and before we close the tunnel.
|
locked_sendEncryptedTunnelData(cs) ; // that needs to be done off-mutex and before we close the tunnel also ignoring failure.
|
||||||
|
|
||||||
#ifdef DEBUG_GXS_TUNNEL
|
#ifdef DEBUG_GXS_TUNNEL
|
||||||
std::cerr << " This is client side. Stopping tunnel manageement for tunnel_id " << tunnel_id << std::endl;
|
std::cerr << " This is client side. Stopping tunnel manageement for tunnel_id " << tunnel_id << std::endl;
|
||||||
|
@ -116,24 +116,23 @@ static const uint32_t GXS_TUNNEL_AES_KEY_SIZE = 16 ;
|
|||||||
class p3GxsTunnelService: public RsGxsTunnelService, public RsTurtleClientService
|
class p3GxsTunnelService: public RsGxsTunnelService, public RsTurtleClientService
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
p3GxsTunnelService(RsGixs *pids)
|
p3GxsTunnelService(RsGixs *pids) ;
|
||||||
: mGixs(pids), mGxsTunnelMtx("GXS tunnel")
|
|
||||||
{
|
|
||||||
mTurtle = NULL ;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void connectToTurtleRouter(p3turtle *) ;
|
virtual void connectToTurtleRouter(p3turtle *) ;
|
||||||
|
|
||||||
// Creates the invite if the public key of the distant peer is available.
|
// Creates the invite if the public key of the distant peer is available.
|
||||||
// Om success, stores the invite in the map above, so that we can respond to tunnel requests.
|
// Om success, stores the invite in the map above, so that we can respond to tunnel requests.
|
||||||
//
|
//
|
||||||
virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,RsGxsTunnelId& tunnel_id,uint32_t& error_code) ;
|
virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,RsGxsTunnelId& tunnel_id,uint32_t& error_code) ;
|
||||||
|
|
||||||
virtual bool closeExistingTunnel(const RsGxsTunnelId &tunnel_id) ;
|
virtual bool closeExistingTunnel(const RsGxsTunnelId &tunnel_id) ;
|
||||||
virtual bool getTunnelStatus(const RsGxsTunnelId& tunnel_id,uint32_t &status);
|
virtual bool getTunnelStatus(const RsGxsTunnelId& tunnel_id,uint32_t &status);
|
||||||
|
virtual bool sendData(const RsGxsTunnelId& tunnel_id,uint32_t service_id,const uint8_t *data,uint32_t size) ;
|
||||||
|
|
||||||
|
virtual bool registerClientService(uint32_t service_id,RsGxsTunnelClientService *service) ;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void flush() ;
|
void flush() ;
|
||||||
virtual bool handleIncomingItem(RsGxsTunnelItem *) ;
|
virtual void handleIncomingItem(const RsGxsTunnelId &tunnel_id, RsGxsTunnelItem *) ;
|
||||||
|
|
||||||
class GxsTunnelPeerInfo
|
class GxsTunnelPeerInfo
|
||||||
{
|
{
|
||||||
@ -170,6 +169,12 @@ private:
|
|||||||
TurtleFileHash hash ;
|
TurtleFileHash hash ;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GxsTunnelData
|
||||||
|
{
|
||||||
|
RsGxsTunnelDataItem *data_item ;
|
||||||
|
time_t last_sending_attempt ;
|
||||||
|
};
|
||||||
|
|
||||||
// This maps contains the current peers to talk to with distant chat.
|
// This maps contains the current peers to talk to with distant chat.
|
||||||
//
|
//
|
||||||
std::map<RsGxsTunnelId,GxsTunnelPeerInfo> _gxs_tunnel_contacts ; // current peers we can talk to
|
std::map<RsGxsTunnelId,GxsTunnelPeerInfo> _gxs_tunnel_contacts ; // current peers we can talk to
|
||||||
@ -178,7 +183,9 @@ private:
|
|||||||
// List of items to be sent asap. Used to store items that we cannot pass directly to
|
// List of items to be sent asap. Used to store items that we cannot pass directly to
|
||||||
// sendTurtleData(), because of Mutex protection.
|
// sendTurtleData(), because of Mutex protection.
|
||||||
|
|
||||||
std::list<RsGxsTunnelItem*> pendingGxsTunnelItems ;
|
std::map<uint64_t,GxsTunnelData> pendingGxsTunnelDataItems ; // items that need provable transport and encryption
|
||||||
|
std::list<RsGxsTunnelItem*> pendingGxsTunnelItems ; // items that do not need provable transport, yet need encryption
|
||||||
|
std::list<RsGxsTunnelDHPublicKeyItem*> pendingDHItems ;
|
||||||
|
|
||||||
// Overloaded from RsTurtleClientService
|
// Overloaded from RsTurtleClientService
|
||||||
|
|
||||||
@ -209,12 +216,15 @@ private:
|
|||||||
|
|
||||||
// item handling
|
// item handling
|
||||||
|
|
||||||
void handleRecvStatusItem(RsGxsTunnelStatusItem *item) ;
|
void handleRecvStatusItem(const RsGxsTunnelId& id,RsGxsTunnelStatusItem *item) ;
|
||||||
|
void handleRecvTunnelDataItem(const RsGxsTunnelId& id,RsGxsTunnelDataItem *item) ;
|
||||||
|
void handleRecvTunnelDataAckItem(const RsGxsTunnelId &id, RsGxsTunnelDataAckItem *item);
|
||||||
|
|
||||||
// Comunication with Turtle service
|
// Comunication with Turtle service
|
||||||
|
|
||||||
void sendTurtleData(RsGxsTunnelItem *) ;
|
bool locked_sendEncryptedTunnelData(RsGxsTunnelItem *item) ;
|
||||||
void sendEncryptedTurtleData(const uint8_t *buff, uint32_t rssize, const TurtleVirtualPeerId &vpid) ;
|
bool locked_sendClearTunnelData(RsGxsTunnelDHPublicKeyItem *item); // this limits the usage to DH items. Others should be encrypted!
|
||||||
|
|
||||||
bool handleEncryptedData(const uint8_t *data_bytes,uint32_t data_size,const TurtleFileHash& hash,const RsPeerId& virtual_peer_id) ;
|
bool handleEncryptedData(const uint8_t *data_bytes,uint32_t data_size,const TurtleFileHash& hash,const RsPeerId& virtual_peer_id) ;
|
||||||
|
|
||||||
static TurtleFileHash hashFromVirtualPeerId(const DistantChatPeerId& peerId) ; // converts IDs so that we can talk to RsPeerId from outside
|
static TurtleFileHash hashFromVirtualPeerId(const DistantChatPeerId& peerId) ; // converts IDs so that we can talk to RsPeerId from outside
|
||||||
@ -224,4 +234,9 @@ private:
|
|||||||
p3turtle *mTurtle ;
|
p3turtle *mTurtle ;
|
||||||
RsGixs *mGixs ;
|
RsGixs *mGixs ;
|
||||||
RsMutex mGxsTunnelMtx ;
|
RsMutex mGxsTunnelMtx ;
|
||||||
|
|
||||||
|
uint64_t global_item_counter ;
|
||||||
|
|
||||||
|
std::map<uint32_t,RsGxsTunnelClientService*> mRegisteredServices ;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,33 +61,32 @@ class RsGxsTunnelItem: public RsItem
|
|||||||
virtual uint32_t serial_size() = 0 ; // deserialise is handled using a constructor
|
virtual uint32_t serial_size() = 0 ; // deserialise is handled using a constructor
|
||||||
};
|
};
|
||||||
|
|
||||||
// /*!
|
/*!
|
||||||
// * For sending distant communication data. The item is not encrypted after being serialised, but the data it.
|
* For sending distant communication data. The item is not encrypted after being serialised, but the data it.
|
||||||
// * The MAC is computed over encrypted data using the PFS key. All other items (except DH keys) are serialised, encrypted, and
|
* The MAC is computed over encrypted data using the PFS key. All other items (except DH keys) are serialised, encrypted, and
|
||||||
// * sent as data in a RsGxsTunnelDataItem.
|
* sent as data in a RsGxsTunnelDataItem.
|
||||||
// *
|
*
|
||||||
// * @see p3GxsTunnelService
|
* @see p3GxsTunnelService
|
||||||
// */
|
*/
|
||||||
// class RsGxsTunnelDataItem: public RsGxsTunnelItem
|
class RsGxsTunnelDataItem: public RsGxsTunnelItem
|
||||||
// {
|
{
|
||||||
// public:
|
public:
|
||||||
// RsGxsTunnelDataItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DATA) {}
|
RsGxsTunnelDataItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DATA) {}
|
||||||
// RsGxsTunnelDataItem(uint8_t subtype) :RsGxsTunnelItem(subtype) {}
|
RsGxsTunnelDataItem(uint8_t subtype) :RsGxsTunnelItem(subtype) {}
|
||||||
//
|
|
||||||
// virtual ~RsGxsTunnelDataItem() {}
|
virtual ~RsGxsTunnelDataItem() {}
|
||||||
// virtual void clear() {}
|
virtual void clear() {}
|
||||||
// virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
|
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
|
||||||
//
|
|
||||||
// virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
|
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
|
||||||
// virtual uint32_t serial_size() ; // deserialise is handled using a constructor
|
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
|
||||||
//
|
|
||||||
// uint32_t sendTime;
|
uint64_t unique_item_counter; // this allows to make the item unique
|
||||||
// uint32_t flags; // mainly NEEDS_HACK?
|
uint32_t flags; // mainly NEEDS_HACK?
|
||||||
// unsigned char *data ; // encrypted data
|
uint32_t service_id ;
|
||||||
// uint32_t data_size ; // encrypted data size
|
uint32_t data_size ; // encrypted data size
|
||||||
// unsigned char IV[IV_LENGTH] ; // IV for the encrypted data
|
unsigned char *data ; // encrypted data
|
||||||
// unsigned char encrypted_data_mac[SHA_DIGEST_LENGTH] ; // mac of the encrypted data, in order to avoid
|
};
|
||||||
// };
|
|
||||||
|
|
||||||
// Used to send status of connection. This can be closing orders, flushing orders, etc.
|
// Used to send status of connection. This can be closing orders, flushing orders, etc.
|
||||||
// These items are always sent encrypted.
|
// These items are always sent encrypted.
|
||||||
@ -121,7 +120,7 @@ class RsGxsTunnelDataAckItem: public RsGxsTunnelItem
|
|||||||
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
|
virtual bool serialise(void *data,uint32_t& size) ; // Isn't it better that items can serialize themselves ?
|
||||||
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
|
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
|
||||||
|
|
||||||
Sha1CheckSum data_hash ;
|
uint64_t unique_item_counter ; // unique identifier for that item
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ public:
|
|||||||
// Data obtained from the corresponding GXS id. The memory ownership is transferred to the client, which
|
// Data obtained from the corresponding GXS id. The memory ownership is transferred to the client, which
|
||||||
// is responsible to free it using free() once used.
|
// is responsible to free it using free() once used.
|
||||||
|
|
||||||
virtual void receiveData(const RsGxsTunnelId& id,const RsGxsId& from_id,unsigned char *data,uint32_t data_size) =0;
|
virtual void receiveData(const RsGxsTunnelId& id,unsigned char *data,uint32_t data_size) =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GxsTunnelInfo
|
class GxsTunnelInfo
|
||||||
@ -84,6 +84,11 @@ public:
|
|||||||
// Communication to other services. //
|
// Communication to other services. //
|
||||||
//===================================================//
|
//===================================================//
|
||||||
|
|
||||||
|
// Register a new client service. The service ID needs to be unique, and it's the coder's resonsibility to use an ID that is not used elsewhere
|
||||||
|
// for the same purpose.
|
||||||
|
|
||||||
|
virtual bool registerClientService(uint32_t service_id,RsGxsTunnelClientService *service) =0;
|
||||||
|
|
||||||
// Asks for a tunnel. The service will request it to turtle router, and exchange a AES key using DH.
|
// Asks for a tunnel. The service will request it to turtle router, and exchange a AES key using DH.
|
||||||
// When the tunnel is secured, the client---here supplied as argument---will be notified. He can
|
// When the tunnel is secured, the client---here supplied as argument---will be notified. He can
|
||||||
// then send data into the tunnel. The same tunnel may be used by different clients.
|
// then send data into the tunnel. The same tunnel may be used by different clients.
|
||||||
@ -91,9 +96,9 @@ public:
|
|||||||
virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,RsGxsTunnelId& tunnel_id,uint32_t& error_code) =0 ;
|
virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,RsGxsTunnelId& tunnel_id,uint32_t& error_code) =0 ;
|
||||||
|
|
||||||
// Data is sent through the established tunnel, possibly multiple times, until reception is acknowledged. If the tunnel does not exist, the item is rejected and
|
// Data is sent through the established tunnel, possibly multiple times, until reception is acknowledged. If the tunnel does not exist, the item is rejected and
|
||||||
// an error is issued. In any case, the memory ownership of the data is transferred to the tunnel service, so the client should not use it afterwards.
|
// an error is issued. In any case, the memory ownership of the data is *not* transferred to the tunnel service, so the client should delete it afterwards, if needed.
|
||||||
|
|
||||||
virtual bool sendData(RsGxsTunnelId tunnel_id, uint32_t client_service_id, const uint8_t *data, uint32_t data_size) =0;
|
virtual bool sendData(const RsGxsTunnelId tunnel_id, uint32_t client_service_id, const uint8_t *data, uint32_t data_size) =0;
|
||||||
|
|
||||||
// Removes any established tunnel to this GXS id. This makes the tunnel refuse further data, but the tunnel will be however kept alive
|
// Removes any established tunnel to this GXS id. This makes the tunnel refuse further data, but the tunnel will be however kept alive
|
||||||
// until all pending data is flushed. All clients attached to the tunnel will be notified that the tunnel gets closed.
|
// until all pending data is flushed. All clients attached to the tunnel will be notified that the tunnel gets closed.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user