turtle dev. Worked on serialisation, mainly, and connexion to gui.

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@1076 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2009-03-13 21:14:30 +00:00
parent decb7442bc
commit 29bd4795fd
8 changed files with 364 additions and 26 deletions

View File

@ -0,0 +1,65 @@
#ifndef RETROSHARE_TURTLE_GUI_INTERFACE_H
#define RETROSHARE_TURTLE_GUI_INTERFACE_H
/*
* libretroshare/src/rsiface: rsturtle.h
*
* RetroShare C++ Interface.
*
* Copyright 2009 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 <inttypes.h>
#include <string>
#include <list>
class RsTurtle;
extern RsTurtle *rsTurtle ;
typedef uint32_t TurtleRequestId ;
// Interface class for turtle hopping.
//
// This class mainly interacts with the turtle router, that is responsible
// for routing turtle packets between peers, accepting/forwarding search
// requests and dowloading files.
//
// As seen from here, the interface is really simple.
//
class RsTurtle
{
public:
RsTurtle() {}
virtual ~RsTurtle() {}
// 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.
//
virtual TurtleRequestId turtleSearch(const std::string& match_string) = 0 ;
// Launches a complete download file operation: diggs one or more
// tunnels. Launches an exception if an error occurs during the
// initialization process.
//
virtual void turtleDownload(const std::string& file_hash) = 0 ;
};
#endif

View File

@ -36,6 +36,10 @@
*/
RsFiles *rsFiles = NULL;
#ifdef TURTLE_HOPPING
#include "rsiface/rsturtle.h"
RsTurtle *rsTurtle = NULL ;
#endif
#include "pqi/pqipersongrp.h"
#include "pqi/pqisslpersongrp.h"
@ -60,6 +64,10 @@ RsFiles *rsFiles = NULL;
#include "services/p3status.h"
#include "services/p3Qblog.h"
#ifdef TURTLE_HOPPING
#include "services/p3turtle.h"
#endif
#include <list>
#include <string>
#include <sstream>
@ -642,6 +650,11 @@ int RsServer::StartupRetroShare()
msgSrv = new p3MsgService(mConnMgr);
chatSrv = new p3ChatService(mConnMgr);
#ifdef TURTLE_HOPPING
p3turtle *tr = new p3turtle(mConnMgr) ;
rsTurtle = tr ;
pqih -> addService(tr);
#endif
pqih -> addService(ad);
pqih -> addService(msgSrv);
pqih -> addService(chatSrv);

View File

