half-way through GxsTunnel service

This commit is contained in:
csoler 2015-11-18 23:56:35 -05:00
parent 7bcbc70d21
commit cb97ce6f72
4 changed files with 191 additions and 409 deletions

View File

@ -51,6 +51,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 GXS_TUNNEL_HMAC_SIZE = SHA_DIGEST_LENGTH ;
static const uint32_t GXS_TUNNEL_IV_SIZE = 8 ;
void p3GxsTunnelService::connectToTurtleRouter(p3turtle *tr)
{
mTurtle = tr ;
@ -93,7 +100,7 @@ void p3GxsTunnelService::flush()
}
if(it->second.last_keep_alive_sent + GXS_TUNNEL_KEEP_ALIVE_TIMEOUT < now && it->second.status == RS_GXS_TUNNEL_STATUS_CAN_TALK)
{
RsChatStatusItem *cs = new RsChatStatusItem ;
RsGxsTunnelStatusItem *cs = new RsGxsTunnelStatusItem ;
#warning should we send that unencrypted??
cs->status_string.clear() ;
@ -112,21 +119,26 @@ void p3GxsTunnelService::flush()
}
}
bool p3GxsTunnelService::handleRecvItem(RsChatItem *item)
bool p3GxsTunnelService::handleRecvItem(RsGxsTunnelItem *item)
{
if(item == NULL)
return false ;
switch(item->PacketSubType())
{
case RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY: handleRecvDHPublicKey(dynamic_cast<RsGxsTunnelDHPublicKeyItem*>(item)) ; break ;
return true ;
case RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY: handleRecvDHPublicKey(dynamic_cast<RsGxsTunnelDHPublicKeyItem*>(item)) ; break ;
return true ;
case RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS:
{
// Keep alive packets should not be forwarded to the GUI. It's just for keeping the tunnel up.
return true ;
#warning need to implement tunnel data handling here
case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA:
return true ;
#warning need to implement tunnel data ACK handling here
case RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK:
return true ;
case RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS: handleRecvStatusItem(dynamic_cast<RsGxsTunnelStatusItem*>(item)) ;
return true ;
}
default:
@ -135,7 +147,9 @@ bool p3GxsTunnelService::handleRecvItem(RsChatItem *item)
return false ;
}
bool p3GxsTunnelService::handleOutgoingItem(RsChatItem *item)
#warning is this function still used??
bool p3GxsTunnelService::handleOutgoingItem(RsGxsTunnelItem *item)
{
{
RS_STACK_MUTEX(mGxsTunnelMtx) ;
@ -147,7 +161,7 @@ bool p3GxsTunnelService::handleOutgoingItem(RsChatItem *item)
}
#ifdef CHAT_DEBUG
std::cerr << "p3ChatService::handleOutgoingItem(): sending to " << item->PeerId() << ": interpreted as a distant chat virtual peer id." << std::endl;
std::cerr << "p3GxsTunnelService::handleOutgoingItem(): sending to " << item->PeerId() << ": interpreted as a distant chat virtual peer id." << std::endl;
#endif
sendTurtleData(item) ;
return true;
@ -161,7 +175,7 @@ void p3GxsTunnelService::handleRecvStatusItem(RsGxsTunnelStatusItem *cs)
// 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)
std::cerr << "GxsTunnelService::handleRecvChatStatusItem(): 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() << std::endl;
}
bool p3GxsTunnelService::handleTunnelRequest(const RsFileHash& hash,const RsPeerId& /*peer_id*/)
@ -192,64 +206,64 @@ bool p3GxsTunnelService::handleTunnelRequest(const RsFileHash& hash,const RsPeer
void p3GxsTunnelService::addVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction dir)
{
#ifdef DEBUG_GXS_TUNNEL
std::cerr << "GxsTunnelService:: received new virtual peer " << virtual_peer_id << " for hash " << hash << ", dir=" << dir << std::endl;
std::cerr << "GxsTunnelService:: received new virtual peer " << virtual_peer_id << " for hash " << hash << ", dir=" << dir << std::endl;
#endif
RsGxsId own_gxs_id ;
RsGxsId own_gxs_id ;
{
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
{
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
GxsTunnelDHInfo& dhinfo( _gxs_tunnel_virtual_peer_ids[virtual_peer_id] ) ;
dhinfo.gxs_id.clear() ;
GxsTunnelDHInfo& dhinfo( _gxs_tunnel_virtual_peer_ids[virtual_peer_id] ) ;
dhinfo.gxs_id.clear() ;
if(dhinfo.dh != NULL)
DH_free(dhinfo.dh) ;
if(dhinfo.dh != NULL)
DH_free(dhinfo.dh) ;
dhinfo.dh = NULL ;
dhinfo.direction = dir ;
dhinfo.hash = hash ;
dhinfo.status = RS_GXS_TUNNEL_DH_STATUS_UNINITIALIZED ;
dhinfo.dh = NULL ;
dhinfo.direction = dir ;
dhinfo.hash = hash ;
dhinfo.status = RS_GXS_TUNNEL_DH_STATUS_UNINITIALIZED ;
if(dir == RsTurtleGenericTunnelItem::DIRECTION_CLIENT)
{
// check that a tunnel is not already working for this hash. If so, give up.
if(dir == RsTurtleGenericTunnelItem::DIRECTION_CLIENT)
{
// check that a tunnel is not already working for this hash. If so, give up.
own_gxs_id = gxsIdFromHash(hash) ;
}
else // client side
{
RsGxsId to_gxs_id = gxsIdFromHash(hash) ;
std::map<RsGxsId,GxsTunnelPeerInfo>::const_iterator it = _gxs_tunnel_contacts.find(to_gxs_id) ;
own_gxs_id = gxsIdFromHash(hash) ;
}
else // client side
{
RsGxsId to_gxs_id = gxsIdFromHash(hash) ;
std::map<RsGxsId,GxsTunnelPeerInfo>::const_iterator it = _gxs_tunnel_contacts.find(to_gxs_id) ;
if(it == _gxs_tunnel_contacts.end())
{
std::cerr << "(EE) no pre-registered peer for hash " << hash << " on client side. This is a bug." << std::endl;
return ;
}
if(it == _gxs_tunnel_contacts.end())
{
std::cerr << "(EE) no pre-registered peer for hash " << hash << " on client side. This is a bug." << std::endl;
return ;
}
if(it->second.status == RS_GXS_TUNNEL_STATUS_CAN_TALK)
{
std::cerr << " virtual peer is for a distant chat session that is already openned and alive. Giving it up." << std::endl;
return ;
}
if(it->second.status == RS_GXS_TUNNEL_STATUS_CAN_TALK)
{
std::cerr << " virtual peer is for a distant chat session that is already openned and alive. Giving it up." << std::endl;
return ;
}
own_gxs_id = it->second.own_gxs_id ;
}
own_gxs_id = it->second.own_gxs_id ;
}
#ifdef DEBUG_GXS_TUNNEL
std::cerr << " Creating new virtual peer ID entry and empty DH session key." << std::endl;
std::cerr << " Creating new virtual peer ID entry and empty DH session key." << std::endl;
#endif
}
}
#ifdef DEBUG_GXS_TUNNEL
std::cerr << " Adding virtual peer " << virtual_peer_id << " for chat hash " << hash << std::endl;
std::cerr << " Adding virtual peer " << virtual_peer_id << " for chat hash " << hash << std::endl;
#endif
// Start a new DH session for this tunnel
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
// Start a new DH session for this tunnel
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
locked_restartDHSession(virtual_peer_id,own_gxs_id) ;
locked_restartDHSession(virtual_peer_id,own_gxs_id) ;
}
void p3GxsTunnelService::locked_restartDHSession(const RsPeerId& virtual_peer_id,const RsGxsId& own_gxs_id)
@ -350,8 +364,6 @@ void p3GxsTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *gitem,cons
std::cerr << "(EE) item encrypted data stream is too small: size = " << item->data_size << std::endl;
return ;
}
#warning use flags here!!
#warning add a MAC to make sure the data is not forged
if(*((uint64_t*)item->data_bytes) != 0) // WTF?? we should use flags
{
#ifdef DEBUG_GXS_TUNNEL
@ -392,6 +404,7 @@ void p3GxsTunnelService::receiveTurtleData(RsTurtleGenericTunnelItem *gitem,cons
}
}
// This function encrypts the given data and adds a MAC and an IV into a serialised memory chunk that is then sent through the tunnel.
bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t data_size,const TurtleFileHash& hash,const RsPeerId& virtual_peer_id)
{
@ -409,7 +422,9 @@ bool p3GxsTunnelService::handleEncryptedData(const uint8_t *data_bytes,uint32_t
{
RS_STACK_MUTEX(mGxsTunnelMtx); /********** STACK LOCKED MTX ******/
uint32_t decrypted_size = RsAES::get_buffer_size(data_size-8);
uint32_t encrypted_size = data_size - GXS_TUNNEL_IV_SIZE - GXS_TUNNEL_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 *decrypted_data = new uint8_t[decrypted_size];
uint8_t aes_key[GXS_TUNNEL_AES_KEY_SIZE] ;
@ -434,11 +449,27 @@ 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,16) << ; std::cerr << 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;
#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))
{
std::cerr << "(EE) packet HMAC does not match. Computed HMAC=" << Bin2Hex(md,GXS_TUNNEL_HMAC_SIZE) << std::endl;
std::cerr << "(EE) resetting new DH session." << std::endl;
if(!RsAES::aes_decrypt_8_16((uint8_t*)data_bytes+8,data_size-8,aes_key,(uint8_t*)data_bytes,decrypted_data,decrypted_size))
delete[] decrypted_data ;
locked_restartDHSession(virtual_peer_id,it2->second.own_gxs_id) ;
return false ;
}
if(!RsAES::aes_decrypt_8_16(encrypted_data,encrypted_size, aes_key,(uint8_t*)data_bytes,decrypted_data,decrypted_size))
{
std::cerr << "(EE) packet decryption failed." << std::endl;
std::cerr << "(EE) resetting new DH session." << std::endl;
@ -750,7 +781,9 @@ bool GxsTunnelService::locked_initDHSessionKey(DH *& dh)
return true ;
}
void p3GxsTunnelService::sendTurtleData(RsChatItem *item)
// Encrypts and sends the item.
void p3GxsTunnelService::sendTurtleData(RsGxsTunnelItem *item)
{
#ifdef DEBUG_GXS_TUNNEL
std::cerr << "GxsTunnelService::sendTurtleData(): try sending item " << (void*)item << " to peer " << item->PeerId() << std::endl;
@ -767,6 +800,7 @@ void p3GxsTunnelService::sendTurtleData(RsChatItem *item)
gitem->data_size = rssize + 8 ;
gitem->data_bytes = malloc(rssize+8) ;
// by convention, we use a IV of 0 for unencrypted data.
memset(gitem->data_bytes,0,8) ;
if(!item->serialise(&((uint8_t*)gitem->data_bytes)[8],rssize))
@ -842,10 +876,6 @@ void p3GxsTunnelService::sendEncryptedTurtleData(const uint8_t *buff,uint32_t rs
uint8_t *encrypted_data = new uint8_t[RsAES::get_buffer_size(rssize)];
uint32_t encrypted_size = RsAES::get_buffer_size(rssize);
#ifdef DEBUG_GXS_TUNNEL
std::cerr << " Using IV: " << std::hex << IV << std::dec << std::endl;
std::cerr << " Using Key: " << Bin2Hex(aes_key,16) ; std::cerr << std::endl;
#endif
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;
@ -857,18 +887,27 @@ void p3GxsTunnelService::sendEncryptedTurtleData(const uint8_t *buff,uint32_t rs
//
RsTurtleGenericDataItem *gitem = new RsTurtleGenericDataItem ;
gitem->data_size = encrypted_size + 8 ;
gitem->data_size = encrypted_size + GXS_TUNNEL_ENCRYPTION_IV_SIZE + GXS_TUNNEL_HMAC_SIZE ;
gitem->data_bytes = malloc(gitem->data_size) ;
memcpy(gitem->data_bytes ,&IV,8) ;
memcpy(& (((uint8_t*)gitem->data_bytes)[8]),encrypted_data,encrypted_size) ;
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) ;
memcpy(& (((uint8_t*)gitem->data_bytes)[GXS_TUNNEL_HMAC_SIZE+GXS_TUNNEL_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) ;
#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 << " data = " << Bin2Hex(gitem->data_bytes,gitem->data_size) ;
std::cerr << " serialised data = " << Bin2Hex(gitem->data_bytes,gitem->data_size) ;
std::cerr << std::endl;
#endif
@ -946,11 +985,11 @@ void p3GxsTunnelService::startClientGxsTunnelConnection(const RsGxsId& to_gxs_id
#warning check that this code should go.
#ifdef TO_BE_REMOVED
// spawn a status item so as to open the chat window.
RsChatMsgItem *item = new RsChatMsgItem;
RsGxsTunnelMsgItem *item = new RsGxsTunnelMsgItem;
item->message = "[Starting distant chat. Please wait for secure tunnel to be established]" ;
item->chatFlags = RS_CHAT_FLAG_PRIVATE ;
item->PeerId(RsPeerId(to_gxs_id)) ;
handleRecvChatMsgItem(item) ;
handleRecvGxsTunnelMsgItem(item) ;
#endif
}

View File

@ -27,6 +27,7 @@
#include <turtle/turtleclientservice.h>
#include <retroshare/rsgxstunnel.h>
#include <gxstunnel/rsgxstunnelitems.h>
class RsGixs ;
@ -120,7 +121,7 @@ private:
bool locked_sendDHPublicKey(const DH *dh, const RsGxsId& own_gxs_id, const RsPeerId& virtual_peer_id) ;
bool locked_initDHSessionKey(DH *&dh);
GxsTunnelPeerId virtualPeerIdFromHash(const TurtleFileHash& hash) ; // ... and to a hash for p3turtle
TurtleVirtualPeerId virtualPeerIdFromHash(const TurtleFileHash& hash) ; // ... and to a hash for p3turtle
// Comunication with Turtle service

View File

@ -25,7 +25,6 @@
#pragma once
#include "openssl/bn.h"
#include "retroshare/rstypes.h"
#include "serialiser/rstlvkeys.h"
#include "serialiser/rsserviceids.h"
@ -35,60 +34,26 @@
#include "serialiser/rstlvfileitem.h"
/* chat Flags */
const uint32_t RS_CHAT_FLAG_PRIVATE = 0x0001;
const uint32_t RS_CHAT_FLAG_REQUESTS_AVATAR = 0x0002;
const uint32_t RS_CHAT_FLAG_CONTAINS_AVATAR = 0x0004;
const uint32_t RS_CHAT_FLAG_AVATAR_AVAILABLE = 0x0008;
const uint32_t RS_CHAT_FLAG_CUSTOM_STATE = 0x0010; // used for transmitting peer status string
const uint32_t RS_CHAT_FLAG_PUBLIC = 0x0020;
const uint32_t RS_CHAT_FLAG_REQUEST_CUSTOM_STATE = 0x0040;
const uint32_t RS_CHAT_FLAG_CUSTOM_STATE_AVAILABLE = 0x0080;
const uint32_t RS_CHAT_FLAG_PARTIAL_MESSAGE = 0x0100;
const uint32_t RS_CHAT_FLAG_LOBBY = 0x0200;
const uint32_t RS_CHAT_FLAG_CLOSING_DISTANT_CONNECTION = 0x0400;
const uint32_t RS_CHAT_FLAG_ACK_DISTANT_CONNECTION = 0x0800;
const uint32_t RS_CHAT_FLAG_KEEP_ALIVE = 0x1000;
const uint32_t RS_GXS_TUNNEL_FLAG_CLOSING_DISTANT_CONNECTION = 0x0400;
const uint32_t RS_GXS_TUNNEL_FLAG_ACK_DISTANT_CONNECTION = 0x0800;
const uint32_t RS_GXS_TUNNEL_FLAG_KEEP_ALIVE = 0x1000;
const uint32_t RS_CHATMSG_CONFIGFLAG_INCOMING = 0x0001;
const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_DATA = 0x01 ;
const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY = 0x02 ;
const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS = 0x03 ;
const uint8_t RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK = 0x04 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_AVATAR = 0x03 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_STATUS = 0x04 ;
const uint8_t RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG = 0x05 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_MSG_DEPRECATED = 0x06 ; // don't use ! Deprecated
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE_DEPREC = 0x07 ; // don't use ! Deprecated
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_ACCEPT = 0x08 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_CHALLENGE = 0x09 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_UNSUBSCRIBE = 0x0A ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_EVENT_DEPREC = 0x0B ; // don't use ! Deprecated
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_MSG = 0x0C ; // will be deprecated when only signed messages are accepted (02/2015)
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST = 0x0D ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated = 0x0E ; // to be removed
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE_deprecated = 0x0F ; // to be removed
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_EVENT = 0x10 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated2 = 0x11 ; // to be removed (deprecated since 02 Dec. 2012)
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_deprecated3 = 0x12 ;
const uint8_t RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG = 0x13 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG = 0x15 ;
const uint8_t RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY = 0x16 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_MSG = 0x17 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_EVENT = 0x18 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_LIST = 0x19 ;
const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE = 0x1A ;
typedef uint64_t GxsTunnelDHSessionId ;
typedef uint64_t ChatLobbyId ;
typedef uint64_t ChatLobbyMsgId ;
typedef std::string ChatLobbyNickName ;
typedef uint64_t DistantChatDHSessionId ;
class RsChatItem: public RsItem
class RsGxsTunnelItem: public RsItem
{
public:
RsChatItem(uint8_t chat_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_CHAT,chat_subtype)
RsGxsTunnelItem(uint8_t item_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_GXS_TUNNEL,item_subtype)
{
setPriorityLevel(QOS_PRIORITY_RS_CHAT_ITEM) ;
}
virtual ~RsChatItem() {}
virtual ~RsGxsTunnelItem() {}
virtual void clear() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0) = 0 ;
@ -96,305 +61,80 @@ class RsChatItem: public RsItem
virtual uint32_t serial_size() = 0 ; // deserialise is handled using a constructor
};
/*!
* For sending chat msgs
* @see p3ChatService
*/
class RsChatMsgItem: public RsChatItem
{
public:
RsChatMsgItem() :RsChatItem(RS_PKT_SUBTYPE_DEFAULT) {}
RsChatMsgItem(uint8_t subtype) :RsChatItem(subtype) {}
// /*!
// * 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
// * sent as data in a RsGxsTunnelDataItem.
// *
// * @see p3GxsTunnelService
// */
// class RsGxsTunnelDataItem: public RsGxsTunnelItem
// {
// public:
// RsGxsTunnelDataItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DATA) {}
// RsGxsTunnelDataItem(uint8_t subtype) :RsGxsTunnelItem(subtype) {}
//
// virtual ~RsGxsTunnelDataItem() {}
// virtual void clear() {}
// 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 uint32_t serial_size() ; // deserialise is handled using a constructor
//
// uint32_t sendTime;
// uint32_t flags; // mainly NEEDS_HACK?
// unsigned char *data ; // encrypted data
// uint32_t data_size ; // encrypted data size
// unsigned char IV[IV_LENGTH] ; // IV for the encrypted data
// unsigned char encrypted_data_mac[SHA_DIGEST_LENGTH] ; // mac of the encrypted data, in order to avoid
// };
RsChatMsgItem(void *data,uint32_t size,uint8_t subtype = RS_PKT_SUBTYPE_DEFAULT) ; // deserialization
// Used to send status of connection. This can be closing orders, flushing orders, etc.
// These items are always sent encrypted.
virtual ~RsChatMsgItem() {}
virtual void clear() {}
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 uint32_t serial_size() ; // deserialise is handled using a constructor
uint32_t chatFlags;
uint32_t sendTime;
std::string message;
/* not serialised */
uint32_t recvTime;
};
// This class contains the info to bounce an object throughout a lobby, while
// maintaining cache info to avoid duplicates.
//
class RsChatLobbyBouncingObject
{
public:
ChatLobbyId lobby_id ;
ChatLobbyMsgId msg_id ;
ChatLobbyNickName nick ; // Nickname of sender
RsTlvKeySignature signature ;
virtual RsChatLobbyBouncingObject *duplicate() const = 0 ;
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
// returns the size in bytes of the data chunk to sign.
virtual uint32_t signed_serial_size() =0;
virtual bool serialise_signed_part(void *data,uint32_t& size) = 0;
protected:
// The functions below handle the serialisation of data that is specific to the bouncing object level.
// They are called by serial_size() and serialise() from children, but should not overload the serial_size() and
// serialise() methods, otherwise the wrong method will be called when serialising from this top level class.
uint32_t serialized_size(bool include_signature) ;
bool serialise_to_memory(void *data,uint32_t tlvsize,uint32_t& offset,bool include_signature) ;
bool deserialise_from_memory(void *data,uint32_t rssize,uint32_t& offset) ;
};
class RsChatLobbyMsgItem: public RsChatMsgItem, public RsChatLobbyBouncingObject
{
public:
RsChatLobbyMsgItem() :RsChatMsgItem(RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_MSG) {}
RsChatLobbyMsgItem(void *data,uint32_t size) ; // deserialization /// TODO!!!
virtual ~RsChatLobbyMsgItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual RsChatLobbyBouncingObject *duplicate() const { return new RsChatLobbyMsgItem(*this) ; }
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 signed_serial_size() ;
virtual bool serialise_signed_part(void *data,uint32_t& size) ;// Isn't it better that items can serialize themselves ?
ChatLobbyMsgId parent_msg_id ; // Used for threaded chat.
};
class RsChatLobbyEventItem: public RsChatItem, public RsChatLobbyBouncingObject
{
public:
RsChatLobbyEventItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_SIGNED_EVENT) {}
RsChatLobbyEventItem(void *data,uint32_t size) ; // deserialization /// TODO!!!
virtual ~RsChatLobbyEventItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual RsChatLobbyBouncingObject *duplicate() const { return new RsChatLobbyEventItem(*this) ; }
//
virtual bool serialise(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
virtual uint32_t signed_serial_size() ;
virtual bool serialise_signed_part(void *data,uint32_t& size) ;
// members.
//
uint8_t event_type ; // used for defining the type of event.
std::string string1; // used for any string
uint32_t sendTime; // used to check for old looping messages
};
class RsChatLobbyListRequestItem: public RsChatItem
class RsGxsTunnelStatusItem: public RsGxsTunnelItem
{
public:
RsChatLobbyListRequestItem() : RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_LIST_REQUEST) {}
RsChatLobbyListRequestItem(void *data,uint32_t size) ;
virtual ~RsChatLobbyListRequestItem() {}
RsGxsTunnelStatusItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_STATUS) {}
RsGxsTunnelStatusItem(void *data,uint32_t size) ; // deserialization
virtual bool serialise(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
};
struct VisibleChatLobbyInfo
{
ChatLobbyId id ;
std::string name ;
std::string topic ;
uint32_t count ;
ChatLobbyFlags flags ;
};
class RsChatLobbyListItem: public RsChatItem
{
public:
RsChatLobbyListItem() : RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_LIST) {}
RsChatLobbyListItem(void *data,uint32_t size) ;
virtual ~RsChatLobbyListItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
virtual bool serialise(void *data,uint32_t& size) ;
virtual uint32_t serial_size() ;
std::vector<VisibleChatLobbyInfo> lobbies ;
};
class RsChatLobbyUnsubscribeItem: public RsChatItem
{
public:
RsChatLobbyUnsubscribeItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_UNSUBSCRIBE) {}
RsChatLobbyUnsubscribeItem(void *data,uint32_t size) ; // deserialization
virtual ~RsChatLobbyUnsubscribeItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
uint64_t lobby_id ;
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
};
class RsChatLobbyConnectChallengeItem: public RsChatItem
{
public:
RsChatLobbyConnectChallengeItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_CHALLENGE) {}
RsChatLobbyConnectChallengeItem(void *data,uint32_t size) ; // deserialization
virtual ~RsChatLobbyConnectChallengeItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
uint64_t challenge_code ;
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
};
class RsChatLobbyInviteItem: public RsChatItem
{
public:
RsChatLobbyInviteItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE) {}
RsChatLobbyInviteItem(void *data,uint32_t size) ; // deserialization
virtual ~RsChatLobbyInviteItem() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0);
ChatLobbyId lobby_id ;
std::string lobby_name ;
std::string lobby_topic ;
ChatLobbyFlags lobby_flags ;
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
};
/*!
* For saving incoming and outgoing chat msgs
* @see p3ChatService
*/
class RsPrivateChatMsgConfigItem: public RsChatItem
{
public:
RsPrivateChatMsgConfigItem() :RsChatItem(RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG) {}
RsPrivateChatMsgConfigItem(void *data,uint32_t size) ; // deserialization
virtual ~RsPrivateChatMsgConfigItem() {}
virtual void clear() {}
virtual ~RsGxsTunnelStatusItem() {}
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 uint32_t serial_size() ; // deserialise is handled using a constructor
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
/* set data from RsChatMsgItem to RsPrivateChatMsgConfigItem */
void set(RsChatMsgItem *ci, const RsPeerId &peerId, uint32_t confFlags);
/* get data from RsPrivateChatMsgConfigItem to RsChatMsgItem */
void get(RsChatMsgItem *ci);
RsPeerId configPeerId;
uint32_t chatFlags;
uint32_t configFlags;
uint32_t sendTime;
std::string message;
uint32_t recvTime;
};
class RsPrivateChatDistantInviteConfigItem: public RsChatItem
{
public:
RsPrivateChatDistantInviteConfigItem() :RsChatItem(RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG) {}
RsPrivateChatDistantInviteConfigItem(void *data,uint32_t size) ; // deserialization
virtual ~RsPrivateChatDistantInviteConfigItem() {}
virtual void clear() {}
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 uint32_t serial_size() ; // deserialise is handled using a constructor
unsigned char aes_key[16] ;
RsFileHash hash ;
std::string encrypted_radix64_string ;
RsPgpId destination_pgp_id ;
uint32_t time_of_validity ;
uint32_t last_hit_time ;
uint32_t flags ;
};
class RsChatLobbyConfigItem: public RsChatItem
{
public:
RsChatLobbyConfigItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_LOBBY_CONFIG) { lobby_Id = 0; }
RsChatLobbyConfigItem(void *data,uint32_t size) ; // deserialization
virtual ~RsChatLobbyConfigItem() {}
// Used to confirm reception of an encrypted item.
virtual void clear() { lobby_Id = 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 uint32_t serial_size() ; // deserialise is handled using a constructor
uint64_t lobby_Id;
uint32_t flags ;
};
// This class contains activity info for the sending peer: active, idle, typing, etc.
//
class RsChatStatusItem: public RsChatItem
class RsGxsTunnelDataAckItem: public RsGxsTunnelItem
{
public:
RsChatStatusItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_STATUS) {}
RsChatStatusItem(void *data,uint32_t size) ; // deserialization
RsGxsTunnelDataAckItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DATA_ACK) {}
RsGxsTunnelDataAckItem(void *data,uint32_t size) ; // deserialization
virtual ~RsChatStatusItem() {}
virtual ~RsGxsTunnelDataAckItem() {}
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 uint32_t serial_size() ; // deserialise is handled using a constructor
virtual uint32_t serial_size() ; // deserialise is handled using a constructor
uint32_t flags ;
std::string status_string;
Sha1CheckSum data_hash ;
};
// This class contains avatar images in Qt format.
//
class RsChatAvatarItem: public RsChatItem
{
public:
RsChatAvatarItem() :RsChatItem(RS_PKT_SUBTYPE_CHAT_AVATAR) {setPriorityLevel(QOS_PRIORITY_RS_CHAT_AVATAR_ITEM) ;}
RsChatAvatarItem(void *data,uint32_t size) ; // deserialization
virtual ~RsChatAvatarItem() ;
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 uint32_t serial_size() ; // deserialise is handled using a constructor
uint32_t image_size ; // size of data in bytes
unsigned char *image_data ; // image
};
// This class contains the public Diffie-Hellman parameters to be sent
// when performing a DH agreement over a distant chat tunnel.
//
class RsChatDHPublicKeyItem: public RsChatItem
class RsGxsTunnelDHPublicKeyItem: public RsGxsTunnelItem
{
public:
RsChatDHPublicKeyItem() :RsChatItem(RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY) {setPriorityLevel(QOS_PRIORITY_RS_CHAT_ITEM) ;}
RsChatDHPublicKeyItem(void *data,uint32_t size) ; // deserialization
RsGxsTunnelDHPublicKeyItem() :RsGxsTunnelItem(RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY) {}
RsGxsTunnelDHPublicKeyItem(void *data,uint32_t size) ; // deserialization
virtual ~RsChatDHPublicKeyItem() { BN_free(public_key) ; }
virtual ~RsGxsTunnelDHPublicKeyItem() { BN_free(public_key) ; }
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 ?
@ -408,22 +148,23 @@ class RsChatDHPublicKeyItem: public RsChatItem
RsTlvSecurityKey gxs_key ; // public key of the signer
private:
RsChatDHPublicKeyItem(const RsChatDHPublicKeyItem&) : RsChatItem(RS_PKT_SUBTYPE_DISTANT_CHAT_DH_PUBLIC_KEY) {} // make the object non copy-able
const RsChatDHPublicKeyItem& operator=(const RsChatDHPublicKeyItem&) { return *this ;}
// make the object non copy-able
RsGxsTunnelDHPublicKeyItem(const RsGxsTunnelDHPublicKeyItem&) : RsGxsTunnelItem(RS_PKT_SUBTYPE_GXS_TUNNEL_DH_PUBLIC_KEY) {}
const RsGxsTunnelDHPublicKeyItem& operator=(const RsGxsTunnelDHPublicKeyItem&) { return *this ;}
};
class RsChatSerialiser: public RsSerialType
class RsGxsTunnelSerialiser: public RsSerialType
{
public:
RsChatSerialiser() :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_CHAT) {}
RsGxsTunnelSerialiser() :RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_TUNNEL) {}
virtual uint32_t size (RsItem *item)
{
return static_cast<RsChatItem *>(item)->serial_size() ;
return static_cast<RsGxsTunnelItem *>(item)->serial_size() ;
}
virtual bool serialise(RsItem *item, void *data, uint32_t *size)
{
return static_cast<RsChatItem *>(item)->serialise(data,*size) ;
return static_cast<RsGxsTunnelItem *>(item)->serialise(data,*size) ;
}
virtual RsItem *deserialise (void *data, uint32_t *size) ;
};

