mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-03-20 05:56:05 -04:00
Merged branch v0.5-GenericTunneling into trunk (Rev. 6284 to 6410).
- adds turtle router as a generic tunneling service - made ftServer a client of the service. Now turtle file items are handled in ftServer - added new client: p3MsgService to send/recv pgp-encrypted distant messages - added new client: p3ChatService to perform private (AES-encrypted) distant chat through tunnels. - The GUI is disabled for now, since it needs some polishing before being fully usable. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6411 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
commit
dc2521cf71
@ -47,6 +47,7 @@
|
||||
#include "ft/ftsearch.h"
|
||||
#include "ft/ftdatamultiplex.h"
|
||||
#include "ft/ftextralist.h"
|
||||
#include "ft/ftserver.h"
|
||||
|
||||
#include "turtle/p3turtle.h"
|
||||
|
||||
@ -102,6 +103,7 @@ ftController::ftController(CacheStrapper *cs, ftDataMultiplex *dm, std::string /
|
||||
last_clean_time(0),
|
||||
mDataplex(dm),
|
||||
mTurtle(NULL),
|
||||
mFtServer(NULL),
|
||||
ctrlMutex("ftController"),
|
||||
doneMutex("ftController"),
|
||||
mFtActive(false),
|
||||
@ -112,10 +114,9 @@ ftController::ftController(CacheStrapper *cs, ftDataMultiplex *dm, std::string /
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void ftController::setTurtleRouter(p3turtle *pt)
|
||||
{
|
||||
mTurtle = pt ;
|
||||
}
|
||||
void ftController::setTurtleRouter(p3turtle *pt) { mTurtle = pt ; }
|
||||
void ftController::setFtServer(ftServer *ft) { mFtServer = ft ; }
|
||||
|
||||
void ftController::setFtSearchNExtra(ftSearch *search, ftExtraList *list)
|
||||
{
|
||||
mSearch = search;
|
||||
@ -646,7 +647,7 @@ void ftController::locked_checkQueueElement(uint32_t pos)
|
||||
_queue[pos]->mState = ftFileControl::DOWNLOADING ;
|
||||
|
||||
if(_queue[pos]->mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING)
|
||||
mTurtle->monitorFileTunnels(_queue[pos]->mName,_queue[pos]->mHash,_queue[pos]->mSize) ;
|
||||
mTurtle->monitorTunnels(_queue[pos]->mHash,mFtServer) ;
|
||||
}
|
||||
|
||||
if(pos >= _max_active_downloads && _queue[pos]->mState != ftFileControl::QUEUED && _queue[pos]->mState != ftFileControl::PAUSED)
|
||||
@ -655,7 +656,7 @@ void ftController::locked_checkQueueElement(uint32_t pos)
|
||||
_queue[pos]->mCreator->closeFile() ;
|
||||
|
||||
if(_queue[pos]->mFlags & RS_FILE_REQ_ANONYMOUS_ROUTING)
|
||||
mTurtle->stopMonitoringFileTunnels(_queue[pos]->mHash) ;
|
||||
mTurtle->stopMonitoringTunnels(_queue[pos]->mHash) ;
|
||||
}
|
||||
}
|
||||
|
||||
@ -899,7 +900,7 @@ bool ftController::completeFile(std::string hash)
|
||||
mDownloads.erase(it);
|
||||
|
||||
if(flags & RS_FILE_REQ_ANONYMOUS_ROUTING)
|
||||
mTurtle->stopMonitoringFileTunnels(hash_to_suppress) ;
|
||||
mTurtle->stopMonitoringTunnels(hash_to_suppress) ;
|
||||
|
||||
} /******* UNLOCKED ********/
|
||||
|
||||
@ -1264,7 +1265,7 @@ bool ftController::FileRequest(const std::string& fname, const std::string& has
|
||||
// We check that flags are consistent.
|
||||
|
||||
if(flags & RS_FILE_REQ_ANONYMOUS_ROUTING)
|
||||
mTurtle->monitorFileTunnels(fname,hash,size) ;
|
||||
mTurtle->monitorTunnels(hash,mFtServer) ;
|
||||
|
||||
bool assume_availability = flags & RS_FILE_REQ_CACHE ; // assume availability for cache files
|
||||
|
||||
@ -1365,7 +1366,7 @@ bool ftController::setChunkStrategy(const std::string& hash,FileChunksInfo::Chun
|
||||
|
||||
bool ftController::FileCancel(const std::string& hash)
|
||||
{
|
||||
rsTurtle->stopMonitoringFileTunnels(hash) ;
|
||||
rsTurtle->stopMonitoringTunnels(hash) ;
|
||||
|
||||
#ifdef CONTROL_DEBUG
|
||||
std::cerr << "ftController::FileCancel" << std::endl;
|
||||
|
@ -42,6 +42,7 @@ class ftFileCreator;
|
||||
class ftTransferModule;
|
||||
class ftFileProvider;
|
||||
class ftSearch;
|
||||
class ftServer;
|
||||
class ftExtraList;
|
||||
class ftDataMultiplex;
|
||||
class p3turtle ;
|
||||
@ -119,6 +120,7 @@ class ftController: public CacheTransfer, public RsThread, public pqiMonitor, pu
|
||||
|
||||
void setFtSearchNExtra(ftSearch *, ftExtraList *);
|
||||
void setTurtleRouter(p3turtle *) ;
|
||||
void setFtServer(ftServer *) ;
|
||||
bool activate();
|
||||
bool isActiveAndNoPending();
|
||||
|
||||
@ -234,6 +236,7 @@ class ftController: public CacheTransfer, public RsThread, public pqiMonitor, pu
|
||||
ftDataMultiplex *mDataplex;
|
||||
ftExtraList *mExtraList;
|
||||
p3turtle *mTurtle ;
|
||||
ftServer *mFtServer ;
|
||||
|
||||
RsMutex ctrlMutex;
|
||||
|
||||
|
@ -1085,7 +1085,7 @@ bool ftDataMultiplex::locked_handleServerRequest(ftFileProvider *provider,
|
||||
std::string peerId, std::string hash, uint64_t size,
|
||||
uint64_t offset, uint32_t chunksize)
|
||||
{
|
||||
if(chunksize > std::min(size,uint64_t(10*1024*1024)))
|
||||
if(chunksize > uint32_t(10*1024*1024))
|
||||
{
|
||||
std::cerr << "Warning: peer " << peerId << " is asking a large chunk (s=" << chunksize << ") for hash " << hash << ", filesize=" << size << ". This is unexpected." << std::endl ;
|
||||
return false ;
|
||||
|
@ -153,6 +153,12 @@ bool ftFileProvider::getFileData(const std::string& peer_id,uint64_t offset, uin
|
||||
* FIXME: Warning of comparison between unsigned and signed int?
|
||||
*/
|
||||
|
||||
if(offset >= mSize)
|
||||
{
|
||||
std::cerr << "ftFileProvider::getFileData(): request (" << offset << ") exceeds file size (" << mSize << "! " << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
uint32_t data_size = chunk_size;
|
||||
uint64_t base_loc = offset;
|
||||
|
||||
|
@ -28,8 +28,10 @@
|
||||
#include "util/rsdebug.h"
|
||||
#include "util/rsdir.h"
|
||||
#include "retroshare/rstypes.h"
|
||||
#include "retroshare/rspeers.h"
|
||||
const int ftserverzone = 29539;
|
||||
|
||||
#include "ft/ftturtlefiletransferitem.h"
|
||||
#include "ft/ftserver.h"
|
||||
#include "ft/ftextralist.h"
|
||||
#include "ft/ftfilesearch.h"
|
||||
@ -153,6 +155,9 @@ void ftServer::connectToTurtleRouter(p3turtle *fts)
|
||||
mTurtleRouter = fts ;
|
||||
|
||||
mFtController->setTurtleRouter(fts) ;
|
||||
mFtController->setFtServer(this) ;
|
||||
|
||||
mTurtleRouter->registerTunnelService(this) ;
|
||||
}
|
||||
|
||||
void ftServer::StartupThreads()
|
||||
@ -450,6 +455,77 @@ bool ftServer::FileDetails(const std::string &hash, FileSearchFlags hintflags, F
|
||||
return false;
|
||||
}
|
||||
|
||||
RsTurtleGenericTunnelItem *ftServer::deserialiseItem(void *data,uint32_t size) const
|
||||
{
|
||||
uint32_t rstype = getRsItemId(data);
|
||||
|
||||
#ifdef SERVER_DEBUG
|
||||
std::cerr << "p3turtle: deserialising packet: " << std::endl ;
|
||||
#endif
|
||||
#ifdef SERVER_DEBUG
|
||||
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_TYPE_TURTLE != getRsItemService(rstype)))
|
||||
{
|
||||
#ifdef SERVER_DEBUG
|
||||
std::cerr << " Wrong type !!" << std::endl ;
|
||||
#endif
|
||||
return NULL; /* wrong type */
|
||||
}
|
||||
#endif
|
||||
|
||||
switch(getRsItemSubType(rstype))
|
||||
{
|
||||
case RS_TURTLE_SUBTYPE_FILE_REQUEST : return new RsTurtleFileRequestItem(data,size) ;
|
||||
case RS_TURTLE_SUBTYPE_FILE_DATA : return new RsTurtleFileDataItem(data,size) ;
|
||||
case RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST : return new RsTurtleFileMapRequestItem(data,size) ;
|
||||
case RS_TURTLE_SUBTYPE_FILE_MAP : return new RsTurtleFileMapItem(data,size) ;
|
||||
case RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST : return new RsTurtleFileCrcRequestItem(data,size) ;
|
||||
case RS_TURTLE_SUBTYPE_FILE_CRC : return new RsTurtleFileCrcItem(data,size) ;
|
||||
case RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST : return new RsTurtleChunkCrcRequestItem(data,size) ;
|
||||
case RS_TURTLE_SUBTYPE_CHUNK_CRC : return new RsTurtleChunkCrcItem(data,size) ;
|
||||
|
||||
default:
|
||||
return NULL ;
|
||||
}
|
||||
}
|
||||
|
||||
void ftServer::addVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction dir)
|
||||
{
|
||||
if(dir == RsTurtleGenericTunnelItem::DIRECTION_SERVER)
|
||||
mFtController->addFileSource(hash,virtual_peer_id) ;
|
||||
}
|
||||
void ftServer::removeVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id)
|
||||
{
|
||||
mFtController->removeFileSource(hash,virtual_peer_id) ;
|
||||
}
|
||||
|
||||
bool ftServer::handleTunnelRequest(const std::string& hash,const std::string& peer_id)
|
||||
{
|
||||
FileInfo info ;
|
||||
bool res = FileDetails(hash, RS_FILE_HINTS_NETWORK_WIDE | RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_SPEC_ONLY | RS_FILE_HINTS_DOWNLOAD, info);
|
||||
|
||||
#ifdef SERVER_DEBUG
|
||||
std::cerr << "ftServer: performing local hash search for hash " << hash << std::endl;
|
||||
|
||||
if(res)
|
||||
{
|
||||
std::cerr << "Found hash: " << std::endl;
|
||||
std::cerr << " hash = " << hash << std::endl;
|
||||
std::cerr << " peer = " << peer_id << std::endl;
|
||||
std::cerr << " flags = " << info.storage_permission_flags << std::endl;
|
||||
std::cerr << " local = " << rsFiles->FileDetails(hash, RS_FILE_HINTS_NETWORK_WIDE | RS_FILE_HINTS_LOCAL | RS_FILE_HINTS_EXTRA | RS_FILE_HINTS_SPEC_ONLY | RS_FILE_HINTS_DOWNLOAD, info) << std::endl;
|
||||
std::cerr << " groups= " ; for(std::list<std::string>::const_iterator it(info.parent_groups.begin());it!=info.parent_groups.end();++it) std::cerr << (*it) << ", " ; std::cerr << std::endl;
|
||||
std::cerr << " clear = " << rsPeers->computePeerPermissionFlags(peer_id,info.storage_permission_flags,info.parent_groups) << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
// The call to computeHashPeerClearance() return a combination of RS_FILE_HINTS_NETWORK_WIDE and RS_FILE_HINTS_BROWSABLE
|
||||
// This is an additional computation cost, but the way it's written here, it's only called when res is true.
|
||||
//
|
||||
res = res && (RS_FILE_HINTS_NETWORK_WIDE & rsPeers->computePeerPermissionFlags(peer_id,info.storage_permission_flags,info.parent_groups)) ;
|
||||
|
||||
return res ;
|
||||
}
|
||||
|
||||
/***************************************************************/
|
||||
/******************* ExtraFileList Access **********************/
|
||||
/***************************************************************/
|
||||
@ -809,7 +885,14 @@ bool ftServer::loadConfigMap(std::map<std::string, std::string> &/*configMap*/)
|
||||
bool ftServer::sendDataRequest(const std::string& peerId, const std::string& hash, uint64_t size, uint64_t offset, uint32_t chunksize)
|
||||
{
|
||||
if(mTurtleRouter->isTurtlePeer(peerId))
|
||||
mTurtleRouter->sendDataRequest(peerId,hash,size,offset,chunksize) ;
|
||||
{
|
||||
RsTurtleFileRequestItem *item = new RsTurtleFileRequestItem ;
|
||||
|
||||
item->chunk_offset = offset ;
|
||||
item->chunk_size = chunksize ;
|
||||
|
||||
mTurtleRouter->sendTurtleData(peerId,item) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create a packet */
|
||||
@ -836,7 +919,10 @@ bool ftServer::sendDataRequest(const std::string& peerId, const std::string& has
|
||||
bool ftServer::sendChunkMapRequest(const std::string& peerId,const std::string& hash,bool is_client)
|
||||
{
|
||||
if(mTurtleRouter->isTurtlePeer(peerId))
|
||||
mTurtleRouter->sendChunkMapRequest(peerId,hash,is_client) ;
|
||||
{
|
||||
RsTurtleFileMapRequestItem *item = new RsTurtleFileMapRequestItem ;
|
||||
mTurtleRouter->sendTurtleData(peerId,item) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create a packet */
|
||||
@ -859,7 +945,11 @@ bool ftServer::sendChunkMapRequest(const std::string& peerId,const std::string&
|
||||
bool ftServer::sendChunkMap(const std::string& peerId,const std::string& hash,const CompressedChunkMap& map,bool is_client)
|
||||
{
|
||||
if(mTurtleRouter->isTurtlePeer(peerId))
|
||||
mTurtleRouter->sendChunkMap(peerId,hash,map,is_client) ;
|
||||
{
|
||||
RsTurtleFileMapItem *item = new RsTurtleFileMapItem ;
|
||||
item->compressed_map = map ;
|
||||
mTurtleRouter->sendTurtleData(peerId,item) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create a packet */
|
||||
@ -882,7 +972,11 @@ bool ftServer::sendChunkMap(const std::string& peerId,const std::string& hash,co
|
||||
bool ftServer::sendCRC32MapRequest(const std::string& peerId,const std::string& hash)
|
||||
{
|
||||
if(mTurtleRouter->isTurtlePeer(peerId))
|
||||
mTurtleRouter->sendCRC32MapRequest(peerId,hash) ;
|
||||
{
|
||||
RsTurtleFileCrcRequestItem *item = new RsTurtleFileCrcRequestItem;
|
||||
|
||||
mTurtleRouter->sendTurtleData(peerId,item) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create a packet */
|
||||
@ -903,7 +997,12 @@ bool ftServer::sendCRC32MapRequest(const std::string& peerId,const std::string&
|
||||
bool ftServer::sendSingleChunkCRCRequest(const std::string& peerId,const std::string& hash,uint32_t chunk_number)
|
||||
{
|
||||
if(mTurtleRouter->isTurtlePeer(peerId))
|
||||
mTurtleRouter->sendSingleChunkCRCRequest(peerId,hash,chunk_number) ;
|
||||
{
|
||||
RsTurtleChunkCrcRequestItem *item = new RsTurtleChunkCrcRequestItem;
|
||||
item->chunk_number = chunk_number ;
|
||||
|
||||
mTurtleRouter->sendTurtleData(peerId,item) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create a packet */
|
||||
@ -926,7 +1025,12 @@ bool ftServer::sendSingleChunkCRCRequest(const std::string& peerId,const std::st
|
||||
bool ftServer::sendCRC32Map(const std::string& peerId,const std::string& hash,const CRC32Map& crcmap)
|
||||
{
|
||||
if(mTurtleRouter->isTurtlePeer(peerId))
|
||||
mTurtleRouter->sendCRC32Map(peerId,hash,crcmap) ;
|
||||
{
|
||||
RsTurtleFileCrcItem *item = new RsTurtleFileCrcItem ;
|
||||
item->crc_map = crcmap ;
|
||||
|
||||
mTurtleRouter->sendTurtleData(peerId,item) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create a packet */
|
||||
@ -948,7 +1052,13 @@ bool ftServer::sendCRC32Map(const std::string& peerId,const std::string& hash,co
|
||||
bool ftServer::sendSingleChunkCRC(const std::string& peerId,const std::string& hash,uint32_t chunk_number,const Sha1CheckSum& crc)
|
||||
{
|
||||
if(mTurtleRouter->isTurtlePeer(peerId))
|
||||
mTurtleRouter->sendSingleChunkCRC(peerId,hash,chunk_number,crc) ;
|
||||
{
|
||||
RsTurtleChunkCrcItem *item = new RsTurtleChunkCrcItem;
|
||||
item->chunk_number = chunk_number ;
|
||||
item->check_sum = crc ;
|
||||
|
||||
mTurtleRouter->sendTurtleData(peerId,item) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* create a packet */
|
||||
@ -1003,7 +1113,23 @@ bool ftServer::sendData(const std::string& peerId, const std::string& hash, uint
|
||||
/******** New Serialiser Type *******/
|
||||
|
||||
if(mTurtleRouter->isTurtlePeer(peerId))
|
||||
mTurtleRouter->sendFileData(peerId,hash,size,baseoffset+offset,chunk,&(((uint8_t *) data)[offset])) ;
|
||||
{
|
||||
RsTurtleFileDataItem *item = new RsTurtleFileDataItem ;
|
||||
|
||||
item->chunk_offset = offset+baseoffset ;
|
||||
item->chunk_size = chunk;
|
||||
item->chunk_data = malloc(chunk) ;
|
||||
|
||||
if(item->chunk_data == NULL)
|
||||
{
|
||||
std::cerr << "p3turtle: Warning: failed malloc of " << chunk << " bytes for sending data packet." << std::endl ;
|
||||
delete item;
|
||||
return false;
|
||||
}
|
||||
memcpy(item->chunk_data,&(((uint8_t *) data)[offset]),chunk) ;
|
||||
|
||||
mTurtleRouter->sendTurtleData(peerId,item) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
RsFileData *rfd = new RsFileData();
|
||||
@ -1047,6 +1173,76 @@ bool ftServer::sendData(const std::string& peerId, const std::string& hash, uint
|
||||
return true;
|
||||
}
|
||||
|
||||
void ftServer::receiveTurtleData(RsTurtleGenericTunnelItem *i,
|
||||
const std::string& hash,
|
||||
const std::string& virtual_peer_id,
|
||||
RsTurtleGenericTunnelItem::Direction direction)
|
||||
{
|
||||
switch(i->PacketSubType())
|
||||
{
|
||||
case RS_TURTLE_SUBTYPE_FILE_REQUEST:
|
||||
{
|
||||
RsTurtleFileRequestItem *item = dynamic_cast<RsTurtleFileRequestItem *>(i) ;
|
||||
getMultiplexer()->recvDataRequest(virtual_peer_id,hash,0,item->chunk_offset,item->chunk_size) ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case RS_TURTLE_SUBTYPE_FILE_DATA :
|
||||
{
|
||||
RsTurtleFileDataItem *item = dynamic_cast<RsTurtleFileDataItem *>(i) ;
|
||||
getMultiplexer()->recvData(virtual_peer_id,hash,0,item->chunk_offset,item->chunk_size,item->chunk_data) ;
|
||||
|
||||
item->chunk_data = NULL ; // this prevents deletion in the destructor of RsFileDataItem, because data will be deleted
|
||||
// down _ft_server->getMultiplexer()->recvData()...in ftTransferModule::recvFileData
|
||||
|
||||
}
|
||||
break ;
|
||||
|
||||
case RS_TURTLE_SUBTYPE_FILE_MAP :
|
||||
{
|
||||
RsTurtleFileMapItem *item = dynamic_cast<RsTurtleFileMapItem *>(i) ;
|
||||
getMultiplexer()->recvChunkMap(virtual_peer_id,hash,item->compressed_map,direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST:
|
||||
{
|
||||
RsTurtleFileMapRequestItem *item = dynamic_cast<RsTurtleFileMapRequestItem *>(i) ;
|
||||
getMultiplexer()->recvChunkMapRequest(virtual_peer_id,hash,direction == RsTurtleGenericTunnelItem::DIRECTION_CLIENT) ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case RS_TURTLE_SUBTYPE_FILE_CRC :
|
||||
{
|
||||
RsTurtleFileCrcItem *item = dynamic_cast<RsTurtleFileCrcItem *>(i) ;
|
||||
getMultiplexer()->recvCRC32Map(virtual_peer_id,hash,item->crc_map) ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST:
|
||||
{
|
||||
getMultiplexer()->recvCRC32MapRequest(virtual_peer_id,hash) ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case RS_TURTLE_SUBTYPE_CHUNK_CRC :
|
||||
{
|
||||
RsTurtleChunkCrcItem *item = dynamic_cast<RsTurtleChunkCrcItem *>(i) ;
|
||||
getMultiplexer()->recvSingleChunkCRC(virtual_peer_id,hash,item->chunk_number,item->check_sum) ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST:
|
||||
{
|
||||
RsTurtleChunkCrcRequestItem *item = dynamic_cast<RsTurtleChunkCrcRequestItem *>(i) ;
|
||||
getMultiplexer()->recvSingleChunkCRCRequest(virtual_peer_id,hash,item->chunk_number) ;
|
||||
}
|
||||
break ;
|
||||
default:
|
||||
std::cerr << "WARNING: Unknown packet type received: sub_id=" << reinterpret_cast<void*>(i->PacketSubType()) << ". Is somebody trying to poison you ?" << std::endl ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* NB: The rsCore lock must be activated before calling this.
|
||||
* This Lock should be moved lower into the system...
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "ft/ftdata.h"
|
||||
#include "turtle/turtleclientservice.h"
|
||||
#include "retroshare/rsfiles.h"
|
||||
//#include "dbase/cachestrapper.h"
|
||||
|
||||
@ -72,142 +73,151 @@ class ftDwlQueue;
|
||||
class p3PeerMgr;
|
||||
class p3LinkMgr;
|
||||
|
||||
class ftServer: public RsFiles, public ftDataSend, public RsThread
|
||||
class ftServer: public RsFiles, public ftDataSend, public RsTurtleClientService, public RsThread
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/***************************************************************/
|
||||
/******************** Setup ************************************/
|
||||
/***************************************************************/
|
||||
/***************************************************************/
|
||||
/******************** Setup ************************************/
|
||||
/***************************************************************/
|
||||
|
||||
ftServer(p3PeerMgr *peerMgr, p3LinkMgr *linkMgr);
|
||||
ftServer(p3PeerMgr *peerMgr, p3LinkMgr *linkMgr);
|
||||
|
||||
/* Assign important variables */
|
||||
void setConfigDirectory(std::string path);
|
||||
/* Assign important variables */
|
||||
void setConfigDirectory(std::string path);
|
||||
|
||||
void setP3Interface(P3Interface *pqi);
|
||||
void setP3Interface(P3Interface *pqi);
|
||||
|
||||
/* add Config Items (Extra, Controller) */
|
||||
void addConfigComponents(p3ConfigMgr *mgr);
|
||||
/* add Config Items (Extra, Controller) */
|
||||
void addConfigComponents(p3ConfigMgr *mgr);
|
||||
|
||||
virtual CacheStrapper *getCacheStrapper();
|
||||
virtual CacheTransfer *getCacheTransfer();
|
||||
virtual CacheStrapper *getCacheStrapper();
|
||||
virtual CacheTransfer *getCacheTransfer();
|
||||
|
||||
std::string OwnId();
|
||||
std::string OwnId();
|
||||
|
||||
/* Final Setup (once everything is assigned) */
|
||||
//void SetupFtServer();
|
||||
void SetupFtServer(NotifyBase *cb);
|
||||
void connectToTurtleRouter(p3turtle *p) ;
|
||||
/* Final Setup (once everything is assigned) */
|
||||
//void SetupFtServer();
|
||||
void SetupFtServer(NotifyBase *cb);
|
||||
void connectToTurtleRouter(p3turtle *p) ;
|
||||
|
||||
void StartupThreads();
|
||||
void StopThreads();
|
||||
void StartupThreads();
|
||||
void StopThreads();
|
||||
|
||||
/* own thread */
|
||||
virtual void run();
|
||||
/* own thread */
|
||||
virtual void run();
|
||||
|
||||
// Checks that the given hash is well formed. Used to chase
|
||||
// string bugs.
|
||||
static bool checkHash(const std::string& hash,std::string& error_string) ;
|
||||
// Checks that the given hash is well formed. Used to chase
|
||||
// string bugs.
|
||||
static bool checkHash(const std::string& hash,std::string& error_string) ;
|
||||
|
||||
/***************************************************************/
|
||||
/*************** Control Interface *****************************/
|
||||
/************** (Implements RsFiles) ***************************/
|
||||
/***************************************************************/
|
||||
// Implements RsTurtleClientService
|
||||
//
|
||||
virtual bool handleTunnelRequest(const std::string& hash,const std::string& peer_id) ;
|
||||
virtual void receiveTurtleData(RsTurtleGenericTunnelItem *item,const std::string& hash,const std::string& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction) ;
|
||||
virtual RsTurtleGenericTunnelItem *deserialiseItem(void *data,uint32_t size) const ;
|
||||
|
||||
// member access
|
||||
void addVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&,RsTurtleGenericTunnelItem::Direction dir) ;
|
||||
void removeVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&) ;
|
||||
|
||||
ftDataMultiplex *getMultiplexer() const { return mFtDataplex ; }
|
||||
ftController *getController() const { return mFtController ; }
|
||||
/***************************************************************/
|
||||
/*************** Control Interface *****************************/
|
||||
/************** (Implements RsFiles) ***************************/
|
||||
/***************************************************************/
|
||||
|
||||
/***
|
||||
* Control of Downloads
|
||||
***/
|
||||
virtual bool alreadyHaveFile(const std::string& hash, FileInfo &info);
|
||||
virtual bool FileRequest(const std::string& fname, const std::string& hash, uint64_t size, const std::string& dest, TransferRequestFlags flags, const std::list<std::string>& srcIds);
|
||||
virtual bool FileCancel(const std::string& hash);
|
||||
virtual bool FileControl(const std::string& hash, uint32_t flags);
|
||||
virtual bool FileClearCompleted();
|
||||
virtual bool setDestinationDirectory(const std::string& hash,const std::string& new_path) ;
|
||||
virtual bool setDestinationName(const std::string& hash,const std::string& new_name) ;
|
||||
virtual bool setChunkStrategy(const std::string& hash,FileChunksInfo::ChunkStrategy s) ;
|
||||
virtual void setDefaultChunkStrategy(FileChunksInfo::ChunkStrategy) ;
|
||||
virtual FileChunksInfo::ChunkStrategy defaultChunkStrategy() ;
|
||||
virtual uint32_t freeDiskSpaceLimit() const ;
|
||||
virtual void setFreeDiskSpaceLimit(uint32_t size_in_mb) ;
|
||||
// member access
|
||||
|
||||
ftDataMultiplex *getMultiplexer() const { return mFtDataplex ; }
|
||||
ftController *getController() const { return mFtController ; }
|
||||
|
||||
/***
|
||||
* Control of Downloads
|
||||
***/
|
||||
virtual bool alreadyHaveFile(const std::string& hash, FileInfo &info);
|
||||
virtual bool FileRequest(const std::string& fname, const std::string& hash, uint64_t size, const std::string& dest, TransferRequestFlags flags, const std::list<std::string>& srcIds);
|
||||
virtual bool FileCancel(const std::string& hash);
|
||||
virtual bool FileControl(const std::string& hash, uint32_t flags);
|
||||
virtual bool FileClearCompleted();
|
||||
virtual bool setDestinationDirectory(const std::string& hash,const std::string& new_path) ;
|
||||
virtual bool setDestinationName(const std::string& hash,const std::string& new_name) ;
|
||||
virtual bool setChunkStrategy(const std::string& hash,FileChunksInfo::ChunkStrategy s) ;
|
||||
virtual void setDefaultChunkStrategy(FileChunksInfo::ChunkStrategy) ;
|
||||
virtual FileChunksInfo::ChunkStrategy defaultChunkStrategy() ;
|
||||
virtual uint32_t freeDiskSpaceLimit() const ;
|
||||
virtual void setFreeDiskSpaceLimit(uint32_t size_in_mb) ;
|
||||
|
||||
|
||||
/***
|
||||
* Control of Downloads Priority.
|
||||
***/
|
||||
virtual uint32_t getMinPrioritizedTransfers() ;
|
||||
virtual void setMinPrioritizedTransfers(uint32_t s) ;
|
||||
virtual uint32_t getQueueSize() ;
|
||||
virtual void setQueueSize(uint32_t s) ;
|
||||
virtual bool changeQueuePosition(const std::string hash, QueueMove queue_mv);
|
||||
virtual bool changeDownloadSpeed(const std::string hash, int speed);
|
||||
virtual bool getDownloadSpeed(const std::string hash, int & speed);
|
||||
virtual bool clearDownload(const std::string hash);
|
||||
//virtual void getDwlDetails(std::list<DwlDetails> & details);
|
||||
/***
|
||||
* Control of Downloads Priority.
|
||||
***/
|
||||
virtual uint32_t getMinPrioritizedTransfers() ;
|
||||
virtual void setMinPrioritizedTransfers(uint32_t s) ;
|
||||
virtual uint32_t getQueueSize() ;
|
||||
virtual void setQueueSize(uint32_t s) ;
|
||||
virtual bool changeQueuePosition(const std::string hash, QueueMove queue_mv);
|
||||
virtual bool changeDownloadSpeed(const std::string hash, int speed);
|
||||
virtual bool getDownloadSpeed(const std::string hash, int & speed);
|
||||
virtual bool clearDownload(const std::string hash);
|
||||
//virtual void getDwlDetails(std::list<DwlDetails> & details);
|
||||
|
||||
/***
|
||||
* Download/Upload Details
|
||||
***/
|
||||
virtual bool FileDownloads(std::list<std::string> &hashs);
|
||||
virtual bool FileUploads(std::list<std::string> &hashs);
|
||||
virtual bool FileDetails(const std::string &hash, FileSearchFlags hintflags, FileInfo &info);
|
||||
virtual bool FileDownloadChunksDetails(const std::string& hash,FileChunksInfo& info) ;
|
||||
virtual bool FileUploadChunksDetails(const std::string& hash,const std::string& peer_id,CompressedChunkMap& map) ;
|
||||
/***
|
||||
* Download/Upload Details
|
||||
***/
|
||||
virtual bool FileDownloads(std::list<std::string> &hashs);
|
||||
virtual bool FileUploads(std::list<std::string> &hashs);
|
||||
virtual bool FileDetails(const std::string &hash, FileSearchFlags hintflags, FileInfo &info);
|
||||
virtual bool FileDownloadChunksDetails(const std::string& hash,FileChunksInfo& info) ;
|
||||
virtual bool FileUploadChunksDetails(const std::string& hash,const std::string& peer_id,CompressedChunkMap& map) ;
|
||||
|
||||
|
||||
/***
|
||||
* Extra List Access
|
||||
***/
|
||||
virtual bool ExtraFileAdd(std::string fname, std::string hash, uint64_t size, uint32_t period, TransferRequestFlags flags);
|
||||
virtual bool ExtraFileRemove(std::string hash, TransferRequestFlags flags);
|
||||
virtual bool ExtraFileHash(std::string localpath, uint32_t period, TransferRequestFlags flags);
|
||||
virtual bool ExtraFileStatus(std::string localpath, FileInfo &info);
|
||||
virtual bool ExtraFileMove(std::string fname, std::string hash, uint64_t size, std::string destpath);
|
||||
/***
|
||||
* Extra List Access
|
||||
***/
|
||||
virtual bool ExtraFileAdd(std::string fname, std::string hash, uint64_t size, uint32_t period, TransferRequestFlags flags);
|
||||
virtual bool ExtraFileRemove(std::string hash, TransferRequestFlags flags);
|
||||
virtual bool ExtraFileHash(std::string localpath, uint32_t period, TransferRequestFlags flags);
|
||||
virtual bool ExtraFileStatus(std::string localpath, FileInfo &info);
|
||||
virtual bool ExtraFileMove(std::string fname, std::string hash, uint64_t size, std::string destpath);
|
||||
|
||||
|
||||
/***
|
||||
* Directory Listing / Search Interface
|
||||
***/
|
||||
virtual int RequestDirDetails(const std::string& uid, const std::string& path, DirDetails &details);
|
||||
virtual int RequestDirDetails(void *ref, DirDetails &details, FileSearchFlags flags);
|
||||
virtual uint32_t getType(void *ref,FileSearchFlags flags) ;
|
||||
/***
|
||||
* Directory Listing / Search Interface
|
||||
***/
|
||||
virtual int RequestDirDetails(const std::string& uid, const std::string& path, DirDetails &details);
|
||||
virtual int RequestDirDetails(void *ref, DirDetails &details, FileSearchFlags flags);
|
||||
virtual uint32_t getType(void *ref,FileSearchFlags flags) ;
|
||||
|
||||
virtual int SearchKeywords(std::list<std::string> keywords, std::list<DirDetails> &results,FileSearchFlags flags);
|
||||
virtual int SearchKeywords(std::list<std::string> keywords, std::list<DirDetails> &results,FileSearchFlags flags,const std::string& peer_id);
|
||||
virtual int SearchBoolExp(Expression * exp, std::list<DirDetails> &results,FileSearchFlags flags);
|
||||
virtual int SearchBoolExp(Expression * exp, std::list<DirDetails> &results,FileSearchFlags flags,const std::string& peer_id);
|
||||
virtual int SearchKeywords(std::list<std::string> keywords, std::list<DirDetails> &results,FileSearchFlags flags);
|
||||
virtual int SearchKeywords(std::list<std::string> keywords, std::list<DirDetails> &results,FileSearchFlags flags,const std::string& peer_id);
|
||||
virtual int SearchBoolExp(Expression * exp, std::list<DirDetails> &results,FileSearchFlags flags);
|
||||
virtual int SearchBoolExp(Expression * exp, std::list<DirDetails> &results,FileSearchFlags flags,const std::string& peer_id);
|
||||
|
||||
/***
|
||||
* Utility Functions
|
||||
***/
|
||||
virtual bool ConvertSharedFilePath(std::string path, std::string &fullpath);
|
||||
virtual void ForceDirectoryCheck();
|
||||
virtual void updateSinceGroupPermissionsChanged() ;
|
||||
virtual bool InDirectoryCheck();
|
||||
virtual bool CopyFile(const std::string& source, const std::string& dest);
|
||||
/***
|
||||
* Utility Functions
|
||||
***/
|
||||
virtual bool ConvertSharedFilePath(std::string path, std::string &fullpath);
|
||||
virtual void ForceDirectoryCheck();
|
||||
virtual void updateSinceGroupPermissionsChanged() ;
|
||||
virtual bool InDirectoryCheck();
|
||||
virtual bool CopyFile(const std::string& source, const std::string& dest);
|
||||
|
||||
/***
|
||||
* Directory Handling
|
||||
***/
|
||||
virtual void setDownloadDirectory(std::string path);
|
||||
virtual void setPartialsDirectory(std::string path);
|
||||
virtual std::string getDownloadDirectory();
|
||||
virtual std::string getPartialsDirectory();
|
||||
/***
|
||||
* Directory Handling
|
||||
***/
|
||||
virtual void setDownloadDirectory(std::string path);
|
||||
virtual void setPartialsDirectory(std::string path);
|
||||
virtual std::string getDownloadDirectory();
|
||||
virtual std::string getPartialsDirectory();
|
||||
|
||||
virtual bool getSharedDirectories(std::list<SharedDirInfo> &dirs);
|
||||
virtual bool setSharedDirectories(std::list<SharedDirInfo> &dirs);
|
||||
virtual bool addSharedDirectory(const SharedDirInfo& dir);
|
||||
virtual bool updateShareFlags(const SharedDirInfo& dir); // updates the flags. The directory should already exist !
|
||||
virtual bool removeSharedDirectory(std::string dir);
|
||||
virtual bool getSharedDirectories(std::list<SharedDirInfo> &dirs);
|
||||
virtual bool setSharedDirectories(std::list<SharedDirInfo> &dirs);
|
||||
virtual bool addSharedDirectory(const SharedDirInfo& dir);
|
||||
virtual bool updateShareFlags(const SharedDirInfo& dir); // updates the flags. The directory should already exist !
|
||||
virtual bool removeSharedDirectory(std::string dir);
|
||||
|
||||
virtual bool getShareDownloadDirectory();
|
||||
virtual bool shareDownloadDirectory(bool share);
|
||||
virtual bool getShareDownloadDirectory();
|
||||
virtual bool shareDownloadDirectory(bool share);
|
||||
|
||||
virtual void setRememberHashFilesDuration(uint32_t days) ;
|
||||
virtual uint32_t rememberHashFilesDuration() const ;
|
||||
@ -217,84 +227,84 @@ virtual bool shareDownloadDirectory(bool share);
|
||||
virtual void setWatchPeriod(int minutes) ;
|
||||
virtual int watchPeriod() const ;
|
||||
|
||||
/***************************************************************/
|
||||
/*************** Control Interface *****************************/
|
||||
/***************************************************************/
|
||||
/***************************************************************/
|
||||
/*************** Control Interface *****************************/
|
||||
/***************************************************************/
|
||||
|
||||
/***************************************************************/
|
||||
/*************** Data Transfer Interface ***********************/
|
||||
/***************************************************************/
|
||||
public:
|
||||
virtual bool sendData(const std::string& peerId, const std::string& hash, uint64_t size, uint64_t offset, uint32_t chunksize, void *data);
|
||||
virtual bool sendDataRequest(const std::string& peerId, const std::string& hash, uint64_t size, uint64_t offset, uint32_t chunksize);
|
||||
virtual bool sendChunkMapRequest(const std::string& peer_id,const std::string& hash,bool is_client) ;
|
||||
virtual bool sendChunkMap(const std::string& peer_id,const std::string& hash,const CompressedChunkMap& cmap,bool is_client) ;
|
||||
virtual bool sendCRC32MapRequest(const std::string&, const std::string&) ;
|
||||
virtual bool sendCRC32Map(const std::string&, const std::string&, const CRC32Map&) ;
|
||||
virtual bool sendSingleChunkCRCRequest(const std::string& peer_id,const std::string& hash,uint32_t chunk_number) ;
|
||||
virtual bool sendSingleChunkCRC(const std::string& peer_id,const std::string& hash,uint32_t chunk_number,const Sha1CheckSum& crc) ;
|
||||
/***************************************************************/
|
||||
/*************** Data Transfer Interface ***********************/
|
||||
/***************************************************************/
|
||||
public:
|
||||
virtual bool sendData(const std::string& peerId, const std::string& hash, uint64_t size, uint64_t offset, uint32_t chunksize, void *data);
|
||||
virtual bool sendDataRequest(const std::string& peerId, const std::string& hash, uint64_t size, uint64_t offset, uint32_t chunksize);
|
||||
virtual bool sendChunkMapRequest(const std::string& peer_id,const std::string& hash,bool is_client) ;
|
||||
virtual bool sendChunkMap(const std::string& peer_id,const std::string& hash,const CompressedChunkMap& cmap,bool is_client) ;
|
||||
virtual bool sendCRC32MapRequest(const std::string&, const std::string&) ;
|
||||
virtual bool sendCRC32Map(const std::string&, const std::string&, const CRC32Map&) ;
|
||||
virtual bool sendSingleChunkCRCRequest(const std::string& peer_id,const std::string& hash,uint32_t chunk_number) ;
|
||||
virtual bool sendSingleChunkCRC(const std::string& peer_id,const std::string& hash,uint32_t chunk_number,const Sha1CheckSum& crc) ;
|
||||
|
||||
/*************** Internal Transfer Fns *************************/
|
||||
virtual int tick();
|
||||
/*************** Internal Transfer Fns *************************/
|
||||
virtual int tick();
|
||||
|
||||
/* Configuration */
|
||||
bool addConfiguration(p3ConfigMgr *cfgmgr);
|
||||
bool ResumeTransfers();
|
||||
/* Configuration */
|
||||
bool addConfiguration(p3ConfigMgr *cfgmgr);
|
||||
bool ResumeTransfers();
|
||||
|
||||
private:
|
||||
bool handleInputQueues();
|
||||
bool handleCacheData();
|
||||
bool handleFileData();
|
||||
private:
|
||||
bool handleInputQueues();
|
||||
bool handleCacheData();
|
||||
bool handleFileData();
|
||||
|
||||
/******************* p3 Config Overload ************************/
|
||||
/******************* p3 Config Overload ************************/
|
||||
protected:
|
||||
/* Key Functions to be overloaded for Full Configuration */
|
||||
virtual RsSerialiser *setupSerialiser();
|
||||
virtual bool saveList(bool &cleanup, std::list<RsItem *>&);
|
||||
virtual bool loadList(std::list<RsItem *>& load);
|
||||
/* Key Functions to be overloaded for Full Configuration */
|
||||
virtual RsSerialiser *setupSerialiser();
|
||||
virtual bool saveList(bool &cleanup, std::list<RsItem *>&);
|
||||
virtual bool loadList(std::list<RsItem *>& load);
|
||||
|
||||
private:
|
||||
bool loadConfigMap(std::map<std::string, std::string> &configMap);
|
||||
/******************* p3 Config Overload ************************/
|
||||
bool loadConfigMap(std::map<std::string, std::string> &configMap);
|
||||
/******************* p3 Config Overload ************************/
|
||||
|
||||
/*************************** p3 Config Overload ********************/
|
||||
/*************************** p3 Config Overload ********************/
|
||||
|
||||
private:
|
||||
|
||||
/**** INTERNAL FUNCTIONS ***/
|
||||
//virtual int reScanDirs();
|
||||
//virtual int check_dBUpdate();
|
||||
/**** INTERNAL FUNCTIONS ***/
|
||||
//virtual int reScanDirs();
|
||||
//virtual int check_dBUpdate();
|
||||
|
||||
private:
|
||||
|
||||
/* no need for Mutex protection -
|
||||
* as each component is protected independently.
|
||||
*/
|
||||
/* no need for Mutex protection -
|
||||
* as each component is protected independently.
|
||||
*/
|
||||
|
||||
P3Interface *mP3iface; /* XXX THIS NEEDS PROTECTION */
|
||||
P3Interface *mP3iface; /* XXX THIS NEEDS PROTECTION */
|
||||
|
||||
p3PeerMgr *mPeerMgr;
|
||||
p3LinkMgr *mLinkMgr;
|
||||
|
||||
ftCacheStrapper *mCacheStrapper;
|
||||
ftFiStore *mFiStore;
|
||||
ftFiMonitor *mFiMon;
|
||||
p3PeerMgr *mPeerMgr;
|
||||
p3LinkMgr *mLinkMgr;
|
||||
|
||||
ftController *mFtController;
|
||||
ftExtraList *mFtExtra;
|
||||
ftCacheStrapper *mCacheStrapper;
|
||||
ftFiStore *mFiStore;
|
||||
ftFiMonitor *mFiMon;
|
||||
|
||||
ftDataMultiplex *mFtDataplex;
|
||||
p3turtle *mTurtleRouter ;
|
||||
ftController *mFtController;
|
||||
ftExtraList *mFtExtra;
|
||||
|
||||
ftDataMultiplex *mFtDataplex;
|
||||
p3turtle *mTurtleRouter ;
|
||||
|
||||
|
||||
ftFileSearch *mFtSearch;
|
||||
ftFileSearch *mFtSearch;
|
||||
|
||||
ftDwlQueue *mFtDwlQueue;
|
||||
ftDwlQueue *mFtDwlQueue;
|
||||
|
||||
RsMutex srvMutex;
|
||||
std::string mConfigPath;
|
||||
std::string mDownloadPath;
|
||||
std::string mPartialsPath;
|
||||
RsMutex srvMutex;
|
||||
std::string mConfigPath;
|
||||
std::string mDownloadPath;
|
||||
std::string mPartialsPath;
|
||||
|
||||
};
|
||||
|
||||
|
739
libretroshare/src/ft/ftturtlefiletransferitem.cc
Normal file
739
libretroshare/src/ft/ftturtlefiletransferitem.cc
Normal file
@ -0,0 +1,739 @@
|
||||
/*
|
||||
* libretroshare/src/services: ftturtlefiletransferitem.cc
|
||||
*
|
||||
* Services for RetroShare.
|
||||
*
|
||||
* Copyright 2013 by Cyril Soler
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "csoler@users.sourceforge.net".
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <serialiser/itempriorities.h>
|
||||
#include <ft/ftturtlefiletransferitem.h>
|
||||
|
||||
uint32_t RsTurtleFileRequestItem::serial_size()
|
||||
{
|
||||
uint32_t s = 0 ;
|
||||
|
||||
s += 8 ; // header
|
||||
s += 4 ; // tunnel id
|
||||
s += 8 ; // file offset
|
||||
s += 4 ; // chunk size
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
||||
uint32_t RsTurtleFileDataItem::serial_size()
|
||||
{
|
||||
uint32_t s = 0 ;
|
||||
|
||||
s += 8 ; // header
|
||||
s += 4 ; // tunnel id
|
||||
s += 8 ; // file offset
|
||||
s += 4 ; // chunk size
|
||||
s += chunk_size ; // actual data size.
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
||||
uint32_t RsTurtleFileMapRequestItem::serial_size()
|
||||
{
|
||||
uint32_t s = 0 ;
|
||||
|
||||
s += 8 ; // header
|
||||
s += 4 ; // tunnel id
|
||||
s += 4 ; // direction
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
||||
uint32_t RsTurtleFileMapItem::serial_size()
|
||||
{
|
||||
uint32_t s = 0 ;
|
||||
|
||||
s += 8 ; // header
|
||||
s += 4 ; // tunnel id
|
||||
s += 4 ; // direction
|
||||
s += 4 ; // compressed_map.size()
|
||||
|
||||
s += 4 * compressed_map._map.size() ;
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
||||
uint32_t RsTurtleFileCrcRequestItem::serial_size()
|
||||
{
|
||||
uint32_t s = 0 ;
|
||||
|
||||
s += 8 ; // header
|
||||
s += 4 ; // tunnel id
|
||||
|
||||
return s ;
|
||||
}
|
||||
uint32_t RsTurtleChunkCrcItem::serial_size()
|
||||
{
|
||||
uint32_t s = 0 ;
|
||||
|
||||
s += 8 ; // header
|
||||
s += 4 ; // tunnel id
|
||||
s += 4 ; // chunk number
|
||||
s += 20 ; // check_sum
|
||||
|
||||
return s ;
|
||||
}
|
||||
uint32_t RsTurtleChunkCrcRequestItem::serial_size()
|
||||
{
|
||||
uint32_t s = 0 ;
|
||||
|
||||
s += 8 ; // header
|
||||
s += 4 ; // tunnel id
|
||||
s += 4 ; // chunk number
|
||||
|
||||
return s ;
|
||||
}
|
||||
uint32_t RsTurtleFileCrcItem::serial_size()
|
||||
{
|
||||
uint32_t s = 0 ;
|
||||
|
||||
s += 8 ; // header
|
||||
s += 4 ; // tunnel id
|
||||
|
||||
s += 4 ; // size of _map
|
||||
s += 4 ; // size of _crcs
|
||||
|
||||
s += 4 * crc_map._crcs.size() ;
|
||||
s += 4 * crc_map._ccmap._map.size() ;
|
||||
|
||||
return s ;
|
||||
}
|
||||
bool RsTurtleFileMapRequestItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size();
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, direction);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool RsTurtleFileMapItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size();
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, direction);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, compressed_map._map.size());
|
||||
|
||||
for(uint32_t i=0;i<compressed_map._map.size() && ok;++i)
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, compressed_map._map[i]);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool RsTurtleFileCrcRequestItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << "RsTurtleFileCrcRequestItem::serialize(): serializing packet:" << std::endl ;
|
||||
print(std::cerr,2) ;
|
||||
#endif
|
||||
uint32_t tlvsize = serial_size();
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool RsTurtleChunkCrcRequestItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << "RsTurtleChunkCrcRequestItem::serialize(): serializing packet:" << std::endl ;
|
||||
print(std::cerr,2) ;
|
||||
#endif
|
||||
uint32_t tlvsize = serial_size();
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, chunk_number);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
bool RsTurtleFileCrcItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << "RsTurtleFileCrcItem::serialize(): serializing packet:" << std::endl ;
|
||||
print(std::cerr,2) ;
|
||||
#endif
|
||||
uint32_t tlvsize = serial_size();
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, crc_map._ccmap._map.size());
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, crc_map._crcs.size());
|
||||
|
||||
for(uint32_t i=0;i<crc_map._ccmap._map.size() && ok;++i)
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, crc_map._ccmap._map[i]);
|
||||
|
||||
for(uint32_t i=0;i<crc_map._crcs.size() && ok;++i)
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, crc_map._crcs[i]);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
bool RsTurtleChunkCrcItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << "RsTurtleChunkCrcRequestItem::serialize(): serializing packet:" << std::endl ;
|
||||
print(std::cerr,2) ;
|
||||
#endif
|
||||
uint32_t tlvsize = serial_size();
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, chunk_number);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[0]);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[1]);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[2]);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[3]);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[4]);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
RsTurtleFileMapItem::RsTurtleFileMapItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_MAP)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_MAP) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " type = file map item" << std::endl ;
|
||||
#endif
|
||||
uint32_t offset = 8; // skip the header
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
bool ok = true ;
|
||||
uint32_t s,d ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id);
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &d);
|
||||
direction = d ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &s) ;
|
||||
|
||||
compressed_map._map.resize(s) ;
|
||||
|
||||
for(uint32_t i=0;i<s && ok;++i)
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &(compressed_map._map[i])) ;
|
||||
|
||||
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
|
||||
#else
|
||||
if (offset != pktsize)
|
||||
throw std::runtime_error("Size error while deserializing.") ;
|
||||
if (!ok)
|
||||
throw std::runtime_error("Unknown error while deserializing.") ;
|
||||
#endif
|
||||
}
|
||||
|
||||
RsTurtleFileMapRequestItem::RsTurtleFileMapRequestItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_MAP_REQUEST) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " type = file map request item" << std::endl ;
|
||||
#endif
|
||||
uint32_t offset = 8; // skip the header
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
bool ok = true ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id);
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &direction);
|
||||
|
||||
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
|
||||
#else
|
||||
if (offset != pktsize)
|
||||
throw std::runtime_error("Size error while deserializing.") ;
|
||||
if (!ok)
|
||||
throw std::runtime_error("Unknown error while deserializing.") ;
|
||||
#endif
|
||||
}
|
||||
|
||||
RsTurtleFileCrcItem::RsTurtleFileCrcItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_CRC)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_CRC) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " type = file map item" << std::endl ;
|
||||
#endif
|
||||
uint32_t offset = 8; // skip the header
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
bool ok = true ;
|
||||
uint32_t s1,s2 ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id);
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &s1) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &s2) ;
|
||||
|
||||
crc_map._ccmap._map.resize(s1) ;
|
||||
crc_map._crcs.resize(s2) ;
|
||||
|
||||
for(uint32_t i=0;i<s1 && ok;++i)
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &(crc_map._ccmap._map[i])) ;
|
||||
|
||||
for(uint32_t i=0;i<s2 && ok;++i)
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &(crc_map._crcs[i])) ;
|
||||
|
||||
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
|
||||
#else
|
||||
if (offset != pktsize)
|
||||
throw std::runtime_error("Size error while deserializing.") ;
|
||||
if (!ok)
|
||||
throw std::runtime_error("Unknown error while deserializing.") ;
|
||||
#endif
|
||||
}
|
||||
RsTurtleChunkCrcItem::RsTurtleChunkCrcItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_CHUNK_CRC)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_CHUNK_CRC) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " type = file map item" << std::endl ;
|
||||
#endif
|
||||
uint32_t offset = 8; // skip the header
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
bool ok = true ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &chunk_number) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[0]) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[1]) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[2]) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[3]) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[4]) ;
|
||||
|
||||
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
|
||||
#else
|
||||
if (offset != pktsize)
|
||||
throw std::runtime_error("Size error while deserializing.") ;
|
||||
if (!ok)
|
||||
throw std::runtime_error("Unknown error while deserializing.") ;
|
||||
#endif
|
||||
}
|
||||
RsTurtleFileCrcRequestItem::RsTurtleFileCrcRequestItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_CRC_REQUEST) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " type = file map request item" << std::endl ;
|
||||
#endif
|
||||
uint32_t offset = 8; // skip the header
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
bool ok = true ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id);
|
||||
|
||||
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
|
||||
#else
|
||||
if (offset != pktsize)
|
||||
throw std::runtime_error("Size error while deserializing.") ;
|
||||
if (!ok)
|
||||
throw std::runtime_error("Unknown error while deserializing.") ;
|
||||
#endif
|
||||
}
|
||||
RsTurtleChunkCrcRequestItem::RsTurtleChunkCrcRequestItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_CHUNK_CRC_REQUEST) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " type = file map item" << std::endl ;
|
||||
#endif
|
||||
uint32_t offset = 8; // skip the header
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
bool ok = true ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &chunk_number) ;
|
||||
|
||||
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
|
||||
#else
|
||||
if (offset != pktsize)
|
||||
throw std::runtime_error("Size error while deserializing.") ;
|
||||
if (!ok)
|
||||
throw std::runtime_error("Unknown error while deserializing.") ;
|
||||
#endif
|
||||
}
|
||||
bool RsTurtleFileRequestItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size();
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id) ;
|
||||
ok &= setRawUInt64(data, tlvsize, &offset, chunk_offset);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, chunk_size);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsTurtleTunnelOkItem::serialiseTransfer() Size Error! " << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
RsTurtleFileRequestItem::RsTurtleFileRequestItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_REQUEST)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_REQUEST) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " type = file request" << std::endl ;
|
||||
#endif
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
bool ok = true ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id) ;
|
||||
ok &= getRawUInt64(data, pktsize, &offset, &chunk_offset);
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &chunk_size);
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " tunnel_id=" << (void*)tunnel_id << ", chunk_offset=" << chunk_offset << ", chunk_size=" << chunk_size << std::endl ;
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
|
||||
UNREFERENCED_LOCAL_VARIABLE(rssize);
|
||||
#else
|
||||
if (offset != rssize)
|
||||
throw std::runtime_error("RsTurtleTunnelOkItem::() error while deserializing.") ;
|
||||
if (!ok)
|
||||
throw std::runtime_error("RsTurtleTunnelOkItem::() unknown error while deserializing.") ;
|
||||
#endif
|
||||
}
|
||||
|
||||
RsTurtleFileDataItem::~RsTurtleFileDataItem()
|
||||
{
|
||||
free(chunk_data) ;
|
||||
}
|
||||
RsTurtleFileDataItem::RsTurtleFileDataItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_DATA)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_DATA) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " type = file request" << std::endl ;
|
||||
#endif
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
bool ok = true ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id) ;
|
||||
ok &= getRawUInt64(data, pktsize, &offset, &chunk_offset);
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &chunk_size);
|
||||
|
||||
chunk_data = (void*)malloc(chunk_size) ;
|
||||
memcpy(chunk_data,(void*)((unsigned char*)data+offset),chunk_size) ;
|
||||
|
||||
offset += chunk_size ;
|
||||
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " tunnel_id=" << (void*)tunnel_id << ", chunk_offset=" << chunk_offset << ", chunk_size=" << chunk_size << std::endl ;
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
|
||||
UNREFERENCED_LOCAL_VARIABLE(rssize);
|
||||
#else
|
||||
if (offset != rssize)
|
||||
throw std::runtime_error("RsTurtleFileDataItem::() error while deserializing.") ;
|
||||
if (!ok)
|
||||
throw std::runtime_error("RsTurtleFileDataItem::() unknown error while deserializing.") ;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool RsTurtleFileDataItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size();
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id) ;
|
||||
ok &= setRawUInt64(data, tlvsize, &offset, chunk_offset);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, chunk_size);
|
||||
|
||||
memcpy((void*)((unsigned char*)data+offset),chunk_data,chunk_size) ;
|
||||
offset += chunk_size ;
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsTurtleTunnelOkItem::serialiseTransfer() Size Error! " << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
std::ostream& RsTurtleFileRequestItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "File request item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
|
||||
o << " offset : " << chunk_offset << std::endl ;
|
||||
o << " chunk size: " << chunk_size << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
|
||||
std::ostream& RsTurtleFileDataItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "File request item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
|
||||
o << " offset : " << chunk_offset << std::endl ;
|
||||
o << " chunk size: " << chunk_size << std::endl ;
|
||||
o << " data : " << std::hex << chunk_data << std::dec << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
|
||||
std::ostream& RsTurtleFileMapItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "File map item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
|
||||
o << " direction : " << direction << std::endl ;
|
||||
o << " map : " ;
|
||||
|
||||
for(uint32_t i=0;i<compressed_map._map.size();++i)
|
||||
o << std::hex << compressed_map._map[i] << std::dec << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
|
||||
std::ostream& RsTurtleFileMapRequestItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "File map request item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
|
||||
o << " direction : " << direction << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
|
||||
std::ostream& RsTurtleFileCrcItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "File CRC item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
|
||||
o << " map : " ;
|
||||
|
||||
for(uint32_t i=0;i<crc_map._ccmap._map.size();++i)
|
||||
o << std::hex << crc_map._ccmap._map[i] << std::endl ;
|
||||
|
||||
o << " CRC : " ;
|
||||
|
||||
for(uint32_t i=0;i<crc_map._crcs.size();++i)
|
||||
o << std::hex << crc_map._crcs[i] << std::dec << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
std::ostream& RsTurtleFileCrcRequestItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "File CRC request item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
std::ostream& RsTurtleChunkCrcRequestItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "Chunk CRC request item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
|
||||
o << " chunk num : " << chunk_number << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
std::ostream& RsTurtleChunkCrcItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "Chunk CRC request item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
|
||||
o << " chunk num : " << chunk_number << std::endl ;
|
||||
o << " sha1 sum : " << check_sum.toStdString() << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
|
168
libretroshare/src/ft/ftturtlefiletransferitem.h
Normal file
168
libretroshare/src/ft/ftturtlefiletransferitem.h
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* libretroshare/src/services: ftturtlefiletransferitem.h
|
||||
*
|
||||
* Services for RetroShare.
|
||||
*
|
||||
* Copyright 2013 by Cyril Soler
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "csoler@users.sourceforge.net".
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <turtle/rsturtleitem.h>
|
||||
|
||||
/***********************************************************************************/
|
||||
/* Turtle File Transfer item classes */
|
||||
/***********************************************************************************/
|
||||
|
||||
class RsTurtleFileRequestItem: public RsTurtleGenericTunnelItem
|
||||
{
|
||||
public:
|
||||
RsTurtleFileRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_REQUEST) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_REQUEST);}
|
||||
RsTurtleFileRequestItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual bool shouldStampTunnel() const { return false ; }
|
||||
virtual Direction travelingDirection() const { return DIRECTION_SERVER ; }
|
||||
|
||||
uint64_t chunk_offset ;
|
||||
uint32_t chunk_size ;
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
protected:
|
||||
virtual bool serialize(void *data,uint32_t& size) ;
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
class RsTurtleFileDataItem: public RsTurtleGenericTunnelItem
|
||||
{
|
||||
public:
|
||||
RsTurtleFileDataItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_DATA) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_DATA) ;}
|
||||
~RsTurtleFileDataItem() ;
|
||||
RsTurtleFileDataItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual bool shouldStampTunnel() const { return true ; }
|
||||
virtual Direction travelingDirection() const { return DIRECTION_CLIENT ; }
|
||||
|
||||
uint64_t chunk_offset ; // offset in the file
|
||||
uint32_t chunk_size ; // size of the file chunk
|
||||
void *chunk_data ; // actual data.
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
|
||||
virtual bool serialize(void *data,uint32_t& size) ;
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
class RsTurtleFileMapRequestItem: public RsTurtleGenericTunnelItem
|
||||
{
|
||||
public:
|
||||
RsTurtleFileMapRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_MAP_REQUEST) ;}
|
||||
RsTurtleFileMapRequestItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual bool shouldStampTunnel() const { return false ; }
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
|
||||
virtual bool serialize(void *data,uint32_t& size) ;
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
class RsTurtleFileMapItem: public RsTurtleGenericTunnelItem
|
||||
{
|
||||
public:
|
||||
RsTurtleFileMapItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_MAP) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_MAP) ;}
|
||||
RsTurtleFileMapItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual bool shouldStampTunnel() const { return false ; }
|
||||
|
||||
CompressedChunkMap compressed_map ; // Map info for the file in compressed format. Each *bit* in the array uint's says "I have" or "I don't have"
|
||||
// by default, we suppose the peer has all the chunks. This info will thus be and-ed
|
||||
// with the default file map for this source.
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
|
||||
virtual bool serialize(void *data,uint32_t& size) ;
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
class RsTurtleFileCrcRequestItem: public RsTurtleGenericTunnelItem
|
||||
{
|
||||
public:
|
||||
RsTurtleFileCrcRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST) { setPriorityLevel(QOS_PRIORITY_RS_FILE_CRC_REQUEST);}
|
||||
RsTurtleFileCrcRequestItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual bool shouldStampTunnel() const { return false ; }
|
||||
virtual Direction travelingDirection() const { return DIRECTION_SERVER ; }
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
|
||||
virtual bool serialize(void *data,uint32_t& size) ;
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
class RsTurtleChunkCrcRequestItem: public RsTurtleGenericTunnelItem
|
||||
{
|
||||
public:
|
||||
RsTurtleChunkCrcRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST) { setPriorityLevel(QOS_PRIORITY_RS_CHUNK_CRC_REQUEST);}
|
||||
RsTurtleChunkCrcRequestItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual bool shouldStampTunnel() const { return false ; }
|
||||
virtual Direction travelingDirection() const { return DIRECTION_SERVER ; }
|
||||
|
||||
uint32_t chunk_number ; // id of the chunk to CRC.
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
|
||||
virtual bool serialize(void *data,uint32_t& size) ;
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
class RsTurtleFileCrcItem: public RsTurtleGenericTunnelItem
|
||||
{
|
||||
public:
|
||||
RsTurtleFileCrcItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_CRC) { setPriorityLevel(QOS_PRIORITY_RS_FILE_CRC);}
|
||||
RsTurtleFileCrcItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual bool shouldStampTunnel() const { return true ; }
|
||||
virtual Direction travelingDirection() const { return DIRECTION_CLIENT ; }
|
||||
|
||||
CRC32Map crc_map ;// Map info for the file in compressed format. Each *bit* in the array uint's says "I have" or "I don't have"
|
||||
// by default, we suppose the peer has all the chunks. This info will thus be and-ed
|
||||
// with the default file map for this source.
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
virtual bool serialize(void *data,uint32_t& size) ;
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
class RsTurtleChunkCrcItem: public RsTurtleGenericTunnelItem
|
||||
{
|
||||
public:
|
||||
RsTurtleChunkCrcItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_CHUNK_CRC) { setPriorityLevel(QOS_PRIORITY_RS_CHUNK_CRC);}
|
||||
RsTurtleChunkCrcItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual bool shouldStampTunnel() const { return true ; }
|
||||
virtual Direction travelingDirection() const { return DIRECTION_CLIENT ; }
|
||||
|
||||
uint32_t chunk_number ;
|
||||
Sha1CheckSum check_sum ;
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
virtual bool serialize(void *data,uint32_t& size) ;
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
@ -306,12 +306,14 @@ HEADERS += ft/ftchunkmap.h \
|
||||
ft/ftfilesearch.h \
|
||||
ft/ftsearch.h \
|
||||
ft/ftserver.h \
|
||||
ft/fttransfermodule.h
|
||||
ft/fttransfermodule.h \
|
||||
ft/ftturtlefiletransferitem.h
|
||||
|
||||
HEADERS += pqi/authssl.h \
|
||||
pqi/authgpg.h \
|
||||
pgp/pgphandler.h \
|
||||
pgp/pgpkeyutil.h \
|
||||
pgp/rsaes.h \
|
||||
pgp/rscertificate.h \
|
||||
pqi/p3cfgmgr.h \
|
||||
pqi/p3peermgr.h \
|
||||
@ -446,6 +448,7 @@ SOURCES += ft/ftchunkmap.cc \
|
||||
ft/ftfilesearch.cc \
|
||||
ft/ftserver.cc \
|
||||
ft/fttransfermodule.cc \
|
||||
ft/ftturtlefiletransferitem.cc
|
||||
|
||||
SOURCES += pqi/authgpg.cc \
|
||||
pqi/authssl.cc \
|
||||
@ -565,6 +568,7 @@ SOURCES += util/folderiterator.cc \
|
||||
util/rsthreads.cc \
|
||||
util/rsversion.cc \
|
||||
util/rswin.cc \
|
||||
util/rsaes.cc \
|
||||
util/rsrandom.cc \
|
||||
util/rstickevent.cc \
|
||||
|
||||
|
@ -943,7 +943,37 @@ bool PGPHandler::addOrMergeKey(ops_keyring_t *keyring,std::map<std::string,PGPCe
|
||||
|
||||
return ret ;
|
||||
}
|
||||
|
||||
// bool PGPHandler::encryptTextToString(const PGPIdType& key_id,const std::string& text,std::string& outstring)
|
||||
// {
|
||||
// RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures.
|
||||
//
|
||||
// const ops_keydata_t *public_key = getPublicKey(key_id) ;
|
||||
//
|
||||
// if(public_key == NULL)
|
||||
// {
|
||||
// std::cerr << "Cannot get public key of id " << key_id.toStdString() << std::endl;
|
||||
// return false ;
|
||||
// }
|
||||
//
|
||||
// if(public_key->type != OPS_PTAG_CT_PUBLIC_KEY)
|
||||
// {
|
||||
// std::cerr << "PGPHandler::encryptTextToFile(): ERROR: supplied id did not return a public key!" << std::endl;
|
||||
// return false ;
|
||||
// }
|
||||
//
|
||||
// ops_create_info_t *info;
|
||||
// ops_memory_t *buf = NULL ;
|
||||
// ops_setup_memory_write(&info, &buf, 0);
|
||||
//
|
||||
// ops_encrypt_stream(info, public_key, NULL, ops_false, ops_true);
|
||||
// ops_write(text.c_str(), text.length(), info);
|
||||
// ops_writer_close(info);
|
||||
//
|
||||
// outstring = std::string((char *)ops_memory_get_data(buf),ops_memory_get_length(buf)) ;
|
||||
// ops_create_info_delete(info);
|
||||
//
|
||||
// return true ;
|
||||
// }
|
||||
bool PGPHandler::encryptTextToFile(const PGPIdType& key_id,const std::string& text,const std::string& outfile)
|
||||
{
|
||||
RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures.
|
||||
@ -978,6 +1008,73 @@ bool PGPHandler::encryptTextToFile(const PGPIdType& key_id,const std::string& te
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool PGPHandler::encryptDataBin(const PGPIdType& key_id,const void *data, const uint32_t len, unsigned char *encrypted_data, unsigned int *encrypted_data_len)
|
||||
{
|
||||
RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures.
|
||||
|
||||
const ops_keydata_t *public_key = locked_getPublicKey(key_id,true) ;
|
||||
|
||||
if(public_key == NULL)
|
||||
{
|
||||
std::cerr << "Cannot get public key of id " << key_id.toStdString() << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
if(public_key->type != OPS_PTAG_CT_PUBLIC_KEY)
|
||||
{
|
||||
std::cerr << "PGPHandler::encryptTextToFile(): ERROR: supplied id did not return a public key!" << std::endl;
|
||||
return false ;
|
||||
}
|
||||
ops_create_info_t *info;
|
||||
ops_memory_t *buf = NULL ;
|
||||
ops_setup_memory_write(&info, &buf, 0);
|
||||
|
||||
ops_encrypt_stream(info, public_key, NULL, ops_false, ops_false);
|
||||
|
||||
ops_write(data,len,info);
|
||||
ops_writer_close(info);
|
||||
ops_create_info_delete(info);
|
||||
|
||||
int tlen = ops_memory_get_length(buf) ;
|
||||
bool res ;
|
||||
|
||||
if( (int)*encrypted_data_len >= tlen)
|
||||
{
|
||||
memcpy(encrypted_data,ops_memory_get_data(buf),tlen) ;
|
||||
*encrypted_data_len = tlen ;
|
||||
res = true ;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Not enough room to fit encrypted data. Size given=" << *encrypted_data_len << ", required=" << tlen << std::endl;
|
||||
res = false ;
|
||||
}
|
||||
|
||||
ops_memory_release(buf) ;
|
||||
free(buf) ;
|
||||
|
||||
return res ;
|
||||
}
|
||||
|
||||
bool PGPHandler::decryptDataBin(const PGPIdType& key_id,const void *encrypted_data, const uint32_t encrypted_len, unsigned char *data, unsigned int *data_len)
|
||||
{
|
||||
int out_length ;
|
||||
unsigned char *out ;
|
||||
ops_boolean_t res = ops_decrypt_memory((const unsigned char *)encrypted_data,encrypted_len,&out,&out_length,_secring,ops_false,cb_get_passphrase) ;
|
||||
|
||||
if(*data_len < out_length)
|
||||
{
|
||||
std::cerr << "Not enough room to store decrypted data! Please give more."<< std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
*data_len = out_length ;
|
||||
memcpy(data,out,out_length) ;
|
||||
free(out) ;
|
||||
|
||||
return (bool)res ;
|
||||
}
|
||||
|
||||
bool PGPHandler::decryptTextFromFile(const PGPIdType&,std::string& text,const std::string& inputfile)
|
||||
{
|
||||
RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures.
|
||||
@ -1054,10 +1151,21 @@ bool PGPHandler::SignDataBin(const PGPIdType& id,const void *data, const uint32_
|
||||
if(!memres)
|
||||
return false ;
|
||||
|
||||
uint32_t tlen = std::min(*signlen,(uint32_t)ops_memory_get_length(memres)) ;
|
||||
bool res ;
|
||||
uint32_t slen = (uint32_t)ops_memory_get_length(memres);
|
||||
|
||||
memcpy(sign,ops_memory_get_data(memres),tlen) ;
|
||||
*signlen = tlen ;
|
||||
if(*signlen >= slen)
|
||||
{
|
||||
*signlen = slen ;
|
||||
|
||||
memcpy(sign,ops_memory_get_data(memres),*signlen) ;
|
||||
res = true ;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "(EE) memory chunk is not large enough for signature packet. Requred size: " << slen << " bytes." << std::endl;
|
||||
res = false ;
|
||||
}
|
||||
|
||||
ops_memory_release(memres) ;
|
||||
free(memres) ;
|
||||
@ -1073,7 +1181,7 @@ bool PGPHandler::SignDataBin(const PGPIdType& id,const void *data, const uint32_
|
||||
hexdump( (unsigned char *)sign,*signlen) ;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
return true ;
|
||||
return res ;
|
||||
}
|
||||
|
||||
bool PGPHandler::privateSignCertificate(const PGPIdType& ownId,const PGPIdType& id_of_key_to_sign)
|
||||
|
@ -94,8 +94,15 @@ class PGPHandler
|
||||
bool VerifySignBin(const void *data, uint32_t data_len, unsigned char *sign, unsigned int sign_len, const PGPFingerprintType& withfingerprint) ;
|
||||
bool privateSignCertificate(const PGPIdType& own_id,const PGPIdType& id_of_key_to_sign) ;
|
||||
|
||||
// The client should supply a memory chunk to store the data. The length will be updated to the real length of the data.
|
||||
//
|
||||
bool encryptDataBin(const PGPIdType& key_id,const void *data, const uint32_t len, unsigned char *encrypted_data, unsigned int *encrypted_data_len) ;
|
||||
bool decryptDataBin(const PGPIdType& key_id,const void *data, const uint32_t len, unsigned char *decrypted_data, unsigned int *decrypted_data_len) ;
|
||||
|
||||
bool encryptTextToFile(const PGPIdType& key_id,const std::string& text,const std::string& outfile) ;
|
||||
bool decryptTextFromFile(const PGPIdType& key_id,std::string& text,const std::string& inputfile) ;
|
||||
bool decryptTextFromFile(const PGPIdType& key_id,std::string& text,const std::string& encrypted_inputfile) ;
|
||||
//bool encryptTextToString(const PGPIdType& key_id,const std::string& text,std::string& outstring) ;
|
||||
//bool decryptTextFromString(const PGPIdType& key_id,const std::string& encrypted_text,std::string& outstring) ;
|
||||
|
||||
bool getKeyFingerprint(const PGPIdType& id,PGPFingerprintType& fp) const ;
|
||||
void setAcceptConnexion(const PGPIdType&,bool) ;
|
||||
|
@ -70,11 +70,21 @@ bool AuthGPG::removeKeysFromPGPKeyring(const std::list<std::string>& pgp_ids,std
|
||||
return PGPHandler::removeKeysFromPGPKeyring(pids,backup_file,error_code) ;
|
||||
}
|
||||
|
||||
// bool AuthGPG::decryptTextFromString(std::string& encrypted_text,std::string& output)
|
||||
// {
|
||||
// return PGPHandler::decryptTextFromString(mOwnGpgId,encrypted_text,output) ;
|
||||
// }
|
||||
|
||||
bool AuthGPG::encryptTextToFile(const std::string& text,const std::string& outfile)
|
||||
{
|
||||
return PGPHandler::encryptTextToFile(mOwnGpgId,text,outfile) ;
|
||||
}
|
||||
|
||||
// bool AuthGPG::encryptTextToString(const std::string& pgp_id,const std::string& text,std::string& outstr)
|
||||
// {
|
||||
// return PGPHandler::encryptTextToString(PGPIdType(pgp_id),text,outstr) ;
|
||||
// }
|
||||
|
||||
std::string pgp_pwd_callback(void * /*hook*/, const char *uid_hint, const char * /*passphrase_info*/, int prev_was_bad)
|
||||
{
|
||||
#define GPG_DEBUG2
|
||||
@ -640,6 +650,15 @@ bool AuthGPG::TrustCertificate(const std::string &id, int trustlvl)
|
||||
return privateTrustCertificate(id, trustlvl) ;
|
||||
}
|
||||
|
||||
bool AuthGPG::encryptDataBin(const std::string& pgp_id,const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen)
|
||||
{
|
||||
return PGPHandler::encryptDataBin(PGPIdType(pgp_id),data,datalen,sign,signlen) ;
|
||||
}
|
||||
|
||||
bool AuthGPG::decryptDataBin(const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen)
|
||||
{
|
||||
return PGPHandler::decryptDataBin(mOwnGpgId,data,datalen,sign,signlen) ;
|
||||
}
|
||||
bool AuthGPG::SignDataBin(const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen)
|
||||
{
|
||||
return DoOwnSignature(data, datalen, sign, signlen);
|
||||
|
@ -217,9 +217,15 @@ class AuthGPG: public p3Config, public RsThread, public PGPHandler
|
||||
virtual bool SignDataBin(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen);
|
||||
virtual bool VerifySignBin(const void*, uint32_t, unsigned char*, unsigned int, const std::string &withfingerprint);
|
||||
|
||||
virtual bool encryptDataBin(const std::string& pgp_id,const void *data, const uint32_t len, unsigned char *encr, unsigned int *encrlen);
|
||||
virtual bool decryptDataBin(const void *data, const uint32_t len, unsigned char *decr, unsigned int *decrlen);
|
||||
|
||||
virtual bool decryptTextFromFile( std::string& text,const std::string& filename);
|
||||
virtual bool encryptTextToFile (const std::string& text,const std::string& filename);
|
||||
|
||||
// virtual bool decryptTextFromString( std::string& encrypted_text,std::string& clear_string);
|
||||
// virtual bool encryptTextToString (const std::string& pgp_id,const std::string& clear_text,std::string& encrypted_string);
|
||||
|
||||
bool getGPGFilteredList(std::list<std::string>& list,bool (*filter)(const PGPCertificateInfo&) = NULL) ;
|
||||
|
||||
//END of PGP public functions
|
||||
|
@ -58,6 +58,7 @@
|
||||
#define RS_MSG_USER_REQUEST 0x0400 /* user request */
|
||||
#define RS_MSG_FRIEND_RECOMMENDATION 0x0800 /* friend recommendation */
|
||||
#define RS_MSG_SYSTEM (RS_MSG_USER_REQUEST | RS_MSG_FRIEND_RECOMMENDATION)
|
||||
#define RS_MSG_ENCRYPTED 0x1000 /* message is encrypted */
|
||||
|
||||
#define RS_CHAT_LOBBY_EVENT_PEER_LEFT 0x01
|
||||
#define RS_CHAT_LOBBY_EVENT_PEER_STATUS 0x02
|
||||
@ -99,6 +100,7 @@ class MessageInfo
|
||||
std::wstring attach_title;
|
||||
std::wstring attach_comment;
|
||||
std::list<FileInfo> files;
|
||||
std::map<std::string,std::string> encryption_keys ; // for concerned ids only the public pgp key id to encrypt the message with.
|
||||
int size; /* total of files */
|
||||
int count; /* file count */
|
||||
|
||||
@ -144,6 +146,16 @@ public:
|
||||
#define RS_CHAT_PRIVATE 0x0002
|
||||
#define RS_CHAT_AVATAR_AVAILABLE 0x0004
|
||||
|
||||
#define RS_DISTANT_CHAT_STATUS_UNKNOWN 0x0000
|
||||
#define RS_DISTANT_CHAT_STATUS_TUNNEL_DN 0x0001
|
||||
#define RS_DISTANT_CHAT_STATUS_TUNNEL_OK 0x0002
|
||||
#define RS_DISTANT_CHAT_STATUS_CAN_TALK 0x0003
|
||||
|
||||
#define RS_DISTANT_CHAT_ERROR_NO_ERROR 0x0000
|
||||
#define RS_DISTANT_CHAT_ERROR_DECRYPTION_FAILED 0x0001
|
||||
#define RS_DISTANT_CHAT_ERROR_SIGNATURE_MISMATCH 0x0002
|
||||
#define RS_DISTANT_CHAT_ERROR_UNKNOWN_KEY 0x0003
|
||||
|
||||
class ChatInfo
|
||||
{
|
||||
public:
|
||||
@ -195,6 +207,14 @@ class ChatLobbyInfo
|
||||
time_t last_activity ; // last recorded activity. Useful for removing dead lobbies.
|
||||
};
|
||||
|
||||
struct DistantChatInviteInfo
|
||||
{
|
||||
std::string hash ; // hash to contact the invite and refer to it.
|
||||
std::string encrypted_radix64_string ; // encrypted radix string used to for the chat link
|
||||
std::string destination_pgp_id ; // pgp is of the destination of the chat link
|
||||
time_t time_of_validity ; // time when te invite becomes unusable
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const MessageInfo &info);
|
||||
std::ostream &operator<<(std::ostream &out, const ChatInfo &info);
|
||||
|
||||
@ -203,6 +223,14 @@ bool operator==(const ChatInfo&, const ChatInfo&);
|
||||
class RsMsgs;
|
||||
extern RsMsgs *rsMsgs;
|
||||
|
||||
struct DistantOfflineMessengingInvite
|
||||
{
|
||||
std::string issuer_pgp_id ;
|
||||
std::string hash ;
|
||||
time_t time_of_validity ;
|
||||
};
|
||||
|
||||
|
||||
class RsMsgs
|
||||
{
|
||||
public:
|
||||
@ -211,11 +239,13 @@ class RsMsgs
|
||||
virtual ~RsMsgs() { return; }
|
||||
|
||||
/****************************************/
|
||||
/* Message Items */
|
||||
/* Message Items */
|
||||
/****************************************/
|
||||
|
||||
virtual bool getMessageSummaries(std::list<MsgInfoSummary> &msgList) = 0;
|
||||
virtual bool getMessage(const std::string &mId, MessageInfo &msg) = 0;
|
||||
virtual void getMessageCount(unsigned int *pnInbox, unsigned int *pnInboxNew, unsigned int *pnOutbox, unsigned int *pnDraftbox, unsigned int *pnSentbox, unsigned int *pnTrashbox) = 0;
|
||||
virtual bool decryptMessage(const std::string& mId) = 0 ;
|
||||
|
||||
virtual bool MessageSend(MessageInfo &info) = 0;
|
||||
virtual bool SystemMessage(const std::wstring &title, const std::wstring &message, uint32_t systemFlag) = 0;
|
||||
@ -241,8 +271,14 @@ virtual bool setMessageTag(const std::string &msgId, uint32_t tagId, bool set) =
|
||||
|
||||
virtual bool resetMessageStandardTagTypes(MsgTagType& tags) = 0;
|
||||
|
||||
/* private distant messages */
|
||||
|
||||
virtual bool createDistantOfflineMessengingInvite(time_t validity_time_stamp, std::string& hash)=0 ;
|
||||
virtual bool getDistantOfflineMessengingInvites(std::vector<DistantOfflineMessengingInvite>& invites) = 0 ;
|
||||
|
||||
/****************************************/
|
||||
/* Chat */
|
||||
/****************************************/
|
||||
/* Chat */
|
||||
virtual bool sendPublicChat(const std::wstring& msg) = 0;
|
||||
virtual bool sendPrivateChat(const std::string& id, const std::wstring& msg) = 0;
|
||||
virtual int getPublicChatQueueCount() = 0;
|
||||
@ -265,6 +301,10 @@ virtual void getAvatarData(const std::string& pid,unsigned char *& data,int& siz
|
||||
virtual void setOwnAvatarData(const unsigned char *data,int size) = 0 ;
|
||||
virtual void getOwnAvatarData(unsigned char *& data,int& size) = 0 ;
|
||||
|
||||
/****************************************/
|
||||
/* Chat lobbies */
|
||||
/****************************************/
|
||||
|
||||
virtual bool joinVisibleChatLobby(const ChatLobbyId& lobby_id) = 0 ;
|
||||
virtual bool isLobbyId(const std::string& virtual_peer_id,ChatLobbyId& lobby_id) = 0;
|
||||
virtual bool getVirtualPeerId(const ChatLobbyId& lobby_id,std::string& vpid) = 0;
|
||||
@ -282,6 +322,13 @@ virtual bool getDefaultNickNameForChatLobby(std::string& nick) = 0 ;
|
||||
virtual ChatLobbyId createChatLobby(const std::string& lobby_name,const std::string& lobby_topic,const std::list<std::string>& invited_friends,uint32_t lobby_privacy_type) = 0 ;
|
||||
|
||||
/****************************************/
|
||||
/* Distant chat */
|
||||
/****************************************/
|
||||
|
||||
virtual bool createDistantChatInvite(const std::string& pgp_id,time_t time_of_validity,std::string& encrypted_string) = 0 ;
|
||||
virtual bool getDistantChatInviteList(std::vector<DistantChatInviteInfo>& invites) = 0;
|
||||
virtual bool initiateDistantChatConnexion(const std::string& encrypted_string,std::string& hash,uint32_t& error_code) = 0;
|
||||
virtual bool getDistantChatStatus(const std::string& hash,uint32_t& status,std::string& pgp_id) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <vector>
|
||||
|
||||
class LinearizedExpression ;
|
||||
class RsTurtleClientService ;
|
||||
|
||||
class RsTurtle;
|
||||
extern RsTurtle *rsTurtle ;
|
||||
@ -83,8 +84,6 @@ class TurtleTrafficStatisticsInfo
|
||||
class RsTurtle
|
||||
{
|
||||
public:
|
||||
enum FileSharingStrategy { SHARE_ENTIRE_NETWORK, SHARE_FRIENDS_ONLY } ;
|
||||
|
||||
RsTurtle() {}
|
||||
virtual ~RsTurtle() {}
|
||||
|
||||
@ -103,23 +102,27 @@ class RsTurtle
|
||||
virtual TurtleRequestId turtleSearch(const std::string& match_string) = 0 ;
|
||||
virtual TurtleRequestId turtleSearch(const LinearizedExpression& expr) = 0 ;
|
||||
|
||||
// Sets the file sharing strategy. It concerns all local files. It would
|
||||
// be better to handle this for each file, of course.
|
||||
|
||||
void setFileSharingStrategy(FileSharingStrategy f) { _sharing_strategy = f ; }
|
||||
|
||||
// Initiates tunnel handling for the given file hash. tunnels. Launches
|
||||
// an exception if an error occurs during the initialization process. The
|
||||
// turtle router itself does not initiate downloads, it only maintains
|
||||
// tunnels for the given hash. The download should be driven by the file
|
||||
// transfer module by calling ftServer::FileRequest().
|
||||
//
|
||||
virtual void monitorFileTunnels(const std::string& name,const std::string& file_hash,uint64_t size) = 0 ;
|
||||
virtual void monitorTunnels(const std::string& file_hash,RsTurtleClientService *client_service) = 0 ;
|
||||
|
||||
// Tells the turtle router to stop handling tunnels for the given file hash. Traditionally this should
|
||||
// be called after calling ftServer::fileCancel().
|
||||
//
|
||||
virtual void stopMonitoringFileTunnels(const std::string& file_hash) = 0 ;
|
||||
virtual void stopMonitoringTunnels(const std::string& file_hash) = 0 ;
|
||||
|
||||
/// Adds a client tunnel service. This means that the service will be added
|
||||
/// to the list of services that might respond to tunnel requests.
|
||||
/// Example tunnel services include:
|
||||
///
|
||||
/// p3ChatService: tunnels correspond to private distant chatting
|
||||
/// ftServer : tunnels correspond to file data transfer
|
||||
///
|
||||
virtual void registerTunnelService(RsTurtleClientService *service) = 0;
|
||||
|
||||
// Get info from the turtle router. I use std strings to hide the internal structs.
|
||||
//
|
||||
@ -136,8 +139,6 @@ class RsTurtle
|
||||
// Hardcore handles
|
||||
virtual void setMaxTRForwardRate(int max_tr_up_rate) = 0 ;
|
||||
virtual int getMaxTRForwardRate() const = 0 ;
|
||||
protected:
|
||||
FileSharingStrategy _sharing_strategy ;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -96,6 +96,20 @@ bool p3Msgs::MessageSend(MessageInfo &info)
|
||||
return mMsgSrv->MessageSend(info);
|
||||
}
|
||||
|
||||
bool p3Msgs::decryptMessage(const std::string& mId)
|
||||
{
|
||||
return mMsgSrv->decryptMessage(mId);
|
||||
}
|
||||
bool p3Msgs::createDistantOfflineMessengingInvite(time_t ts, std::string& hash)
|
||||
{
|
||||
return mMsgSrv->createDistantOfflineMessengingInvite(ts,hash) ;
|
||||
}
|
||||
bool p3Msgs::getDistantOfflineMessengingInvites(std::vector<DistantOfflineMessengingInvite>& invites)
|
||||
{
|
||||
return mMsgSrv->getDistantOfflineMessengingInvites(invites);
|
||||
}
|
||||
|
||||
|
||||
bool p3Msgs::SystemMessage(const std::wstring &title, const std::wstring &message, uint32_t systemFlag)
|
||||
{
|
||||
return mMsgSrv->SystemMessage(title, message, systemFlag);
|
||||
@ -330,5 +344,20 @@ void p3Msgs::getPendingChatLobbyInvites(std::list<ChatLobbyInvite>& invites)
|
||||
{
|
||||
mChatSrv->getPendingChatLobbyInvites(invites) ;
|
||||
}
|
||||
|
||||
bool p3Msgs::createDistantChatInvite(const std::string& pgp_id,time_t time_of_validity,std::string& encrypted_string)
|
||||
{
|
||||
return mChatSrv->createDistantChatInvite(pgp_id,time_of_validity,encrypted_string) ;
|
||||
}
|
||||
bool p3Msgs::getDistantChatInviteList(std::vector<DistantChatInviteInfo>& invites)
|
||||
{
|
||||
return mChatSrv->getDistantChatInviteList(invites) ;
|
||||
}
|
||||
bool p3Msgs::initiateDistantChatConnexion(const std::string& encrypted_str,std::string& hash,uint32_t& error_code)
|
||||
{
|
||||
return mChatSrv->initiateDistantChatConnexion(encrypted_str,hash,error_code) ;
|
||||
}
|
||||
bool p3Msgs::getDistantChatStatus(const std::string& hash,uint32_t& status,std::string& pgp_id)
|
||||
{
|
||||
return mChatSrv->getDistantChatStatus(hash,status,pgp_id) ;
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,7 @@ class p3Msgs: public RsMsgs
|
||||
virtual void getMessageCount(unsigned int *pnInbox, unsigned int *pnInboxNew, unsigned int *pnOutbox, unsigned int *pnDraftbox, unsigned int *pnSentbox, unsigned int *pnTrashbox);
|
||||
|
||||
virtual bool MessageSend(MessageInfo &info);
|
||||
virtual bool decryptMessage(const std::string& mid);
|
||||
virtual bool SystemMessage(const std::wstring &title, const std::wstring &message, uint32_t systemFlag);
|
||||
virtual bool MessageToDraft(MessageInfo &info, const std::string &msgParentId);
|
||||
virtual bool MessageToTrash(const std::string &mid, bool bTrash);
|
||||
@ -78,6 +79,9 @@ class p3Msgs: public RsMsgs
|
||||
|
||||
virtual bool resetMessageStandardTagTypes(MsgTagType& tags);
|
||||
|
||||
virtual bool createDistantOfflineMessengingInvite(time_t, std::string&) ;
|
||||
virtual bool getDistantOfflineMessengingInvites(std::vector<DistantOfflineMessengingInvite>&);
|
||||
|
||||
/*!
|
||||
* gets avatar from peer, image data in jpeg format
|
||||
*/
|
||||
@ -183,6 +187,11 @@ class p3Msgs: public RsMsgs
|
||||
virtual bool getDefaultNickNameForChatLobby(std::string& nick) ;
|
||||
virtual ChatLobbyId createChatLobby(const std::string& lobby_name,const std::string& lobby_topic,const std::list<std::string>& invited_friends,uint32_t privacy_type) ;
|
||||
|
||||
virtual bool createDistantChatInvite(const std::string& pgp_id,time_t time_of_validity,std::string& encrypted_string) ;
|
||||
virtual bool getDistantChatInviteList(std::vector<DistantChatInviteInfo>& invites);
|
||||
virtual bool initiateDistantChatConnexion(const std::string& encrypted_string,std::string& hash,uint32_t& error_code) ;
|
||||
virtual bool getDistantChatStatus(const std::string& hash,uint32_t& status,std::string& pgp_id) ;
|
||||
|
||||
private:
|
||||
|
||||
p3MsgService *mMsgSrv;
|
||||
|
@ -2230,10 +2230,13 @@ int RsServer::StartupRetroShare()
|
||||
mConnMgr->setP3tunnel(tn);
|
||||
#endif
|
||||
|
||||
p3turtle *tr = new p3turtle(mLinkMgr,ftserver) ;
|
||||
p3turtle *tr = new p3turtle(mLinkMgr) ;
|
||||
rsTurtle = tr ;
|
||||
pqih -> addService(tr);
|
||||
|
||||
ftserver->connectToTurtleRouter(tr) ;
|
||||
chatSrv->connectToTurtleRouter(tr) ;
|
||||
msgSrv->connectToTurtleRouter(tr) ;
|
||||
|
||||
pqih -> addService(ad);
|
||||
pqih -> addService(msgSrv);
|
||||
|
@ -23,6 +23,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// This file centralises QoS priorities for all transfer RsItems.
|
||||
//
|
||||
const uint8_t QOS_PRIORITY_UNKNOWN = 0 ;
|
||||
@ -45,6 +49,7 @@ const uint8_t QOS_PRIORITY_RS_TURTLE_CHUNK_CRC = 5 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_FILE_MAP = 3 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_GENERIC_ITEM = 3 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_FORWARD_FILE_DATA= 3 ;
|
||||
const uint8_t QOS_PRIORITY_RS_TURTLE_GENERIC_DATA = 5 ;
|
||||
|
||||
// File transfer
|
||||
//
|
||||
|
@ -188,6 +188,30 @@ std::ostream& RsPrivateChatMsgConfigItem::print(std::ostream &out, uint16_t inde
|
||||
printRsItemEnd(out, "RsPrivateChatMsgConfigItem", indent);
|
||||
return out;
|
||||
}
|
||||
std::ostream& RsPrivateChatDistantInviteConfigItem::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printRsItemBase(out, "RsPrivateChatDistantInviteConfigItem", indent);
|
||||
uint16_t int_Indent = indent + 2;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "radix string: " << encrypted_radix64_string << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "hash: " << hash << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "destination pgp_id: " << destination_pgp_id << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "time of validity: " << time_of_validity << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "time of last hit: " << last_hit_time << std::endl;
|
||||
|
||||
printRsItemEnd(out, "RsPrivateChatDistantInviteConfigItem", indent);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& RsChatStatusItem::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
@ -195,7 +219,7 @@ std::ostream& RsChatStatusItem::print(std::ostream &out, uint16_t indent)
|
||||
uint16_t int_Indent = indent + 2;
|
||||
printIndent(out, int_Indent);
|
||||
out << "Status string: " << status_string << std::endl;
|
||||
out << "Flags : " << (void*)flags << std::endl;
|
||||
out << "Flags : " << std::hex << flags << std::dec << std::endl;
|
||||
|
||||
printRsItemEnd(out, "RsChatStatusItem", indent);
|
||||
return out;
|
||||
@ -245,6 +269,7 @@ RsItem *RsChatSerialiser::deserialise(void *data, uint32_t *pktsize)
|
||||
{
|
||||
case RS_PKT_SUBTYPE_DEFAULT: return new RsChatMsgItem(data,*pktsize) ;
|
||||
case RS_PKT_SUBTYPE_PRIVATECHATMSG_CONFIG: return new RsPrivateChatMsgConfigItem(data,*pktsize) ;
|
||||
case RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG: return new RsPrivateChatDistantInviteConfigItem(data,*pktsize) ;
|
||||
case RS_PKT_SUBTYPE_CHAT_STATUS: return new RsChatStatusItem(data,*pktsize) ;
|
||||
case RS_PKT_SUBTYPE_CHAT_AVATAR: return new RsChatAvatarItem(data,*pktsize) ;
|
||||
case RS_PKT_SUBTYPE_CHAT_LOBBY_MSG: return new RsChatLobbyMsgItem(data,*pktsize) ;
|
||||
@ -387,7 +412,18 @@ uint32_t RsPrivateChatMsgConfigItem::serial_size()
|
||||
|
||||
return s;
|
||||
}
|
||||
uint32_t RsPrivateChatDistantInviteConfigItem::serial_size()
|
||||
{
|
||||
uint32_t s = 8; /* header */
|
||||
s += GetTlvStringSize(hash);
|
||||
s += GetTlvStringSize(encrypted_radix64_string);
|
||||
s += GetTlvStringSize(destination_pgp_id);
|
||||
s += 16; /* aes_key */
|
||||
s += 4; /* time_of_validity */
|
||||
s += 4; /* last_hit_time */
|
||||
|
||||
return s;
|
||||
}
|
||||
uint32_t RsChatStatusItem::serial_size()
|
||||
{
|
||||
uint32_t s = 8; /* header */
|
||||
@ -780,7 +816,49 @@ bool RsPrivateChatMsgConfigItem::serialise(void *data, uint32_t& pktsize)
|
||||
|
||||
return ok;
|
||||
}
|
||||
bool RsPrivateChatDistantInviteConfigItem::serialise(void *data, uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size() ;
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data, tlvsize, PacketId(), tlvsize);
|
||||
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "RsChatSerialiser::serialiseItem() Header: " << ok << std::endl;
|
||||
std::cerr << "RsChatSerialiser::serialiseItem() Size: " << tlvsize << std::endl;
|
||||
#endif
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_KEY, hash);
|
||||
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_LINK, encrypted_radix64_string);
|
||||
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_GPGID, destination_pgp_id);
|
||||
|
||||
memcpy(&((unsigned char *)data)[offset],aes_key,16) ;
|
||||
offset += 16 ;
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, time_of_validity);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, last_hit_time);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "RsChatSerialiser::serialiseItem() Size Error! " << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
bool RsChatStatusItem::serialise(void *data, uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size() ;
|
||||
@ -1122,6 +1200,32 @@ RsPrivateChatMsgConfigItem::RsPrivateChatMsgConfigItem(void *data,uint32_t /*siz
|
||||
ok &= GetTlvWideString(data, rssize, &offset, TLV_TYPE_WSTR_MSG, message);
|
||||
ok &= getRawUInt32(data, rssize, &offset, &recvTime);
|
||||
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "Building new chat msg config item." << std::endl ;
|
||||
#endif
|
||||
if (offset != rssize)
|
||||
std::cerr << "Size error while deserializing." << std::endl ;
|
||||
if (!ok)
|
||||
std::cerr << "Unknown error while deserializing." << std::endl ;
|
||||
}
|
||||
RsPrivateChatDistantInviteConfigItem::RsPrivateChatDistantInviteConfigItem(void *data,uint32_t /*size*/)
|
||||
: RsChatItem(RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG)
|
||||
{
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
bool ok = true ;
|
||||
|
||||
/* get mandatory parts first */
|
||||
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_KEY, hash);
|
||||
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_LINK, encrypted_radix64_string);
|
||||
ok &= GetTlvString(data, rssize, &offset, TLV_TYPE_STR_GPGID, destination_pgp_id);
|
||||
|
||||
memcpy(aes_key,&((unsigned char*)data)[offset],16) ;
|
||||
offset += 16 ;
|
||||
|
||||
ok &= getRawUInt32(data, rssize, &offset, &time_of_validity);
|
||||
ok &= getRawUInt32(data, rssize, &offset, &last_hit_time);
|
||||
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "Building new chat msg config item." << std::endl ;
|
||||
#endif
|
||||
@ -1278,6 +1382,26 @@ void RsMsgTagType::clear()
|
||||
}
|
||||
|
||||
|
||||
void RsPublicMsgInviteConfigItem::clear()
|
||||
{
|
||||
hash.clear() ;
|
||||
time_stamp = 0 ;
|
||||
}
|
||||
std::ostream& RsPublicMsgInviteConfigItem::print(std::ostream &out, uint16_t indent)
|
||||
{
|
||||
printRsItemBase(out, "RsPublicMsgInviteConfigItem", indent);
|
||||
uint16_t int_Indent = indent + 2;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "hash : " << hash << std::endl;
|
||||
|
||||
printIndent(out, int_Indent);
|
||||
out << "timt : " << time_stamp << std::endl;
|
||||
|
||||
printRsItemEnd(out, "RsPublicMsgInviteConfigItem", indent);
|
||||
|
||||
return out;
|
||||
}
|
||||
void RsMsgTags::clear()
|
||||
{
|
||||
msgId = 0;
|
||||
@ -1476,7 +1600,15 @@ RsMsgItem *RsMsgSerialiser::deserialiseMsgItem(void *data, uint32_t *pktsize)
|
||||
|
||||
return item;
|
||||
}
|
||||
uint32_t RsMsgSerialiser::sizePublicMsgInviteConfigItem(RsPublicMsgInviteConfigItem* item)
|
||||
{
|
||||
uint32_t s = 8; /* header */
|
||||
|
||||
s += GetTlvStringSize(item->hash);
|
||||
s += 4; /* time_stamp */
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
uint32_t RsMsgSerialiser::sizeTagItem(RsMsgTagType* item)
|
||||
{
|
||||
@ -1489,6 +1621,44 @@ uint32_t RsMsgSerialiser::sizeTagItem(RsMsgTagType* item)
|
||||
return s;
|
||||
}
|
||||
|
||||
bool RsMsgSerialiser::serialisePublicMsgInviteConfigItem(RsPublicMsgInviteConfigItem *item, void *data, uint32_t* pktsize)
|
||||
{
|
||||
uint32_t tlvsize = sizePublicMsgInviteConfigItem(item);
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (*pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
*pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
|
||||
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsMsgSerialiser::serialiseMsgTagItem() Header: " << ok << std::endl;
|
||||
std::cerr << "RsMsgSerialiser::serialiseMsgTagItem() Size: " << tlvsize << std::endl;
|
||||
#endif
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= SetTlvString(data,tlvsize,&offset, TLV_TYPE_STR_HASH_SHA1, item->hash);
|
||||
ok &= setRawUInt32(data,tlvsize,&offset, item->time_stamp);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsMsgSerialiser::serialiseMsgTagItem() Size Error! " << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
bool RsMsgSerialiser::serialiseTagItem(RsMsgTagType *item, void *data, uint32_t* pktsize)
|
||||
{
|
||||
@ -1528,6 +1698,59 @@ bool RsMsgSerialiser::serialiseTagItem(RsMsgTagType *item, void *data, uint32_t*
|
||||
|
||||
return ok;
|
||||
}
|
||||
RsPublicMsgInviteConfigItem* RsMsgSerialiser::deserialisePublicMsgInviteConfigItem(void *data,uint32_t* pktsize)
|
||||
{
|
||||
/* get the type and size */
|
||||
uint32_t rstype = getRsItemId(data);
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
|
||||
uint32_t offset = 0;
|
||||
|
||||
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
|
||||
(RS_SERVICE_TYPE_MSG != getRsItemService(rstype)) ||
|
||||
(RS_PKT_SUBTYPE_MSG_INVITE != getRsItemSubType(rstype)))
|
||||
{
|
||||
return NULL; /* wrong type */
|
||||
}
|
||||
|
||||
if (*pktsize < rssize) /* check size */
|
||||
return NULL; /* not enough data */
|
||||
|
||||
/* set the packet length */
|
||||
*pktsize = rssize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
/* ready to load */
|
||||
RsPublicMsgInviteConfigItem *item = new RsPublicMsgInviteConfigItem();
|
||||
item->clear();
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* get mandatory parts first */
|
||||
ok &= GetTlvString(data,rssize,&offset,TLV_TYPE_STR_HASH_SHA1,item->hash);
|
||||
|
||||
uint32_t ts ;
|
||||
ok &= getRawUInt32(data, rssize, &offset, &ts) ;
|
||||
item->time_stamp = ts ;
|
||||
|
||||
if (offset != rssize)
|
||||
{
|
||||
/* error */
|
||||
delete item;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
delete item;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
RsMsgTagType* RsMsgSerialiser::deserialiseTagItem(void *data,uint32_t* pktsize)
|
||||
{
|
||||
@ -2006,7 +2229,7 @@ bool RsMsgSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize)
|
||||
RsMsgParentId* msp;
|
||||
RsMsgTagType *mtt;
|
||||
RsMsgTags *mts;
|
||||
|
||||
RsPublicMsgInviteConfigItem *mtu;
|
||||
|
||||
if (NULL != (mi = dynamic_cast<RsMsgItem *>(i)))
|
||||
{
|
||||
@ -2028,6 +2251,10 @@ bool RsMsgSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize)
|
||||
{
|
||||
return serialiseMsgTagItem(mts, data, pktsize);
|
||||
}
|
||||
else if (NULL != (mtu = dynamic_cast<RsPublicMsgInviteConfigItem *>(i)))
|
||||
{
|
||||
return serialisePublicMsgInviteConfigItem(mtu, data, pktsize);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@ -2061,6 +2288,9 @@ RsItem* RsMsgSerialiser::deserialise(void *data, uint32_t *pktsize)
|
||||
case RS_PKT_SUBTYPE_MSG_TAG_TYPE:
|
||||
return deserialiseTagItem(data, pktsize);
|
||||
break;
|
||||
case RS_PKT_SUBTYPE_MSG_INVITE:
|
||||
return deserialisePublicMsgInviteConfigItem(data, pktsize);
|
||||
break;
|
||||
case RS_PKT_SUBTYPE_MSG_TAGS:
|
||||
return deserialiseMsgTagItem(data, pktsize);
|
||||
break;
|
||||
|
@ -64,12 +64,14 @@ const uint8_t RS_PKT_SUBTYPE_CHAT_LOBBY_INVITE = 0x0F ;
|
||||
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 = 0x12 ;
|
||||
const uint8_t RS_PKT_SUBTYPE_DISTANT_INVITE_CONFIG = 0x13 ;
|
||||
|
||||
// for defining tags themselves and msg tags
|
||||
const uint8_t RS_PKT_SUBTYPE_MSG_TAG_TYPE = 0x03;
|
||||
const uint8_t RS_PKT_SUBTYPE_MSG_TAGS = 0x04;
|
||||
const uint8_t RS_PKT_SUBTYPE_MSG_SRC_TAG = 0x05;
|
||||
const uint8_t RS_PKT_SUBTYPE_MSG_PARENT_TAG = 0x06;
|
||||
const uint8_t RS_PKT_SUBTYPE_MSG_INVITE = 0x07;
|
||||
|
||||
typedef uint64_t ChatLobbyId ;
|
||||
typedef uint64_t ChatLobbyMsgId ;
|
||||
@ -314,6 +316,27 @@ class RsPrivateChatMsgConfigItem: public RsChatItem
|
||||
std::wstring 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] ;
|
||||
std::string hash ;
|
||||
std::string encrypted_radix64_string ;
|
||||
std::string destination_pgp_id ;
|
||||
uint32_t time_of_validity ;
|
||||
uint32_t last_hit_time ;
|
||||
};
|
||||
|
||||
|
||||
// This class contains activity info for the sending peer: active, idle, typing, etc.
|
||||
//
|
||||
@ -384,6 +407,9 @@ const uint32_t RS_MSG_FLAGS_PARTIAL = 0x0400;
|
||||
const uint32_t RS_MSG_FLAGS_USER_REQUEST = 0x0800;
|
||||
const uint32_t RS_MSG_FLAGS_FRIEND_RECOMMENDATION = 0x1000;
|
||||
const uint32_t RS_MSG_FLAGS_SYSTEM = RS_MSG_FLAGS_USER_REQUEST | RS_MSG_FLAGS_FRIEND_RECOMMENDATION;
|
||||
const uint32_t RS_MSG_FLAGS_RETURN_RECEPT = 0x2000;
|
||||
const uint32_t RS_MSG_FLAGS_ENCRYPTED = 0x4000;
|
||||
const uint32_t RS_MSG_FLAGS_DISTANT = 0x8000;
|
||||
|
||||
class RsMsgItem: public RsItem
|
||||
{
|
||||
@ -474,6 +500,24 @@ public:
|
||||
std::string srcId;
|
||||
|
||||
};
|
||||
class RsPublicMsgInviteConfigItem : public RsItem
|
||||
{
|
||||
|
||||
public:
|
||||
RsPublicMsgInviteConfigItem()
|
||||
: RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_MSG,
|
||||
RS_PKT_SUBTYPE_MSG_INVITE)
|
||||
{ return;}
|
||||
|
||||
std::ostream &print(std::ostream &out, uint16_t indent = 0);
|
||||
|
||||
virtual ~RsPublicMsgInviteConfigItem() {}
|
||||
virtual void clear();
|
||||
|
||||
std::string hash ;
|
||||
time_t time_stamp ;
|
||||
};
|
||||
|
||||
|
||||
class RsMsgParentId : public RsItem
|
||||
{
|
||||
@ -498,45 +542,48 @@ public:
|
||||
class RsMsgSerialiser: public RsSerialType
|
||||
{
|
||||
public:
|
||||
RsMsgSerialiser(bool bConfiguration = false)
|
||||
:RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_MSG), m_bConfiguration (bConfiguration)
|
||||
{ return; }
|
||||
|
||||
RsMsgSerialiser(uint16_t type)
|
||||
:RsSerialType(RS_PKT_VERSION_SERVICE, type), m_bConfiguration (false)
|
||||
{ return; }
|
||||
|
||||
virtual ~RsMsgSerialiser() { return; }
|
||||
|
||||
virtual uint32_t size(RsItem *);
|
||||
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
|
||||
virtual RsItem * deserialise(void *data, uint32_t *size);
|
||||
RsMsgSerialiser(bool bConfiguration = false)
|
||||
:RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_MSG), m_bConfiguration (bConfiguration)
|
||||
{ return; }
|
||||
|
||||
RsMsgSerialiser(uint16_t type)
|
||||
:RsSerialType(RS_PKT_VERSION_SERVICE, type), m_bConfiguration (false)
|
||||
{ return; }
|
||||
|
||||
virtual ~RsMsgSerialiser() { return; }
|
||||
|
||||
virtual uint32_t size(RsItem *);
|
||||
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
|
||||
virtual RsItem * deserialise(void *data, uint32_t *size);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
virtual uint32_t sizeMsgItem(RsMsgItem *);
|
||||
virtual bool serialiseMsgItem (RsMsgItem *item, void *data, uint32_t *size);
|
||||
virtual RsMsgItem *deserialiseMsgItem(void *data, uint32_t *size);
|
||||
virtual uint32_t sizeMsgItem(RsMsgItem *);
|
||||
virtual bool serialiseMsgItem (RsMsgItem *item, void *data, uint32_t *size);
|
||||
virtual RsMsgItem *deserialiseMsgItem(void *data, uint32_t *size);
|
||||
|
||||
virtual uint32_t sizeTagItem(RsMsgTagType *);
|
||||
virtual bool serialiseTagItem (RsMsgTagType *item, void *data, uint32_t *size);
|
||||
virtual RsMsgTagType *deserialiseTagItem(void *data, uint32_t *size);
|
||||
virtual uint32_t sizeTagItem(RsMsgTagType *);
|
||||
virtual bool serialiseTagItem (RsMsgTagType *item, void *data, uint32_t *size);
|
||||
virtual RsMsgTagType *deserialiseTagItem(void *data, uint32_t *size);
|
||||
|
||||
virtual uint32_t sizeMsgTagItem(RsMsgTags *);
|
||||
virtual bool serialiseMsgTagItem (RsMsgTags *item, void *data, uint32_t *size);
|
||||
virtual RsMsgTags *deserialiseMsgTagItem(void *data, uint32_t *size);
|
||||
virtual uint32_t sizeMsgTagItem(RsMsgTags *);
|
||||
virtual bool serialiseMsgTagItem (RsMsgTags *item, void *data, uint32_t *size);
|
||||
virtual RsMsgTags *deserialiseMsgTagItem(void *data, uint32_t *size);
|
||||
|
||||
virtual uint32_t sizeMsgSrcIdItem(RsMsgSrcId *);
|
||||
virtual bool serialiseMsgSrcIdItem (RsMsgSrcId *item, void *data, uint32_t *size);
|
||||
virtual RsMsgSrcId *deserialiseMsgSrcIdItem(void *data, uint32_t *size);
|
||||
virtual uint32_t sizeMsgSrcIdItem(RsMsgSrcId *);
|
||||
virtual bool serialiseMsgSrcIdItem (RsMsgSrcId *item, void *data, uint32_t *size);
|
||||
virtual RsMsgSrcId *deserialiseMsgSrcIdItem(void *data, uint32_t *size);
|
||||
|
||||
virtual uint32_t sizeMsgParentIdItem(RsMsgParentId *);
|
||||
virtual bool serialiseMsgParentIdItem (RsMsgParentId *item, void *data, uint32_t *size);
|
||||
virtual RsMsgParentId *deserialiseMsgParentIdItem(void *data, uint32_t *size);
|
||||
virtual uint32_t sizeMsgParentIdItem(RsMsgParentId *);
|
||||
virtual bool serialiseMsgParentIdItem (RsMsgParentId *item, void *data, uint32_t *size);
|
||||
virtual RsMsgParentId *deserialiseMsgParentIdItem(void *data, uint32_t *size);
|
||||
|
||||
virtual uint32_t sizePublicMsgInviteConfigItem(RsPublicMsgInviteConfigItem *) ;
|
||||
virtual bool serialisePublicMsgInviteConfigItem(RsPublicMsgInviteConfigItem *item, void *data, uint32_t *size);
|
||||
virtual RsPublicMsgInviteConfigItem *deserialisePublicMsgInviteConfigItem(void *data, uint32_t *size);
|
||||
|
||||
bool m_bConfiguration; // is set to true for saving configuration (enables serialising msgId)
|
||||
bool m_bConfiguration; // is set to true for saving configuration (enables serialising msgId)
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
|
@ -24,11 +24,18 @@
|
||||
*/
|
||||
#include <math.h>
|
||||
|
||||
#include "openssl/rand.h"
|
||||
#include "pgp/rscertificate.h"
|
||||
#include "pqi/authgpg.h"
|
||||
#include "util/rsdir.h"
|
||||
#include "util/radix64.h"
|
||||
#include "util/rsaes.h"
|
||||
#include "util/rsrandom.h"
|
||||
#include "util/rsstring.h"
|
||||
#include "turtle/p3turtle.h"
|
||||
#include "retroshare/rsiface.h"
|
||||
#include "retroshare/rspeers.h"
|
||||
#include "retroshare/rsstatus.h"
|
||||
#include "pqi/pqibin.h"
|
||||
#include "pqi/pqinotify.h"
|
||||
#include "pqi/pqistore.h"
|
||||
@ -40,6 +47,7 @@
|
||||
|
||||
/****
|
||||
* #define CHAT_DEBUG 1
|
||||
* #define DEBUG_DISTANT_CHAT 1
|
||||
****/
|
||||
|
||||
static const int CONNECTION_CHALLENGE_MAX_COUNT = 20 ; // sends a connexion challenge every 20 messages
|
||||
@ -52,18 +60,30 @@ static const time_t MAX_DELAY_BETWEEN_LOBBY_KEEP_ALIVE = 120 ; // send keep al
|
||||
static const time_t MAX_KEEP_PUBLIC_LOBBY_RECORD = 60 ; // keep inactive lobbies records for 60 secs max.
|
||||
static const time_t MIN_DELAY_BETWEEN_PUBLIC_LOBBY_REQ = 20 ; // don't ask for lobby list more than once every 30 secs.
|
||||
|
||||
static const time_t DISTANT_CHAT_CLEANING_PERIOD = 60 ; // don't ask for lobby list more than once every 30 secs.
|
||||
static const uint32_t DISTANT_CHAT_AES_KEY_SIZE = 16 ; // size of AES encryption key for distant chat.
|
||||
static const uint32_t DISTANT_CHAT_HASH_SIZE = 20 ; // This is sha1 size in bytes.
|
||||
|
||||
p3ChatService::p3ChatService(p3LinkMgr *lm, p3HistoryMgr *historyMgr)
|
||||
:p3Service(RS_SERVICE_TYPE_CHAT), p3Config(CONFIG_TYPE_CHAT), mChatMtx("p3ChatService"), mLinkMgr(lm) , mHistoryMgr(historyMgr)
|
||||
{
|
||||
addSerialType(new RsChatSerialiser());
|
||||
|
||||
_serializer = new RsChatSerialiser() ;
|
||||
_own_avatar = NULL ;
|
||||
_custom_status_string = "" ;
|
||||
_time_shift_average = 0.0f ;
|
||||
_default_nick_name = rsPeers->getPeerName(rsPeers->getOwnId());
|
||||
_should_reset_lobby_counts = false ;
|
||||
mTurtle = NULL ;
|
||||
|
||||
last_visible_lobby_info_request_time = 0 ;
|
||||
|
||||
addSerialType(_serializer) ;
|
||||
}
|
||||
|
||||
void p3ChatService::connectToTurtleRouter(p3turtle *tr)
|
||||
{
|
||||
mTurtle = tr ;
|
||||
tr->registerTunnelService(this) ;
|
||||
}
|
||||
|
||||
int p3ChatService::tick()
|
||||
@ -71,15 +91,21 @@ int p3ChatService::tick()
|
||||
if(receivedItems())
|
||||
receiveChatQueue();
|
||||
|
||||
static time_t last_clean_time = 0 ;
|
||||
static time_t last_clean_time_lobby = 0 ;
|
||||
static time_t last_clean_time_dchat = 0 ;
|
||||
|
||||
time_t now = time(NULL) ;
|
||||
|
||||
if(last_clean_time + LOBBY_CACHE_CLEANING_PERIOD < now)
|
||||
if(last_clean_time_lobby + LOBBY_CACHE_CLEANING_PERIOD < now)
|
||||
{
|
||||
cleanLobbyCaches() ;
|
||||
last_clean_time = now ;
|
||||
last_clean_time_lobby = now ;
|
||||
}
|
||||
if(last_clean_time_dchat + DISTANT_CHAT_CLEANING_PERIOD < now)
|
||||
{
|
||||
cleanDistantChatInvites() ;
|
||||
last_clean_time_dchat = now ;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -221,10 +247,27 @@ void p3ChatService::sendStatusString( const std::string& id , const std::string&
|
||||
std::cerr << "sending chat status packet:" << std::endl ;
|
||||
cs->print(std::cerr) ;
|
||||
#endif
|
||||
sendItem(cs);
|
||||
sendPrivateChatItem(cs);
|
||||
}
|
||||
}
|
||||
|
||||
void p3ChatService::sendPrivateChatItem(RsChatItem *item)
|
||||
{
|
||||
bool found = false ;
|
||||
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
if(_distant_chat_peers.find(item->PeerId()) != _distant_chat_peers.end())
|
||||
found = true ;
|
||||
}
|
||||
|
||||
if(found)
|
||||
sendTurtleData(item) ;
|
||||
else
|
||||
sendItem(item) ;
|
||||
}
|
||||
|
||||
void p3ChatService::checkSizeAndSendMessage_deprecated(RsChatMsgItem *msg)
|
||||
{
|
||||
// We check the message item, and possibly split it into multiple messages, if the message is too big.
|
||||
@ -248,9 +291,9 @@ void p3ChatService::checkSizeAndSendMessage_deprecated(RsChatMsgItem *msg)
|
||||
// Indicate that the message is to be continued.
|
||||
//
|
||||
item->chatFlags |= RS_CHAT_FLAG_PARTIAL_MESSAGE ;
|
||||
sendItem(item) ;
|
||||
sendPrivateChatItem(item) ;
|
||||
}
|
||||
sendItem(msg) ;
|
||||
sendPrivateChatItem(msg) ;
|
||||
}
|
||||
// This function should be used for all types of chat messages. But this requires a non backward compatible change in
|
||||
// chat protocol. To be done for version 0.6
|
||||
@ -374,6 +417,18 @@ bool p3ChatService::isLobbyId(const std::string& id,ChatLobbyId& lobby_id)
|
||||
return false ;
|
||||
}
|
||||
|
||||
bool p3ChatService::isOnline(const std::string& id)
|
||||
{
|
||||
// check if the id is a tunnel id or a peer id.
|
||||
|
||||
uint32_t status ;
|
||||
std::string pgp_id ;
|
||||
|
||||
if(!getDistantChatStatus(id,status,pgp_id))
|
||||
return mLinkMgr->isOnline(id) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool p3ChatService::sendPrivateChat(const std::string &id, const std::wstring &msg)
|
||||
{
|
||||
@ -398,7 +453,8 @@ bool p3ChatService::sendPrivateChat(const std::string &id, const std::wstrin
|
||||
ci->recvTime = ci->sendTime;
|
||||
ci->message = msg;
|
||||
|
||||
if (!mLinkMgr->isOnline(id)) {
|
||||
if(!isOnline(id))
|
||||
{
|
||||
/* peer is offline, add to outgoing list */
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
@ -471,7 +527,7 @@ bool p3ChatService::sendPrivateChat(const std::string &id, const std::wstrin
|
||||
#endif
|
||||
RsChatStatusItem *cs = makeOwnCustomStateStringItem() ;
|
||||
cs->PeerId(id) ;
|
||||
sendItem(cs) ;
|
||||
sendPrivateChatItem(cs) ;
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -608,20 +664,24 @@ void p3ChatService::receiveChatQueue()
|
||||
RsItem *item ;
|
||||
|
||||
while(NULL != (item=recvItem()))
|
||||
{
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "p3ChatService::receiveChatQueue() Item:" << (void*)item << std::endl ;
|
||||
#endif
|
||||
// RsChatMsgItems needs dynamic_cast, since they have derived siblings.
|
||||
//
|
||||
RsChatMsgItem *ci = dynamic_cast<RsChatMsgItem*>(item) ;
|
||||
if(ci != NULL)
|
||||
{
|
||||
if(! handleRecvChatMsgItem(ci))
|
||||
delete ci ;
|
||||
handleIncomingItem(item) ;
|
||||
}
|
||||
|
||||
continue ; // don't delete! It's handled by handleRecvChatMsgItem in some specific cases only.
|
||||
}
|
||||
void p3ChatService::handleIncomingItem(RsItem *item)
|
||||
{
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "p3ChatService::receiveChatQueue() Item:" << (void*)item << std::endl ;
|
||||
#endif
|
||||
// RsChatMsgItems needs dynamic_cast, since they have derived siblings.
|
||||
//
|
||||
RsChatMsgItem *ci = dynamic_cast<RsChatMsgItem*>(item) ;
|
||||
if(ci != NULL)
|
||||
{
|
||||
if(! handleRecvChatMsgItem(ci))
|
||||
delete ci ;
|
||||
|
||||
return ; // don't delete! It's handled by handleRecvChatMsgItem in some specific cases only.
|
||||
}
|
||||
|
||||
switch(item->PacketSubType())
|
||||
{
|
||||
@ -647,7 +707,6 @@ void p3ChatService::receiveChatQueue()
|
||||
}
|
||||
}
|
||||
delete item ;
|
||||
}
|
||||
}
|
||||
|
||||
void p3ChatService::handleRecvChatLobbyListRequest(RsChatLobbyListRequestItem *clr)
|
||||
@ -1479,17 +1538,19 @@ void p3ChatService::getOwnAvatarJpegData(unsigned char *& data,int& size)
|
||||
|
||||
std::string p3ChatService::getCustomStateString(const std::string& peer_id)
|
||||
{
|
||||
// should be a Mutex here.
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::map<std::string,StateStringInfo>::iterator it = _state_strings.find(peer_id) ;
|
||||
|
||||
// has it. Return it strait away.
|
||||
//
|
||||
if(it!=_state_strings.end())
|
||||
{
|
||||
it->second._peer_is_new = false ;
|
||||
return it->second._custom_status_string ;
|
||||
// should be a Mutex here.
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::map<std::string,StateStringInfo>::iterator it = _state_strings.find(peer_id) ;
|
||||
|
||||
// has it. Return it strait away.
|
||||
//
|
||||
if(it!=_state_strings.end())
|
||||
{
|
||||
it->second._peer_is_new = false ;
|
||||
return it->second._custom_status_string ;
|
||||
}
|
||||
}
|
||||
|
||||
sendCustomStateRequest(peer_id);
|
||||
@ -1498,33 +1559,35 @@ std::string p3ChatService::getCustomStateString(const std::string& peer_id)
|
||||
|
||||
void p3ChatService::getAvatarJpegData(const std::string& peer_id,unsigned char *& data,int& size)
|
||||
{
|
||||
// should be a Mutex here.
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::map<std::string,AvatarInfo *>::const_iterator it = _avatars.find(peer_id) ;
|
||||
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "p3chatservice:: avatar for peer " << peer_id << " requested from above. " << std::endl ;
|
||||
#endif
|
||||
// has avatar. Return it straight away.
|
||||
//
|
||||
if(it!=_avatars.end())
|
||||
{
|
||||
uint32_t s=0 ;
|
||||
it->second->toUnsignedChar(data,s) ;
|
||||
size = s ;
|
||||
it->second->_peer_is_new = false ;
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "Already has avatar. Returning it" << std::endl ;
|
||||
#endif
|
||||
return ;
|
||||
} else {
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "No avatar for this peer. Requesting it by sending request packet." << std::endl ;
|
||||
#endif
|
||||
}
|
||||
// should be a Mutex here.
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
sendAvatarRequest(peer_id);
|
||||
std::map<std::string,AvatarInfo *>::const_iterator it = _avatars.find(peer_id) ;
|
||||
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "p3chatservice:: avatar for peer " << peer_id << " requested from above. " << std::endl ;
|
||||
#endif
|
||||
// has avatar. Return it straight away.
|
||||
//
|
||||
if(it!=_avatars.end())
|
||||
{
|
||||
uint32_t s=0 ;
|
||||
it->second->toUnsignedChar(data,s) ;
|
||||
size = s ;
|
||||
it->second->_peer_is_new = false ;
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "Already has avatar. Returning it" << std::endl ;
|
||||
#endif
|
||||
return ;
|
||||
} else {
|
||||
#ifdef CHAT_DEBUG
|
||||
std::cerr << "No avatar for this peer. Requesting it by sending request packet." << std::endl ;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
sendAvatarRequest(peer_id);
|
||||
}
|
||||
|
||||
void p3ChatService::sendAvatarRequest(const std::string& peer_id)
|
||||
@ -1543,7 +1606,7 @@ void p3ChatService::sendAvatarRequest(const std::string& peer_id)
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
sendItem(ci);
|
||||
sendPrivateChatItem(ci);
|
||||
}
|
||||
|
||||
void p3ChatService::sendCustomStateRequest(const std::string& peer_id){
|
||||
@ -1559,7 +1622,7 @@ void p3ChatService::sendCustomStateRequest(const std::string& peer_id){
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
sendItem(cs);
|
||||
sendPrivateChatItem(cs);
|
||||
}
|
||||
|
||||
RsChatStatusItem *p3ChatService::makeOwnCustomStateStringItem()
|
||||
@ -1601,7 +1664,7 @@ void p3ChatService::sendAvatarJpegData(const std::string& peer_id)
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
sendItem(ci) ;
|
||||
sendPrivateChatItem(ci) ;
|
||||
}
|
||||
else {
|
||||
#ifdef CHAT_DEBUG
|
||||
@ -1619,7 +1682,7 @@ std::cerr << "p3chatservice: sending requested status string for peer " << peer_
|
||||
RsChatStatusItem *cs = makeOwnCustomStateStringItem();
|
||||
cs->PeerId(peer_id);
|
||||
|
||||
sendItem(cs);
|
||||
sendPrivateChatItem(cs);
|
||||
}
|
||||
|
||||
bool p3ChatService::loadList(std::list<RsItem*>& load)
|
||||
@ -1683,6 +1746,24 @@ bool p3ChatService::loadList(std::list<RsItem*>& load)
|
||||
continue;
|
||||
}
|
||||
|
||||
RsPrivateChatDistantInviteConfigItem *ditem = NULL ;
|
||||
|
||||
if(NULL != (ditem = dynamic_cast<RsPrivateChatDistantInviteConfigItem *>(*it)))
|
||||
{
|
||||
DistantChatInvite invite ;
|
||||
|
||||
memcpy(invite.aes_key,ditem->aes_key,DISTANT_CHAT_AES_KEY_SIZE) ;
|
||||
invite.encrypted_radix64_string = ditem->encrypted_radix64_string ;
|
||||
invite.destination_pgp_id = ditem->destination_pgp_id ;
|
||||
invite.time_of_validity = ditem->time_of_validity ;
|
||||
invite.last_hit_time = ditem->last_hit_time ;
|
||||
|
||||
_distant_chat_invites[ditem->hash] = invite ;
|
||||
|
||||
delete *it ;
|
||||
continue ;
|
||||
}
|
||||
|
||||
RsConfigKeyValueSet *vitem = NULL ;
|
||||
|
||||
if(NULL != (vitem = dynamic_cast<RsConfigKeyValueSet*>(*it)))
|
||||
@ -1746,6 +1827,21 @@ bool p3ChatService::saveList(bool& cleanup, std::list<RsItem*>& list)
|
||||
list.push_back(ci);
|
||||
}
|
||||
|
||||
/* save ongoing distant chat invites */
|
||||
|
||||
for(std::map<TurtleFileHash,DistantChatInvite>::const_iterator it(_distant_chat_invites.begin());it!=_distant_chat_invites.end();++it)
|
||||
{
|
||||
RsPrivateChatDistantInviteConfigItem *ei = new RsPrivateChatDistantInviteConfigItem ;
|
||||
ei->hash = it->first ;
|
||||
memcpy(ei->aes_key,it->second.aes_key,DISTANT_CHAT_AES_KEY_SIZE) ;
|
||||
ei->encrypted_radix64_string = it->second.encrypted_radix64_string ;
|
||||
ei->destination_pgp_id = it->second.destination_pgp_id ;
|
||||
ei->time_of_validity = it->second.time_of_validity ;
|
||||
ei->last_hit_time = it->second.last_hit_time ;
|
||||
|
||||
list.push_back(ei) ;
|
||||
}
|
||||
|
||||
RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ;
|
||||
RsTlvKeyValue kv;
|
||||
kv.key = "DEFAULT_NICK_NAME" ;
|
||||
@ -1780,10 +1876,14 @@ void p3ChatService::statusChange(const std::list<pqipeer> &plist)
|
||||
for (it = plist.begin(); it != plist.end(); it++) {
|
||||
if (it->state & RS_PEER_S_FRIEND) {
|
||||
if (it->actions & RS_PEER_CONNECTED) {
|
||||
|
||||
/* send the saved outgoing messages */
|
||||
bool changed = false;
|
||||
|
||||
if (privateOutgoingList.size()) {
|
||||
std::vector<RsChatMsgItem*> to_send ;
|
||||
|
||||
if (privateOutgoingList.size())
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::string ownId = mLinkMgr->getOwnId();
|
||||
@ -1795,7 +1895,7 @@ void p3ChatService::statusChange(const std::list<pqipeer> &plist)
|
||||
if (c->PeerId() == it->id) {
|
||||
mHistoryMgr->addMessage(false, c->PeerId(), ownId, c);
|
||||
|
||||
checkSizeAndSendMessage_deprecated(c); // delete item
|
||||
to_send.push_back(c) ;
|
||||
|
||||
changed = true;
|
||||
|
||||
@ -1808,6 +1908,9 @@ void p3ChatService::statusChange(const std::list<pqipeer> &plist)
|
||||
}
|
||||
} /* UNLOCKED */
|
||||
|
||||
for(uint32_t i=0;i<to_send.size();++i)
|
||||
checkSizeAndSendMessage_deprecated(to_send[i]); // delete item
|
||||
|
||||
if (changed) {
|
||||
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_PRIVATE_OUTGOING_CHAT, NOTIFY_TYPE_DEL);
|
||||
|
||||
@ -2745,4 +2848,534 @@ void p3ChatService::cleanLobbyCaches()
|
||||
sendConnectionChallenge(*it) ;
|
||||
}
|
||||
|
||||
bool p3ChatService::handleTunnelRequest(const std::string& hash,const std::string& peer_id)
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::map<TurtleFileHash,DistantChatInvite>::iterator it = _distant_chat_invites.find(hash) ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << "p3ChatService::handleTunnelRequest: received tunnel request for hash " << hash << std::endl;
|
||||
#endif
|
||||
|
||||
if(it == _distant_chat_invites.end())
|
||||
return false ;
|
||||
|
||||
it->second.last_hit_time = time(NULL) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
void p3ChatService::addVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction dir)
|
||||
{
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << "p3ChatService:: adding new virtual peer " << virtual_peer_id << " for hash " << hash << std::endl;
|
||||
#endif
|
||||
time_t now = time(NULL) ;
|
||||
|
||||
if(dir == RsTurtleGenericTunnelItem::DIRECTION_SERVER)
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << " Side is in direction to server." << std::endl;
|
||||
#endif
|
||||
|
||||
std::map<TurtleFileHash,DistantChatPeerInfo>::iterator it = _distant_chat_peers.find(hash) ;
|
||||
|
||||
if(it == _distant_chat_peers.end())
|
||||
{
|
||||
std::cerr << "(EE) Cannot add virtual peer for hash " << hash << ": no chat invite found for that hash." << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
it->second.last_contact = now ;
|
||||
it->second.status = RS_DISTANT_CHAT_STATUS_TUNNEL_OK ;
|
||||
it->second.virtual_peer_id = virtual_peer_id ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << "(II) Adding virtual peer " << virtual_peer_id << " for chat hash " << hash << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
if(dir == RsTurtleGenericTunnelItem::DIRECTION_CLIENT)
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << " Side is in direction to client." << std::endl;
|
||||
std::cerr << " Initing encryption parameters from existing distant chat invites." << std::endl;
|
||||
#endif
|
||||
|
||||
std::map<TurtleFileHash,DistantChatInvite>::iterator it = _distant_chat_invites.find(hash) ;
|
||||
|
||||
if(it == _distant_chat_invites.end())
|
||||
{
|
||||
std::cerr << "(EE) Cannot find distant chat invite for hash " << hash << ": no chat invite found for that hash." << std::endl;
|
||||
return ;
|
||||
}
|
||||
DistantChatPeerInfo info ;
|
||||
info.last_contact = now ;
|
||||
info.status = RS_DISTANT_CHAT_STATUS_TUNNEL_OK ;
|
||||
info.virtual_peer_id = virtual_peer_id ;
|
||||
info.pgp_id = it->second.destination_pgp_id ;
|
||||
memcpy(info.aes_key,it->second.aes_key,DISTANT_CHAT_AES_KEY_SIZE) ;
|
||||
|
||||
_distant_chat_peers[hash] = info ;
|
||||
it->second.last_hit_time = now ;
|
||||
}
|
||||
|
||||
rsicontrol->getNotify().notifyChatStatus(hash,"tunnel is up again!",true) ;
|
||||
rsicontrol->getNotify().notifyPeerStatusChanged(hash,RS_STATUS_ONLINE) ;
|
||||
|
||||
getPqiNotify()->AddPopupMessage(RS_POPUP_CHAT, hash, "Distant peer", "Conversation starts...");
|
||||
}
|
||||
|
||||
void p3ChatService::removeVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id)
|
||||
{
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::map<std::string,DistantChatPeerInfo>::iterator it = _distant_chat_peers.find(hash) ;
|
||||
|
||||
if(it == _distant_chat_peers.end())
|
||||
{
|
||||
std::cerr << "(EE) Cannot remove virtual peer " << virtual_peer_id << ": not found in chat list!!" << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
it->second.status = RS_DISTANT_CHAT_STATUS_TUNNEL_DN ;
|
||||
}
|
||||
rsicontrol->getNotify().notifyChatStatus(hash,"tunnel is down...",true) ;
|
||||
rsicontrol->getNotify().notifyPeerStatusChanged(hash,RS_STATUS_OFFLINE) ;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
static void printBinaryData(void *data,uint32_t size)
|
||||
{
|
||||
static const char outl[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' } ;
|
||||
|
||||
for(uint32_t j = 0; j < size; j++)
|
||||
{
|
||||
std::cerr << outl[ ( ((uint8_t*)data)[j]>>4) ] ;
|
||||
std::cerr << outl[ ((uint8_t*)data)[j] & 0xf ] ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void p3ChatService::receiveTurtleData( RsTurtleGenericTunnelItem *gitem,const std::string& hash,
|
||||
const std::string& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction)
|
||||
{
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << "p3ChatService::receiveTurtleData(): Received turtle data. " << std::endl;
|
||||
std::cerr << " hash = " << hash << std::endl;
|
||||
std::cerr << " vpid = " << virtual_peer_id << std::endl;
|
||||
std::cerr << " dir = " << virtual_peer_id << std::endl;
|
||||
#endif
|
||||
|
||||
RsTurtleGenericDataItem *item = dynamic_cast<RsTurtleGenericDataItem*>(gitem) ;
|
||||
|
||||
if(item == NULL)
|
||||
{
|
||||
std::cerr << "(EE) item is not a data item. That is an error." << std::endl;
|
||||
return ;
|
||||
}
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << " size = " << item->data_size << std::endl;
|
||||
std::cerr << " data = " << (void*)item->data_bytes << std::endl;
|
||||
std::cerr << " IV = " << std::hex << *(uint64_t*)item->data_bytes << std::dec << std::endl;
|
||||
std::cerr << " data = " ;
|
||||
|
||||
printBinaryData(item->data_bytes,item->data_size) ;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
uint8_t aes_key[DISTANT_CHAT_AES_KEY_SIZE] ;
|
||||
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
std::map<std::string,DistantChatPeerInfo>::iterator it = _distant_chat_peers.find(hash) ;
|
||||
|
||||
if(it == _distant_chat_peers.end())
|
||||
{
|
||||
std::cerr << "(EE) item is not coming out of a registered tunnel. Weird. hash=" << hash << ", peer id = " << virtual_peer_id << std::endl;
|
||||
return ;
|
||||
}
|
||||
it->second.last_contact = time(NULL) ;
|
||||
memcpy(aes_key,it->second.aes_key,DISTANT_CHAT_AES_KEY_SIZE) ;
|
||||
it->second.status = RS_DISTANT_CHAT_STATUS_CAN_TALK ;
|
||||
}
|
||||
|
||||
// Call the AES crypto module
|
||||
// - the IV is the first 8 bytes of item->data_bytes
|
||||
|
||||
if(item->data_size < 8)
|
||||
{
|
||||
std::cerr << "(EE) item encrypted data stream is too small: size = " << item->data_size << std::endl;
|
||||
return ;
|
||||
}
|
||||
uint32_t decrypted_size = RsAES::get_buffer_size(item->data_size-8);
|
||||
uint8_t *decrypted_data = new uint8_t[decrypted_size];
|
||||
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << " Using IV: " << std::hex << *(uint64_t*)item->data_bytes << std::dec << std::endl;
|
||||
std::cerr << " Decrypted buffer size: " << decrypted_size << std::endl;
|
||||
std::cerr << " key : " ; printBinaryData(aes_key,16) ; std::cerr << std::endl;
|
||||
std::cerr << " data : " ; printBinaryData(item->data_bytes,item->data_size) ; std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
if(!RsAES::aes_decrypt_8_16((uint8_t*)item->data_bytes+8,item->data_size-8,aes_key,(uint8_t*)item->data_bytes,decrypted_data,decrypted_size))
|
||||
{
|
||||
std::cerr << "(EE) packet decryption failed." << std::endl;
|
||||
delete[] decrypted_data ;
|
||||
return ;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << "(II) Decrypted data: size=" << decrypted_size << std::endl;
|
||||
#endif
|
||||
|
||||
// Now try deserialise the decrypted data to make an RsItem out of it.
|
||||
//
|
||||
RsItem *citem = _serializer->deserialise(decrypted_data,&decrypted_size) ;
|
||||
delete[] decrypted_data ;
|
||||
|
||||
if(citem == NULL)
|
||||
{
|
||||
std::cerr << "(EE) item could not be de-serialized. That is an error." << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
// Setup the virtual peer to be the origin, and pass it on.
|
||||
//
|
||||
citem->PeerId(hash) ;
|
||||
handleIncomingItem(citem) ; // Treats the item, and deletes it
|
||||
}
|
||||
|
||||
void p3ChatService::sendTurtleData(RsChatItem *item)
|
||||
{
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << "p3ChatService::sendTurtleData(): try sending item " << (void*)item << " to tunnel " << item->PeerId() << std::endl;
|
||||
#endif
|
||||
|
||||
uint32_t rssize = item->serial_size();
|
||||
uint8_t *buff = new uint8_t[rssize] ;
|
||||
|
||||
if(!item->serialise(buff,rssize))
|
||||
{
|
||||
std::cerr << "(EE) p3ChatService::sendTurtleData(): Could not serialise item!" << std::endl;
|
||||
delete[] buff ;
|
||||
return ;
|
||||
}
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << " Serialized item has size " << rssize << std::endl;
|
||||
#endif
|
||||
|
||||
uint8_t aes_key[DISTANT_CHAT_AES_KEY_SIZE] ;
|
||||
std::string virtual_peer_id ;
|
||||
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
std::map<std::string,DistantChatPeerInfo>::iterator it = _distant_chat_peers.find(item->PeerId()) ;
|
||||
|
||||
if(it == _distant_chat_peers.end())
|
||||
{
|
||||
std::cerr << "(EE) item is not coming out of a registered tunnel. Weird. peer id = " << virtual_peer_id << std::endl;
|
||||
delete[] buff ;
|
||||
return ;
|
||||
}
|
||||
it->second.last_contact = time(NULL) ;
|
||||
virtual_peer_id = it->second.virtual_peer_id ;
|
||||
memcpy(aes_key,it->second.aes_key,DISTANT_CHAT_AES_KEY_SIZE) ;
|
||||
}
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << "p3ChatService::sendTurtleData(): tunnel found. Encrypting data." << std::endl;
|
||||
#endif
|
||||
|
||||
// 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);
|
||||
|
||||
uint64_t IV = RSRandom::random_u64() ; // make a random 8 bytes IV
|
||||
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << " Using IV: " << std::hex << IV << std::dec << std::endl;
|
||||
std::cerr << " Using Key: " ; printBinaryData(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;
|
||||
delete[] encrypted_data ;
|
||||
delete[] buff ;
|
||||
return ;
|
||||
}
|
||||
delete[] buff ;
|
||||
|
||||
// make a TurtleGenericData item out of it:
|
||||
//
|
||||
RsTurtleGenericDataItem *gitem = new RsTurtleGenericDataItem ;
|
||||
|
||||
gitem->data_size = encrypted_size + 8 ;
|
||||
gitem->data_bytes = malloc(gitem->data_size) ;
|
||||
|
||||
memcpy(gitem->data_bytes ,&IV,8) ;
|
||||
memcpy(gitem->data_bytes+8,encrypted_data,encrypted_size) ;
|
||||
|
||||
delete[] encrypted_data ;
|
||||
delete item ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << "p3ChatService::sendTurtleData(): Sending through virtual peer: " << virtual_peer_id << std::endl;
|
||||
std::cerr << " gitem->data_size = " << gitem->data_size << std::endl;
|
||||
std::cerr << " data = " ;
|
||||
|
||||
printBinaryData(gitem->data_bytes,gitem->data_size) ;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
mTurtle->sendTurtleData(virtual_peer_id,gitem) ;
|
||||
}
|
||||
|
||||
bool p3ChatService::createDistantChatInvite(const std::string& pgp_id,time_t time_of_validity,std::string& encrypted_radix64_string)
|
||||
{
|
||||
// create the invite
|
||||
|
||||
time_t now = time(NULL) ;
|
||||
|
||||
DistantChatInvite invite ;
|
||||
invite.time_of_validity = now + time_of_validity ;
|
||||
invite.last_hit_time = now ;
|
||||
|
||||
RAND_bytes( (unsigned char *)&invite.aes_key[0],DISTANT_CHAT_AES_KEY_SIZE ) ; // generate a random AES encryption key
|
||||
|
||||
// Create a random hash for that invite.
|
||||
//
|
||||
unsigned char hash_bytes[DISTANT_CHAT_HASH_SIZE] ;
|
||||
RAND_bytes( hash_bytes, DISTANT_CHAT_HASH_SIZE) ;
|
||||
|
||||
std::string hash = t_RsGenericIdType<DISTANT_CHAT_HASH_SIZE>(hash_bytes).toStdString(false) ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << "Created new distant chat invite: " << std::endl;
|
||||
std::cerr << " validity time stamp = " << invite.time_of_validity << std::endl;
|
||||
std::cerr << " hash = " << hash << std::endl;
|
||||
std::cerr << " encryption key = " ;
|
||||
static const char outl[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' } ;
|
||||
for(uint32_t j = 0; j < 16; j++) { std::cerr << outl[ (invite.aes_key[j]>>4) ] ; std::cerr << outl[ invite.aes_key[j] & 0xf ] ; }
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
// Now encrypt the data to create the link info. We need
|
||||
//
|
||||
// [E] - the hash
|
||||
// [E] - the aes key
|
||||
// [E] - the signature
|
||||
// - pgp id
|
||||
// - timestamp
|
||||
//
|
||||
// The link will be
|
||||
//
|
||||
// retroshare://chat?time_stamp=3243242&private_data=[radix64 string]
|
||||
|
||||
uint32_t header_size = DISTANT_CHAT_AES_KEY_SIZE + DISTANT_CHAT_HASH_SIZE + KEY_ID_SIZE;
|
||||
unsigned char *data = new unsigned char[header_size+400] ;
|
||||
|
||||
PGPIdType OwnId(AuthGPG::getAuthGPG()->getGPGOwnId());
|
||||
|
||||
memcpy(data ,hash_bytes ,DISTANT_CHAT_HASH_SIZE) ;
|
||||
memcpy(data+DISTANT_CHAT_HASH_SIZE ,invite.aes_key ,DISTANT_CHAT_AES_KEY_SIZE) ;
|
||||
memcpy(data+DISTANT_CHAT_HASH_SIZE+DISTANT_CHAT_AES_KEY_SIZE,OwnId.toByteArray(),KEY_ID_SIZE) ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << "Performing signature " << std::endl;
|
||||
#endif
|
||||
uint32_t signlen = 400;
|
||||
|
||||
if(!AuthGPG::getAuthGPG()->SignDataBin(data,header_size,data+header_size,&signlen))
|
||||
return false ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << "Signature length = " << signlen << std::endl;
|
||||
#endif
|
||||
|
||||
// Then encrypt the whole data into a single string.
|
||||
|
||||
unsigned char *encrypted_data = new unsigned char[2000] ;
|
||||
uint32_t encrypted_size = 2000 ;
|
||||
|
||||
if(!AuthGPG::getAuthGPG()->encryptDataBin(pgp_id,(unsigned char *)data,signlen+header_size,encrypted_data,&encrypted_size))
|
||||
return false ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << "Encrypted data size: " << encrypted_size << std::endl;
|
||||
#endif
|
||||
|
||||
Radix64::encode((const char *)encrypted_data,encrypted_size,invite.encrypted_radix64_string) ;
|
||||
invite.destination_pgp_id = pgp_id ;
|
||||
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
_distant_chat_invites[hash] = invite ;
|
||||
}
|
||||
|
||||
encrypted_radix64_string = invite.encrypted_radix64_string ;
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << "Encrypted radix64 string: " << invite.encrypted_radix64_string << std::endl;
|
||||
#endif
|
||||
|
||||
IndicateConfigChanged();
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool p3ChatService::initiateDistantChatConnexion(const std::string& encrypted_str,std::string& hash,uint32_t& error_code)
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
// Un-radix the string.
|
||||
//
|
||||
char *encrypted_data_bin = NULL ;
|
||||
size_t encrypted_data_len ;
|
||||
|
||||
Radix64::decode(encrypted_str,encrypted_data_bin,encrypted_data_len) ;
|
||||
|
||||
// Decrypt it.
|
||||
//
|
||||
uint32_t data_size = encrypted_data_len+1000;
|
||||
unsigned char *data = new unsigned char[data_size] ;
|
||||
|
||||
if(!AuthGPG::getAuthGPG()->decryptDataBin((unsigned char *)encrypted_data_bin,encrypted_data_len,data,&data_size))
|
||||
{
|
||||
error_code = RS_DISTANT_CHAT_ERROR_DECRYPTION_FAILED ;
|
||||
return false ;
|
||||
}
|
||||
delete[] encrypted_data_bin ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << "Chat invite was successfuly decrypted!" << std::endl;
|
||||
#endif
|
||||
|
||||
uint32_t header_size = DISTANT_CHAT_HASH_SIZE + DISTANT_CHAT_AES_KEY_SIZE + KEY_ID_SIZE ;
|
||||
|
||||
PGPIdType pgp_id( data + DISTANT_CHAT_HASH_SIZE + DISTANT_CHAT_AES_KEY_SIZE ) ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << "Got this PGP id: " << pgp_id.toStdString() << std::endl;
|
||||
#endif
|
||||
|
||||
PGPFingerprintType fingerprint ;
|
||||
if(!AuthGPG::getAuthGPG()->getKeyFingerprint(pgp_id,fingerprint))
|
||||
{
|
||||
error_code = RS_DISTANT_CHAT_ERROR_UNKNOWN_KEY ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
if(!AuthGPG::getAuthGPG()->VerifySignBin(data,header_size,data+header_size,data_size-header_size,fingerprint.toStdString()))
|
||||
{
|
||||
error_code = RS_DISTANT_CHAT_ERROR_SIGNATURE_MISMATCH ;
|
||||
return false ;
|
||||
}
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << "Signature successfuly verified!" << std::endl;
|
||||
#endif
|
||||
|
||||
hash = t_RsGenericIdType<DISTANT_CHAT_HASH_SIZE>(data).toStdString(false) ;
|
||||
DistantChatPeerInfo info ;
|
||||
|
||||
info.last_contact = time(NULL) ;
|
||||
info.status = RS_DISTANT_CHAT_STATUS_TUNNEL_DN ;
|
||||
info.pgp_id = pgp_id.toStdString() ;
|
||||
memcpy(info.aes_key,data+DISTANT_CHAT_HASH_SIZE,DISTANT_CHAT_AES_KEY_SIZE) ;
|
||||
|
||||
_distant_chat_peers[hash] = info ;
|
||||
|
||||
delete[] data ;
|
||||
|
||||
// Now ask the turtle router to manage a tunnel for that hash.
|
||||
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << "Asking turtle router to monitor tunnels for hash " << hash << std::endl;
|
||||
#endif
|
||||
|
||||
mTurtle->monitorTunnels(hash,this) ;
|
||||
|
||||
// And notify about chatting.
|
||||
|
||||
error_code = RS_DISTANT_CHAT_ERROR_NO_ERROR ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
void p3ChatService::cleanDistantChatInvites()
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
time_t now = time(NULL) ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << "p3ChatService::cleanDistantChatInvites: " << std::endl;
|
||||
#endif
|
||||
|
||||
for(std::map<TurtleFileHash,DistantChatInvite>::iterator it(_distant_chat_invites.begin());it!=_distant_chat_invites.end(); )
|
||||
if(it->second.time_of_validity < now)
|
||||
{
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << " Removing hash " << it->first << std::endl;
|
||||
#endif
|
||||
std::map<TurtleFileHash,DistantChatInvite>::iterator tmp(it) ;
|
||||
++it ;
|
||||
_distant_chat_invites.erase(tmp) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG_DISTANT_CHAT
|
||||
std::cerr << " Keeping hash " << it->first << std::endl;
|
||||
#endif
|
||||
++it ;
|
||||
}
|
||||
}
|
||||
|
||||
bool p3ChatService::getDistantChatInviteList(std::vector<DistantChatInviteInfo>& invites)
|
||||
{
|
||||
invites.clear() ;
|
||||
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
for(std::map<std::string,DistantChatInvite>::const_iterator it(_distant_chat_invites.begin());it!=_distant_chat_invites.end();++it)
|
||||
{
|
||||
DistantChatInviteInfo info ;
|
||||
info.hash = it->first ;
|
||||
info.encrypted_radix64_string = it->second.encrypted_radix64_string ;
|
||||
info.time_of_validity = it->second.time_of_validity ;
|
||||
info.destination_pgp_id = it->second.destination_pgp_id ;
|
||||
|
||||
invites.push_back(info);
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool p3ChatService::getDistantChatStatus(const std::string& hash,uint32_t& status,std::string& pgp_id)
|
||||
{
|
||||
RsStackMutex stack(mChatMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::map<TurtleFileHash,DistantChatPeerInfo>::const_iterator it = _distant_chat_peers.find(hash) ;
|
||||
|
||||
if(it == _distant_chat_peers.end())
|
||||
return false ;
|
||||
|
||||
status = it->second.status ;
|
||||
pgp_id = it->second.pgp_id ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -33,10 +33,13 @@
|
||||
|
||||
#include "serialiser/rsmsgitems.h"
|
||||
#include "services/p3service.h"
|
||||
#include "pgp/pgphandler.h"
|
||||
#include "turtle/turtleclientservice.h"
|
||||
#include "retroshare/rsmsgs.h"
|
||||
|
||||
class p3LinkMgr;
|
||||
class p3HistoryMgr;
|
||||
class p3turtle ;
|
||||
|
||||
//!The basic Chat service.
|
||||
/**
|
||||
@ -45,7 +48,7 @@ class p3HistoryMgr;
|
||||
* This service uses rsnotify (callbacks librs clients (e.g. rs-gui))
|
||||
* @see NotifyBase
|
||||
*/
|
||||
class p3ChatService: public p3Service, public p3Config, public pqiMonitor
|
||||
class p3ChatService: public p3Service, public p3Config, public pqiMonitor, public RsTurtleClientService
|
||||
{
|
||||
public:
|
||||
p3ChatService(p3LinkMgr *cm, p3HistoryMgr *historyMgr);
|
||||
@ -183,6 +186,7 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor
|
||||
virtual void saveDone();
|
||||
virtual bool loadList(std::list<RsItem*>& load) ;
|
||||
|
||||
bool isOnline(const std::string& id) ;
|
||||
private:
|
||||
RsMutex mChatMtx;
|
||||
|
||||
@ -191,6 +195,7 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor
|
||||
|
||||
// Receive chat queue
|
||||
void receiveChatQueue();
|
||||
void handleIncomingItem(RsItem *); // called by the former, and turtle handler for incoming encrypted items
|
||||
|
||||
void initRsChatInfo(RsChatMsgItem *c, ChatInfo &i);
|
||||
|
||||
@ -289,9 +294,69 @@ class p3ChatService: public p3Service, public p3Config, public pqiMonitor
|
||||
std::map<std::string,ChatLobbyId> _lobby_ids ;
|
||||
std::string _default_nick_name ;
|
||||
float _time_shift_average ;
|
||||
time_t last_lobby_challenge_time ; // prevents bruteforce attack
|
||||
time_t last_lobby_challenge_time ; // prevents bruteforce attack
|
||||
time_t last_visible_lobby_info_request_time ; // allows to ask for updates
|
||||
bool _should_reset_lobby_counts ;
|
||||
|
||||
RsChatSerialiser *_serializer ;
|
||||
|
||||
// ===========================================================//
|
||||
// Members related to anonymous distant chat. //
|
||||
// ===========================================================//
|
||||
|
||||
public:
|
||||
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 createDistantChatInvite(const std::string& pgp_id,time_t time_of_validity,TurtleFileHash& hash) ;
|
||||
bool getDistantChatInviteList(std::vector<DistantChatInviteInfo>& invites) ;
|
||||
bool initiateDistantChatConnexion(const std::string& encrypted_string,std::string& hash,uint32_t& error_code) ;
|
||||
|
||||
virtual bool getDistantChatStatus(const std::string& hash,uint32_t& status,std::string& pgp_id) ;
|
||||
|
||||
private:
|
||||
struct DistantChatInvite
|
||||
{
|
||||
unsigned char aes_key[16] ;
|
||||
std::string encrypted_radix64_string ;
|
||||
std::string destination_pgp_id ;
|
||||
time_t time_of_validity ;
|
||||
time_t last_hit_time ;
|
||||
};
|
||||
struct DistantChatPeerInfo
|
||||
{
|
||||
time_t last_contact ; // used to send keep alive packets
|
||||
unsigned char aes_key[16] ; // key to encrypt packets
|
||||
uint32_t status ; // info: do we have a tunnel ?
|
||||
std::string virtual_peer_id; // given by the turtle router. Identifies the tunnel.
|
||||
std::string pgp_id ; // pgp id of the peer we're talking to.
|
||||
};
|
||||
|
||||
// This map contains the ongoing invites. This is the list where to look to
|
||||
// handle tunnel requests.
|
||||
//
|
||||
std::map<TurtleFileHash,DistantChatInvite> _distant_chat_invites ;
|
||||
|
||||
// This maps contains the current peers to talk to with distant chat.
|
||||
//
|
||||
std::map<std::string,DistantChatPeerInfo> _distant_chat_peers ;
|
||||
|
||||
// Overloaded from RsTurtleClientService
|
||||
|
||||
virtual bool handleTunnelRequest(const std::string& hash,const std::string& peer_id) ;
|
||||
virtual void receiveTurtleData(RsTurtleGenericTunnelItem *item,const std::string& hash,const std::string& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction) ;
|
||||
void addVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&,RsTurtleGenericTunnelItem::Direction dir) ;
|
||||
void removeVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&) ;
|
||||
|
||||
// Utility functions
|
||||
|
||||
void cleanDistantChatInvites() ;
|
||||
void sendTurtleData(RsChatItem *) ;
|
||||
void sendPrivateChatItem(RsChatItem *) ;
|
||||
|
||||
p3turtle *mTurtle ;
|
||||
};
|
||||
|
||||
class p3ChatService::StateStringInfo
|
||||
|
@ -25,23 +25,34 @@
|
||||
|
||||
|
||||
#include "retroshare/rsiface.h"
|
||||
#include "retroshare/rspeers.h"
|
||||
|
||||
#include "pqi/pqibin.h"
|
||||
#include "pqi/pqiarchive.h"
|
||||
#include "pqi/p3linkmgr.h"
|
||||
#include "pqi/authgpg.h"
|
||||
|
||||
#include "services/p3msgservice.h"
|
||||
#include "pgp/pgpkeyutil.h"
|
||||
#include "pqi/pqinotify.h"
|
||||
|
||||
#include "util/rsdebug.h"
|
||||
#include "util/rsdir.h"
|
||||
#include "util/rsstring.h"
|
||||
#include "util/radix64.h"
|
||||
#include "util/rsrandom.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <map>
|
||||
|
||||
//#define DEBUG_DISTANT_MSG
|
||||
|
||||
const int msgservicezone = 54319;
|
||||
|
||||
static const uint32_t RS_DISTANT_MSG_STATUS_TUNNEL_OK = 0x0001 ;
|
||||
static const uint32_t RS_DISTANT_MSG_STATUS_TUNNEL_DN = 0x0000 ;
|
||||
static const uint32_t DISTANT_MSG_HASH_SIZE = 20 ;
|
||||
|
||||
/* Another little hack ..... unique message Ids
|
||||
* will be handled in this class.....
|
||||
* These are unique within this run of the server,
|
||||
@ -58,7 +69,8 @@ p3MsgService::p3MsgService(p3LinkMgr *lm)
|
||||
:p3Service(RS_SERVICE_TYPE_MSG), p3Config(CONFIG_TYPE_MSGS),
|
||||
mLinkMgr(lm), mMsgMtx("p3MsgService"), mMsgUniqueId(time(NULL))
|
||||
{
|
||||
addSerialType(new RsMsgSerialiser());
|
||||
_serialiser = new RsMsgSerialiser();
|
||||
addSerialType(_serialiser);
|
||||
|
||||
/* Initialize standard tag types */
|
||||
if(lm)
|
||||
@ -81,6 +93,15 @@ int p3MsgService::tick()
|
||||
*/
|
||||
|
||||
incomingMsgs();
|
||||
|
||||
static time_t last_management_time = 0 ;
|
||||
time_t now = time(NULL) ;
|
||||
|
||||
if(now > last_management_time + 5)
|
||||
{
|
||||
manageDistantPeers() ;
|
||||
last_management_time = now ;
|
||||
}
|
||||
//checkOutgoingMessages();
|
||||
|
||||
return 0;
|
||||
@ -107,7 +128,7 @@ void p3MsgService::processMsg(RsMsgItem *mi, bool incoming)
|
||||
{
|
||||
/* from a peer */
|
||||
|
||||
mi->msgFlags &= RS_MSG_FLAGS_SYSTEM; // remove flags
|
||||
mi->msgFlags &= (RS_MSG_FLAGS_ENCRYPTED | RS_MSG_FLAGS_SYSTEM); // remove flags except those
|
||||
mi->msgFlags |= RS_MSG_FLAGS_NEW;
|
||||
|
||||
pqiNotify *notify = getPqiNotify();
|
||||
@ -187,22 +208,27 @@ int p3MsgService::incomingMsgs()
|
||||
{
|
||||
RsMsgItem *mi;
|
||||
int i = 0;
|
||||
bool changed = false ;
|
||||
|
||||
while((mi = (RsMsgItem *) recvItem()) != NULL)
|
||||
{
|
||||
changed = true ;
|
||||
++i;
|
||||
handleIncomingItem(mi) ;
|
||||
++i ;
|
||||
}
|
||||
|
||||
if(checkAndRebuildPartialMessage(mi)) // only returns true when a msg is complete.
|
||||
{
|
||||
processMsg(mi, true);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
void p3MsgService::handleIncomingItem(RsMsgItem *mi)
|
||||
{
|
||||
bool changed = false ;
|
||||
|
||||
if(checkAndRebuildPartialMessage(mi)) // only returns true when a msg is complete.
|
||||
{
|
||||
processMsg(mi, true);
|
||||
changed = true ;
|
||||
}
|
||||
if(changed)
|
||||
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void p3MsgService::statusChange(const std::list<pqipeer> &/*plist*/)
|
||||
@ -233,10 +259,18 @@ void p3MsgService::checkSizeAndSendMessage(RsMsgItem *msg)
|
||||
// Indicate that the message is to be continued.
|
||||
//
|
||||
item->msgFlags |= RS_MSG_FLAGS_PARTIAL ;
|
||||
sendItem(item) ;
|
||||
|
||||
if(msg->msgFlags & RS_MSG_FLAGS_DISTANT)
|
||||
sendPrivateMsgItem(msg) ;
|
||||
else
|
||||
sendItem(item) ;
|
||||
}
|
||||
std::cerr << " Chopped off msg of size " << msg->message.size() << std::endl;
|
||||
sendItem(msg) ;
|
||||
|
||||
if(msg->msgFlags & RS_MSG_FLAGS_DISTANT)
|
||||
sendPrivateMsgItem(msg) ;
|
||||
else
|
||||
sendItem(msg) ;
|
||||
}
|
||||
|
||||
int p3MsgService::checkOutgoingMessages()
|
||||
@ -247,6 +281,7 @@ int p3MsgService::checkOutgoingMessages()
|
||||
*/
|
||||
|
||||
bool changed = false ;
|
||||
std::list<RsMsgItem*> output_queue ;
|
||||
|
||||
{
|
||||
const std::string ownId = mLinkMgr->getOwnId();
|
||||
@ -264,18 +299,8 @@ int p3MsgService::checkOutgoingMessages()
|
||||
|
||||
/* find the certificate */
|
||||
std::string pid = mit->second->PeerId();
|
||||
bool toSend = false;
|
||||
|
||||
if (mLinkMgr->isOnline(pid))
|
||||
{
|
||||
toSend = true;
|
||||
}
|
||||
else if (pid == ownId) /* FEEDBACK Msg to Ourselves */
|
||||
{
|
||||
toSend = true;
|
||||
}
|
||||
|
||||
if (toSend)
|
||||
if(mit->second->msgFlags & RS_MSG_FLAGS_DISTANT || mLinkMgr->isOnline(pid) || pid == ownId) /* FEEDBACK Msg to Ourselves */
|
||||
{
|
||||
/* send msg */
|
||||
pqioutput(PQL_DEBUG_BASIC, msgservicezone,
|
||||
@ -283,7 +308,7 @@ int p3MsgService::checkOutgoingMessages()
|
||||
/* remove the pending flag */
|
||||
(mit->second)->msgFlags &= ~RS_MSG_FLAGS_PENDING;
|
||||
|
||||
checkSizeAndSendMessage(mit->second) ;
|
||||
output_queue.push_back(mit->second) ;
|
||||
toErase.push_back(mit->first);
|
||||
|
||||
changed = true ;
|
||||
@ -317,6 +342,9 @@ int p3MsgService::checkOutgoingMessages()
|
||||
}
|
||||
}
|
||||
|
||||
for(std::list<RsMsgItem*>::const_iterator it(output_queue.begin());it!=output_queue.end();++it)
|
||||
checkSizeAndSendMessage(*it) ;
|
||||
|
||||
if(changed)
|
||||
rsicontrol->getNotify().notifyListChange(NOTIFY_LIST_MESSAGELIST,NOTIFY_TYPE_MOD);
|
||||
|
||||
@ -357,6 +385,14 @@ bool p3MsgService::saveList(bool& cleanup, std::list<RsItem*>& itemList)
|
||||
for(mit4 = mParentId.begin(); mit4 != mParentId.end(); mit4++)
|
||||
itemList.push_back(mit4->second);
|
||||
|
||||
for(std::map<std::string,DistantMessengingInvite>::const_iterator it(_messenging_invites.begin());it!=_messenging_invites.end();++it)
|
||||
{
|
||||
RsPublicMsgInviteConfigItem *item = new RsPublicMsgInviteConfigItem ;
|
||||
item->hash = it->first ;
|
||||
item->time_stamp = it->second.time_of_validity ;
|
||||
|
||||
itemList.push_back(item) ;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -421,6 +457,7 @@ bool p3MsgService::loadList(std::list<RsItem*>& load)
|
||||
RsMsgTags* mti;
|
||||
RsMsgSrcId* msi;
|
||||
RsMsgParentId* msp;
|
||||
RsPublicMsgInviteConfigItem* msv;
|
||||
|
||||
std::list<RsMsgItem*> items;
|
||||
std::list<RsItem*>::iterator it;
|
||||
@ -442,18 +479,18 @@ bool p3MsgService::loadList(std::list<RsItem*>& load)
|
||||
items.push_back(mitem);
|
||||
}
|
||||
else if(NULL != (mtt = dynamic_cast<RsMsgTagType *>(*it)))
|
||||
{
|
||||
// delete standard tags as they are now save in config
|
||||
if(mTags.end() == (tagIt = mTags.find(mtt->tagId)))
|
||||
{
|
||||
mTags.insert(std::pair<uint32_t, RsMsgTagType* >(mtt->tagId, mtt));
|
||||
}
|
||||
else
|
||||
{
|
||||
delete mTags[mtt->tagId];
|
||||
mTags.erase(tagIt);
|
||||
mTags.insert(std::pair<uint32_t, RsMsgTagType* >(mtt->tagId, mtt));
|
||||
}
|
||||
{
|
||||
// delete standard tags as they are now save in config
|
||||
if(mTags.end() == (tagIt = mTags.find(mtt->tagId)))
|
||||
{
|
||||
mTags.insert(std::pair<uint32_t, RsMsgTagType* >(mtt->tagId, mtt));
|
||||
}
|
||||
else
|
||||
{
|
||||
delete mTags[mtt->tagId];
|
||||
mTags.erase(tagIt);
|
||||
mTags.insert(std::pair<uint32_t, RsMsgTagType* >(mtt->tagId, mtt));
|
||||
}
|
||||
|
||||
}
|
||||
else if(NULL != (mti = dynamic_cast<RsMsgTags *>(*it)))
|
||||
@ -469,6 +506,10 @@ bool p3MsgService::loadList(std::list<RsItem*>& load)
|
||||
{
|
||||
mParentId.insert(std::pair<uint32_t, RsMsgParentId*>(msp->msgId, msp));
|
||||
}
|
||||
else if(NULL != (msv = dynamic_cast<RsPublicMsgInviteConfigItem *>(*it)))
|
||||
{
|
||||
_messenging_invites[msv->hash].time_of_validity = msv->time_stamp ;
|
||||
}
|
||||
}
|
||||
|
||||
// sort items into lists
|
||||
@ -1357,6 +1398,10 @@ void p3MsgService::initRsMI(RsMsgItem *msg, MessageInfo &mi)
|
||||
{
|
||||
mi.msgflags |= RS_MSG_NEW;
|
||||
}
|
||||
|
||||
if (msg->msgFlags & RS_MSG_FLAGS_ENCRYPTED)
|
||||
mi.msgflags |= RS_MSG_ENCRYPTED ;
|
||||
|
||||
if (msg->msgFlags & RS_MSG_FLAGS_TRASH)
|
||||
{
|
||||
mi.msgflags |= RS_MSG_TRASH;
|
||||
@ -1442,6 +1487,9 @@ void p3MsgService::initRsMIS(RsMsgItem *msg, MsgInfoSummary &mis)
|
||||
{
|
||||
mis.msgflags = 0;
|
||||
|
||||
if (msg->msgFlags & RS_MSG_FLAGS_ENCRYPTED)
|
||||
mis.msgflags |= RS_MSG_ENCRYPTED ;
|
||||
|
||||
/* translate flags, if we sent it... outgoing */
|
||||
if ((msg->msgFlags & RS_MSG_FLAGS_OUTGOING)
|
||||
/*|| (msg->PeerId() == mLinkMgr->getOwnId())*/)
|
||||
@ -1513,7 +1561,8 @@ RsMsgItem *p3MsgService::initMIRsMsg(MessageInfo &info, const std::string &to)
|
||||
msg -> recvTime = 0;
|
||||
|
||||
msg -> subject = info.title;
|
||||
msg -> message = info.msg;
|
||||
|
||||
msg -> message = info.msg;
|
||||
|
||||
std::list<std::string>::iterator pit;
|
||||
for(pit = info.msgto.begin(); pit != info.msgto.end(); pit++)
|
||||
@ -1538,6 +1587,10 @@ RsMsgItem *p3MsgService::initMIRsMsg(MessageInfo &info, const std::string &to)
|
||||
msg -> attachment.title = info.attach_title;
|
||||
msg -> attachment.comment = info.attach_comment;
|
||||
|
||||
RsPeerDetails details ;
|
||||
if(!rsPeers->getPeerDetails(to,details))
|
||||
msg->msgFlags |= RS_MSG_FLAGS_DISTANT;
|
||||
|
||||
std::list<FileInfo>::iterator it;
|
||||
for(it = info.files.begin(); it != info.files.end(); it++)
|
||||
{
|
||||
@ -1550,15 +1603,428 @@ RsMsgItem *p3MsgService::initMIRsMsg(MessageInfo &info, const std::string &to)
|
||||
|
||||
/* translate flags from outside */
|
||||
if (info.msgflags & RS_MSG_USER_REQUEST)
|
||||
{
|
||||
msg->msgFlags |= RS_MSG_FLAGS_USER_REQUEST;
|
||||
}
|
||||
if (info.msgflags & RS_MSG_FRIEND_RECOMMENDATION)
|
||||
{
|
||||
msg->msgFlags |= RS_MSG_FLAGS_FRIEND_RECOMMENDATION;
|
||||
}
|
||||
|
||||
//std::cerr << "p3MsgService::initMIRsMsg()" << std::endl;
|
||||
if (info.msgflags & RS_MSG_FRIEND_RECOMMENDATION)
|
||||
msg->msgFlags |= RS_MSG_FLAGS_FRIEND_RECOMMENDATION;
|
||||
|
||||
// See if we need to encrypt this message. If so, we replace the msg text
|
||||
// by the whole message serialized and binary encrypted, so as to obfuscate
|
||||
// all its content.
|
||||
//
|
||||
bool enc_ok = false ;
|
||||
|
||||
if(info.encryption_keys.find(to) != info.encryption_keys.end())
|
||||
encryptMessage(info.encryption_keys[to],msg) ;
|
||||
|
||||
//std::cerr << "p3MsgService::initMIRsMsg()" << std::endl;
|
||||
//msg->print(std::cerr);
|
||||
return msg;
|
||||
}
|
||||
|
||||
bool p3MsgService::encryptMessage(const std::string& pgp_id,RsMsgItem *item)
|
||||
{
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << "Encrypting message with public key " << pgp_id << " in place." << std::endl;
|
||||
#endif
|
||||
|
||||
// 1 - serialise the whole message item into a binary chunk.
|
||||
//
|
||||
uint32_t rssize = _serialiser->size(item) ;
|
||||
unsigned char *data = new unsigned char[rssize] ;
|
||||
|
||||
if(!_serialiser->serialise(item,data,&rssize))
|
||||
{
|
||||
std::cerr << "(EE) p3MsgService::sendTurtleData(): Serialization error." << std::endl;
|
||||
delete[] data ;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2 - pgp-encrypt the chunk with the user-supplied public key.
|
||||
//
|
||||
uint32_t encrypted_size = rssize + 1000 ;
|
||||
unsigned char *encrypted_data = new unsigned char[encrypted_size] ;
|
||||
|
||||
if(!AuthGPG::getAuthGPG()->encryptDataBin(pgp_id,data,rssize,encrypted_data,&encrypted_size))
|
||||
{
|
||||
delete[] data ;
|
||||
delete[] encrypted_data ;
|
||||
std::cerr << "Encryption failed!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
delete[] data ;
|
||||
|
||||
// Now turn the binary encrypted chunk into a readable radix string.
|
||||
//
|
||||
std::string armoured_data ;
|
||||
Radix64::encode((char *)encrypted_data,encrypted_size,armoured_data) ;
|
||||
delete[] encrypted_data ;
|
||||
|
||||
std::wstring encrypted_msg ;
|
||||
|
||||
if(!librs::util::ConvertUtf8ToUtf16(armoured_data,encrypted_msg))
|
||||
return false;
|
||||
|
||||
// wipe the item clean and replace the message by the encrypted data.
|
||||
|
||||
item->message = encrypted_msg ;
|
||||
item->subject = L"" ;
|
||||
item->msgcc.ids.clear() ;
|
||||
item->msgbcc.ids.clear() ;
|
||||
item->msgto.ids.clear() ;
|
||||
item->msgFlags |= RS_MSG_FLAGS_ENCRYPTED ;
|
||||
item->attachment.TlvClear() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool p3MsgService::decryptMessage(const std::string& mId)
|
||||
{
|
||||
uint32_t msgId = atoi(mId.c_str());
|
||||
std::string encrypted_string ;
|
||||
|
||||
{
|
||||
RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
std::map<uint32_t, RsMsgItem *>::iterator mit = imsg.find(msgId);
|
||||
|
||||
if(mit == imsg.end() || !librs::util::ConvertUtf16ToUtf8(mit->second->message,encrypted_string))
|
||||
return false;
|
||||
}
|
||||
|
||||
char *encrypted_data ;
|
||||
size_t encrypted_size ;
|
||||
|
||||
Radix64::decode(encrypted_string,encrypted_data,encrypted_size) ;
|
||||
|
||||
uint32_t decrypted_size = encrypted_size + 500 ;
|
||||
unsigned char *decrypted_data = new unsigned char[decrypted_size] ;
|
||||
|
||||
if(!AuthGPG::getAuthGPG()->decryptDataBin(encrypted_data,encrypted_size,decrypted_data,&decrypted_size))
|
||||
{
|
||||
delete[] encrypted_data ;
|
||||
delete[] decrypted_data ;
|
||||
std::cerr << "decryption failed!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
RsMsgItem *item = dynamic_cast<RsMsgItem*>(_serialiser->deserialise(decrypted_data,&decrypted_size)) ;
|
||||
|
||||
if(item == NULL)
|
||||
return false ;
|
||||
|
||||
{
|
||||
RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
|
||||
*imsg[msgId] = *item ;
|
||||
}
|
||||
delete item ;
|
||||
|
||||
IndicateConfigChanged() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
void p3MsgService::connectToTurtleRouter(p3turtle *pt)
|
||||
{
|
||||
mTurtle = pt ;
|
||||
pt->registerTunnelService(this) ;
|
||||
}
|
||||
bool p3MsgService::createDistantOfflineMessengingInvite(time_t time_of_validity,TurtleFileHash& hash)
|
||||
{
|
||||
unsigned char hash_bytes[DISTANT_MSG_HASH_SIZE] ;
|
||||
RSRandom::random_bytes( hash_bytes, DISTANT_MSG_HASH_SIZE) ;
|
||||
|
||||
hash = t_RsGenericIdType<DISTANT_MSG_HASH_SIZE>(hash_bytes).toStdString(false) ;
|
||||
|
||||
DistantMessengingInvite invite ;
|
||||
invite.time_of_validity = time_of_validity + time(NULL);
|
||||
|
||||
{
|
||||
RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
|
||||
_messenging_invites[hash] = invite ;
|
||||
}
|
||||
IndicateConfigChanged() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
bool p3MsgService::getDistantOfflineMessengingInvites(std::vector<DistantOfflineMessengingInvite>& invites)
|
||||
{
|
||||
RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
for(std::map<std::string,DistantMessengingInvite>::const_iterator it(_messenging_invites.begin());it!=_messenging_invites.end();++it)
|
||||
{
|
||||
DistantOfflineMessengingInvite invite ;
|
||||
invite.hash = it->first ;
|
||||
invite.issuer_pgp_id = AuthGPG::getAuthGPG()->getGPGOwnId() ;
|
||||
invite.time_of_validity = it->second.time_of_validity ;
|
||||
|
||||
invites.push_back(invite) ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " adding invite with hash " << invite.hash << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
bool p3MsgService::handleTunnelRequest(const std::string& hash,const std::string& peer_id)
|
||||
{
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << "p3MsgService::handleTunnelRequest: received TR for hash " << hash << std::endl;
|
||||
#endif
|
||||
|
||||
RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
|
||||
std::map<std::string,DistantMessengingInvite>::const_iterator it = _messenging_invites.find(hash) ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
if(it != _messenging_invites.end())
|
||||
std::cerr << "Responding OK!" << std::endl;
|
||||
#endif
|
||||
|
||||
return it != _messenging_invites.end() ;
|
||||
}
|
||||
|
||||
void p3MsgService::manageDistantPeers()
|
||||
{
|
||||
// now possibly flush pending messages
|
||||
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << "p3MsgService::manageDistantPeers()" << std::endl;
|
||||
#endif
|
||||
|
||||
std::vector<std::pair<std::string,RsMsgItem*> > to_send ;
|
||||
|
||||
{
|
||||
RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
|
||||
for(std::map<std::string,DistantMessengingContact>::iterator it(_messenging_contacts.begin());it!=_messenging_contacts.end();++it)
|
||||
if(it->second.status == RS_DISTANT_MSG_STATUS_TUNNEL_OK)
|
||||
{
|
||||
for(uint32_t i=0;i<it->second.pending_messages.size();++i)
|
||||
to_send.push_back(std::pair<std::string,RsMsgItem*>(it->first,it->second.pending_messages[i])) ;
|
||||
|
||||
it->second.pending_messages.clear() ;
|
||||
}
|
||||
}
|
||||
|
||||
for(uint32_t i=0;i<to_send.size();++i)
|
||||
{
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " Flushing msg " << to_send[i].second->msgId << std::endl;
|
||||
#endif
|
||||
sendTurtleData(to_send[i].first,to_send[i].second) ;
|
||||
}
|
||||
|
||||
time_t now = time(NULL) ;
|
||||
{
|
||||
RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
// clean dead invites.
|
||||
//
|
||||
for(std::map<std::string,DistantMessengingInvite>::iterator it(_messenging_invites.begin());it!=_messenging_invites.end();)
|
||||
if(it->second.time_of_validity < now)
|
||||
{
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " Removing outdated invite " << it->second.time_of_validity << ", hash=" << it->first << std::endl;
|
||||
#endif
|
||||
std::map<std::string,DistantMessengingInvite>::iterator tmp(it) ;
|
||||
++tmp ;
|
||||
_messenging_invites.erase(it) ;
|
||||
it = tmp ;
|
||||
}
|
||||
else
|
||||
++it ;
|
||||
|
||||
// clean dead contacts.
|
||||
//
|
||||
for(std::map<std::string,DistantMessengingContact>::iterator it(_messenging_contacts.begin());it!=_messenging_contacts.end();)
|
||||
if(it->second.pending_messages.empty() && it->second.status == RS_DISTANT_MSG_STATUS_TUNNEL_DN)
|
||||
{
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << " Removing dead contact with no pending msgs and dead tunnel. hash=" << it->first << std::endl;
|
||||
#endif
|
||||
std::map<std::string,DistantMessengingContact>::iterator tmp(it) ;
|
||||
++tmp ;
|
||||
_messenging_contacts.erase(it) ;
|
||||
it = tmp ;
|
||||
}
|
||||
else
|
||||
++it ;
|
||||
}
|
||||
}
|
||||
|
||||
void p3MsgService::addVirtualPeer(const TurtleFileHash& hash, const TurtleVirtualPeerId& vpid,RsTurtleGenericTunnelItem::Direction dir)
|
||||
{
|
||||
RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
|
||||
// A new tunnel has been created. We need to flush pending messages for the corresponding peer.
|
||||
|
||||
//std::map<std::string,DistantMessengingContact>::const_iterator it = _messenging_contacts.find(hash) ;
|
||||
|
||||
DistantMessengingContact& contact(_messenging_contacts[hash]) ; // possibly creates it.
|
||||
|
||||
contact.virtual_peer_id = vpid ;
|
||||
contact.last_hit_time = time(NULL) ;
|
||||
contact.status = RS_DISTANT_MSG_STATUS_TUNNEL_OK ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << "p3MsgService::addVirtualPeer(): adding virtual peer " << vpid << " for hash " << hash << std::endl;
|
||||
#endif
|
||||
}
|
||||
void p3MsgService::removeVirtualPeer(const TurtleFileHash& hash, const TurtleVirtualPeerId& vpid)
|
||||
{
|
||||
RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
|
||||
// A new tunnel has been created. We need to flush pending messages for the corresponding peer.
|
||||
|
||||
//std::map<std::string,DistantMessengingContact>::const_iterator it = _messenging_contacts.find(hash) ;
|
||||
|
||||
DistantMessengingContact& contact(_messenging_contacts[hash]) ; // possibly creates it.
|
||||
|
||||
contact.status = RS_DISTANT_MSG_STATUS_TUNNEL_DN ;
|
||||
contact.virtual_peer_id.clear() ;
|
||||
}
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
static void printBinaryData(void *data,uint32_t size)
|
||||
{
|
||||
static const char outl[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' } ;
|
||||
|
||||
for(uint32_t j = 0; j < size; j++)
|
||||
{
|
||||
std::cerr << outl[ ( ((uint8_t*)data)[j]>>4) ] ;
|
||||
std::cerr << outl[ ((uint8_t*)data)[j] & 0xf ] ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void p3MsgService::sendTurtleData(const std::string& hash,RsMsgItem *msgitem)
|
||||
{
|
||||
// The item is serialized and turned into a generic turtle item.
|
||||
|
||||
uint32_t rssize = _serialiser->size(msgitem) ;
|
||||
unsigned char *data = new unsigned char[rssize] ;
|
||||
|
||||
if(!_serialiser->serialise(msgitem,data,&rssize))
|
||||
{
|
||||
std::cerr << "(EE) p3MsgService::sendTurtleData(): Serialization error." << std::endl;
|
||||
delete[] data ;
|
||||
return ;
|
||||
}
|
||||
|
||||
RsTurtleGenericDataItem *item = new RsTurtleGenericDataItem ;
|
||||
item->data_bytes = malloc(rssize) ;
|
||||
item->data_size = rssize ;
|
||||
memcpy(item->data_bytes,data,rssize) ;
|
||||
|
||||
delete[] data ;
|
||||
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
printBinaryData(item->data_bytes,item->data_size) ;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
// do we have a working tunnel for that hash ?
|
||||
// If not, put on the contact's waiting list.
|
||||
|
||||
std::string virtual_peer_id ;
|
||||
{
|
||||
RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
|
||||
std::map<std::string,DistantMessengingContact>::const_iterator it = _messenging_contacts.find(hash) ;
|
||||
|
||||
if(it == _messenging_contacts.end())
|
||||
{
|
||||
std::cerr << "(EE) p3MsgService::sendTurtleData(): Can't find hash " << hash << " in recorded contact list." << std::endl;
|
||||
delete[] data ;
|
||||
return ;
|
||||
}
|
||||
|
||||
if(!it->second.status == RS_DISTANT_MSG_STATUS_TUNNEL_OK)
|
||||
{
|
||||
std::cerr << "p3MsgService::sendTurtleData(): tunnel is not ok. Putting items on waiting list." << std::endl;
|
||||
return ;
|
||||
}
|
||||
virtual_peer_id = it->second.virtual_peer_id ;
|
||||
}
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << "p3MsgService::sendTurtleData(): Sending through virtual peer: " << virtual_peer_id << std::endl;
|
||||
std::cerr << " item->data_size = " << item->data_size << std::endl;
|
||||
std::cerr << " data = " ;
|
||||
#endif
|
||||
|
||||
mTurtle->sendTurtleData(virtual_peer_id,item) ;
|
||||
}
|
||||
|
||||
void p3MsgService::receiveTurtleData(RsTurtleGenericTunnelItem *gitem,const std::string& hash,
|
||||
const std::string& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction)
|
||||
{
|
||||
RsTurtleGenericDataItem *item = dynamic_cast<RsTurtleGenericDataItem*>(gitem) ;
|
||||
|
||||
if(item == NULL)
|
||||
{
|
||||
std::cerr << "(EE) p3MsgService::receiveTurtleData(): item is not a data item. That is an error." << std::endl;
|
||||
return ;
|
||||
}
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << "p3MsgService::sendTurtleData(): Receiving through virtual peer: " << virtual_peer_id << std::endl;
|
||||
std::cerr << " gitem->data_size = " << item->data_size << std::endl;
|
||||
std::cerr << " data = " ;
|
||||
printBinaryData(item->data_bytes,item->data_size) ;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
{
|
||||
RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
|
||||
std::map<std::string,DistantMessengingContact>::iterator it = _messenging_contacts.find(hash) ;
|
||||
|
||||
if(it == _messenging_contacts.end())
|
||||
{
|
||||
std::cerr << "(EE) p3MsgService::sendTurtleData(): Can't find hash " << hash << " in recorded contact list." << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
it->second.status = RS_DISTANT_MSG_STATUS_TUNNEL_OK ;
|
||||
it->second.last_hit_time = time(NULL) ;
|
||||
}
|
||||
|
||||
RsItem *itm = _serialiser->deserialise(item->data_bytes,&item->data_size) ;
|
||||
|
||||
RsMsgItem *mitm = dynamic_cast<RsMsgItem*>(itm) ;
|
||||
|
||||
if(mitm != NULL)
|
||||
{
|
||||
mitm->PeerId(hash) ;
|
||||
handleIncomingItem(mitm) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "(EE) p3MsgService::receiveTurtleData(): received item is not a RsMsgItem!!" << std::endl;
|
||||
delete itm ;
|
||||
}
|
||||
}
|
||||
|
||||
void p3MsgService::sendPrivateMsgItem(RsMsgItem *msgitem)
|
||||
{
|
||||
#ifdef DEBUG_DISTANT_MSG
|
||||
std::cerr << "p3MsgService::sendDistanteMsgItem(): sending distant msg item to peer " << msgitem->PeerId() << std::endl;
|
||||
std::cerr << " asking for tunnels" << std::endl;
|
||||
std::cerr << " recording msg info" << std::endl;
|
||||
#endif
|
||||
const std::string& hash = msgitem->PeerId() ;
|
||||
rsTurtle->monitorTunnels(hash,this) ; // create a tunnel for it, and put the msg on the waiting list.
|
||||
|
||||
{
|
||||
RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
|
||||
|
||||
// allocate a new contact. If it does not exist, set its tunnel state to DN
|
||||
//
|
||||
std::map<std::string,DistantMessengingContact>::iterator it = _messenging_contacts.find(hash) ;
|
||||
|
||||
DistantMessengingContact& contact( _messenging_contacts[hash] ) ;
|
||||
|
||||
if(it == _messenging_contacts.end())
|
||||
it->second.status = RS_DISTANT_MSG_STATUS_TUNNEL_DN ;
|
||||
|
||||
contact.pending_messages.push_back(msgitem) ; // record the msg to be sent.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -42,10 +42,12 @@
|
||||
#include "services/p3service.h"
|
||||
#include "serialiser/rsmsgitems.h"
|
||||
#include "util/rsthreads.h"
|
||||
#include "turtle/p3turtle.h"
|
||||
#include "turtle/turtleclientservice.h"
|
||||
|
||||
class p3LinkMgr;
|
||||
|
||||
class p3MsgService: public p3Service, public p3Config, public pqiMonitor
|
||||
class p3MsgService: public p3Service, public p3Config, public pqiMonitor, public RsTurtleClientService
|
||||
{
|
||||
public:
|
||||
p3MsgService(p3LinkMgr *lm);
|
||||
@ -55,6 +57,7 @@ bool getMessageSummaries(std::list<MsgInfoSummary> &msgList);
|
||||
bool getMessage(const std::string &mid, MessageInfo &msg);
|
||||
void getMessageCount(unsigned int *pnInbox, unsigned int *pnInboxNew, unsigned int *pnOutbox, unsigned int *pnDraftbox, unsigned int *pnSentbox, unsigned int *pnTrashbox);
|
||||
|
||||
bool decryptMessage(const std::string& mid) ;
|
||||
bool removeMsgId(const std::string &mid);
|
||||
bool markMsgIdRead(const std::string &mid, bool bUnreadByUser);
|
||||
bool setMsgFlag(const std::string &mid, uint32_t flag, uint32_t mask);
|
||||
@ -97,7 +100,51 @@ virtual void statusChange(const std::list<pqipeer> &plist);
|
||||
int checkOutgoingMessages();
|
||||
/*** Overloaded from pqiMonitor ***/
|
||||
|
||||
/*** overloaded from p3turtle ***/
|
||||
|
||||
void connectToTurtleRouter(p3turtle *) ;
|
||||
|
||||
struct DistantMessengingInvite
|
||||
{
|
||||
time_t time_of_validity ;
|
||||
};
|
||||
struct DistantMessengingContact
|
||||
{
|
||||
time_t last_hit_time ;
|
||||
std::string virtual_peer_id ;
|
||||
uint32_t status ;
|
||||
std::vector<RsMsgItem*> pending_messages ;
|
||||
};
|
||||
|
||||
bool createDistantOfflineMessengingInvite(time_t time_of_validity,TurtleFileHash& hash) ;
|
||||
bool getDistantOfflineMessengingInvites(std::vector<DistantOfflineMessengingInvite>& invites) ;
|
||||
void sendPrivateMsgItem(RsMsgItem *) ;
|
||||
|
||||
private:
|
||||
// This maps contains the current invitations to respond to.
|
||||
//
|
||||
std::map<std::string,DistantMessengingInvite> _messenging_invites ;
|
||||
|
||||
// This contains the ongoing tunnel handling contacts.
|
||||
//
|
||||
std::map<std::string,DistantMessengingContact> _messenging_contacts ;
|
||||
|
||||
// Overloaded from RsTurtleClientService
|
||||
|
||||
virtual bool handleTunnelRequest(const std::string& hash,const std::string& peer_id) ;
|
||||
virtual void receiveTurtleData(RsTurtleGenericTunnelItem *item,const std::string& hash,const std::string& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction) ;
|
||||
void addVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&,RsTurtleGenericTunnelItem::Direction dir) ;
|
||||
void removeVirtualPeer(const TurtleFileHash&, const TurtleVirtualPeerId&) ;
|
||||
|
||||
// Utility functions
|
||||
|
||||
bool encryptMessage(const std::string& pgp_id,RsMsgItem *msg) ;
|
||||
|
||||
void manageDistantPeers() ;
|
||||
void sendTurtleData(const std::string& hash,RsMsgItem *) ;
|
||||
void handleIncomingItem(RsMsgItem *) ;
|
||||
|
||||
p3turtle *mTurtle ;
|
||||
|
||||
uint32_t getNewUniqueMsgId();
|
||||
int sendMessage(RsMsgItem *item);
|
||||
@ -118,6 +165,7 @@ void initStandardTagTypes();
|
||||
/* Mutex Required for stuff below */
|
||||
|
||||
RsMutex mMsgMtx;
|
||||
RsMsgSerialiser *_serialiser ;
|
||||
|
||||
/* stored list of messages */
|
||||
std::map<uint32_t, RsMsgItem *> imsg;
|
||||
|
@ -4,7 +4,7 @@ class MonitoredTurtleRouter: public p3turtle
|
||||
{
|
||||
public:
|
||||
MonitoredTurtleRouter(p3LinkMgr *lmgr,ftServer *fts)
|
||||
: p3turtle(lmgr,fts)
|
||||
: p3turtle(lmgr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ void PeerNode::provideFileHash(const std::string& hash)
|
||||
void PeerNode::manageFileHash(const std::string& hash)
|
||||
{
|
||||
_managed_hashes.insert(hash) ;
|
||||
_turtle->monitorFileTunnels("file 1",hash,10000) ;
|
||||
_turtle->monitorTunnels(hash,_ftserver) ;
|
||||
}
|
||||
|
||||
void PeerNode::getTrafficInfo(NodeTrafficInfo& info)
|
||||
|
@ -47,6 +47,7 @@ class PeerNode
|
||||
private:
|
||||
p3ServiceServer *_service_server ;
|
||||
MonitoredTurtleRouter *_turtle ;
|
||||
ftServer *_ftserver ;
|
||||
std::string _id ;
|
||||
|
||||
std::set<TurtleFileHash> _provided_hashes ;
|
||||
|
@ -9,8 +9,8 @@ OPS_TOP_DIR = ../../../../openpgpsdk/src
|
||||
include $(RS_TOP_DIR)/tests/scripts/config.mk
|
||||
###############################################################
|
||||
|
||||
TESTOBJ = dirtest.o sha1_test.o
|
||||
TESTS = dirtest sha1_test
|
||||
TESTOBJ = dirtest.o sha1_test.o aes_test.o dchat_decrypt.o
|
||||
TESTS = dirtest sha1_test aes_test dchat_decrypt
|
||||
|
||||
all: tests
|
||||
|
||||
@ -18,6 +18,10 @@ sha1_test: sha1_test.o
|
||||
$(CC) $(CFLAGS) -o sha1_test sha1_test.o $(LIBS)
|
||||
dirtest: dirtest.o
|
||||
$(CC) $(CFLAGS) -o dirtest dirtest.o $(LIBS)
|
||||
dirtest: aes_test.o
|
||||
$(CC) $(CFLAGS) -o aes_test aes_test.o $(LIBS)
|
||||
dchat_decrypt: dchat_decrypt.o
|
||||
$(CC) $(CFLAGS) -o dchat_decrypt dchat_decrypt.o $(LIBS)
|
||||
|
||||
###############################################################
|
||||
include $(RS_TOP_DIR)/tests/scripts/rules.mk
|
||||
|
115
libretroshare/src/tests/util/aes_test.cc
Normal file
115
libretroshare/src/tests/util/aes_test.cc
Normal file
@ -0,0 +1,115 @@
|
||||
|
||||
/*
|
||||
* "$Id: dirtest.cc,v 1.1 2007-02-19 20:08:30 rmf24 Exp $"
|
||||
*
|
||||
* RetroShare C++ Interface.
|
||||
*
|
||||
* Copyright 2012-2012 by Cyril Soler
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "util/rsaes.h"
|
||||
#include "util/utest.h"
|
||||
#include <common/argstream.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <stdio.h>
|
||||
|
||||
void printHelp(int argc,char *argv[])
|
||||
{
|
||||
std::cerr << argv[0] << ": tests AES encryption/decryption functions." << std::endl;
|
||||
std::cerr << "Usage: " << argv[0] << std::endl ;
|
||||
}
|
||||
|
||||
void printHex(unsigned char *data,uint32_t length)
|
||||
{
|
||||
static const char outh[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' } ;
|
||||
static const char outl[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' } ;
|
||||
|
||||
for(uint32_t j = 0; j < length; j++)
|
||||
{
|
||||
std::cerr << outh[ (data[j]>>4) ] ;
|
||||
std::cerr << outh[ data[j] & 0xf ] ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
INITTEST() ;
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
std::string inputfile ;
|
||||
argstream as(argc,argv) ;
|
||||
|
||||
as >> help() ;
|
||||
|
||||
as.defaultErrorHandling() ;
|
||||
|
||||
std::cerr << "Testing AES crypt" << std::endl;
|
||||
|
||||
std::string source_string = "This is a very secret string, but ultimately it will always be decyphered" ;
|
||||
std::cerr << "Input string: length=" << source_string.length() << ", s=\"" << source_string << "\"" << std::endl;
|
||||
|
||||
unsigned char key_data[16] ;
|
||||
unsigned char salt[8] ;
|
||||
|
||||
for(int i=0;i<16;++i)
|
||||
key_data[i] = lrand48() & 0xff ;
|
||||
|
||||
std::cerr << "Key: " ; printHex(key_data,16);
|
||||
std::cerr << std::endl;
|
||||
|
||||
for(int i=5;i<source_string.length();++i)
|
||||
{
|
||||
for(int j=0;j<8;++j)
|
||||
salt[j] = lrand48() & 0xff ;
|
||||
|
||||
std::string S(source_string.c_str(),i) ;
|
||||
|
||||
unsigned char output_data[S.size() + 16] ;
|
||||
uint32_t output_data_length = S.size() + 16 ;
|
||||
|
||||
CHECK(RsAES::aes_crypt_8_16( (const uint8_t*)S.c_str(),S.length(),key_data,salt,output_data,output_data_length)) ;
|
||||
|
||||
std::cerr << "Round " << i << " salt=" ;
|
||||
printHex(salt,8) ;
|
||||
std::cerr << ": real_length = " << S.length() << ", output_length = " << output_data_length << ", encrypted string = " ;
|
||||
printHex(output_data,output_data_length) ;
|
||||
std::cerr << std::endl;
|
||||
|
||||
unsigned char output_data2[output_data_length + 16] ;
|
||||
uint32_t output_data_length2 = output_data_length + 16 ;
|
||||
|
||||
CHECK(RsAES::aes_decrypt_8_16(output_data,output_data_length,key_data,salt,output_data2,output_data_length2)) ;
|
||||
|
||||
std::cerr << " output_length = " << output_data_length2 << ", decrypted string = " ;
|
||||
printHex(output_data2,output_data_length2) ;
|
||||
std::cerr << std::endl;
|
||||
|
||||
CHECK(std::string( (const char *)output_data2,output_data_length2) == S) ;
|
||||
}
|
||||
|
||||
FINALREPORT("AESTest") ;
|
||||
return TESTRESULT() ;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -150,6 +150,7 @@
|
||||
#include "ft/ftsearch.h"
|
||||
#include "retroshare/rsturtle.h"
|
||||
#include "rsturtleitem.h"
|
||||
#include "turtleclientservice.h"
|
||||
#include "turtlestatistics.h"
|
||||
|
||||
//#define TUNNEL_STATISTICS
|
||||
@ -191,15 +192,14 @@ class TurtleTunnel
|
||||
|
||||
// This class keeps trace of the activity for the file hashes the turtle router is asked to monitor.
|
||||
//
|
||||
class TurtleFileHashInfo
|
||||
|
||||
class TurtleHashInfo
|
||||
{
|
||||
public:
|
||||
std::vector<TurtleTunnelId> tunnels ; // list of active tunnel ids for this file hash
|
||||
TurtleRequestId last_request ; // last request for the tunnels of this hash
|
||||
|
||||
TurtleFileName name ;
|
||||
time_t last_digg_time ;
|
||||
uint64_t size ;
|
||||
time_t last_digg_time ; // last time the tunnel digging happenned.
|
||||
RsTurtleClientService *service ; // client service to which items should be sent. Never NULL.
|
||||
};
|
||||
|
||||
// Subclassing:
|
||||
@ -216,22 +216,25 @@ class TurtleFileHashInfo
|
||||
class p3turtle: public p3Service, public RsTurtle, public p3Config
|
||||
{
|
||||
public:
|
||||
p3turtle(p3LinkMgr *lm,ftServer *m);
|
||||
p3turtle(p3LinkMgr *lm) ;
|
||||
|
||||
// Enables/disable the service. Still ticks, but does nothing. Default is true.
|
||||
//
|
||||
virtual void setEnabled(bool) ;
|
||||
virtual bool enabled() const ;
|
||||
|
||||
// This is temporary, used by Operating Mode.
|
||||
// This is temporary, used by Operating Mode.
|
||||
// Turtle operates when both enabled() && sessionEnabled() are true.
|
||||
virtual void setSessionEnabled(bool);
|
||||
virtual bool sessionEnabled() const;
|
||||
virtual void setSessionEnabled(bool);
|
||||
virtual bool sessionEnabled() const;
|
||||
|
||||
// Lauches a search request through the pipes, and immediately returns
|
||||
// the request id, which will be further used by the gui to store results
|
||||
// as they come back.
|
||||
//
|
||||
// Eventually, search requests should be handled by client services. We will therefore
|
||||
// remove the specific file search packets from the turtle router.
|
||||
//
|
||||
virtual TurtleSearchRequestId turtleSearch(const std::string& string_to_match) ;
|
||||
virtual TurtleSearchRequestId turtleSearch(const LinearizedExpression& expr) ;
|
||||
|
||||
@ -247,12 +250,21 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
|
||||
// This function should be called in addition to ftServer::FileRequest() so that the turtle router
|
||||
// automatically provide tunnels for the file to download.
|
||||
//
|
||||
virtual void monitorFileTunnels(const std::string& name,const std::string& file_hash,uint64_t size) ;
|
||||
virtual void monitorTunnels(const std::string& file_hash,RsTurtleClientService *client_service) ;
|
||||
|
||||
/// This should be called when canceling a file download, so that the turtle router stops
|
||||
/// handling tunnels for this file.
|
||||
///
|
||||
virtual void stopMonitoringFileTunnels(const std::string& file_hash) ;
|
||||
virtual void stopMonitoringTunnels(const std::string& file_hash) ;
|
||||
|
||||
/// Adds a client tunnel service. This means that the service will be added
|
||||
/// to the list of services that might respond to tunnel requests.
|
||||
/// Example tunnel services include:
|
||||
///
|
||||
/// p3ChatService: tunnels correspond to private distant chatting
|
||||
/// ftServer : tunnels correspond to file data transfer
|
||||
///
|
||||
virtual void registerTunnelService(RsTurtleClientService *service) ;
|
||||
|
||||
/// get info about tunnels
|
||||
virtual void getInfo(std::vector<std::vector<std::string> >&,
|
||||
@ -277,7 +289,7 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
|
||||
virtual bool saveList(bool& cleanup, std::list<RsItem*>&) ;
|
||||
virtual bool loadList(std::list<RsItem*>& /*load*/) ;
|
||||
|
||||
/************* Communication with ftserver *******************/
|
||||
/************* Communication with clients *******************/
|
||||
/// Does the turtle router manages tunnels to this peer ? (this is not a
|
||||
/// real id, but a fake one, that the turtle router is capable of connecting with a tunnel id).
|
||||
virtual bool isTurtlePeer(const std::string& peer_id) const ;
|
||||
@ -296,28 +308,7 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
|
||||
void getVirtualPeersList(std::list<pqipeer>& list) ;
|
||||
|
||||
/// Send a data request into the correct tunnel for the given file hash
|
||||
void sendDataRequest(const std::string& peerId, const std::string& hash, uint64_t size, uint64_t offset, uint32_t chunksize) ;
|
||||
|
||||
/// Send file data into the correct tunnel for the given file hash
|
||||
void sendFileData(const std::string& peerId, const std::string& hash, uint64_t size, uint64_t baseoffset, uint32_t chunksize, void *data) ;
|
||||
|
||||
/// Send a request for the chunk map of this file to the given peer
|
||||
void sendChunkMapRequest(const std::string& peerId, const std::string& hash,bool is_client) ;
|
||||
|
||||
/// Send a chunk map of this file to the given peer
|
||||
void sendChunkMap(const std::string& peerId, const std::string& hash,const CompressedChunkMap& cmap,bool is_client) ;
|
||||
|
||||
/// Send a request for the crc32 map of this file to the given peer
|
||||
void sendCRC32MapRequest(const std::string& peerId, const std::string& hash) ;
|
||||
|
||||
/// Send a crc32 map of this file to the given peer
|
||||
void sendCRC32Map(const std::string& peerId, const std::string& hash,const CRC32Map& cmap) ;
|
||||
|
||||
/// Send a request for the CRC of a single chunk of this file to the given peer
|
||||
void sendSingleChunkCRCRequest(const std::string& peerId, const std::string& hash,uint32_t chunk_number) ;
|
||||
|
||||
/// Send a crc32 map of this file to the given peer
|
||||
void sendSingleChunkCRC(const std::string& peerId, const std::string& hash,uint32_t chunk_number,const Sha1CheckSum& sum) ;
|
||||
void sendTurtleData(const std::string& virtual_peer_id, RsTurtleGenericTunnelItem *item) ;
|
||||
|
||||
private:
|
||||
//--------------------------- Admin/Helper functions -------------------------//
|
||||
@ -360,18 +351,14 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
|
||||
void routeGenericTunnelItem(RsTurtleGenericTunnelItem *item) ;
|
||||
|
||||
/// specific routing functions for handling particular packets.
|
||||
void handleRecvGenericTunnelItem(RsTurtleGenericTunnelItem *item);
|
||||
bool getTunnelServiceInfo(TurtleTunnelId, std::string& virtual_peer_id, std::string& hash, RsTurtleClientService*&) ;
|
||||
|
||||
// following functions should go to ftServer
|
||||
void handleSearchRequest(RsTurtleSearchRequestItem *item);
|
||||
void handleSearchResult(RsTurtleSearchResultItem *item);
|
||||
void handleTunnelRequest(RsTurtleOpenTunnelItem *item);
|
||||
void handleTunnelResult(RsTurtleTunnelOkItem *item);
|
||||
void handleRecvFileRequest(RsTurtleFileRequestItem *item);
|
||||
void handleRecvFileData(RsTurtleFileDataItem *item);
|
||||
void handleRecvFileMapRequest(RsTurtleFileMapRequestItem*);
|
||||
void handleRecvFileMap(RsTurtleFileMapItem*);
|
||||
void handleRecvFileCRC32MapRequest(RsTurtleFileCrcRequestItem*);
|
||||
void handleRecvFileCRC32Map(RsTurtleFileCrcItem*);
|
||||
void handleRecvChunkCRCRequest(RsTurtleChunkCrcRequestItem*);
|
||||
void handleRecvChunkCRC(RsTurtleChunkCrcItem*);
|
||||
|
||||
//------ Functions connecting the turtle router to other components.----------//
|
||||
|
||||
@ -382,14 +369,13 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
|
||||
void returnSearchResult(RsTurtleSearchResultItem *item) ;
|
||||
|
||||
/// Returns true if the file with given hash is hosted locally, and accessible in anonymous mode the supplied peer.
|
||||
virtual bool performLocalHashSearch(const TurtleFileHash& hash,const std::string& client_peer_id,FileInfo& info) ;
|
||||
virtual bool performLocalHashSearch(const TurtleFileHash& hash,const std::string& client_peer_id,RsTurtleClientService *& service);
|
||||
|
||||
//--------------------------- Local variables --------------------------------//
|
||||
|
||||
/* data */
|
||||
p3LinkMgr *mLinkMgr;
|
||||
ftServer *_ft_server ;
|
||||
ftController *_ft_controller ;
|
||||
RsTurtleSerialiser *_serialiser ;
|
||||
|
||||
mutable RsMutex mTurtleMtx;
|
||||
|
||||
@ -400,10 +386,10 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
|
||||
std::map<TurtleTunnelRequestId,TurtleRequestInfo> _tunnel_requests_origins ;
|
||||
|
||||
/// stores adequate tunnels for each file hash locally managed
|
||||
std::map<TurtleFileHash,TurtleFileHashInfo> _incoming_file_hashes ;
|
||||
std::map<TurtleFileHash,TurtleHashInfo> _incoming_file_hashes ;
|
||||
|
||||
/// stores file info for each file we provide.
|
||||
std::map<TurtleFileHash,FileInfo> _outgoing_file_hashes ;
|
||||
std::map<TurtleFileHash,RsTurtleClientService *> _outgoing_file_hashes ;
|
||||
|
||||
/// local tunnels, stored by ids (Either transiting or ending).
|
||||
std::map<TurtleTunnelId,TurtleTunnel > _local_tunnels ;
|
||||
@ -414,6 +400,9 @@ class p3turtle: public p3Service, public RsTurtle, public p3Config
|
||||
/// Hashes marked to be deleted.
|
||||
std::vector<TurtleFileHash> _hashes_to_remove ;
|
||||
|
||||
/// List of client services that have regitered.
|
||||
std::list<RsTurtleClientService*> _registered_services ;
|
||||
|
||||
time_t _last_clean_time ;
|
||||
time_t _last_tunnel_management_time ;
|
||||
time_t _last_tunnel_campaign_time ;
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <iostream>
|
||||
#include "turtletypes.h"
|
||||
#include "rsturtleitem.h"
|
||||
#include "turtleclientservice.h"
|
||||
|
||||
//#define P3TURTLE_DEBUG
|
||||
// -----------------------------------------------------------------------------------//
|
||||
@ -90,98 +91,14 @@ uint32_t RsTurtleTunnelOkItem::serial_size()
|
||||
return s ;
|
||||
}
|
||||
|
||||
uint32_t RsTurtleFileRequestItem::serial_size()
|
||||
uint32_t RsTurtleGenericDataItem::serial_size()
|
||||
{
|
||||
uint32_t s = 0 ;
|
||||
|
||||
s += 8 ; // header
|
||||
s += 4 ; // tunnel id
|
||||
s += 8 ; // file offset
|
||||
s += 4 ; // chunk size
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
||||
uint32_t RsTurtleFileDataItem::serial_size()
|
||||
{
|
||||
uint32_t s = 0 ;
|
||||
|
||||
s += 8 ; // header
|
||||
s += 4 ; // tunnel id
|
||||
s += 8 ; // file offset
|
||||
s += 4 ; // chunk size
|
||||
s += chunk_size ; // actual data size.
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
||||
uint32_t RsTurtleFileMapRequestItem::serial_size()
|
||||
{
|
||||
uint32_t s = 0 ;
|
||||
|
||||
s += 8 ; // header
|
||||
s += 4 ; // tunnel id
|
||||
s += 4 ; // direction
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
||||
uint32_t RsTurtleFileMapItem::serial_size()
|
||||
{
|
||||
uint32_t s = 0 ;
|
||||
|
||||
s += 8 ; // header
|
||||
s += 4 ; // tunnel id
|
||||
s += 4 ; // direction
|
||||
s += 4 ; // compressed_map.size()
|
||||
|
||||
s += 4 * compressed_map._map.size() ;
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
||||
uint32_t RsTurtleFileCrcRequestItem::serial_size()
|
||||
{
|
||||
uint32_t s = 0 ;
|
||||
|
||||
s += 8 ; // header
|
||||
s += 4 ; // tunnel id
|
||||
|
||||
return s ;
|
||||
}
|
||||
uint32_t RsTurtleChunkCrcItem::serial_size()
|
||||
{
|
||||
uint32_t s = 0 ;
|
||||
|
||||
s += 8 ; // header
|
||||
s += 4 ; // tunnel id
|
||||
s += 4 ; // chunk number
|
||||
s += 20 ; // check_sum
|
||||
|
||||
return s ;
|
||||
}
|
||||
uint32_t RsTurtleChunkCrcRequestItem::serial_size()
|
||||
{
|
||||
uint32_t s = 0 ;
|
||||
|
||||
s += 8 ; // header
|
||||
s += 4 ; // tunnel id
|
||||
s += 4 ; // chunk number
|
||||
|
||||
return s ;
|
||||
}
|
||||
uint32_t RsTurtleFileCrcItem::serial_size()
|
||||
{
|
||||
uint32_t s = 0 ;
|
||||
|
||||
s += 8 ; // header
|
||||
s += 4 ; // tunnel id
|
||||
|
||||
s += 4 ; // size of _map
|
||||
s += 4 ; // size of _crcs
|
||||
|
||||
s += 4 * crc_map._crcs.size() ;
|
||||
s += 4 * crc_map._ccmap._map.size() ;
|
||||
s += 4 ; // data size
|
||||
s += data_size ; // data
|
||||
|
||||
return s ;
|
||||
}
|
||||
@ -216,19 +133,21 @@ RsItem *RsTurtleSerialiser::deserialise(void *data, uint32_t *size)
|
||||
case RS_TURTLE_SUBTYPE_SEARCH_RESULT : return new RsTurtleSearchResultItem(data,*size) ;
|
||||
case RS_TURTLE_SUBTYPE_OPEN_TUNNEL : return new RsTurtleOpenTunnelItem(data,*size) ;
|
||||
case RS_TURTLE_SUBTYPE_TUNNEL_OK : return new RsTurtleTunnelOkItem(data,*size) ;
|
||||
case RS_TURTLE_SUBTYPE_FILE_REQUEST : return new RsTurtleFileRequestItem(data,*size) ;
|
||||
case RS_TURTLE_SUBTYPE_FILE_DATA : return new RsTurtleFileDataItem(data,*size) ;
|
||||
case RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST : return new RsTurtleFileMapRequestItem(data,*size) ;
|
||||
case RS_TURTLE_SUBTYPE_FILE_MAP : return new RsTurtleFileMapItem(data,*size) ;
|
||||
case RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST : return new RsTurtleFileCrcRequestItem(data,*size) ;
|
||||
case RS_TURTLE_SUBTYPE_FILE_CRC : return new RsTurtleFileCrcItem(data,*size) ;
|
||||
case RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST : return new RsTurtleChunkCrcRequestItem(data,*size) ;
|
||||
case RS_TURTLE_SUBTYPE_CHUNK_CRC : return new RsTurtleChunkCrcItem(data,*size) ;
|
||||
|
||||
case RS_TURTLE_SUBTYPE_GENERIC_DATA : return new RsTurtleGenericDataItem(data,*size) ;
|
||||
|
||||
default:
|
||||
std::cerr << "Unknown packet type in RsTurtle!" << std::endl ;
|
||||
return NULL ;
|
||||
break ;
|
||||
}
|
||||
// now try all client services
|
||||
//
|
||||
RsItem *item = NULL ;
|
||||
|
||||
for(uint32_t i=0;i<_client_services.size();++i)
|
||||
if((item = _client_services[i]->deserialiseItem(data,*size)) != NULL)
|
||||
return item ;
|
||||
|
||||
std::cerr << "Unknown packet type in RsTurtle (not even handled by client services)!" << std::endl ;
|
||||
return NULL ;
|
||||
#ifndef WINDOWS_SYS
|
||||
}
|
||||
catch(std::exception& e)
|
||||
@ -240,224 +159,6 @@ RsItem *RsTurtleSerialiser::deserialise(void *data, uint32_t *size)
|
||||
|
||||
}
|
||||
|
||||
bool RsTurtleFileMapRequestItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size();
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, direction);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool RsTurtleFileMapItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size();
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, direction);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, compressed_map._map.size());
|
||||
|
||||
for(uint32_t i=0;i<compressed_map._map.size() && ok;++i)
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, compressed_map._map[i]);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool RsTurtleFileCrcRequestItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << "RsTurtleFileCrcRequestItem::serialize(): serializing packet:" << std::endl ;
|
||||
print(std::cerr,2) ;
|
||||
#endif
|
||||
uint32_t tlvsize = serial_size();
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool RsTurtleChunkCrcRequestItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << "RsTurtleChunkCrcRequestItem::serialize(): serializing packet:" << std::endl ;
|
||||
print(std::cerr,2) ;
|
||||
#endif
|
||||
uint32_t tlvsize = serial_size();
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, chunk_number);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
bool RsTurtleFileCrcItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << "RsTurtleFileCrcItem::serialize(): serializing packet:" << std::endl ;
|
||||
print(std::cerr,2) ;
|
||||
#endif
|
||||
uint32_t tlvsize = serial_size();
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, crc_map._ccmap._map.size());
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, crc_map._crcs.size());
|
||||
|
||||
for(uint32_t i=0;i<crc_map._ccmap._map.size() && ok;++i)
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, crc_map._ccmap._map[i]);
|
||||
|
||||
for(uint32_t i=0;i<crc_map._crcs.size() && ok;++i)
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, crc_map._crcs[i]);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
bool RsTurtleChunkCrcItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << "RsTurtleChunkCrcRequestItem::serialize(): serializing packet:" << std::endl ;
|
||||
print(std::cerr,2) ;
|
||||
#endif
|
||||
uint32_t tlvsize = serial_size();
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, chunk_number);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[0]);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[1]);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[2]);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[3]);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, check_sum.fourbytes[4]);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
bool RsTurtleStringSearchRequestItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size();
|
||||
@ -648,169 +349,6 @@ bool RsTurtleSearchResultItem::serialize(void *data,uint32_t& pktsize)
|
||||
return ok;
|
||||
}
|
||||
|
||||
RsTurtleFileMapItem::RsTurtleFileMapItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_MAP)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_MAP) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " type = file map item" << std::endl ;
|
||||
#endif
|
||||
uint32_t offset = 8; // skip the header
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
bool ok = true ;
|
||||
uint32_t s,d ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id);
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &d);
|
||||
direction = d ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &s) ;
|
||||
|
||||
compressed_map._map.resize(s) ;
|
||||
|
||||
for(uint32_t i=0;i<s && ok;++i)
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &(compressed_map._map[i])) ;
|
||||
|
||||
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
|
||||
#else
|
||||
if (offset != pktsize)
|
||||
throw std::runtime_error("Size error while deserializing.") ;
|
||||
if (!ok)
|
||||
throw std::runtime_error("Unknown error while deserializing.") ;
|
||||
#endif
|
||||
}
|
||||
|
||||
RsTurtleFileMapRequestItem::RsTurtleFileMapRequestItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_MAP_REQUEST) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " type = file map request item" << std::endl ;
|
||||
#endif
|
||||
uint32_t offset = 8; // skip the header
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
bool ok = true ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id);
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &direction);
|
||||
|
||||
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
|
||||
#else
|
||||
if (offset != pktsize)
|
||||
throw std::runtime_error("Size error while deserializing.") ;
|
||||
if (!ok)
|
||||
throw std::runtime_error("Unknown error while deserializing.") ;
|
||||
#endif
|
||||
}
|
||||
|
||||
RsTurtleFileCrcItem::RsTurtleFileCrcItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_CRC)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_CRC) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " type = file map item" << std::endl ;
|
||||
#endif
|
||||
uint32_t offset = 8; // skip the header
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
bool ok = true ;
|
||||
uint32_t s1,s2 ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id);
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &s1) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &s2) ;
|
||||
|
||||
crc_map._ccmap._map.resize(s1) ;
|
||||
crc_map._crcs.resize(s2) ;
|
||||
|
||||
for(uint32_t i=0;i<s1 && ok;++i)
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &(crc_map._ccmap._map[i])) ;
|
||||
|
||||
for(uint32_t i=0;i<s2 && ok;++i)
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &(crc_map._crcs[i])) ;
|
||||
|
||||
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
|
||||
#else
|
||||
if (offset != pktsize)
|
||||
throw std::runtime_error("Size error while deserializing.") ;
|
||||
if (!ok)
|
||||
throw std::runtime_error("Unknown error while deserializing.") ;
|
||||
#endif
|
||||
}
|
||||
RsTurtleChunkCrcItem::RsTurtleChunkCrcItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_CHUNK_CRC)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_CHUNK_CRC) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " type = file map item" << std::endl ;
|
||||
#endif
|
||||
uint32_t offset = 8; // skip the header
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
bool ok = true ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &chunk_number) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[0]) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[1]) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[2]) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[3]) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &check_sum.fourbytes[4]) ;
|
||||
|
||||
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
|
||||
#else
|
||||
if (offset != pktsize)
|
||||
throw std::runtime_error("Size error while deserializing.") ;
|
||||
if (!ok)
|
||||
throw std::runtime_error("Unknown error while deserializing.") ;
|
||||
#endif
|
||||
}
|
||||
RsTurtleFileCrcRequestItem::RsTurtleFileCrcRequestItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_CRC_REQUEST) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " type = file map request item" << std::endl ;
|
||||
#endif
|
||||
uint32_t offset = 8; // skip the header
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
bool ok = true ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id);
|
||||
|
||||
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
|
||||
#else
|
||||
if (offset != pktsize)
|
||||
throw std::runtime_error("Size error while deserializing.") ;
|
||||
if (!ok)
|
||||
throw std::runtime_error("Unknown error while deserializing.") ;
|
||||
#endif
|
||||
}
|
||||
RsTurtleChunkCrcRequestItem::RsTurtleChunkCrcRequestItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_CHUNK_CRC_REQUEST) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " type = file map item" << std::endl ;
|
||||
#endif
|
||||
uint32_t offset = 8; // skip the header
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
bool ok = true ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &chunk_number) ;
|
||||
|
||||
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
|
||||
#else
|
||||
if (offset != pktsize)
|
||||
throw std::runtime_error("Size error while deserializing.") ;
|
||||
if (!ok)
|
||||
throw std::runtime_error("Unknown error while deserializing.") ;
|
||||
#endif
|
||||
}
|
||||
RsTurtleSearchResultItem::RsTurtleSearchResultItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleItem(RS_TURTLE_SUBTYPE_SEARCH_RESULT)
|
||||
{
|
||||
@ -983,46 +521,12 @@ RsTurtleTunnelOkItem::RsTurtleTunnelOkItem(void *data,uint32_t pktsize)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool RsTurtleFileRequestItem::serialize(void *data,uint32_t& pktsize)
|
||||
RsTurtleGenericDataItem::RsTurtleGenericDataItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_GENERIC_DATA)
|
||||
{
|
||||
uint32_t tlvsize = serial_size();
|
||||
uint32_t offset = 0;
|
||||
|
||||
if (pktsize < tlvsize)
|
||||
return false; /* not enough space */
|
||||
|
||||
pktsize = tlvsize;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
ok &= setRsItemHeader(data,tlvsize,PacketId(), tlvsize);
|
||||
|
||||
/* skip the header */
|
||||
offset += 8;
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id) ;
|
||||
ok &= setRawUInt64(data, tlvsize, &offset, chunk_offset);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, chunk_size);
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
ok = false;
|
||||
#ifdef RSSERIAL_DEBUG
|
||||
std::cerr << "RsTurtleTunnelOkItem::serialiseTransfer() Size Error! " << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
RsTurtleFileRequestItem::RsTurtleFileRequestItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_REQUEST)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_REQUEST) ;
|
||||
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_GENERIC_DATA) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " type = file request" << std::endl ;
|
||||
std::cerr << " type = tunnel ok" << std::endl ;
|
||||
#endif
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
@ -1030,12 +534,24 @@ RsTurtleFileRequestItem::RsTurtleFileRequestItem(void *data,uint32_t pktsize)
|
||||
/* add mandatory parts first */
|
||||
|
||||
bool ok = true ;
|
||||
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id) ;
|
||||
ok &= getRawUInt64(data, pktsize, &offset, &chunk_offset);
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &chunk_size);
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &data_size);
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " tunnel_id=" << (void*)tunnel_id << ", chunk_offset=" << chunk_offset << ", chunk_size=" << chunk_size << std::endl ;
|
||||
std::cerr << " request_id=" << (void*)request_id << ", tunnel_id=" << (void*)tunnel_id << std::endl ;
|
||||
#endif
|
||||
data_bytes = malloc(data_size) ;
|
||||
|
||||
if(data_bytes != NULL)
|
||||
{
|
||||
memcpy(data_bytes,data+offset,data_size) ;
|
||||
offset += data_size ;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "(EE) RsTurtleGenericDataItem: Error. Cannot allocate data for a size of " << data_size << " bytes." <<std::endl;
|
||||
offset = 0 ; // generate an error
|
||||
}
|
||||
|
||||
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
|
||||
UNREFERENCED_LOCAL_VARIABLE(rssize);
|
||||
@ -1046,48 +562,8 @@ RsTurtleFileRequestItem::RsTurtleFileRequestItem(void *data,uint32_t pktsize)
|
||||
throw std::runtime_error("RsTurtleTunnelOkItem::() unknown error while deserializing.") ;
|
||||
#endif
|
||||
}
|
||||
|
||||
RsTurtleFileDataItem::~RsTurtleFileDataItem()
|
||||
{
|
||||
free(chunk_data) ;
|
||||
}
|
||||
RsTurtleFileDataItem::RsTurtleFileDataItem(void *data,uint32_t pktsize)
|
||||
: RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_DATA)
|
||||
{
|
||||
setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_DATA) ;
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " type = file request" << std::endl ;
|
||||
#endif
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
bool ok = true ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &tunnel_id) ;
|
||||
ok &= getRawUInt64(data, pktsize, &offset, &chunk_offset);
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &chunk_size);
|
||||
|
||||
chunk_data = (void*)malloc(chunk_size) ;
|
||||
memcpy(chunk_data,(void*)((unsigned char*)data+offset),chunk_size) ;
|
||||
|
||||
offset += chunk_size ;
|
||||
|
||||
#ifdef P3TURTLE_DEBUG
|
||||
std::cerr << " tunnel_id=" << (void*)tunnel_id << ", chunk_offset=" << chunk_offset << ", chunk_size=" << chunk_size << std::endl ;
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS_SYS // No Exceptions in Windows compile. (drbobs).
|
||||
UNREFERENCED_LOCAL_VARIABLE(rssize);
|
||||
#else
|
||||
if (offset != rssize)
|
||||
throw std::runtime_error("RsTurtleFileDataItem::() error while deserializing.") ;
|
||||
if (!ok)
|
||||
throw std::runtime_error("RsTurtleFileDataItem::() unknown error while deserializing.") ;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool RsTurtleFileDataItem::serialize(void *data,uint32_t& pktsize)
|
||||
bool RsTurtleGenericDataItem::serialize(void *data,uint32_t& pktsize)
|
||||
{
|
||||
uint32_t tlvsize = serial_size();
|
||||
uint32_t offset = 0;
|
||||
@ -1106,12 +582,11 @@ bool RsTurtleFileDataItem::serialize(void *data,uint32_t& pktsize)
|
||||
|
||||
/* add mandatory parts first */
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id) ;
|
||||
ok &= setRawUInt64(data, tlvsize, &offset, chunk_offset);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, chunk_size);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, tunnel_id);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, data_size);
|
||||
|
||||
memcpy((void*)((unsigned char*)data+offset),chunk_data,chunk_size) ;
|
||||
offset += chunk_size ;
|
||||
memcpy(data+offset,data_bytes,data_size) ;
|
||||
offset += data_size ;
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
@ -1190,95 +665,13 @@ std::ostream& RsTurtleTunnelOkItem::print(std::ostream& o, uint16_t)
|
||||
return o ;
|
||||
}
|
||||
|
||||
std::ostream& RsTurtleFileRequestItem::print(std::ostream& o, uint16_t)
|
||||
std::ostream& RsTurtleGenericDataItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "File request item:" << std::endl ;
|
||||
o << "Generic Data item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
|
||||
o << " offset : " << chunk_offset << std::endl ;
|
||||
o << " chunk size: " << chunk_size << std::endl ;
|
||||
o << " Peer id : " << PeerId() << std::endl ;
|
||||
o << " data size : " << data_size << std::endl ;
|
||||
o << " data bytes: " << std::hex << (void*)data_bytes << std::dec << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
|
||||
std::ostream& RsTurtleFileDataItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "File request item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
|
||||
o << " offset : " << chunk_offset << std::endl ;
|
||||
o << " chunk size: " << chunk_size << std::endl ;
|
||||
o << " data : " << std::hex << chunk_data << std::dec << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
|
||||
std::ostream& RsTurtleFileMapItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "File map item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
|
||||
o << " direction : " << direction << std::endl ;
|
||||
o << " map : " ;
|
||||
|
||||
for(uint32_t i=0;i<compressed_map._map.size();++i)
|
||||
o << std::hex << compressed_map._map[i] << std::dec << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
|
||||
std::ostream& RsTurtleFileMapRequestItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "File map request item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
|
||||
o << " direction : " << direction << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
|
||||
std::ostream& RsTurtleFileCrcItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "File CRC item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
|
||||
o << " map : " ;
|
||||
|
||||
for(uint32_t i=0;i<crc_map._ccmap._map.size();++i)
|
||||
o << std::hex << crc_map._ccmap._map[i] << std::endl ;
|
||||
|
||||
o << " CRC : " ;
|
||||
|
||||
for(uint32_t i=0;i<crc_map._crcs.size();++i)
|
||||
o << std::hex << crc_map._crcs[i] << std::dec << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
std::ostream& RsTurtleFileCrcRequestItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "File CRC request item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
std::ostream& RsTurtleChunkCrcRequestItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "Chunk CRC request item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
|
||||
o << " chunk num : " << chunk_number << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
std::ostream& RsTurtleChunkCrcItem::print(std::ostream& o, uint16_t)
|
||||
{
|
||||
o << "Chunk CRC request item:" << std::endl ;
|
||||
|
||||
o << " tunnel id : " << std::hex << tunnel_id << std::dec << std::endl ;
|
||||
o << " chunk num : " << chunk_number << std::endl ;
|
||||
o << " sha1 sum : " << check_sum.toStdString() << std::endl ;
|
||||
|
||||
return o ;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ const uint8_t RS_TURTLE_SUBTYPE_TUNNEL_CLOSED = 0x06 ;
|
||||
const uint8_t RS_TURTLE_SUBTYPE_FILE_REQUEST = 0x07 ;
|
||||
const uint8_t RS_TURTLE_SUBTYPE_FILE_DATA = 0x08 ;
|
||||
const uint8_t RS_TURTLE_SUBTYPE_REGEXP_SEARCH_REQUEST = 0x09 ;
|
||||
const uint8_t RS_TURTLE_SUBTYPE_GENERIC_DATA = 0x0a ;
|
||||
const uint8_t RS_TURTLE_SUBTYPE_FILE_MAP = 0x10 ;
|
||||
const uint8_t RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST = 0x11 ;
|
||||
const uint8_t RS_TURTLE_SUBTYPE_FILE_CRC = 0x12 ;
|
||||
@ -171,32 +172,39 @@ class RsTurtleGenericTunnelItem: public RsTurtleItem
|
||||
/// All tunnels derived from RsTurtleGenericTunnelItem should have a tunnel id to
|
||||
/// indicate which tunnel they are travelling through.
|
||||
|
||||
virtual TurtleTunnelId tunnelId() const = 0 ;
|
||||
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
|
||||
|
||||
/// Indicate weither the packet is a client packet (goign back to the
|
||||
/// client) or a server packet (going to the server. Typically file
|
||||
/// requests are server packets, whereas file data are client packets.
|
||||
|
||||
virtual Direction travelingDirection() const = 0 ;
|
||||
virtual Direction travelingDirection() const { return direction ; }
|
||||
virtual void setTravelingDirection(Direction d) { direction = d; }
|
||||
|
||||
Direction direction ; // This does not need to be serialised. It's only used by the client services, optionnally,
|
||||
// and is set by the turtle router according to which direction the item travels.
|
||||
|
||||
uint32_t tunnel_id ; // Id of the tunnel to travel through
|
||||
};
|
||||
|
||||
/***********************************************************************************/
|
||||
/* Turtle File Transfer item classes */
|
||||
/* Specific Turtle Transfer items */
|
||||
/***********************************************************************************/
|
||||
|
||||
class RsTurtleFileRequestItem: public RsTurtleGenericTunnelItem
|
||||
// This item can be used by any service to pass-on arbitrary data into a tunnel.
|
||||
//
|
||||
class RsTurtleGenericDataItem: public RsTurtleGenericTunnelItem
|
||||
{
|
||||
public:
|
||||
RsTurtleFileRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_REQUEST) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_REQUEST);}
|
||||
RsTurtleFileRequestItem(void *data,uint32_t size) ; // deserialization
|
||||
RsTurtleGenericDataItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_GENERIC_DATA) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_REQUEST);}
|
||||
RsTurtleGenericDataItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual bool shouldStampTunnel() const { return false ; }
|
||||
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
|
||||
virtual Direction travelingDirection() const { return DIRECTION_SERVER ; }
|
||||
virtual ~RsTurtleGenericDataItem() { if(data_bytes != NULL) free(data_bytes) ; }
|
||||
|
||||
uint32_t tunnel_id ; // id of the tunnel to travel through
|
||||
uint64_t chunk_offset ;
|
||||
uint32_t chunk_size ;
|
||||
virtual bool shouldStampTunnel() const { return true ; }
|
||||
|
||||
uint32_t data_size ;
|
||||
void *data_bytes ;
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
protected:
|
||||
@ -204,154 +212,6 @@ class RsTurtleFileRequestItem: public RsTurtleGenericTunnelItem
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
class RsTurtleFileDataItem: public RsTurtleGenericTunnelItem
|
||||
{
|
||||
public:
|
||||
RsTurtleFileDataItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_DATA) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_DATA) ;}
|
||||
~RsTurtleFileDataItem() ;
|
||||
RsTurtleFileDataItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual bool shouldStampTunnel() const { return true ; }
|
||||
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
|
||||
virtual Direction travelingDirection() const { return DIRECTION_CLIENT ; }
|
||||
|
||||
uint32_t tunnel_id ; // id of the tunnel to travel through
|
||||
uint64_t chunk_offset ; // offset in the file
|
||||
uint32_t chunk_size ; // size of the file chunk
|
||||
void *chunk_data ; // actual data.
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
|
||||
virtual bool serialize(void *data,uint32_t& size) ;
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
class RsTurtleFileMapRequestItem: public RsTurtleGenericTunnelItem
|
||||
{
|
||||
public:
|
||||
RsTurtleFileMapRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_MAP_REQUEST) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_MAP_REQUEST) ;}
|
||||
RsTurtleFileMapRequestItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual bool shouldStampTunnel() const { return false ; }
|
||||
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
|
||||
virtual Direction travelingDirection() const { return direction ; }
|
||||
|
||||
Direction direction ; // travel direction for this packet (server/client)
|
||||
uint32_t tunnel_id ; // id of the tunnel to travel through. Also used for identifying the file source
|
||||
// this info from the file size, but this allows a security check.
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
|
||||
virtual bool serialize(void *data,uint32_t& size) ;
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
class RsTurtleFileMapItem: public RsTurtleGenericTunnelItem
|
||||
{
|
||||
public:
|
||||
RsTurtleFileMapItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_MAP) { setPriorityLevel(QOS_PRIORITY_RS_TURTLE_FILE_MAP) ;}
|
||||
RsTurtleFileMapItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual bool shouldStampTunnel() const { return false ; }
|
||||
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
|
||||
virtual Direction travelingDirection() const { return direction ; }
|
||||
|
||||
Direction direction ; // travel direction for this packet (server/client)
|
||||
uint32_t tunnel_id ; // id of the tunnel to travel through. Also used for identifying the file source
|
||||
// this info from the file size, but this allows a security check.
|
||||
|
||||
CompressedChunkMap compressed_map ; // Map info for the file in compressed format. Each *bit* in the array uint's says "I have" or "I don't have"
|
||||
// by default, we suppose the peer has all the chunks. This info will thus be and-ed
|
||||
// with the default file map for this source.
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
|
||||
virtual bool serialize(void *data,uint32_t& size) ;
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
class RsTurtleFileCrcRequestItem: public RsTurtleGenericTunnelItem
|
||||
{
|
||||
public:
|
||||
RsTurtleFileCrcRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_CRC_REQUEST) { setPriorityLevel(QOS_PRIORITY_RS_FILE_CRC_REQUEST);}
|
||||
RsTurtleFileCrcRequestItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual bool shouldStampTunnel() const { return false ; }
|
||||
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
|
||||
virtual Direction travelingDirection() const { return DIRECTION_SERVER ; }
|
||||
|
||||
uint32_t tunnel_id ; // id of the tunnel to travel through. Also used for identifying the file source
|
||||
// this info from the file size, but this allows a security check.
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
|
||||
virtual bool serialize(void *data,uint32_t& size) ;
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
class RsTurtleChunkCrcRequestItem: public RsTurtleGenericTunnelItem
|
||||
{
|
||||
public:
|
||||
RsTurtleChunkCrcRequestItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_CHUNK_CRC_REQUEST) { setPriorityLevel(QOS_PRIORITY_RS_CHUNK_CRC_REQUEST);}
|
||||
RsTurtleChunkCrcRequestItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual bool shouldStampTunnel() const { return false ; }
|
||||
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
|
||||
virtual Direction travelingDirection() const { return DIRECTION_SERVER ; }
|
||||
|
||||
uint32_t tunnel_id ; // id of the tunnel to travel through. Also used for identifying the file source
|
||||
// this info from the file size, but this allows a security check.
|
||||
|
||||
uint32_t chunk_number ; // id of the chunk to CRC.
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
|
||||
virtual bool serialize(void *data,uint32_t& size) ;
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
class RsTurtleFileCrcItem: public RsTurtleGenericTunnelItem
|
||||
{
|
||||
public:
|
||||
RsTurtleFileCrcItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_FILE_CRC) { setPriorityLevel(QOS_PRIORITY_RS_FILE_CRC);}
|
||||
RsTurtleFileCrcItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual bool shouldStampTunnel() const { return true ; }
|
||||
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
|
||||
virtual Direction travelingDirection() const { return DIRECTION_CLIENT ; }
|
||||
|
||||
uint32_t tunnel_id ; // id of the tunnel to travel through. Also used for identifying the file source
|
||||
// this info from the file size, but this allows a security check.
|
||||
|
||||
CRC32Map crc_map ;// Map info for the file in compressed format. Each *bit* in the array uint's says "I have" or "I don't have"
|
||||
// by default, we suppose the peer has all the chunks. This info will thus be and-ed
|
||||
// with the default file map for this source.
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
virtual bool serialize(void *data,uint32_t& size) ;
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
|
||||
class RsTurtleChunkCrcItem: public RsTurtleGenericTunnelItem
|
||||
{
|
||||
public:
|
||||
RsTurtleChunkCrcItem() : RsTurtleGenericTunnelItem(RS_TURTLE_SUBTYPE_CHUNK_CRC) { setPriorityLevel(QOS_PRIORITY_RS_CHUNK_CRC);}
|
||||
RsTurtleChunkCrcItem(void *data,uint32_t size) ; // deserialization
|
||||
|
||||
virtual bool shouldStampTunnel() const { return true ; }
|
||||
virtual TurtleTunnelId tunnelId() const { return tunnel_id ; }
|
||||
virtual Direction travelingDirection() const { return DIRECTION_CLIENT ; }
|
||||
|
||||
uint32_t tunnel_id ; // id of the tunnel to travel through. Also used for identifying the file source
|
||||
// this info from the file size, but this allows a security check.
|
||||
|
||||
uint32_t chunk_number ;
|
||||
Sha1CheckSum check_sum ;
|
||||
|
||||
virtual std::ostream& print(std::ostream& o, uint16_t) ;
|
||||
virtual bool serialize(void *data,uint32_t& size) ;
|
||||
virtual uint32_t serial_size() ;
|
||||
};
|
||||
/***********************************************************************************/
|
||||
/* Turtle Serialiser class */
|
||||
/***********************************************************************************/
|
||||
@ -370,5 +230,14 @@ class RsTurtleSerialiser: public RsSerialType
|
||||
return dynamic_cast<RsTurtleItem *>(item)->serialize(data,*size) ;
|
||||
}
|
||||
virtual RsItem *deserialise (void *data, uint32_t *size) ;
|
||||
|
||||
// This is used by the turtle router to add services to its serialiser.
|
||||
// Client services are only used for deserialising, since the serialisation is
|
||||
// performed using the overloaded virtual functions above.
|
||||
//
|
||||
void registerClientService(RsTurtleClientService *service) { _client_services.push_back(service) ; }
|
||||
|
||||
private:
|
||||
std::vector<RsTurtleClientService *> _client_services ;
|
||||
};
|
||||
|
||||
|
86
libretroshare/src/turtle/turtleclientservice.h
Normal file
86
libretroshare/src/turtle/turtleclientservice.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* libretroshare/src/services: turtleclientservice.h
|
||||
*
|
||||
* Services for RetroShare.
|
||||
*
|
||||
* Copyright 2013 by Cyril Soler
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "csoler@users.sourceforge.net".
|
||||
*
|
||||
*/
|
||||
|
||||
// This class is the parent class for any service that will use the turtle router to distribute its packets.
|
||||
// Typical representative clients include:
|
||||
//
|
||||
// p3ChatService: opens tunnels to distant peers for chatting
|
||||
// ftServer: searches and open tunnels to distant sources for file transfer
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <stdlib.h>
|
||||
#include <serialiser/rsserial.h>
|
||||
#include <turtle/rsturtleitem.h>
|
||||
|
||||
class RsItem ;
|
||||
|
||||
class RsTurtleClientService
|
||||
{
|
||||
public:
|
||||
// Handling of tunnel request for the given hash. Most of the time, it's a search in a predefined list.
|
||||
// The output info_string is used by the turtle router to display info about tunnels it manages. It is
|
||||
// not passed to the tunnel.
|
||||
|
||||
virtual bool handleTunnelRequest(const std::string& hash,const std::string& peer_id) { return false ; }
|
||||
|
||||
// This method is called by the turtle router to send data that comes out of a turtle tunnel.
|
||||
// The turtle router stays responsible for the memory management of data. Most of the time the
|
||||
// data chunk is a serialized item to be de-serialized by the client service.
|
||||
//
|
||||
// Parameters:
|
||||
// virtual_peer_id : name of the tunnel that sent the data
|
||||
// data : memory chunk for the data
|
||||
// size : size of data
|
||||
// item->direction : direction of travel:
|
||||
// RsTurtleGenericTunnelItem::DIRECTION_CLIENT: the service is acting as a client
|
||||
// RsTurtleGenericTunnelItem::DIRECTION_CLIENT: the service is acting as a server
|
||||
//
|
||||
// Most of the time this parameter is not used by services, except when some info (such as chunk maps, chat items, etc) go
|
||||
// both ways, and their nature cannot suffice to determine where they should be handled.
|
||||
//
|
||||
// By default (if not overloaded), the method will just free the data, as any subclass should do as well.
|
||||
// Note: p3turtle stays owner of the item, so the client should not delete it!
|
||||
//
|
||||
virtual void receiveTurtleData(RsTurtleGenericTunnelItem *item,const std::string& hash,const std::string& virtual_peer_id,RsTurtleGenericTunnelItem::Direction direction)
|
||||
{
|
||||
std::cerr << "!!!!!! Received Data from turtle router, but the client service is not handling it !!!!!!!!!!" << std::endl ;
|
||||
}
|
||||
|
||||
// Method for deserialising specific items of the client service. The
|
||||
// method has a default behavior of not doing anything, since most client
|
||||
// services might only use the generic item already provided by the turtle
|
||||
// router: RsTurtleGenericDataItem
|
||||
|
||||
virtual RsTurtleGenericTunnelItem *deserialiseItem(void *data, uint32_t size) const { return NULL ; }
|
||||
|
||||
// These methods are called by the turtle router to add/remove virtual peers when tunnels are created/deleted
|
||||
//
|
||||
virtual void addVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id,RsTurtleGenericTunnelItem::Direction dir) = 0 ;
|
||||
virtual void removeVirtualPeer(const TurtleFileHash& hash,const TurtleVirtualPeerId& virtual_peer_id) = 0 ;
|
||||
};
|
||||
|
||||
|
138
libretroshare/src/util/rsaes.cc
Normal file
138
libretroshare/src/util/rsaes.cc
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* libretroshare/src/utils: rsaes.cc
|
||||
*
|
||||
* AES crptography for RetroShare.
|
||||
*
|
||||
* Copyright 2013 by Cyril Soler
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "csoler@users.sourceforge.net".
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/aes.h>
|
||||
|
||||
#include "rsaes.h"
|
||||
|
||||
uint32_t RsAES::get_buffer_size(uint32_t n)
|
||||
{
|
||||
return n + AES_BLOCK_SIZE ;
|
||||
}
|
||||
|
||||
bool RsAES::aes_crypt_8_16(const uint8_t *input_data,uint32_t input_data_length,uint8_t key_data[16],uint8_t salt[8],uint8_t *output_data,uint32_t& output_data_length)
|
||||
{
|
||||
int nrounds = 5;
|
||||
uint8_t key[32], iv[32];
|
||||
|
||||
/*
|
||||
* Gen key & IV for AES 256 CBC mode. A SHA1 digest is used to hash the supplied key material.
|
||||
* nrounds is the number of times the we hash the material. More rounds are more secure but
|
||||
* slower.
|
||||
*/
|
||||
int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, key_data, 16, nrounds, key, iv);
|
||||
|
||||
if (i != 32)
|
||||
{
|
||||
printf("Key size is %d bits - should be 256 bits\n", i);
|
||||
return false ;
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX e_ctx ;
|
||||
EVP_CIPHER_CTX_init(&e_ctx);
|
||||
EVP_EncryptInit_ex(&e_ctx, EVP_aes_256_cbc(), NULL, key, iv);
|
||||
|
||||
/* max ciphertext len for a n bytes of plaintext is n + AES_BLOCK_SIZE -1 bytes */
|
||||
int c_len = input_data_length + AES_BLOCK_SIZE ;
|
||||
int f_len = 0;
|
||||
|
||||
if(output_data_length < (uint32_t)c_len)
|
||||
return false ;
|
||||
|
||||
/* update ciphertext, c_len is filled with the length of ciphertext generated,
|
||||
*len is the size of plaintext in bytes */
|
||||
|
||||
if(!EVP_EncryptUpdate(&e_ctx, output_data, &c_len, input_data, input_data_length))
|
||||
{
|
||||
std::cerr << "RsAES: decryption failed at end. Check padding." << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
/* update ciphertext with the final remaining bytes */
|
||||
if(!EVP_EncryptFinal_ex(&e_ctx, output_data+c_len, &f_len))
|
||||
{
|
||||
std::cerr << "RsAES: decryption failed at end. Check padding." << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
output_data_length = c_len + f_len;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RsAES::aes_decrypt_8_16(const uint8_t *input_data,uint32_t input_data_length,uint8_t key_data[16],uint8_t salt[8],uint8_t *output_data,uint32_t& output_data_length)
|
||||
{
|
||||
int nrounds = 5;
|
||||
uint8_t key[32], iv[32];
|
||||
|
||||
/*
|
||||
* Gen key & IV for AES 256 CBC mode. A SHA1 digest is used to hash the supplied key material.
|
||||
* nrounds is the number of times the we hash the material. More rounds are more secure but
|
||||
* slower.
|
||||
*/
|
||||
int i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, key_data, 16, nrounds, key, iv);
|
||||
|
||||
if (i != 32)
|
||||
{
|
||||
printf("Key size is %d bits - should be 256 bits\n", i);
|
||||
return false ;
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX e_ctx ;
|
||||
EVP_CIPHER_CTX_init(&e_ctx);
|
||||
EVP_DecryptInit_ex(&e_ctx, EVP_aes_256_cbc(), NULL, key, iv);
|
||||
|
||||
/* max ciphertext len for a n bytes of plaintext is n + AES_BLOCK_SIZE -1 bytes */
|
||||
int c_len = input_data_length + AES_BLOCK_SIZE ;
|
||||
int f_len = 0;
|
||||
|
||||
if(output_data_length < (uint32_t)c_len)
|
||||
return false ;
|
||||
|
||||
output_data_length = c_len ;
|
||||
|
||||
/* update ciphertext, c_len is filled with the length of ciphertext generated,
|
||||
*len is the size of plaintext in bytes */
|
||||
|
||||
if(! EVP_DecryptUpdate(&e_ctx, output_data, &c_len, input_data, input_data_length))
|
||||
{
|
||||
std::cerr << "RsAES: decryption failed." << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
/* update ciphertext with the final remaining bytes */
|
||||
if(!EVP_DecryptFinal_ex(&e_ctx, output_data+c_len, &f_len))
|
||||
{
|
||||
std::cerr << "RsAES: decryption failed at end. Check padding." << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
output_data_length = c_len + f_len;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
47
libretroshare/src/util/rsaes.h
Normal file
47
libretroshare/src/util/rsaes.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* libretroshare/src/utils: rsaescrypt.h
|
||||
*
|
||||
* AES crptography for RetroShare.
|
||||
*
|
||||
* Copyright 2013 by Cyril Soler
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "csoler@users.sourceforge.net".
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
class RsAES
|
||||
{
|
||||
public:
|
||||
// Crypt/decrypt data using a 16 bytes key and a 8 bytes salt.
|
||||
//
|
||||
// output_data allocation is left to the client. The size should be at least RsAES::get_buffer_size(input_data_length)
|
||||
//
|
||||
// Return value:
|
||||
// true: encryption/decryption ok
|
||||
//
|
||||
// false: encryption/decryption went bad. Check buffer size.
|
||||
//
|
||||
static bool aes_crypt_8_16(const uint8_t *input_data,uint32_t input_data_length,uint8_t key[16],uint8_t salt[8],uint8_t *output_data,uint32_t& output_data_length) ;
|
||||
static bool aes_decrypt_8_16(const uint8_t *input_data,uint32_t input_data_length,uint8_t key[16],uint8_t salt[8],uint8_t *output_data,uint32_t& output_data_length) ;
|
||||
|
||||
// computes the safe buffer size to store encrypted/decrypted data for the given input stream size
|
||||
//
|
||||
static uint32_t get_buffer_size(uint32_t size) ;
|
||||
};
|
||||
|
@ -51,6 +51,10 @@ bool RSRandom::seed(uint32_t s)
|
||||
return true ;
|
||||
}
|
||||
|
||||
void RSRandom::random_bytes(unsigned char *data,uint32_t size)
|
||||
{
|
||||
RAND_bytes(data,size) ;
|
||||
}
|
||||
void RSRandom::locked_next_state()
|
||||
{
|
||||
#ifdef RSRANDOM_USE_SSL
|
||||
|
@ -46,6 +46,7 @@ class RSRandom
|
||||
static bool seed(uint32_t s) ;
|
||||
|
||||
static std::string random_alphaNumericString(uint32_t length) ;
|
||||
static void random_bytes(unsigned char *data,uint32_t length) ;
|
||||
|
||||
private:
|
||||
static RsMutex rndMtx ;
|
||||
|
@ -49,8 +49,8 @@ AudioPopupChatDialog::AudioPopupChatDialog(QWidget *parent)
|
||||
connect(audioListenToggleButton, SIGNAL(clicked()), this , SLOT(toggleAudioListen()));
|
||||
connect(audioMuteCaptureToggleButton, SIGNAL(clicked()), this , SLOT(toggleAudioMuteCapture()));
|
||||
|
||||
addButton(audioListenToggleButton) ;
|
||||
addButton(audioMuteCaptureToggleButton) ;
|
||||
addChatBarWidget(audioListenToggleButton) ;
|
||||
addChatBarWidget(audioMuteCaptureToggleButton) ;
|
||||
|
||||
//ui.chatWidget->resetStatusBar();
|
||||
|
||||
|
226
retroshare-gui/src/gui/CreateMsgLinkDialog.cpp
Normal file
226
retroshare-gui/src/gui/CreateMsgLinkDialog.cpp
Normal file
@ -0,0 +1,226 @@
|
||||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 2013 Cyril Soler
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
****************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
#include <QMessageBox>
|
||||
#include <QTimer>
|
||||
#include <retroshare/rsmsgs.h>
|
||||
#include <retroshare/rspeers.h>
|
||||
#include "CreateMsgLinkDialog.h"
|
||||
#include <gui/common/FriendSelectionWidget.h>
|
||||
#include <gui/RetroShareLink.h>
|
||||
|
||||
CreateMsgLinkDialog::CreateMsgLinkDialog(QWidget *parent)
|
||||
:QDialog(NULL, Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | Qt::WindowCloseButtonHint)
|
||||
{
|
||||
/* Invoke the Qt Designer generated object setup routine */
|
||||
setupUi(this);
|
||||
|
||||
setAttribute(Qt::WA_DeleteOnClose, false);
|
||||
|
||||
_info_GB->layout()->addWidget( _gpg_selection = new FriendSelectionWidget(this) ) ;
|
||||
|
||||
QObject::connect(_link_type_CB,SIGNAL(currentIndexChanged(int)),this,SLOT(update())) ;
|
||||
QObject::connect(_create_link_PB,SIGNAL(clicked()),this,SLOT(createLink())) ;
|
||||
QObject::connect(_create_new_PB,SIGNAL(toggled(bool)),this,SLOT(toggleCreateLink(bool))) ;
|
||||
QObject::connect(_existing_links_LW,SIGNAL(currentRowChanged(int)),this,SLOT(updateCurrentRow(int))) ;
|
||||
|
||||
_gpg_selection->setModus(FriendSelectionWidget::MODUS_SINGLE) ;
|
||||
_gpg_selection->setShowType(FriendSelectionWidget::SHOW_NON_FRIEND_GPG | FriendSelectionWidget::SHOW_GPG) ;
|
||||
_gpg_selection->setHeaderText(QObject::tr("Select who can contact you:")) ;
|
||||
_gpg_selection->start() ;
|
||||
|
||||
toggleCreateLink(false) ;
|
||||
update() ;
|
||||
updateCurrentRow(-1) ;
|
||||
}
|
||||
|
||||
void CreateMsgLinkDialog::updateCurrentRow(int r)
|
||||
{
|
||||
if(r < 0)
|
||||
{
|
||||
_current_link_type_LE->setText("") ;
|
||||
_current_link_dst_LE->setText("") ;
|
||||
_current_link_date_DE->setDateTime(QDateTime::fromMSecsSinceEpoch(0)) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
QUrl text = _existing_links_LW->item(r)->data(Qt::UserRole).toUrl() ;
|
||||
|
||||
std::cerr << "Parsing link : " << text.toString().toStdString() << std::endl;
|
||||
RetroShareLink link(text) ;
|
||||
|
||||
if( link.type() == RetroShareLink::TYPE_PRIVATE_CHAT )
|
||||
_current_link_type_LE->setText( tr("Private chat invite") ) ;
|
||||
else
|
||||
_current_link_type_LE->setText( tr("Public message invite") ) ;
|
||||
|
||||
_current_link_dst_LE->setText(link.GPGId()) ;
|
||||
_current_link_date_DE->setDateTime(QDateTime::fromMSecsSinceEpoch(link.timeStamp() * 1000 )) ;
|
||||
}
|
||||
|
||||
void CreateMsgLinkDialog::toggleCreateLink(bool b)
|
||||
{
|
||||
_new_link_F->setHidden(!b) ;
|
||||
}
|
||||
void CreateMsgLinkDialog::update()
|
||||
{
|
||||
if(_link_type_CB->currentIndex() == 0)
|
||||
{
|
||||
QString s ;
|
||||
|
||||
s += "A private chat invite allows a specific peer to contact you using encrypted private chat. You need to select a destination peer from your PGP keyring before creating the link. The link contains the encryption code and your PGP signature, so that the peer can authenticate you." ;
|
||||
|
||||
_info_TB->setHtml(s) ;
|
||||
_gpg_selection->setHidden(false) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
QString s ;
|
||||
|
||||
s += "A public message link allows any peer in the nearby network to send a private message to you. The message is encrypted and only you can read it." ;
|
||||
|
||||
_info_TB->setHtml(s) ;
|
||||
_gpg_selection->setHidden(true) ;
|
||||
}
|
||||
|
||||
std::vector<DistantChatInviteInfo> invites ;
|
||||
|
||||
rsMsgs->getDistantChatInviteList(invites) ;
|
||||
|
||||
_existing_links_LW->clear() ;
|
||||
|
||||
for(uint32_t i=0;i<invites.size();++i)
|
||||
{
|
||||
RetroShareLink link ;
|
||||
|
||||
if(!link.createPrivateChatInvite(invites[i].time_of_validity,QString::fromStdString(invites[i].destination_pgp_id),QString::fromStdString(invites[i].encrypted_radix64_string)));
|
||||
std::cerr << "Cannot create link." << std::endl;
|
||||
|
||||
QListWidgetItem *item = new QListWidgetItem;
|
||||
item->setData(Qt::DisplayRole,tr("Private chat invite to ")+QString::fromStdString(invites[i].destination_pgp_id)) ;
|
||||
item->setData(Qt::UserRole,link.toString()) ;
|
||||
|
||||
_existing_links_LW->insertItem(0,item) ;
|
||||
}
|
||||
|
||||
std::vector<DistantOfflineMessengingInvite> invites2 ;
|
||||
rsMsgs->getDistantOfflineMessengingInvites(invites2) ;
|
||||
|
||||
for(uint32_t i=0;i<invites2.size();++i)
|
||||
{
|
||||
RetroShareLink link ;
|
||||
|
||||
if(!link.createPublicMsgInvite(invites2[i].time_of_validity,QString::fromStdString(invites2[i].issuer_pgp_id),QString::fromStdString(invites2[i].hash)))
|
||||
std::cerr << "Cannot create link." << std::endl;
|
||||
else
|
||||
{
|
||||
QListWidgetItem *item = new QListWidgetItem;
|
||||
item->setData(Qt::DisplayRole,tr("Public message link")) ;
|
||||
item->setData(Qt::UserRole,link.toString()) ;
|
||||
|
||||
_existing_links_LW->insertItem(0,item) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
time_t CreateMsgLinkDialog::computeValidityDuration() const
|
||||
{
|
||||
time_t unit ;
|
||||
|
||||
switch(_validity_time_CB->currentIndex())
|
||||
{
|
||||
default:
|
||||
case 0: unit = 3600 ;
|
||||
break ;
|
||||
case 1: unit = 3600*24 ;
|
||||
break ;
|
||||
case 2: unit = 3600*24*7 ;
|
||||
break ;
|
||||
case 3: unit = 3600*24*30 ;
|
||||
break ;
|
||||
case 4: unit = 3600*24*365 ;
|
||||
break ;
|
||||
}
|
||||
|
||||
return unit * _validity_time_SB->value() ;
|
||||
}
|
||||
|
||||
void CreateMsgLinkDialog::createLink()
|
||||
{
|
||||
std::cerr << "Creating link!" << std::endl;
|
||||
|
||||
if(_link_type_CB->currentIndex() == 0)
|
||||
{
|
||||
time_t validity_duration = computeValidityDuration() ;
|
||||
FriendSelectionWidget::IdType type ;
|
||||
std::string current_pgp_id = _gpg_selection->selectedId(type) ;
|
||||
|
||||
std::string encrypted_string ;
|
||||
|
||||
bool res = rsMsgs->createDistantChatInvite(current_pgp_id,validity_duration,encrypted_string) ;
|
||||
|
||||
RetroShareLink link ;
|
||||
|
||||
if(!link.createPrivateChatInvite(validity_duration + time(NULL),QString::fromStdString(current_pgp_id),QString::fromStdString(encrypted_string)) )
|
||||
std::cerr << "Cannot create link." << std::endl;
|
||||
|
||||
QList<RetroShareLink> links ;
|
||||
links.push_back(link) ;
|
||||
|
||||
RSLinkClipboard::copyLinks(links) ;
|
||||
|
||||
if(!res)
|
||||
QMessageBox::critical(NULL,tr("Private chat invite creation failed"),tr("The creation of the chat invite failed")) ;
|
||||
else
|
||||
QMessageBox::information(NULL,tr("Private chat invite created"),tr("Your new chat invite has been copied to clipboard. You can now paste it as a Retroshare link.")) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
time_t validity_duration = computeValidityDuration() ;
|
||||
std::string hash;
|
||||
std::string issuer_pgp_id = rsPeers->getGPGOwnId() ;
|
||||
|
||||
bool res = rsMsgs->createDistantOfflineMessengingInvite(validity_duration,hash) ;
|
||||
|
||||
RetroShareLink link ;
|
||||
|
||||
if(!link.createPublicMsgInvite(validity_duration + time(NULL),QString::fromStdString(issuer_pgp_id),QString::fromStdString(hash)) )
|
||||
{
|
||||
std::cerr << "Cannot create link." << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
QList<RetroShareLink> links ;
|
||||
links.push_back(link) ;
|
||||
|
||||
RSLinkClipboard::copyLinks(links) ;
|
||||
|
||||
if(!res)
|
||||
QMessageBox::critical(NULL,tr("Messenging invite creation failed"),tr("The creation of the messenging invite failed")) ;
|
||||
else
|
||||
QMessageBox::information(NULL,tr("Messenging invite created"),tr("Your new messenging chat invite has been copied to clipboard. You can now paste it as a Retroshare link.")) ;
|
||||
}
|
||||
|
||||
QTimer::singleShot(100,this,SLOT(update())) ;
|
||||
}
|
||||
|
53
retroshare-gui/src/gui/CreateMsgLinkDialog.h
Normal file
53
retroshare-gui/src/gui/CreateMsgLinkDialog.h
Normal file
@ -0,0 +1,53 @@
|
||||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 2008 Robert Fernie
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
******************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ui_CreateMsgLinkDialog.h"
|
||||
|
||||
class FriendSelectionWidget ;
|
||||
|
||||
class CreateMsgLinkDialog : public QDialog, public Ui::CreateMsgLinkDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CreateMsgLinkDialog(QWidget *parent = NULL);
|
||||
virtual ~CreateMsgLinkDialog() {}
|
||||
|
||||
private slots:
|
||||
/* actions to take.... */
|
||||
void createLink();
|
||||
void update() ;
|
||||
void toggleCreateLink(bool) ;
|
||||
void updateCurrentRow(int) ;
|
||||
|
||||
private:
|
||||
time_t computeValidityDuration() const ;
|
||||
|
||||
/** Qt Designer generated object */
|
||||
FriendSelectionWidget *_gpg_selection ;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
220
retroshare-gui/src/gui/CreateMsgLinkDialog.ui
Normal file
220
retroshare-gui/src/gui/CreateMsgLinkDialog.ui
Normal file
@ -0,0 +1,220 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CreateMsgLinkDialog</class>
|
||||
<widget class="QDialog" name="CreateMsgLinkDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>565</width>
|
||||
<height>465</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QListWidget" name="_existing_links_LW">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Valid until:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Usable by:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QDateTimeEdit" name="_current_link_date_DE"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="_current_link_type_LE"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="_current_link_dst_LE"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="text">
|
||||
<string>Copy to clipboard</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="_create_new_PB">
|
||||
<property name="text">
|
||||
<string>Create new</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="_new_link_F">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Invite type:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="_link_type_CB">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Private chat</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Public message</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Validity time :</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="_validity_time_SB">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>30</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="_validity_time_CB">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>hour</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>day</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>week</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>month</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>year</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="_create_link_PB">
|
||||
<property name="text">
|
||||
<string>Create!</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="_info_GB">
|
||||
<property name="title">
|
||||
<string>Information</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="_info_TB"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -23,6 +23,7 @@
|
||||
#include <QShortcut>
|
||||
#include <QTimer>
|
||||
#include <QDateTime>
|
||||
#include <QMessageBox>
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include "MessagesDialog.h"
|
||||
@ -118,8 +119,8 @@ MessagesDialog::MessagesDialog(QWidget *parent)
|
||||
inChange = false;
|
||||
lockUpdate = 0;
|
||||
|
||||
connect(ui.messagestreeView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(messageslistWidgetCostumPopupMenu(QPoint)));
|
||||
connect(ui.listWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(folderlistWidgetCostumPopupMenu(QPoint)));
|
||||
connect(ui.messagestreeView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(messageslistWidgetCustomPopupMenu(QPoint)));
|
||||
connect(ui.listWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(folderlistWidgetCustomPopupMenu(QPoint)));
|
||||
connect(ui.messagestreeView, SIGNAL(clicked(const QModelIndex&)) , this, SLOT(clicked(const QModelIndex&)));
|
||||
connect(ui.messagestreeView, SIGNAL(doubleClicked(const QModelIndex&)) , this, SLOT(doubleClicked(const QModelIndex&)));
|
||||
connect(ui.listWidget, SIGNAL(currentRowChanged(int)), this, SLOT(changeBox(int)));
|
||||
@ -507,7 +508,7 @@ bool MessagesDialog::hasMessageStar(int nRow)
|
||||
return item->data(ROLE_MSGFLAGS).toInt() & RS_MSG_STAR;
|
||||
}
|
||||
|
||||
void MessagesDialog::messageslistWidgetCostumPopupMenu( QPoint /*point*/ )
|
||||
void MessagesDialog::messageslistWidgetCustomPopupMenu( QPoint /*point*/ )
|
||||
{
|
||||
std::string cid;
|
||||
std::string mid;
|
||||
@ -587,6 +588,9 @@ void MessagesDialog::messageslistWidgetCostumPopupMenu( QPoint /*point*/ )
|
||||
action->setDisabled(true);
|
||||
}
|
||||
|
||||
if(nCount==1 && (msgInfo.msgflags & RS_MSG_ENCRYPTED))
|
||||
action = contextMnu.addAction(QIcon(IMAGE_SYSTEM), tr("Decrypt Message"), this, SLOT(decryptSelectedMsg()));
|
||||
|
||||
int listrow = ui.listWidget->currentRow();
|
||||
if (listrow == ROW_TRASHBOX) {
|
||||
action = contextMnu.addAction(tr("Undelete"), this, SLOT(undeletemessage()));
|
||||
@ -605,7 +609,7 @@ void MessagesDialog::messageslistWidgetCostumPopupMenu( QPoint /*point*/ )
|
||||
contextMnu.exec(QCursor::pos());
|
||||
}
|
||||
|
||||
void MessagesDialog::folderlistWidgetCostumPopupMenu(QPoint /*point*/)
|
||||
void MessagesDialog::folderlistWidgetCustomPopupMenu(QPoint /*point*/)
|
||||
{
|
||||
if (ui.listWidget->currentRow() != ROW_TRASHBOX) {
|
||||
/* Context menu only neede for trash box */
|
||||
@ -1112,7 +1116,11 @@ void MessagesDialog::insertMessages()
|
||||
}
|
||||
|
||||
// Subject
|
||||
text = QString::fromStdWString(it->title);
|
||||
if(it->msgflags & RS_MSG_ENCRYPTED)
|
||||
text = tr("Encrypted message. Right-click to decrypt it.") ;
|
||||
else
|
||||
text = QString::fromStdWString(it->title);
|
||||
|
||||
item[COLUMN_SUBJECT]->setText(text);
|
||||
item[COLUMN_SUBJECT]->setData(text + dateString, ROLE_SORT);
|
||||
|
||||
@ -1464,6 +1472,28 @@ void MessagesDialog::insertMsgTxtAndFiles(QModelIndex Index, bool bSetToRead)
|
||||
updateInterface();
|
||||
}
|
||||
|
||||
void MessagesDialog::decryptSelectedMsg()
|
||||
{
|
||||
MessageInfo msgInfo;
|
||||
|
||||
if (!rsMsgs->getMessage(mCurrMsgId, msgInfo))
|
||||
return ;
|
||||
|
||||
if(!msgInfo.msgflags & RS_MSG_ENCRYPTED)
|
||||
{
|
||||
std::cerr << "This message is not encrypted! Cannot decrypt!" << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
if(!rsMsgs->decryptMessage(mCurrMsgId) )
|
||||
QMessageBox::warning(NULL,tr("Decryption failed!"),tr("This message could not be decrypted.")) ;
|
||||
|
||||
//setMsgAsReadUnread(currentIndex.row(), true);
|
||||
updateMessageSummaryList();
|
||||
insertMessages();
|
||||
insertMsgTxtAndFiles();
|
||||
}
|
||||
|
||||
bool MessagesDialog::getCurrentMsg(std::string &cid, std::string &mid)
|
||||
{
|
||||
QModelIndex currentIndex = ui.messagestreeView->currentIndex();
|
||||
|
@ -60,8 +60,9 @@ public slots:
|
||||
|
||||
private slots:
|
||||
/** Create the context popup menu and it's submenus */
|
||||
void messageslistWidgetCostumPopupMenu( QPoint point );
|
||||
void folderlistWidgetCostumPopupMenu(QPoint);
|
||||
void messageslistWidgetCustomPopupMenu( QPoint point );
|
||||
void folderlistWidgetCustomPopupMenu(QPoint);
|
||||
void decryptSelectedMsg() ;
|
||||
|
||||
void changeBox(int newrow);
|
||||
void changeQuickView(int newrow);
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <retroshare/rsiface.h>
|
||||
#include <retroshare/rspeers.h>
|
||||
#include <retroshare/rsdisc.h>
|
||||
#include <retroshare/rsmsgs.h>
|
||||
|
||||
#include "common/vmessagebox.h"
|
||||
#include "common/RSTreeWidgetItem.h"
|
||||
@ -230,7 +231,10 @@ void NetworkDialog::connecttreeWidgetCostumPopupMenu( QPoint /*point*/ )
|
||||
contextMnu->addAction(QIcon(IMAGE_PEERDETAILS), tr("Peer details..."), this, SLOT(peerdetails()));
|
||||
contextMnu->addAction(QIcon(IMAGE_COPYLINK), tr("Copy RetroShare Link"), this, SLOT(copyLink()));
|
||||
contextMnu->addSeparator() ;
|
||||
|
||||
#ifdef ENABLE_DISTANT_CHAT_AND_MSGS
|
||||
contextMnu->addAction(QIcon(IMAGE_COPYLINK), tr("Create a distant chat invitation..."), this, SLOT(createChatLink()));
|
||||
contextMnu->addSeparator() ;
|
||||
#endif
|
||||
contextMnu->addAction(QIcon(IMAGE_CLEAN_UNUSED), tr("Remove unused keys..."), this, SLOT(removeUnusedKeys()));
|
||||
|
||||
contextMnu->exec(QCursor::pos());
|
||||
@ -330,6 +334,19 @@ void NetworkDialog::makeFriend()
|
||||
ConfCertDialog::showIt(getCurrentNeighbour()->text(COLUMN_PEERID).toStdString(), ConfCertDialog::PageTrust);
|
||||
}
|
||||
|
||||
void NetworkDialog::createChatLink()
|
||||
{
|
||||
std::string pgp_id = getCurrentNeighbour()->text(COLUMN_PEERID).toStdString() ;
|
||||
|
||||
std::cerr << "Creating chat link for pgp id " << pgp_id << std::endl;
|
||||
|
||||
std::string hash,estr ;
|
||||
rsMsgs->createDistantChatInvite(pgp_id,time(NULL)+3600,estr) ;
|
||||
|
||||
std::cerr << "Created invite:" << std::endl;
|
||||
std::cerr << " estr = " << estr << std::endl;
|
||||
}
|
||||
|
||||
/** Shows Peer Information/Auth Dialog */
|
||||
void NetworkDialog::peerdetails()
|
||||
{
|
||||
|
@ -69,6 +69,7 @@ private slots:
|
||||
void removeUnusedKeys() ;
|
||||
void makeFriend() ;
|
||||
void denyFriend() ;
|
||||
void createChatLink() ;
|
||||
void deleteCert() ;
|
||||
void peerdetails();
|
||||
void copyLink();
|
||||
|
@ -71,7 +71,7 @@ static NewsFeed *instance = NULL;
|
||||
|
||||
/** Constructor */
|
||||
NewsFeed::NewsFeed(QWidget *parent)
|
||||
: MainPage (parent)
|
||||
: RsAutoUpdatePage(1000,parent)
|
||||
{
|
||||
/* Invoke the Qt Designer generated object setup routine */
|
||||
setupUi(this);
|
||||
@ -83,9 +83,9 @@ NewsFeed::NewsFeed(QWidget *parent)
|
||||
connect(removeAllButton, SIGNAL(clicked()), this, SLOT(removeAll()));
|
||||
connect(feedOptionsButton, SIGNAL(clicked()), this, SLOT(feedoptions()));
|
||||
|
||||
QTimer *timer = new QTimer(this);
|
||||
timer->connect(timer, SIGNAL(timeout()), this, SLOT(updateFeed()));
|
||||
timer->start(1000);
|
||||
// QTimer *timer = new QTimer(this);
|
||||
// timer->connect(timer, SIGNAL(timeout()), this, SLOT(updateFeed()));
|
||||
// timer->start(1000);
|
||||
}
|
||||
|
||||
NewsFeed::~NewsFeed()
|
||||
@ -95,7 +95,7 @@ NewsFeed::~NewsFeed()
|
||||
}
|
||||
}
|
||||
|
||||
void NewsFeed::updateFeed()
|
||||
void NewsFeed::updateDisplay()
|
||||
{
|
||||
if (!rsNotify)
|
||||
return;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "ui_NewsFeed.h"
|
||||
|
||||
#include "gui/feeds/FeedHolder.h"
|
||||
#include <retroshare-gui/RsAutoUpdatePage.h>
|
||||
class RsFeedItem;
|
||||
|
||||
class ForumNewItem;
|
||||
@ -33,7 +34,7 @@ class ChanMsgItem;
|
||||
class ChatMsgItem;
|
||||
class FeedNotify;
|
||||
|
||||
class NewsFeed : public MainPage, public FeedHolder, private Ui::NewsFeed
|
||||
class NewsFeed : public RsAutoUpdatePage, public FeedHolder, private Ui::NewsFeed
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -52,6 +53,7 @@ public:
|
||||
static void testFeeds(uint notifyFlags);
|
||||
static void testFeed(FeedNotify *feedNotify);
|
||||
|
||||
virtual void updateDisplay();
|
||||
signals:
|
||||
void newsFeedChanged(int count);
|
||||
|
||||
@ -59,7 +61,6 @@ private slots:
|
||||
// void toggleChanMsgItems(bool on);
|
||||
void feedoptions();
|
||||
|
||||
void updateFeed();
|
||||
void removeAll();
|
||||
void itemDestroyed(QObject*);
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "gui/connect/ConfCertDialog.h"
|
||||
|
||||
#include <retroshare/rsfiles.h>
|
||||
#include <retroshare/rsmsgs.h>
|
||||
#include <retroshare/rspeers.h>
|
||||
#include <retroshare/rsforums.h>
|
||||
#include <retroshare/rschannels.h>
|
||||
@ -55,7 +56,9 @@
|
||||
#define HOST_MESSAGE "message"
|
||||
#define HOST_SEARCH "search"
|
||||
#define HOST_CERTIFICATE "certificate"
|
||||
#define HOST_REGEXP "file|person|forum|channel|search|message|certificate"
|
||||
#define HOST_PUBLIC_MSG "public_msg"
|
||||
#define HOST_PRIVATE_CHAT "private_chat"
|
||||
#define HOST_REGEXP "file|person|forum|channel|search|message|certificate|private_chat|public_msg"
|
||||
|
||||
#define FILE_NAME "name"
|
||||
#define FILE_SIZE "size"
|
||||
@ -87,6 +90,14 @@
|
||||
#define CERTIFICATE_EXT_IPPORT "extipp"
|
||||
#define CERTIFICATE_LOC_IPPORT "locipp"
|
||||
|
||||
#define PRIVATE_CHAT_TIME_STAMP "time_stamp"
|
||||
#define PRIVATE_CHAT_STRING "encrypted_data"
|
||||
#define PRIVATE_CHAT_GPG_ID "gpgid"
|
||||
|
||||
#define PUBLIC_MSG_TIME_STAMP "time_stamp"
|
||||
#define PUBLIC_MSG_SRC_PGP_ID "gpgid"
|
||||
#define PUBLIC_MSG_HASH "hash"
|
||||
|
||||
RetroShareLink::RetroShareLink(const QUrl& url)
|
||||
{
|
||||
fromUrl(url);
|
||||
@ -107,7 +118,8 @@ void RetroShareLink::fromString(const QString& url)
|
||||
#endif
|
||||
|
||||
if ((url.startsWith(QString(RSLINK_SCHEME) + "://" + QString(HOST_FILE)) && url.count("|") == 3) ||
|
||||
(url.startsWith(QString(RSLINK_SCHEME) + "://" + QString(HOST_PERSON)) && url.count("|") == 2)) {
|
||||
(url.startsWith(QString(RSLINK_SCHEME) + "://" + QString(HOST_PERSON)) && url.count("|") == 2))
|
||||
{
|
||||
/* Old link, we try it */
|
||||
QStringList list = url.split ("|");
|
||||
|
||||
@ -158,6 +170,7 @@ void RetroShareLink::fromUrl(const QUrl& url)
|
||||
|
||||
if (url.scheme() != RSLINK_SCHEME) {
|
||||
/* No RetroShare-Link */
|
||||
std::cerr << "Not a RS link: scheme=" << url.scheme().toStdString() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -181,6 +194,29 @@ void RetroShareLink::fromUrl(const QUrl& url)
|
||||
}
|
||||
}
|
||||
|
||||
if(url.host() == HOST_PRIVATE_CHAT)
|
||||
{
|
||||
bool ok ;
|
||||
_type = TYPE_PRIVATE_CHAT ;
|
||||
_time_stamp = url.queryItemValue(PRIVATE_CHAT_TIME_STAMP).toUInt(&ok) ;
|
||||
_encrypted_chat_info = url.queryItemValue(PRIVATE_CHAT_STRING) ;
|
||||
_GPGid = url.queryItemValue(PRIVATE_CHAT_GPG_ID) ;
|
||||
|
||||
check() ;
|
||||
return;
|
||||
}
|
||||
if(url.host() == HOST_PUBLIC_MSG)
|
||||
{
|
||||
bool ok ;
|
||||
_type = TYPE_PUBLIC_MSG ;
|
||||
_hash = url.queryItemValue(PUBLIC_MSG_HASH) ;
|
||||
_time_stamp = url.queryItemValue(PUBLIC_MSG_TIME_STAMP).toUInt(&ok) ;
|
||||
_GPGid = url.queryItemValue(PUBLIC_MSG_SRC_PGP_ID) ;
|
||||
|
||||
check() ;
|
||||
return;
|
||||
}
|
||||
|
||||
if (url.host() == HOST_EXTRAFILE) {
|
||||
bool ok ;
|
||||
|
||||
@ -299,6 +335,32 @@ bool RetroShareLink::createFile(const QString& name, uint64_t size, const QStrin
|
||||
return valid();
|
||||
}
|
||||
|
||||
bool RetroShareLink::createPrivateChatInvite(time_t time_stamp,const QString& gpg_id,const QString& encrypted_chat_info)
|
||||
{
|
||||
clear() ;
|
||||
|
||||
_type = TYPE_PRIVATE_CHAT ;
|
||||
_time_stamp = time_stamp ;
|
||||
_encrypted_chat_info = encrypted_chat_info ;
|
||||
_GPGid = gpg_id ;
|
||||
|
||||
check() ;
|
||||
|
||||
return valid() ;
|
||||
}
|
||||
bool RetroShareLink::createPublicMsgInvite(time_t time_stamp,const QString& issuer_pgp_id,const QString& hash)
|
||||
{
|
||||
clear() ;
|
||||
|
||||
_type = TYPE_PUBLIC_MSG ;
|
||||
_time_stamp = time_stamp ;
|
||||
_hash = hash ;
|
||||
_GPGid = issuer_pgp_id ;
|
||||
|
||||
check() ;
|
||||
|
||||
return valid() ;
|
||||
}
|
||||
bool RetroShareLink::createPerson(const std::string& id)
|
||||
{
|
||||
clear();
|
||||
@ -491,78 +553,93 @@ void RetroShareLink::clear()
|
||||
_hash = "" ;
|
||||
_size = 0 ;
|
||||
_name = "" ;
|
||||
_GPGid = "" ;
|
||||
_time_stamp = 0 ;
|
||||
_encrypted_chat_info = "" ;
|
||||
}
|
||||
|
||||
void RetroShareLink::check()
|
||||
{
|
||||
_valid = true;
|
||||
|
||||
switch (_type) {
|
||||
case TYPE_UNKNOWN:
|
||||
_valid = false;
|
||||
break;
|
||||
case TYPE_EXTRAFILE:
|
||||
if(!checkSSLId(_SSLid))
|
||||
_valid = false; // no break! We also test file stuff below.
|
||||
case TYPE_FILE:
|
||||
if(_size > (((uint64_t)1)<<40)) // 1TB. Who has such large files?
|
||||
switch (_type)
|
||||
{
|
||||
case TYPE_UNKNOWN:
|
||||
_valid = false;
|
||||
break;
|
||||
case TYPE_EXTRAFILE:
|
||||
if(!checkSSLId(_SSLid))
|
||||
_valid = false; // no break! We also test file stuff below.
|
||||
case TYPE_FILE:
|
||||
if(_size > (((uint64_t)1)<<40)) // 1TB. Who has such large files?
|
||||
_valid = false;
|
||||
|
||||
if(!checkName(_name))
|
||||
_valid = false;
|
||||
if(!checkName(_name))
|
||||
_valid = false;
|
||||
|
||||
if(!checkHash(_hash))
|
||||
_valid = false;
|
||||
break;
|
||||
case TYPE_PERSON:
|
||||
if(_size != 0)
|
||||
_valid = false;
|
||||
if(!checkHash(_hash))
|
||||
_valid = false;
|
||||
break;
|
||||
|
||||
if(_name.isEmpty())
|
||||
_valid = false;
|
||||
case TYPE_PRIVATE_CHAT:
|
||||
if(!checkRadix64(_encrypted_chat_info)) _valid = false ;
|
||||
if(!checkPGPId(_GPGid)) _valid = false ;
|
||||
break ;
|
||||
|
||||
if(_hash.isEmpty())
|
||||
_valid = false;
|
||||
break;
|
||||
case TYPE_FORUM:
|
||||
if(_size != 0)
|
||||
_valid = false;
|
||||
case TYPE_PUBLIC_MSG:
|
||||
if(!checkHash(_hash)) _valid = false ;
|
||||
if(!checkPGPId(_GPGid)) _valid = false ;
|
||||
break ;
|
||||
|
||||
if(_name.isEmpty())
|
||||
_valid = false;
|
||||
case TYPE_PERSON:
|
||||
if(_size != 0)
|
||||
_valid = false;
|
||||
|
||||
if(_hash.isEmpty())
|
||||
_valid = false;
|
||||
break;
|
||||
case TYPE_CHANNEL:
|
||||
if(_size != 0)
|
||||
_valid = false;
|
||||
if(_name.isEmpty())
|
||||
_valid = false;
|
||||
|
||||
if(_name.isEmpty())
|
||||
_valid = false;
|
||||
if(_hash.isEmpty())
|
||||
_valid = false;
|
||||
break;
|
||||
case TYPE_FORUM:
|
||||
if(_size != 0)
|
||||
_valid = false;
|
||||
|
||||
if(_hash.isEmpty())
|
||||
_valid = false;
|
||||
break;
|
||||
case TYPE_SEARCH:
|
||||
if(_size != 0)
|
||||
_valid = false;
|
||||
if(_name.isEmpty())
|
||||
_valid = false;
|
||||
|
||||
if(_name.isEmpty())
|
||||
_valid = false;
|
||||
if(_hash.isEmpty())
|
||||
_valid = false;
|
||||
break;
|
||||
case TYPE_CHANNEL:
|
||||
if(_size != 0)
|
||||
_valid = false;
|
||||
|
||||
if(!_hash.isEmpty())
|
||||
_valid = false;
|
||||
break;
|
||||
case TYPE_MESSAGE:
|
||||
if(_size != 0)
|
||||
_valid = false;
|
||||
if(_name.isEmpty())
|
||||
_valid = false;
|
||||
|
||||
if(_hash.isEmpty())
|
||||
_valid = false;
|
||||
break;
|
||||
case TYPE_CERTIFICATE:
|
||||
break;
|
||||
if(_hash.isEmpty())
|
||||
_valid = false;
|
||||
break;
|
||||
case TYPE_SEARCH:
|
||||
if(_size != 0)
|
||||
_valid = false;
|
||||
|
||||
if(_name.isEmpty())
|
||||
_valid = false;
|
||||
|
||||
if(!_hash.isEmpty())
|
||||
_valid = false;
|
||||
break;
|
||||
case TYPE_MESSAGE:
|
||||
if(_size != 0)
|
||||
_valid = false;
|
||||
|
||||
if(_hash.isEmpty())
|
||||
_valid = false;
|
||||
break;
|
||||
case TYPE_CERTIFICATE:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!_valid) {
|
||||
@ -579,6 +656,22 @@ QString RetroShareLink::title() const
|
||||
switch (_type) {
|
||||
case TYPE_UNKNOWN:
|
||||
break;
|
||||
case TYPE_PUBLIC_MSG:
|
||||
{
|
||||
RsPeerDetails detail;
|
||||
rsPeers->getPeerDetails(_GPGid.toStdString(), detail) ;
|
||||
return QString("Click to send a private message to %1 (%2).").arg(QString::fromStdString(detail.name)).arg(_GPGid) ;
|
||||
}
|
||||
case TYPE_PRIVATE_CHAT:
|
||||
{
|
||||
RsPeerDetails detail;
|
||||
rsPeers->getPeerDetails(_GPGid.toStdString(), detail) ;
|
||||
|
||||
if (_GPGid.toStdString() == rsPeers->getGPGOwnId())
|
||||
return QString("Click to open a private chat canal to %1 (%2).").arg(QString::fromStdString(detail.name)).arg(_GPGid) ;
|
||||
else
|
||||
return QString("This is a private chat invite for %1 (%2). You can't use it.").arg(QString::fromStdString(detail.name)).arg(_GPGid) ;
|
||||
}
|
||||
case TYPE_EXTRAFILE:
|
||||
return QString("%1 (%2, Extra - Source included)").arg(hash()).arg(misc::friendlyUnit(size()));
|
||||
case TYPE_FILE:
|
||||
@ -619,6 +712,29 @@ QString RetroShareLink::toString() const
|
||||
|
||||
return url.toString();
|
||||
}
|
||||
case TYPE_PRIVATE_CHAT:
|
||||
{
|
||||
QUrl url;
|
||||
url.setScheme(RSLINK_SCHEME) ;
|
||||
url.setHost(HOST_PRIVATE_CHAT) ;
|
||||
url.addQueryItem(PRIVATE_CHAT_TIME_STAMP,QString::number(_time_stamp)) ;
|
||||
url.addQueryItem(PRIVATE_CHAT_GPG_ID,_GPGid) ;
|
||||
url.addQueryItem(PRIVATE_CHAT_STRING,_encrypted_chat_info) ;
|
||||
|
||||
return url.toString() ;
|
||||
}
|
||||
case TYPE_PUBLIC_MSG:
|
||||
{
|
||||
QUrl url;
|
||||
url.setScheme(RSLINK_SCHEME) ;
|
||||
url.setHost(HOST_PUBLIC_MSG) ;
|
||||
url.addQueryItem(PUBLIC_MSG_TIME_STAMP,QString::number(_time_stamp)) ;
|
||||
url.addQueryItem(PUBLIC_MSG_HASH,_hash) ;
|
||||
url.addQueryItem(PUBLIC_MSG_SRC_PGP_ID,_GPGid) ;
|
||||
|
||||
return url.toString() ;
|
||||
}
|
||||
|
||||
case TYPE_EXTRAFILE:
|
||||
{
|
||||
QUrl url;
|
||||
@ -724,6 +840,14 @@ QString RetroShareLink::niceName() const
|
||||
return PeerDefs::rsid(name().toUtf8().constData(), hash().toStdString());
|
||||
}
|
||||
|
||||
if(type() == TYPE_PRIVATE_CHAT) {
|
||||
return QString("Private chat invite (Valid only for key %1)").arg(_GPGid);
|
||||
}
|
||||
if(type() == TYPE_PUBLIC_MSG) {
|
||||
RsPeerDetails detail;
|
||||
rsPeers->getPeerDetails(_GPGid.toStdString(), detail) ;
|
||||
return QString("Click this link to send a private message to %1 (%2)").arg(QString::fromStdString(detail.name)).arg(_GPGid) ;
|
||||
}
|
||||
if(type() == TYPE_CERTIFICATE) {
|
||||
if (_location.isEmpty()) {
|
||||
return QString("RetroShare Certificate (%1)").arg(_name);
|
||||
@ -814,6 +938,41 @@ bool RetroShareLink::checkSSLId(const QString& ssl_id)
|
||||
|
||||
return true ;
|
||||
}
|
||||
bool RetroShareLink::checkPGPId(const QString& pgp_id)
|
||||
{
|
||||
if(pgp_id.length() != 16)
|
||||
return false ;
|
||||
|
||||
QByteArray qb(pgp_id.toAscii()) ;
|
||||
|
||||
for(int i=0;i<qb.length();++i)
|
||||
{
|
||||
unsigned char b(qb[i]) ;
|
||||
|
||||
if(!((b>47 && b<58) || (b>64 && b<71)))
|
||||
return false ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
bool RetroShareLink::checkRadix64(const QString& s)
|
||||
{
|
||||
QByteArray qb(s.toAscii()) ;
|
||||
|
||||
for(int i=0;i<qb.length();++i)
|
||||
{
|
||||
unsigned char b(qb[i]) ;
|
||||
|
||||
if(!( (b > 46 && b < 58) || (b > 64 && b < 91) || (b > 96 && b < 123) || b=='+' || b=='='))
|
||||
{
|
||||
std::cerr << "Character not allowed in radix: " << b << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
std::cerr << "Radix check: passed" << std::endl;
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool RetroShareLink::checkHash(const QString& hash)
|
||||
{
|
||||
if(hash.length() != 40)
|
||||
@ -1028,6 +1187,58 @@ static void processList(const QStringList &list, const QString &textSingular, co
|
||||
}
|
||||
break ;
|
||||
|
||||
case TYPE_PUBLIC_MSG:
|
||||
{
|
||||
std::cerr << "Opening a public msg window " << std::endl;
|
||||
std::cerr << " time_stamp = " << link._time_stamp << std::endl;
|
||||
std::cerr << " hash = " << link._hash.toStdString() << std::endl;
|
||||
std::cerr << " Issuer Id = " << link._GPGid.toStdString() << std::endl;
|
||||
|
||||
if(link._time_stamp < time(NULL))
|
||||
{
|
||||
QMessageBox::information(NULL,QObject::tr("Messenging link is expired"),QObject::tr("This Messenging link is expired. The destination peer will not receive it.")) ;
|
||||
break ;
|
||||
}
|
||||
|
||||
MessageComposer::msgDistantPeer(link._hash.toStdString(),link._GPGid.toStdString()) ;
|
||||
}
|
||||
break ;
|
||||
case TYPE_PRIVATE_CHAT:
|
||||
{
|
||||
std::cerr << "Opening a private chat window " << std::endl;
|
||||
std::cerr << " time_stamp = " << link._time_stamp << std::endl;
|
||||
std::cerr << " enc-string = " << link._encrypted_chat_info.toStdString() << std::endl;
|
||||
std::cerr << " PGP Id = " << link._GPGid.toStdString() << std::endl;
|
||||
|
||||
if(link._time_stamp < time(NULL))
|
||||
{
|
||||
QMessageBox::information(NULL,QObject::tr("Chat link is expired"),QObject::tr("This chat link is expired. The destination peer will not answer.")) ;
|
||||
break ;
|
||||
}
|
||||
if(link._GPGid.toStdString() != rsPeers->getGPGOwnId())
|
||||
{
|
||||
QMessageBox::information(NULL,QObject::tr("Chat link cannot be decrypted"),QObject::tr("This chat link is encrypted with a key that is not yours. You can't used it. Key ID = ")+link._GPGid) ;
|
||||
break ;
|
||||
}
|
||||
|
||||
std::string hash ;
|
||||
uint32_t error_code ;
|
||||
|
||||
if(!rsMsgs->initiateDistantChatConnexion(link._encrypted_chat_info.toStdString(),hash,error_code))
|
||||
{
|
||||
QString error_msg ;
|
||||
switch(error_code)
|
||||
{
|
||||
default:
|
||||
case RS_DISTANT_CHAT_ERROR_DECRYPTION_FAILED: error_msg = QObject::tr("The link could not be decrypted.") ; break ;
|
||||
case RS_DISTANT_CHAT_ERROR_SIGNATURE_MISMATCH: error_msg = QObject::tr("The link signature cannot be checked.") ; break ;
|
||||
case RS_DISTANT_CHAT_ERROR_UNKNOWN_KEY: error_msg = QObject::tr("The link is signed by an unknown key.") ; break ;
|
||||
}
|
||||
QMessageBox::information(NULL,QObject::tr("Chat connexion is not possible"),error_msg) ;
|
||||
}
|
||||
}
|
||||
break ;
|
||||
|
||||
case TYPE_FILE:
|
||||
case TYPE_EXTRAFILE:
|
||||
{
|
||||
|
@ -52,7 +52,18 @@
|
||||
class RetroShareLink
|
||||
{
|
||||
public:
|
||||
enum enumType { TYPE_UNKNOWN, TYPE_FILE, TYPE_PERSON, TYPE_FORUM, TYPE_CHANNEL, TYPE_SEARCH, TYPE_MESSAGE, TYPE_CERTIFICATE,TYPE_EXTRAFILE };
|
||||
enum enumType { TYPE_UNKNOWN = 0x00,
|
||||
TYPE_FILE = 0x01,
|
||||
TYPE_PERSON = 0x02,
|
||||
TYPE_FORUM = 0x03,
|
||||
TYPE_CHANNEL = 0x04,
|
||||
TYPE_SEARCH = 0x05,
|
||||
TYPE_MESSAGE = 0x06,
|
||||
TYPE_CERTIFICATE = 0x07,
|
||||
TYPE_EXTRAFILE = 0x08,
|
||||
TYPE_PRIVATE_CHAT = 0x09,
|
||||
TYPE_PUBLIC_MSG = 0x0a
|
||||
};
|
||||
|
||||
public:
|
||||
RetroShareLink();
|
||||
@ -67,6 +78,8 @@ class RetroShareLink
|
||||
bool createSearch(const QString& keywords);
|
||||
bool createMessage(const std::string& peerId, const QString& subject);
|
||||
bool createCertificate(const std::string& ssl_or_gpg_id) ;
|
||||
bool createPrivateChatInvite(time_t time_stamp,const QString& gpg_id,const QString& encrypted_chat_info) ;
|
||||
bool createPublicMsgInvite(time_t time_stamp,const QString& pgp_id,const QString& hash) ;
|
||||
bool createUnknwonSslCertificate(const std::string& sslId, const std::string& gpgId = "") ;
|
||||
|
||||
enumType type() const {return _type; }
|
||||
@ -83,6 +96,8 @@ class RetroShareLink
|
||||
const QString& localIPAndPort() const { return _loc_ip_port ; }
|
||||
const QString& externalIPAndPort() const { return _ext_ip_port ; }
|
||||
const QString& location() const { return _location ; }
|
||||
const time_t timeStamp() const { return _time_stamp ; }
|
||||
const QString& encryptedPrivateChatInfo() const { return _encrypted_chat_info ; }
|
||||
QString title() const;
|
||||
|
||||
unsigned int subType() const { return _subType; }
|
||||
@ -118,8 +133,10 @@ class RetroShareLink
|
||||
void clear();
|
||||
void check();
|
||||
static bool checkHash(const QString& hash);
|
||||
static bool checkRadix64(const QString& s);
|
||||
static bool checkName(const QString& name);
|
||||
static bool checkSSLId(const QString& name);
|
||||
static bool checkPGPId(const QString& name);
|
||||
|
||||
bool _valid;
|
||||
enumType _type;
|
||||
@ -135,6 +152,9 @@ class RetroShareLink
|
||||
QString _location ; // location
|
||||
QString _ext_ip_port ;
|
||||
QString _loc_ip_port ;
|
||||
QString _encrypted_chat_info ; // encrypted data string for the recipient of a chat invite
|
||||
time_t _time_stamp ; // time stamp at which the link will expire.
|
||||
|
||||
unsigned int _subType; // for general use as sub type for _type (RSLINK_SUBTYPE_...)
|
||||
};
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "ChatDialog.h"
|
||||
#include "gui/common/PeerDefs.h"
|
||||
#include "PopupChatDialog.h"
|
||||
#include "PopupDistantChatDialog.h"
|
||||
#include "ChatLobbyDialog.h"
|
||||
#include "PopupChatWindow.h"
|
||||
#include "gui/settings/rsharesettings.h"
|
||||
@ -91,11 +92,19 @@ void ChatDialog::init(const std::string &peerId, const QString &title)
|
||||
ChatDialog *cd = getExistingChat(peerId);
|
||||
|
||||
if (cd == NULL) {
|
||||
ChatLobbyId lobby_id;
|
||||
ChatLobbyId lobby_id = 0;
|
||||
bool distant_peer = false ;
|
||||
|
||||
if (rsMsgs->isLobbyId(peerId, lobby_id)) {
|
||||
chatflags = RS_CHAT_OPEN | RS_CHAT_FOCUS; // use own flags
|
||||
}
|
||||
|
||||
uint32_t distant_peer_status ;
|
||||
std::string distant_chat_pgp_id ;
|
||||
|
||||
if(rsMsgs->getDistantChatStatus(peerId,distant_peer_status,distant_chat_pgp_id))
|
||||
chatflags = RS_CHAT_OPEN | RS_CHAT_FOCUS; // use own flags
|
||||
|
||||
if (chatflags & RS_CHAT_OPEN) {
|
||||
if (lobby_id) {
|
||||
std::list<ChatLobbyInfo> linfos;
|
||||
@ -108,6 +117,12 @@ void ChatDialog::init(const std::string &peerId, const QString &title)
|
||||
cd->init(peerId, QString::fromUtf8((*it).lobby_name.c_str()));
|
||||
}
|
||||
}
|
||||
} else if(distant_peer_status > 0) {
|
||||
cd = new PopupDistantChatDialog();
|
||||
chatDialogs[peerId] = cd;
|
||||
std::string peer_name = rsPeers->getGPGName(distant_chat_pgp_id) ;
|
||||
cd->init(peerId, tr("Talking to ")+QString::fromStdString(peer_name)+" (PGP id="+QString::fromStdString(distant_chat_pgp_id)+")") ;
|
||||
|
||||
} else {
|
||||
RsPeerDetails sslDetails;
|
||||
if (rsPeers->getPeerDetails(peerId, sslDetails)) {
|
||||
|
@ -78,7 +78,7 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::WF
|
||||
|
||||
connect(inviteFriendsButton, SIGNAL(clicked()), this , SLOT(inviteFriends()));
|
||||
|
||||
getChatWidget()->addChatButton(inviteFriendsButton) ;
|
||||
getChatWidget()->addChatBarWidget(inviteFriendsButton) ;
|
||||
|
||||
unsubscribeButton = new QPushButton ;
|
||||
unsubscribeButton->setMinimumSize(QSize(28,28)) ;
|
||||
@ -95,7 +95,7 @@ ChatLobbyDialog::ChatLobbyDialog(const ChatLobbyId& lid, QWidget *parent, Qt::WF
|
||||
|
||||
connect(unsubscribeButton, SIGNAL(clicked()), this , SLOT(leaveLobby()));
|
||||
|
||||
getChatWidget()->addChatButton(unsubscribeButton) ;
|
||||
getChatWidget()->addChatBarWidget(unsubscribeButton) ;
|
||||
}
|
||||
|
||||
void ChatLobbyDialog::leaveLobby()
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "ui_ChatWidget.h"
|
||||
#include "gui/notifyqt.h"
|
||||
#include "gui/RetroShareLink.h"
|
||||
#include "gui/CreateMsgLinkDialog.h"
|
||||
#include "gui/settings/rsharesettings.h"
|
||||
#include "gui/settings/RsharePeerSettings.h"
|
||||
#include "gui/im_history/ImHistoryBrowser.h"
|
||||
@ -139,9 +140,9 @@ void ChatWidget::setDefaultExtraFileFlags(TransferRequestFlags fl)
|
||||
ui->hashBox->setDefaultTransferRequestFlags(fl) ;
|
||||
}
|
||||
|
||||
void ChatWidget::addChatButton(QPushButton *button)
|
||||
void ChatWidget::addChatBarWidget(QWidget *w)
|
||||
{
|
||||
ui->toolBarFrame->layout()->addWidget(button) ;
|
||||
ui->toolBarFrame->layout()->addWidget(w) ;
|
||||
}
|
||||
|
||||
void ChatWidget::init(const std::string &peerId, const QString &title)
|
||||
@ -548,11 +549,22 @@ void ChatWidget::contextMenu(QPoint point)
|
||||
QAction *action = contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste RetroShare Link"), this, SLOT(pasteLink()));
|
||||
action->setDisabled(RSLinkClipboard::empty());
|
||||
contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste my certificate link"), this, SLOT(pasteOwnCertificateLink()));
|
||||
#ifdef ENABLE_DISTANT_CHAT_AND_MSGS
|
||||
contextMnu->addAction(QIcon(":/images/pasterslink.png"), tr("Paste/Create private chat or Message link..."), this, SLOT(pasteCreateMsgLink()));
|
||||
#endif
|
||||
|
||||
contextMnu->exec(QCursor::pos());
|
||||
delete(contextMnu);
|
||||
}
|
||||
|
||||
void ChatWidget::pasteCreateMsgLink()
|
||||
{
|
||||
CreateMsgLinkDialog dialog ;
|
||||
dialog.exec() ;
|
||||
|
||||
ui->chatTextEdit->insertHtml(RSLinkClipboard::toHtml());
|
||||
}
|
||||
|
||||
void ChatWidget::contextMenuTextBrowser(QPoint point)
|
||||
{
|
||||
QMatrix matrix;
|
||||
|
@ -47,7 +47,6 @@ class ChatWidget : public QWidget
|
||||
public:
|
||||
enum enumChatType { TYPE_NORMAL, TYPE_HISTORY, TYPE_OFFLINE, TYPE_SYSTEM };
|
||||
|
||||
public:
|
||||
explicit ChatWidget(QWidget *parent = 0);
|
||||
~ChatWidget();
|
||||
|
||||
@ -74,13 +73,14 @@ public:
|
||||
bool setStyle();
|
||||
const RSStyle *getStyle() { return &style; }
|
||||
|
||||
void addChatButton(QPushButton *button) ;
|
||||
void addChatBarWidget(QWidget *w) ;
|
||||
|
||||
bool isActive();
|
||||
void setDefaultExtraFileFlags(TransferRequestFlags f) ;
|
||||
void pasteText(const QString&);
|
||||
|
||||
private slots:
|
||||
void pasteCreateMsgLink() ;
|
||||
void clearChatHistory();
|
||||
void deleteChatHistory();
|
||||
void messageHistory();
|
||||
|
@ -141,9 +141,9 @@ void PopupChatDialog::addIncomingChatMsg(const ChatInfo& info)
|
||||
}
|
||||
}
|
||||
|
||||
void PopupChatDialog::addButton(QPushButton *button)
|
||||
void PopupChatDialog::addChatBarWidget(QWidget *w)
|
||||
{
|
||||
getChatWidget()->addChatButton(button) ;
|
||||
getChatWidget()->addChatBarWidget(w) ;
|
||||
}
|
||||
|
||||
void PopupChatDialog::onChatChanged(int list, int type)
|
||||
|
@ -57,7 +57,7 @@ protected:
|
||||
void processSettings(bool load);
|
||||
|
||||
// used by plugins
|
||||
void addButton(QPushButton *button) ;
|
||||
void addChatBarWidget(QWidget *w) ;
|
||||
|
||||
protected:
|
||||
virtual void addIncomingChatMsg(const ChatInfo& info);
|
||||
|
98
retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp
Normal file
98
retroshare-gui/src/gui/chat/PopupDistantChatDialog.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 2013, Cyril Soler
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
****************************************************************/
|
||||
|
||||
#include <QTimer>
|
||||
#include "PopupDistantChatDialog.h"
|
||||
|
||||
#define IMAGE_RED_LED ":/images/redled.png"
|
||||
#define IMAGE_YEL_LED ":/images/yellowled.png"
|
||||
#define IMAGE_GRN_LED ":/images/greenled.png"
|
||||
#define IMAGE_GRY_LED ":/images/grayled.png"
|
||||
|
||||
PopupDistantChatDialog::~PopupDistantChatDialog()
|
||||
{
|
||||
delete _tunnel_check_timer ;
|
||||
}
|
||||
|
||||
PopupDistantChatDialog::PopupDistantChatDialog(QWidget *parent, Qt::WFlags flags)
|
||||
: PopupChatDialog(parent,flags)
|
||||
{
|
||||
_tunnel_check_timer = new QTimer;
|
||||
_tunnel_check_timer->setInterval(1000) ;
|
||||
|
||||
QObject::connect(_tunnel_check_timer,SIGNAL(timeout()),this,SLOT(checkTunnel())) ;
|
||||
|
||||
_tunnel_check_timer->start() ;
|
||||
_status_label = new QLabel ;
|
||||
|
||||
addChatBarWidget(_status_label) ;
|
||||
checkTunnel() ;
|
||||
}
|
||||
|
||||
void PopupDistantChatDialog::init(const std::string& hash,const QString & title)
|
||||
{
|
||||
_hash = hash ;
|
||||
PopupChatDialog::init(hash,title) ;
|
||||
}
|
||||
|
||||
void PopupDistantChatDialog::checkTunnel()
|
||||
{
|
||||
if(!isVisible())
|
||||
return ;
|
||||
|
||||
std::cerr << "Checking tunnel..." ;
|
||||
// make sure about the tunnel status
|
||||
//
|
||||
|
||||
uint32_t status= RS_DISTANT_CHAT_STATUS_UNKNOWN;
|
||||
std::string pgp_id ;
|
||||
rsMsgs->getDistantChatStatus(_hash,status,pgp_id) ;
|
||||
|
||||
switch(status)
|
||||
{
|
||||
case RS_DISTANT_CHAT_STATUS_UNKNOWN: std::cerr << "Unknown hash. Error!" << std::endl;
|
||||
_status_label->setPixmap(QPixmap(IMAGE_GRY_LED)) ;
|
||||
_status_label->setToolTip(tr("Hash error")) ;
|
||||
break ;
|
||||
case RS_DISTANT_CHAT_STATUS_TUNNEL_DN: std::cerr << "Tunnel asked. Waiting for reponse. " << std::endl;
|
||||
_status_label->setPixmap(QPixmap(IMAGE_RED_LED)) ;
|
||||
_status_label->setToolTip(tr("Tunnel is broken")) ;
|
||||
break ;
|
||||
case RS_DISTANT_CHAT_STATUS_TUNNEL_OK: std::cerr << "Tunnel is ok. " << std::endl;
|
||||
_status_label->setPixmap(QPixmap(IMAGE_YEL_LED)) ;
|
||||
_status_label->setToolTip(tr("Tunnel established")) ;
|
||||
break ;
|
||||
case RS_DISTANT_CHAT_STATUS_CAN_TALK: std::cerr << "Tunnel is ok and works. You can talk!" << std::endl;
|
||||
_status_label->setPixmap(QPixmap(IMAGE_GRN_LED)) ;
|
||||
_status_label->setToolTip(tr("Tunnel is working")) ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
53
retroshare-gui/src/gui/chat/PopupDistantChatDialog.h
Normal file
53
retroshare-gui/src/gui/chat/PopupDistantChatDialog.h
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
/****************************************************************
|
||||
* RetroShare is distributed under the following license:
|
||||
*
|
||||
* Copyright (C) 2013, Cyril Soler
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
****************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "PopupChatDialog.h"
|
||||
|
||||
class QTimer ;
|
||||
|
||||
class PopupDistantChatDialog: public PopupChatDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class ChatDialog;
|
||||
|
||||
public slots:
|
||||
void checkTunnel() ;
|
||||
|
||||
protected:
|
||||
/** Default constructor */
|
||||
PopupDistantChatDialog(QWidget *parent = 0, Qt::WFlags flags = 0);
|
||||
/** Default destructor */
|
||||
virtual ~PopupDistantChatDialog();
|
||||
|
||||
virtual void init(const std::string& _hash, const QString &title);
|
||||
virtual void updateStatus(int /*status*/) {}
|
||||
|
||||
QTimer *_tunnel_check_timer ;
|
||||
std::string _hash ;
|
||||
std::string _virtual_peer_id ;
|
||||
QLabel *_status_label ;
|
||||
};
|
||||
|
||||
|
@ -352,6 +352,22 @@ void MessageComposer::processSettings(bool bLoad)
|
||||
|
||||
Settings->endGroup();
|
||||
}
|
||||
/*static*/ void MessageComposer::msgDistantPeer(const std::string& hash,const std::string& pgp_id)
|
||||
{
|
||||
// std::cerr << "MessageComposer::msgfriend()" << std::endl;
|
||||
|
||||
/* create a message */
|
||||
|
||||
MessageComposer *pMsgDialog = MessageComposer::newMsg();
|
||||
if (pMsgDialog == NULL)
|
||||
return;
|
||||
|
||||
pMsgDialog->addRecipient(TO, hash,pgp_id) ;
|
||||
pMsgDialog->show();
|
||||
|
||||
/* window will destroy itself! */
|
||||
}
|
||||
|
||||
|
||||
/*static*/ void MessageComposer::msgFriend(const std::string &id, bool group)
|
||||
{
|
||||
@ -1219,7 +1235,7 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (std::find(peers.begin(), peers.end(), id) == peers.end()) {
|
||||
if (_distant_peers.find(id)==_distant_peers.end() && std::find(peers.begin(), peers.end(), id) == peers.end()) {
|
||||
// no friend
|
||||
continue;
|
||||
}
|
||||
@ -1269,6 +1285,7 @@ bool MessageComposer::sendMessage_internal(bool bDraftbox)
|
||||
QMessageBox::warning(this, tr("RetroShare"), tr("Please insert at least one recipient."), QMessageBox::Ok);
|
||||
return false; // Don't send with no recipient
|
||||
}
|
||||
mi.encryption_keys = _distant_peers ;
|
||||
|
||||
if (rsMsgs->MessageSend(mi) == false) {
|
||||
return false;
|
||||
@ -1402,7 +1419,13 @@ void MessageComposer::setRecipientToRow(int row, enumType type, std::string id,
|
||||
}
|
||||
} else {
|
||||
RsPeerDetails details;
|
||||
if (rsPeers->getPeerDetails(id, details)) {
|
||||
if(_distant_peers.find(id) != _distant_peers.end())
|
||||
{
|
||||
name = tr("Distant peer (PGP key: %1)").arg(QString::fromStdString(_distant_peers[id])) ;
|
||||
icon = QIcon(StatusDefs::imageUser(RS_STATUS_ONLINE));
|
||||
}
|
||||
else if (rsPeers->getPeerDetails(id, details))
|
||||
{
|
||||
name = PeerDefs::nameWithLocation(details);
|
||||
|
||||
StatusInfo peerStatusInfo;
|
||||
@ -1546,6 +1569,32 @@ void MessageComposer::editingRecipientFinished()
|
||||
lineEdit->setText(text);
|
||||
}
|
||||
|
||||
void MessageComposer::addRecipient(enumType type, const std::string& hash,const std::string& pgp_id)
|
||||
{
|
||||
_distant_peers[hash] = pgp_id ;
|
||||
|
||||
int rowCount = ui.recipientWidget->rowCount();
|
||||
int row;
|
||||
for (row = 0; row < rowCount; row++)
|
||||
{
|
||||
enumType rowType;
|
||||
std::string rowId;
|
||||
bool rowGroup;
|
||||
|
||||
if (getRecipientFromRow(row, rowType, rowId, rowGroup) == true)
|
||||
{
|
||||
if (rowId.empty()) // use row
|
||||
break;
|
||||
|
||||
if (rowId == hash && rowType == type) // existing row
|
||||
break;
|
||||
}
|
||||
else // use row
|
||||
break;
|
||||
}
|
||||
|
||||
setRecipientToRow(row, type, hash, false);
|
||||
}
|
||||
void MessageComposer::addRecipient(enumType type, const std::string &id, bool group)
|
||||
{
|
||||
std::list<std::string> sslIds;
|
||||
|
@ -49,6 +49,8 @@ public:
|
||||
~MessageComposer();
|
||||
|
||||
static void msgFriend(const std::string &id, bool group);
|
||||
static void msgDistantPeer(const std::string& hash,const std::string& pgp_id) ;
|
||||
|
||||
static QString recommendMessage();
|
||||
static void recommendFriend(const std::list <std::string> &sslIds, const std::string &to = "", const QString &msg = "", bool autoSend = false);
|
||||
static void sendConnectAttemptMsg(const std::string &gpgId, const std::string &sslId, const QString &sslName);
|
||||
@ -65,6 +67,7 @@ public:
|
||||
void setQuotedMsg(const QString &msg, const QString &header);
|
||||
void setMsgText(const QString &msg, bool asHtml = false);
|
||||
void addRecipient(enumType type, const std::string &id, bool group);
|
||||
void addRecipient(enumType type, const std::string &hash, const std::string& pgp_id) ;
|
||||
|
||||
public slots:
|
||||
/* actions to take.... */
|
||||
@ -217,6 +220,7 @@ private:
|
||||
Ui::MessageComposer ui;
|
||||
|
||||
std::list<FileInfo> _recList ;
|
||||
std::map<std::string,std::string> _distant_peers ; // pairs (hash,pgp_id)
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -275,6 +275,7 @@ HEADERS += rshare.h \
|
||||
gui/TurtleRouterStatistics.h \
|
||||
gui/AboutDialog.h \
|
||||
gui/ForumsDialog.h \
|
||||
gui/CreateMsgLinkDialog.h \
|
||||
gui/forums/ForumDetails.h \
|
||||
gui/forums/EditForumDetails.h \
|
||||
gui/forums/CreateForum.h \
|
||||
@ -333,6 +334,7 @@ HEADERS += rshare.h \
|
||||
gui/profile/StatusMessage.h \
|
||||
gui/chat/PopupChatWindow.h \
|
||||
gui/chat/PopupChatDialog.h \
|
||||
gui/chat/PopupDistantChatDialog.h \
|
||||
gui/chat/ChatTabWidget.h \
|
||||
gui/chat/ChatWidget.h \
|
||||
gui/chat/ChatDialog.h \
|
||||
@ -471,6 +473,7 @@ FORMS += gui/StartDialog.ui \
|
||||
gui/MainWindow.ui \
|
||||
gui/TurtleRouterDialog.ui \
|
||||
gui/TurtleRouterStatistics.ui \
|
||||
gui/CreateMsgLinkDialog.ui \
|
||||
gui/forums/CreateForum.ui \
|
||||
gui/forums/CreateForumMsg.ui \
|
||||
gui/forums/ForumDetails.ui \
|
||||
@ -580,6 +583,7 @@ SOURCES += main.cpp \
|
||||
gui/TurtleRouterStatistics.cpp \
|
||||
gui/MainWindow.cpp \
|
||||
gui/ForumsDialog.cpp \
|
||||
gui/CreateMsgLinkDialog.cpp \
|
||||
gui/forums/ForumDetails.cpp \
|
||||
gui/forums/EditForumDetails.cpp \
|
||||
gui/forums/CreateForum.cpp \
|
||||
@ -642,6 +646,7 @@ SOURCES += main.cpp \
|
||||
gui/channels/ChannelUserNotify.cpp \
|
||||
gui/chat/PopupChatWindow.cpp \
|
||||
gui/chat/PopupChatDialog.cpp \
|
||||
gui/chat/PopupDistantChatDialog.cpp \
|
||||
gui/chat/ChatTabWidget.cpp \
|
||||
gui/chat/ChatWidget.cpp \
|
||||
gui/chat/ChatDialog.cpp \
|
||||
|
Loading…
x
Reference in New Issue
Block a user