@ -442,7 +442,7 @@ bool GetTlvString(void *data, uint32_t size, uint32_t *offset,
return true;
}
uint32_t GetTlvStringSize(std::string &in) {
uint32_t GetTlvStringSize(const std::string &in) {
return 4 + in.size();
}

View File

@ -238,7 +238,7 @@ uint32_t GetTlvUInt64Size();
bool SetTlvString(void *data, uint32_t size, uint32_t *offset, uint16_t type, std::string out);
bool GetTlvString(void *data, uint32_t size, uint32_t *offset, uint16_t type, std::string &in);
uint32_t GetTlvStringSize(std::string &in);
uint32_t GetTlvStringSize(const std::string &in);
bool SetTlvWideString(void *data, uint32_t size, uint32_t *offset, uint16_t type, std::wstring out);
bool GetTlvWideString(void *data, uint32_t size, uint32_t *offset, uint16_t type, std::wstring &in);

View File

@ -23,12 +23,15 @@
*
*/
#include <stdexcept>
#include "rsiface/rsiface.h"
#include "rsiface/rspeers.h"
#include "pqi/p3authmgr.h"
#include "pqi/p3connmgr.h"
#include "pqi/pqinotify.h"
#include "p3turtle.h"
#include <iostream>
@ -47,7 +50,7 @@
#define P3TURTLE_DEBUG 1
p3turtle::p3turtle(p3AuthMgr *am, p3ConnectMgr *cm) :p3Service(RS_SERVICE_TYPE_TURTLE), mAuthMgr(am), mConnMgr(cm)
p3turtle::p3turtle(p3ConnectMgr *cm) :p3Service(RS_SERVICE_TYPE_TURTLE), mConnMgr(cm)
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
@ -57,7 +60,7 @@ p3turtle::p3turtle(p3AuthMgr *am, p3ConnectMgr *cm) :p3Service(RS_SERVICE_TYPE_T
int p3turtle::tick()
{
handleIncoming(); // handle incoming packets
handleOutgoing(); // handle outgoing packets
// handleOutgoing(); // handle outgoing packets
// Clean every 10 sec.
time_t now = time(NULL) ;
@ -78,7 +81,14 @@ void p3turtle::autoWash()
// look for tunnels and stored temportary info that have not been used for a while.
}
TurtleRequestId p3turtle::performSearch(const std::string& string_to_match)
uint32_t p3turtle::generateRandomRequestId()
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
return lrand48() ;
}
TurtleRequestId p3turtle::turtleSearch(const std::string& string_to_match)
{
// generate a new search id.
@ -101,6 +111,14 @@ TurtleRequestId p3turtle::performSearch(const std::string& string_to_match)
return id ;
}
void p3turtle::turtleDownload(const std::string& file_hash)
{
pqiNotify *notify = getPqiNotify();
if (notify)
notify->AddSysMessage(0, RS_SYS_WARNING, std::string("Unimplemented"),std::string("turtle download is not yet implemented. Sorry"));
}
int p3turtle::handleIncoming()
{
#ifdef P3TURTLE_DEBUG
@ -137,6 +155,7 @@ int p3turtle::handleIncoming()
void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
// take a look at the item:
// - If the item destimation is
@ -220,6 +239,7 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
void p3turtle::handleSearchResult(RsTurtleSearchResultItem *item)
{
RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/
// Find who actually sent the corresponding request.
//
std::map<TurtleRequestId,TurtlePeerId>::const_iterator it = requests_origins.find(item->request_id) ;
@ -315,3 +335,163 @@ void p3turtle::statusChange(const std::list<pqipeer> &plist)
#endif
}
#include "serialiser/rstlvbase.h"
#include "serialiser/rsbaseserial.h"
uint32_t RsTurtleSearchRequestItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += GetTlvStringSize(match_string) ;
s += 4 ; // request_id
s += 2 ; // depth
return s ;
}
bool RsTurtleSearchRequestItem::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 &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, match_string);
ok &= setRawUInt32(data, tlvsize, &offset, request_id);
ok &= setRawUInt16(data, tlvsize, &offset, depth);
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
#endif
}
return ok;
}
uint32_t RsTurtleSearchResultItem::serial_size()
{
uint32_t s = 0 ;
s += 8 ; // header
s += 4 ; // search request id
s += 4 ; // number of results
for(std::map<TurtleFileHash,TurtleFileName>::const_iterator it(result.begin());it!=result.end();++it)
{
s += GetTlvStringSize(it->first) ; // file hash
s += GetTlvStringSize(it->second) ; // file name
}
return s ;
}
bool RsTurtleSearchResultItem::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, request_id);
ok &= setRawUInt32(data, tlvsize, &offset, result.size());
for(std::map<TurtleFileHash,TurtleFileName>::const_iterator it(result.begin());it!=result.end();++it)
{
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_HASH_SHA1, it->first); // file hash
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_NAME, it->second); // file name
}
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsFileConfigSerialiser::serialiseTransfer() Size Error! " << std::endl;
#endif
}
return ok;
}
RsItem *RsTurtleSerialiser::deserialise(void *data, uint32_t *size)
{
// look what we have...
/* get the type */
uint32_t rstype = getRsItemId(data);
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) || (RS_SERVICE_TYPE_TURTLE != getRsItemService(rstype)))
{
return NULL; /* wrong type */
}
switch(getRsItemSubType(rstype))
{
case RS_TURTLE_SUBTYPE_SEARCH_REQUEST: return new RsTurtleSearchResultItem(data,*size) ;
case RS_TURTLE_SUBTYPE_SEARCH_RESULT: return new RsTurtleSearchResultItem(data,*size) ;
default:
std::cerr << "Unknown packet type in RsTurtle!" << std::endl ;
return NULL ;
}
}
RsTurtleSearchResultItem::RsTurtleSearchResultItem(void *data,uint32_t pktsize)
: RsTurtleItem(RS_TURTLE_SUBTYPE_SEARCH_RESULT)
{
uint32_t offset = 8; // skip the header
uint32_t rssize = getRsItemSize(data);
/* add mandatory parts first */
bool ok = true ;
uint32_t s ;
ok &= getRawUInt32(data, pktsize, &offset, &request_id);
ok &= getRawUInt32(data, pktsize, &offset, &s) ;
result.clear() ;
for(uint i=0;i<s;++i)
{
std::string hash,filename ;
ok &= GetTlvString(data, pktsize, &offset, TLV_TYPE_STR_HASH_SHA1, hash); // file hash
ok &= GetTlvString(data, pktsize, &offset, TLV_TYPE_STR_NAME, filename); // file name
result[hash]=filename ;
}
if (offset != rssize)
throw std::runtime_error("Size error while deserializing.") ;
if (!ok)
throw std::runtime_error("Unknown error while deserializing.") ;
}