View File

@ -38,32 +38,33 @@
*/
/* These are Cache Only */
const uint16_t RS_SERVICE_TYPE_FILE_INDEX = 0x0001;
const uint16_t RS_SERVICE_TYPE_FILE_INDEX = 0x0001;
/* These are Services only */
const uint16_t RS_SERVICE_TYPE_DISC = 0x0011;
const uint16_t RS_SERVICE_TYPE_CHAT = 0x0012;
const uint16_t RS_SERVICE_TYPE_MSG = 0x0013;
const uint16_t RS_SERVICE_TYPE_TURTLE = 0x0014;
const uint16_t RS_SERVICE_TYPE_TUNNEL = 0x0015;
const uint16_t RS_SERVICE_TYPE_HEARTBEAT = 0x0016;
const uint16_t RS_SERVICE_TYPE_FILE_TRANSFER = 0x0017;
const uint16_t RS_SERVICE_TYPE_GROUTER = 0x0018;
const uint16_t RS_SERVICE_TYPE_DISC = 0x0011;
const uint16_t RS_SERVICE_TYPE_CHAT = 0x0012;
const uint16_t RS_SERVICE_TYPE_MSG = 0x0013;
const uint16_t RS_SERVICE_TYPE_TURTLE = 0x0014;
const uint16_t RS_SERVICE_TYPE_TUNNEL = 0x0015;
const uint16_t RS_SERVICE_TYPE_HEARTBEAT = 0x0016;
const uint16_t RS_SERVICE_TYPE_FILE_TRANSFER = 0x0017;
const uint16_t RS_SERVICE_TYPE_GROUTER = 0x0018;
const uint16_t RS_SERVICE_TYPE_SERVICEINFO = 0x0020;
const uint16_t RS_SERVICE_TYPE_SERVICEINFO = 0x0020;
/* Bandwidth Control */
const uint16_t RS_SERVICE_TYPE_BWCTRL = 0x0021;
// New Mail Service (replace old Msg Service)
const uint16_t RS_SERVICE_TYPE_MAIL = 0x0022;
const uint16_t RS_SERVICE_TYPE_DIRECT_MAIL = 0x0023;
const uint16_t RS_SERVICE_TYPE_DISTANT_MAIL = 0x0024;
const uint16_t RS_SERVICE_TYPE_GWEMAIL_MAIL = 0x0025;
const uint16_t RS_SERVICE_TYPE_BWCTRL = 0x0021;
// New Mail Service (replace old Msg Service)
const uint16_t RS_SERVICE_TYPE_MAIL = 0x0022;
const uint16_t RS_SERVICE_TYPE_DIRECT_MAIL = 0x0023;
const uint16_t RS_SERVICE_TYPE_DISTANT_MAIL = 0x0024;
const uint16_t RS_SERVICE_TYPE_GWEMAIL_MAIL = 0x0025;
const uint16_t RS_SERVICE_TYPE_SERVICE_CONTROL= 0x0026;
const uint16_t RS_SERVICE_TYPE_DISTANT_CHAT = 0x0027;
const uint16_t RS_SERVICE_TYPE_DISTANT_CHAT = 0x0027;
const uint16_t RS_SERVICE_TYPE_GXS_TUNNEL = 0x0028;
// Non essential services.
const uint16_t RS_SERVICE_TYPE_BANLIST = 0x0101;
const uint16_t RS_SERVICE_TYPE_STATUS = 0x0102;
const uint16_t RS_SERVICE_TYPE_BANLIST = 0x0101;
const uint16_t RS_SERVICE_TYPE_STATUS = 0x0102;
/* New Cache Services */
/* Rs Network Exchange Service */