diff --git a/libretroshare/src/gxstunnel/p3gxstunnel.cc b/libretroshare/src/gxstunnel/p3gxstunnel.cc index b43aa7ff8..869326795 100644 --- a/libretroshare/src/gxstunnel/p3gxstunnel.cc +++ b/libretroshare/src/gxstunnel/p3gxstunnel.cc @@ -31,6 +31,7 @@ #include "openssl/err.h" #include "util/rsaes.h" +#include "util/rsprint.h" #include #include @@ -51,12 +52,13 @@ static const uint32_t RS_GXS_TUNNEL_DH_STATUS_UNINITIALIZED = 0x0000 ; static const uint32_t RS_GXS_TUNNEL_DH_STATUS_HALF_KEY_DONE = 0x0001 ; static const uint32_t RS_GXS_TUNNEL_DH_STATUS_KEY_AVAILABLE = 0x0002 ; -static const uint32_t RS_GXS_TUNNEL_STATUS_UNKNOWN = 0x00 ; -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_UNKNOWN = 0x00 ; +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_REMOTELY_CLOSED = 0x03 ; -static const uint32_t GXS_TUNNEL_HMAC_SIZE = SHA_DIGEST_LENGTH ; -static const uint32_t GXS_TUNNEL_IV_SIZE = 8 ; +static const uint32_t GXS_TUNNEL_ENCRYPTION_HMAC_SIZE = SHA_DIGEST_LENGTH ; +static const uint32_t GXS_TUNNEL_ENCRYPTION_IV_SIZE = 8 ; void p3GxsTunnelService::connectToTurtleRouter(p3turtle *tr) { @@ -70,7 +72,7 @@ void p3GxsTunnelService::flush() // while(!pendingGxsTunnelItems.empty()) { - sendTurtleData( pendingGxsTunnelItems.front() ) ; + sendTurtleData(pendingGxsTunnelItems.front() ) ; pendingGxsTunnelItems.pop_front() ; } @@ -102,9 +104,7 @@ void p3GxsTunnelService::flush() { RsGxsTunnelStatusItem *cs = new RsGxsTunnelStatusItem ; -#warning should we send that unencrypted?? - cs->status_string.clear() ; - cs->flags = RS_CHAT_FLAG_PRIVATE | RS_CHAT_FLAG_KEEP_ALIVE; + cs->flags = RS_GXS_TUNNEL_FLAG_KEEP_ALIVE; cs->PeerId(RsPeerId(it->first)) ; // we send off-mutex to avoid deadlock. @@ -119,7 +119,7 @@ void p3GxsTunnelService::flush() } } -bool p3GxsTunnelService::handleRecvItem(RsGxsTunnelItem *item) +bool p3GxsTunnelService::handleIncomingItem(RsGxsTunnelItem *item) { if(item == NULL) return false ; @@ -139,7 +139,6 @@ bool p3GxsTunnelService::handleRecvItem(RsGxsTunnelItem *item) case RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS: handleRecvStatusItem(dynamic_cast(item)) ; return true ; - } default: return false ; @@ -148,24 +147,24 @@ bool p3GxsTunnelService::handleRecvItem(RsGxsTunnelItem *item) return false ; } -#warning is this function still used?? -bool p3GxsTunnelService::handleOutgoingItem(RsGxsTunnelItem *item) -{ - { - RS_STACK_MUTEX(mGxsTunnelMtx) ; - - std::map::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; -} +//#warning is this function still used?? +//bool p3GxsTunnelService::handleOutgoingItem(RsGxsTunnelItem *item) +//{ +// { +// RS_STACK_MUTEX(mGxsTunnelMtx) ; +// +// std::map::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) { @@ -383,7 +382,7 @@ void p3GxsTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *gitem,cons // Now try deserialise the decrypted data to make an RsItem out of it. // #warning needs proper passing of item to client - //RsItem *citem = RsChatSerialiser().deserialise(&((uint8_t*)item->data_bytes)[8],&item->data_size) ; + RsItem *citem = RsGxsTunnelSerialiser().deserialise(&((uint8_t*)item->data_bytes)[8],&item->data_size-8) ; if(citem == NULL) { @@ -397,7 +396,7 @@ void p3GxsTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *gitem,cons if(dynamic_cast(citem) != NULL) { citem->PeerId(virtual_peer_id) ; - handleIncomingItem(citem) ; + handleIncomingItem(dynamic_cast(citem)) ; } else std::cerr << "(EE) Deserialiased item has unexpected type." << std::endl; @@ -413,18 +412,18 @@ bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t std::cerr << " size = " << data_size << std::endl; std::cerr << " data = " << (void*)data_bytes << std::endl; std::cerr << " IV = " << std::hex << *(uint64_t*)data_bytes << std::dec << std::endl; - std::cerr << " data = " << Bin2Hex((uint8_t*)data_bytes,data_size) ; + std::cerr << " data = " << RsUtil::BinToHex((char*)data_bytes,data_size) ; std::cerr << std::endl; #endif - RsItem *citem = NULL; + RsGxsTunnelItem *citem = NULL; { RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ - uint32_t encrypted_size = data_size - GXS_TUNNEL_IV_SIZE - GXS_TUNNEL_HMAC_SIZE; + uint32_t encrypted_size = data_size - GXS_TUNNEL_ENCRYPTION_IV_SIZE - GXS_TUNNEL_ENCRYPTION_HMAC_SIZE; uint32_t decrypted_size = RsAES::get_buffer_size(encrypted_size); - uint8_t *encrypted_data = (uint8_t*)data_bytes+GXS_TUNNEL_IV_SIZE+GXS_TUNNEL_HMAC_SIZE; + uint8_t *encrypted_data = (uint8_t*)data_bytes+GXS_TUNNEL_ENCRYPTION_IV_SIZE+GXS_TUNNEL_ENCRYPTION_HMAC_SIZE; uint8_t *decrypted_data = new uint8_t[decrypted_size]; uint8_t aes_key[GXS_TUNNEL_AES_KEY_SIZE] ; @@ -449,17 +448,17 @@ bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t #ifdef DEBUG_GXS_TUNNEL std::cerr << " Using IV: " << std::hex << *(uint64_t*)data_bytes << std::dec << std::endl; std::cerr << " Decrypted buffer size: " << decrypted_size << std::endl; - std::cerr << " key : " << Bin2Hex(aes_key,GXS_TUNNEL_AES_KEY_SIZE) << ; std::cerr << std::endl; - std::cerr << " hmac : " << Bin2Hex((uint8_t*)data_bytes+GXS_TUNNEL_IV_SIZE,GXS_TUNNEL_HMAC_SIZE) << ; std::cerr << std::endl; - std::cerr << " data : " << Bin2Hex((uint8_t*)data_bytes,data_size) << ; std::cerr << std::endl; + std::cerr << " key : " << RsUtil::BinToHex((char*)aes_key,GXS_TUNNEL_AES_KEY_SIZE) << std::endl; + std::cerr << " hmac : " << RsUtil::BinToHex((char*)data_bytes+GXS_TUNNEL_ENCRYPTION_IV_SIZE,GXS_TUNNEL_ENCRYPTION_HMAC_SIZE) << std::endl; + std::cerr << " data : " << RsUtil::BinToHex((char*)data_bytes,data_size) << std::endl; #endif // first, check the HMAC unsigned char *hm = HMAC(EVP_sha1(),aes_key,GXS_TUNNEL_AES_KEY_SIZE,encrypted_data,encrypted_size,NULL,NULL) ; - if(memcmp(hm,&data_bytes[GXS_TUNNEL_IV_SIZE],GXS_TUNNEL_HMAC_SIZE)) + if(memcmp(hm,&data_bytes[GXS_TUNNEL_ENCRYPTION_IV_SIZE],GXS_TUNNEL_ENCRYPTION_HMAC_SIZE)) { - std::cerr << "(EE) packet HMAC does not match. Computed HMAC=" << Bin2Hex(md,GXS_TUNNEL_HMAC_SIZE) << std::endl; + std::cerr << "(EE) packet HMAC does not match. Computed HMAC=" << RsUtil::BinToHex((char*)hm,GXS_TUNNEL_ENCRYPTION_HMAC_SIZE) << std::endl; std::cerr << "(EE) resetting new DH session." << std::endl; delete[] decrypted_data ; @@ -489,8 +488,7 @@ bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t // Now try deserialise the decrypted data to make an RsItem out of it. // -#warning pass on the serialised data directly to client (see what GRouter does) - //citem = RsChatSerialiser().deserialise(decrypted_data,&decrypted_size) ; + citem = RsGxsTunnelSerialiser().deserialiseGxsTunnelItem(decrypted_data,&decrypted_size) ; delete[] decrypted_data ; @@ -657,7 +655,7 @@ void p3GxsTunnelService::handleRecvDHPublicKey(RsGxsTunnelDHPublicKeyItem *item) #ifdef DEBUG_GXS_TUNNEL std::cerr << " DH key computed. Tunnel is now secured!" << std::endl; - std::cerr << " Key computed: " << Bin2Hex(pinfo.aes_key,16) << std::cerr << std::endl; + std::cerr << " Key computed: " << RsUtil::BinToHex((char*)pinfo.aes_key,16) << std::cerr << std::endl; std::cerr << " Sending a ACK packet." << std::endl; #endif @@ -678,7 +676,7 @@ void p3GxsTunnelService::handleRecvDHPublicKey(RsGxsTunnelDHPublicKeyItem *item) //RsServer::notify()->notifyListChange(NOTIFY_LIST_PRIVATE_INCOMING_CHAT, NOTIFY_TYPE_ADD); } -bool GxsTunnelService::locked_sendDHPublicKey(const DH *dh,const RsGxsId& own_gxs_id,const RsPeerId& virtual_peer_id) +bool p3GxsTunnelService::locked_sendDHPublicKey(const DH *dh,const RsGxsId& own_gxs_id,const RsPeerId& virtual_peer_id) { if(dh == NULL) { @@ -739,7 +737,7 @@ bool GxsTunnelService::locked_sendDHPublicKey(const DH *dh,const RsGxsId& own_gx return true ; } -bool GxsTunnelService::locked_initDHSessionKey(DH *& dh) +bool p3GxsTunnelService::locked_initDHSessionKey(DH *& dh) { // We use our own DH group prime. This has been generated with command-line openssl and checked. @@ -795,7 +793,7 @@ void p3GxsTunnelService::sendTurtleData(RsGxsTunnelItem *item) // RsTurtleGenericDataItem *gitem = new RsTurtleGenericDataItem ; - uint32_t rssize = item->serial_size() ; + uint32_t rssize = item->serial_size() ; gitem->data_size = rssize + 8 ; gitem->data_bytes = malloc(rssize+8) ; @@ -814,7 +812,7 @@ void p3GxsTunnelService::sendTurtleData(RsGxsTunnelItem *item) #ifdef DEBUG_GXS_TUNNEL std::cerr << " GxsTunnelService::sendTurtleData(): Sending clear data to virtual peer: " << item->PeerId() << std::endl; std::cerr << " gitem->data_size = " << gitem->data_size << std::endl; - std::cerr << " data = " << Bin2Hex(gitem->data_bytes,gitem->data_size) ; + std::cerr << " data = " << RsUtil::BinToHex((char*)gitem->data_bytes,gitem->data_size) ; std::cerr << std::endl; #endif mTurtle->sendTurtleData(item->PeerId(),gitem) ; @@ -887,34 +885,34 @@ void p3GxsTunnelService::sendEncryptedTurtleData(const uint8_t *buff,uint32_t rs // RsTurtleGenericDataItem *gitem = new RsTurtleGenericDataItem ; - gitem->data_size = encrypted_size + GXS_TUNNEL_ENCRYPTION_IV_SIZE + GXS_TUNNEL_HMAC_SIZE ; + gitem->data_size = encrypted_size + GXS_TUNNEL_ENCRYPTION_IV_SIZE + GXS_TUNNEL_ENCRYPTION_HMAC_SIZE ; gitem->data_bytes = malloc(gitem->data_size) ; - memcpy(& (((uint8_t*)gitem->data_bytes)[0] ,&IV,8) ; + memcpy(& ((uint8_t*)gitem->data_bytes)[0] ,&IV,8) ; - unsigned int md_len = GXS_TUNNEL_HMAC_SIZE ; - HMAC(EVP_sha1(),aes_key,GXS_TUNNEL_AES_KEY_SIZE,encrypted_data,encrypted_size,&(((uint8_t*)gitem->data_bytes)[GXS_TUNNEL_IV_SIZE]),&md_len) ; + unsigned int md_len = GXS_TUNNEL_ENCRYPTION_HMAC_SIZE ; + HMAC(EVP_sha1(),aes_key,GXS_TUNNEL_AES_KEY_SIZE,encrypted_data,encrypted_size,&(((uint8_t*)gitem->data_bytes)[GXS_TUNNEL_ENCRYPTION_IV_SIZE]),&md_len) ; - memcpy(& (((uint8_t*)gitem->data_bytes)[GXS_TUNNEL_HMAC_SIZE+GXS_TUNNEL_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 std::cerr << " Using IV: " << std::hex << IV << std::dec << std::endl; - std::cerr << " Using Key: " << Bin2Hex(aes_key,GXS_TUNNEL_AES_KEY_SIZE) ; std::cerr << std::endl; - std::cerr << " hmac: " << Bin2Hex(gitem->data_bytes,GXS_TUNNEL_HMAC_SIZE) ; + 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) ; #endif #ifdef DEBUG_GXS_TUNNEL std::cerr << "GxsTunnelService::sendTurtleData(): Sending encrypted data to virtual peer: " << virtual_peer_id << std::endl; std::cerr << " gitem->data_size = " << gitem->data_size << std::endl; - std::cerr << " serialised data = " << Bin2Hex(gitem->data_bytes,gitem->data_size) ; + std::cerr << " serialised data = " << RsUtil::BinToHex((char*)gitem->data_bytes,gitem->data_size) ; std::cerr << std::endl; #endif mTurtle->sendTurtleData(virtual_peer_id,gitem) ; } -bool p3GxsTunnelService::initiateGxsTunnelConnexion(const RsGxsId& to_gxs_id,const RsGxsId& from_gxs_id,uint32_t& error_code) +bool p3GxsTunnelService::requestSecuredTunnel(const RsGxsId& to_gxs_id,const RsGxsId& from_gxs_id,RsGxsTunnelClientService *client,uint32_t& error_code) { // should be a parameter. @@ -932,6 +930,7 @@ bool p3GxsTunnelService::initiateGxsTunnelConnexion(const RsGxsId& to_gxs_id,con if(!found) { std::cerr << " (EE) Cannot start distant chat, since GXS id " << from_gxs_id << " is not available." << std::endl; + error_code = RS_GXS_TUNNEL_ERROR_UNKNOWN_GXS_ID ; return false ; } RsGxsId own_gxs_id = from_gxs_id ; @@ -1029,7 +1028,7 @@ RsGxsId p3GxsTunnelService::gxsIdFromHash(const TurtleFileHash& sum) return RsGxsId(sum.toByteArray());// takes the first 16 bytes } -bool p3GxsTunnelService::getGxsTunnelStatus(const RsGxsId& gxs_id,uint32_t& status, RsGxsId *from_gxs_id) +bool p3GxsTunnelService::getTunnelStatus(const RsGxsId& gxs_id,uint32_t& status, RsGxsId *from_gxs_id) { RsStackMutex stack(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/ @@ -1050,7 +1049,7 @@ bool p3GxsTunnelService::getGxsTunnelStatus(const RsGxsId& gxs_id,uint32_t& stat return false ; } -bool p3GxsTunnelService::closeGxsTunnelConnexion(const RsGxsId& gxs_id) +bool p3GxsTunnelService::closeExistingTunnel(const RsGxsId& gxs_id) { // two cases: // - client needs to stop asking for tunnels => remove the hash from the list of tunnelled files @@ -1082,7 +1081,7 @@ bool p3GxsTunnelService::closeGxsTunnelConnexion(const RsGxsId& gxs_id) RsGxsTunnelStatusItem *cs = new RsGxsTunnelStatusItem ; - cs->flags = RS_CHAT_FLAG_CLOSING_DISTANT_CONNECTION; + cs->flags = RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION; cs->PeerId(RsPeerId(gxs_id)); sendTurtleData(cs) ; // that needs to be done off-mutex and before we close the tunnel. diff --git a/libretroshare/src/gxstunnel/p3gxstunnel.h b/libretroshare/src/gxstunnel/p3gxstunnel.h index a26ef6019..a33c60862 100644 --- a/libretroshare/src/gxstunnel/p3gxstunnel.h +++ b/libretroshare/src/gxstunnel/p3gxstunnel.h @@ -3,7 +3,7 @@ * * Services for RetroShare. * - * Copyright 2014 by Cyril Soler + * Copyright 2015 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 @@ -25,6 +25,33 @@ #pragma once +// Generic tunnel service +// +// Preconditions: +// * multiple services can use the same tunnel +// * tunnels are automatically encrypted and ensure transport (items stored in a queue until ACKed by the other side) +// * each tunnel is associated to a specific GXS id on both sides. Consequently, services that request tunnels from different IDs to a +// server for the same GXS id need to be handled correctly. +// +// GUI +// * the GUI should show for each tunnel: +// - starting and ending GXS ids +// - tunnel status (DH ok, closed from distant peer, locally closed, etc) +// - amount of data that is transferred in the tunnel +// - number of pending items (and total size) +// - number ACKed items both ways. +// +// we can use an additional tab "Authenticated tunnels" in the statistics->turtle window +// +// Interaction with services: +// +// Services request tunnels from a given GXS id and to a given GXS id. When ready, they get a handle (virtual peer id) +// +// Services send data in the tunnel using the virtual peer id +// +// Data is send to a service ID (could be any existing service ID). The endpoint of the tunnel must register each service, in order to +// allow the data to be transmitted/sent from/to that service. Otherwise an error is issued. + #include #include #include @@ -42,20 +69,19 @@ public: mTurtle = NULL ; } - void flush() ; - virtual void connectToTurtleRouter(p3turtle *) ; // 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. // - bool initiateTunnelConnexion(const RsGxsId& to_gxs_id,const RsGxsId &from_gxs_id, uint32_t &error_code) ; - bool closeTunnelConnexion(const RsGxsId& pid) ; + virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,RsGxsTunnelClientService *client,uint32_t& error_code) ; + virtual bool closeExistingTunnel(const RsGxsId& pid) ; virtual bool getTunnelStatus(const RsGxsId &gxs_id,uint32_t &status, RsGxsId *from_gxs_id=NULL) ; - virtual void handleIncomingItem(RsItem *) ; - private: + void flush() ; + virtual bool handleIncomingItem(RsGxsTunnelItem *) ; + class GxsTunnelPeerInfo { public: @@ -95,7 +121,7 @@ private: // List of items to be sent asap. Used to store items that we cannot pass directly to // sendTurtleData(), because of Mutex protection. - std::list pendingDistantChatItems ; + std::list pendingGxsTunnelItems ; // Overloaded from RsTurtleClientService @@ -107,7 +133,7 @@ private: // session handling handles void markGxsTunnelAsClosed(const RsGxsId &gxs_id) ; - void startClientGxsTunnelConnection(const RsGxsId &to_gxs_id,const RsGxsId& from_gxs_id) ; + void startClientGxsTunnelConnection(const RsGxsId &to_gxs_id, const RsGxsId& from_gxs_id) ; void locked_restartDHSession(const RsPeerId &virtual_peer_id, const RsGxsId &own_gxs_id) ; // utility functions @@ -123,6 +149,10 @@ private: TurtleVirtualPeerId virtualPeerIdFromHash(const TurtleFileHash& hash) ; // ... and to a hash for p3turtle + // item handling + + void handleRecvStatusItem(RsGxsTunnelStatusItem *item) ; + // Comunication with Turtle service void sendTurtleData(RsGxsTunnelItem *) ; diff --git a/libretroshare/src/gxstunnel/rsgxstunnelitems.h b/libretroshare/src/gxstunnel/rsgxstunnelitems.h index f2f4c0ef5..3de2e207b 100644 --- a/libretroshare/src/gxstunnel/rsgxstunnelitems.h +++ b/libretroshare/src/gxstunnel/rsgxstunnelitems.h @@ -166,6 +166,6 @@ class RsGxsTunnelSerialiser: public RsSerialType { return static_cast(item)->serialise(data,*size) ; } - virtual RsItem *deserialise (void *data, uint32_t *size) ; + virtual RsGxsTunnelItem *deserialiseGxsTunnelItem(void *data, uint32_t *size) ; }; diff --git a/libretroshare/src/retroshare/rsgxstunnel.h b/libretroshare/src/retroshare/rsgxstunnel.h index 8645f587c..3024b96d7 100644 --- a/libretroshare/src/retroshare/rsgxstunnel.h +++ b/libretroshare/src/retroshare/rsgxstunnel.h @@ -27,11 +27,17 @@ #include "util/rsdir.h" #include "retroshare/rsids.h" +#include "retroshare/rsturtle.h" #include "retroshare/rsgxsifacetypes.h" class RsGxsTunnelService { public: + static const uint32_t RS_GXS_TUNNEL_ERROR_NO_ERROR = 0x0000 ; + static const uint32_t RS_GXS_TUNNEL_ERROR_UNKNOWN_GXS_ID = 0x0001 ; + + typedef TurtleVirtualPeerId RsGxsTunnelId ; + class RsGxsTunnelClientService { public: @@ -49,13 +55,19 @@ public: class GxsTunnelInfo { public: - RsGxsId gxs_id ; // GXS Id to which we're talking - uint32_t tunnel_status ; // active, requested, DH pending, etc. - uint32_t pending_data_packets; // number of packets not acknowledged by other side, still on their way. - uint32_t total_size_sent ; // total number bytes sent through that tunnel since openned. - uint32_t total_packets_sent ; // total number of packets sent and acknowledged by other side - - std::vector client_services ; + // Tunnel information + + RsGxsId destination_gxs_id ; // GXS Id we're talking to + RsGxsId source_gxs_id ; // GXS Id we're using to talk + uint32_t tunnel_status ; // active, requested, DH pending, etc. + uint32_t total_size_sent ; // total bytes sent through that tunnel since openned (including management). + uint32_t total_size_received ; // total bytes received through that tunnel since openned (including management). + + // Data packets + + uint32_t pending_data_packets; // number of packets not acknowledged by other side, still on their way. Should be 0 unless something bad happens. + uint32_t total_data_packets_sent ; // total number of data packets sent (does not include tunnel management) + uint32_t total_data_packets_received ; // total number of data packets received (does not include tunnel management) }; // This is the interface file for the secured tunnel service @@ -76,16 +88,17 @@ public: // 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. - virtual bool requestSecuredTunnel(const RsGxsId& to_id,RsGxsTunnelClientService *client) =0 ; + virtual bool requestSecuredTunnel(const RsGxsId& to_id,const RsGxsId& from_id,uint32_t& error_code) =0 ; - // Data is sent through the established tunnel, possibly multiple times, until reception is acknowledged + // 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. - virtual bool sendData(const RsGxsId& destination, const GRouterServiceId& client_id, const uint8_t *data, uint32_t data_size, const RsGxsId& signing_id, GRouterMsgPropagationId& id) =0; + virtual bool sendData(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 // until all pending data is flushed. All clients attached to the tunnel will be notified that the tunnel gets closed. - virtual bool removeExistingTunnel(const RsGxsId& to_id) =0; + virtual bool closeExistingTunnel(const RsGxsId& to_id) =0; //===================================================// // Routage feedback from other services // diff --git a/libretroshare/src/util/rsprint.cc b/libretroshare/src/util/rsprint.cc index 97848b3c0..0d0ec5a04 100644 --- a/libretroshare/src/util/rsprint.cc +++ b/libretroshare/src/util/rsprint.cc @@ -40,6 +40,10 @@ std::string RsUtil::BinToHex(const std::string &bin) return BinToHex(bin.c_str(), bin.length()); } +std::string RsUtil::BinToHex(const unsigned char *arr, const uint32_t len) +{ + return BinToHex((char*)arr,len) ; +} std::string RsUtil::BinToHex(const char *arr, const uint32_t len) { std::string out; diff --git a/libretroshare/src/util/rsprint.h b/libretroshare/src/util/rsprint.h index b5a370a49..9a1dbe7c3 100644 --- a/libretroshare/src/util/rsprint.h +++ b/libretroshare/src/util/rsprint.h @@ -35,6 +35,7 @@ namespace RsUtil { std::string BinToHex(const std::string &bin); std::string BinToHex(const char *arr, const uint32_t len); +std::string BinToHex(const unsigned char *arr, const uint32_t len); std::string HashId(const std::string &id, bool reverse = false); //std::string AccurateTimeString();