View File

@ -49,6 +49,8 @@
#include "pqi/pqi.h"
#include "pqi/pqimonitor.h"
#include "services/p3service.h"
#include "serialiser/rsserviceids.h"
#include "rsiface/rsturtle.h"
class p3AuthMgr;
class p3ConnectMgr;
@ -58,7 +60,6 @@ const uint8_t RS_TURTLE_SUBTYPE_SEARCH_RESULT = 0x02 ;
static const int TURTLE_MAX_SEARCH_DEPTH = 6 ;
typedef uint32_t TurtleRequestId ;
typedef std::string TurtlePeerId ;
typedef std::string TurtleFileHash ;
typedef std::string TurtleFileName ;
@ -68,9 +69,8 @@ class RsTurtleItem: public RsItem
public:
RsTurtleItem(uint8_t turtle_subtype) : RsItem(RS_PKT_VERSION_SERVICE,RS_SERVICE_TYPE_TURTLE,turtle_subtype) {}
virtual bool serialize(void *data,uint32_t& size) = 0 ; // isn't it better that items can (de)serialize themselves ?
virtual RsItem *deserialize(const void *data,uint32_t size) = 0 ;
virtual uint32_t serial_size() const = 0 ;
virtual bool serialize(void *data,uint32_t& size) = 0 ; // Isn't it better that items can serialize themselves ?
virtual uint32_t serial_size() = 0 ; // deserialise is handled using a constructor
virtual void clear() {}
};
@ -79,6 +79,7 @@ class RsTurtleSearchResultItem: public RsTurtleItem
{
public:
RsTurtleSearchResultItem() : RsTurtleItem(RS_TURTLE_SUBTYPE_SEARCH_RESULT) {}
RsTurtleSearchResultItem(void *data,uint32_t size) ; // deserialization
uint16_t depth ;
uint8_t peer_id[16]; // peer id. This will eventually be obfuscated in some way.
@ -90,14 +91,14 @@ class RsTurtleSearchResultItem: public RsTurtleItem
protected:
virtual bool serialize(void *data,uint32_t& size) ;
virtual RsItem *deserialize(const void *data,uint32_t size) ;
virtual uint32_t serial_size() const ;
virtual uint32_t serial_size() ;
};
class RsTurtleSearchRequestItem: public RsTurtleItem
{
public:
RsTurtleSearchRequestItem() : RsTurtleItem(RS_TURTLE_SUBTYPE_SEARCH_REQUEST) {}
RsTurtleSearchRequestItem(void *data,uint32_t size) ; // deserialization
std::string match_string ; // string to match
uint32_t request_id ; // randomly generated request id.
@ -107,8 +108,7 @@ class RsTurtleSearchRequestItem: public RsTurtleItem
protected:
virtual bool serialize(void *data,uint32_t& size) ;
virtual RsItem *deserialize(const void *data,uint32_t size) ;
virtual uint32_t serial_size() const ;
virtual uint32_t serial_size() ;
};
// Class responsible for serializing/deserializing all turtle items.
@ -126,7 +126,7 @@ class RsTurtleSerialiser: public RsSerialType
{
return static_cast<RsTurtleItem *>(item)->serialize(data,*size) ;
}
virtual RsItem * deserialise (void *data, uint32_t *size) ;
virtual RsItem *deserialise (void *data, uint32_t *size) ;
};
class TurtleTunnel
@ -137,16 +137,22 @@ class TurtleTunnel
uint32_t time_stamp ; // last time the tunnel was actually used. Used for cleaning old tunnels.
};
class p3turtle: public p3Service, public pqiMonitor
class p3turtle: public p3Service, public pqiMonitor, public RsTurtle
{
public:
p3turtle(p3AuthMgr *am, p3ConnectMgr *cm);
p3turtle(p3ConnectMgr *cm);
// 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.
//
TurtleRequestId performSearch(const std::string& string_to_match) ;
virtual TurtleRequestId turtleSearch(const std::string& string_to_match) ;
// Launches a complete download file operation: diggs one or more
// tunnels. Launches an exception if an error occurs during the
// initialization process.
//
virtual void turtleDownload(const std::string& file_hash) ;
/************* from pqiMonitor *******************/
// Informs the turtle router that some peers are (dis)connected. This should initiate digging new tunnels,
@ -158,15 +164,15 @@ class p3turtle: public p3Service, public pqiMonitor
// Handles incoming and outgoing packets, sort search requests and
// forward info upward.
int tick();
virtual int tick();
private:
inline uint32_t generateRandomRequestId() const { return lrand48() ; }
uint32_t generateRandomRequestId() ;
void autoWash() ;
/* Network Input */
int handleIncoming();
int handleOutgoing();
// int handleOutgoing();
// Performs a search calling local cache and search structure.
void performLocalSearch(const std::string& s,std::map<TurtleFileHash,TurtleFileName>& result) {}
@ -177,16 +183,15 @@ class p3turtle: public p3Service, public pqiMonitor
// returns a search result upwards (possibly to the gui)
void returnSearchResult(RsTurtleSearchResultItem *item) ;
/* data */
p3ConnectMgr *mConnMgr;
RsMutex mTurtleMtx;
std::map<TurtleRequestId,TurtlePeerId> requests_origins ; // keeps trace of who emmitted a given request
std::map<TurtleFileHash,TurtleTunnel> file_tunnels ; // stores adequate tunnels for each file hash.
p3AuthMgr *mAuthMgr;
p3ConnectMgr *mConnMgr;
time_t _last_clean_time ;
/* data */
RsMutex mTurtleMtx;
};
#endif

View File

@ -26,6 +26,9 @@
#include "rsiface/rsexpr.h"
#include "rsiface/rsfiles.h"
#include "rsiface/rspeers.h"
#ifdef TURTLE_HOPPING
#include "rsiface/rsturtle.h"
#endif
#include "util/misc.h"
#include <iostream>
@ -416,6 +419,12 @@ void SearchDialog::advancedSearch(Expression* expression)
void SearchDialog::searchKeywords()
{
#ifdef TURTLE_HOPPING
QString qTxt = ui.lineEdit->text();
std::string txt = qTxt.toStdString();
TurtleRequestId id = rsTurtle->turtleSearch(txt) ;
#else
QString qTxt = ui.lineEdit->text();
std::string txt = qTxt.toStdString();
@ -488,6 +497,7 @@ void SearchDialog::searchKeywords()
/* abstraction to allow reusee of tree rendering code */
resultsToTree(txt, *finalResults);
#endif
}
void SearchDialog::resultsToTree(std::string txt, std::list<FileDetail> results)

View File

@ -0,0 +1,65 @@
#ifndef RETROSHARE_TURTLE_GUI_INTERFACE_H
#define RETROSHARE_TURTLE_GUI_INTERFACE_H
/*
* libretroshare/src/rsiface: rsturtle.h
*
* RetroShare C++ Interface.
*
* Copyright 2009 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 <inttypes.h>
#include <string>
#include <list>
class RsTurtle;
extern RsTurtle *rsTurtle ;
typedef uint32_t TurtleRequestId ;
// Interface class for turtle hopping.
//
// This class mainly interacts with the turtle router, that is responsible
// for routing turtle packets between peers, accepting/forwarding search
// requests and dowloading files.
//
// As seen from here, the interface is really simple.
//
class RsTurtle
{
public:
RsTurtle() {}
virtual ~RsTurtle() {}
// 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.
//
virtual TurtleRequestId turtleSearch(const std::string& match_string) = 0 ;
// Launches a complete download file operation: diggs one or more
// tunnels. Launches an exception if an error occurs during the
// initialization process.
//
virtual void turtleDownload(const std::string& file_hash) = 0 ;
};
#endif