diff --git a/libretroshare/src/rsiface/rsturtle.h b/libretroshare/src/rsiface/rsturtle.h new file mode 100644 index 000000000..0bfb4937a --- /dev/null +++ b/libretroshare/src/rsiface/rsturtle.h @@ -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 +#include +#include + +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 diff --git a/libretroshare/src/rsserver/p3face-startup.cc b/libretroshare/src/rsserver/p3face-startup.cc index 4c225a40f..f8635c143 100644 --- a/libretroshare/src/rsserver/p3face-startup.cc +++ b/libretroshare/src/rsserver/p3face-startup.cc @@ -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 #include #include @@ -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); diff --git a/libretroshare/src/serialiser/rstlvbase.cc b/libretroshare/src/serialiser/rstlvbase.cc index 9db35f7f8..cfc9b01f0 100644 --- a/libretroshare/src/serialiser/rstlvbase.cc +++ b/libretroshare/src/serialiser/rstlvbase.cc @@ -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(); } diff --git a/libretroshare/src/serialiser/rstlvbase.h b/libretroshare/src/serialiser/rstlvbase.h index b0a34d823..46f1d8ba1 100644 --- a/libretroshare/src/serialiser/rstlvbase.h +++ b/libretroshare/src/serialiser/rstlvbase.h @@ -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); diff --git a/libretroshare/src/services/p3turtle.cc b/libretroshare/src/services/p3turtle.cc index 5f01c93a0..6518945b7 100644 --- a/libretroshare/src/services/p3turtle.cc +++ b/libretroshare/src/services/p3turtle.cc @@ -23,12 +23,15 @@ * */ +#include #include "rsiface/rsiface.h" #include "rsiface/rspeers.h" #include "pqi/p3authmgr.h" #include "pqi/p3connmgr.h" +#include "pqi/pqinotify.h" + #include "p3turtle.h" #include @@ -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::const_iterator it = requests_origins.find(item->request_id) ; @@ -315,3 +335,163 @@ void p3turtle::statusChange(const std::list &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::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::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(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& 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 requests_origins ; // keeps trace of who emmitted a given request std::map file_tunnels ; // stores adequate tunnels for each file hash. - p3AuthMgr *mAuthMgr; - p3ConnectMgr *mConnMgr; - time_t _last_clean_time ; - - /* data */ - RsMutex mTurtleMtx; }; #endif diff --git a/retroshare-gui/src/gui/SearchDialog.cpp b/retroshare-gui/src/gui/SearchDialog.cpp index 4a7638934..a01e8960b 100644 --- a/retroshare-gui/src/gui/SearchDialog.cpp +++ b/retroshare-gui/src/gui/SearchDialog.cpp @@ -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 @@ -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 results) diff --git a/retroshare-gui/src/rsiface/rsturtle.h b/retroshare-gui/src/rsiface/rsturtle.h new file mode 100644 index 000000000..0bfb4937a --- /dev/null +++ b/retroshare-gui/src/rsiface/rsturtle.h @@ -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 +#include +#include + +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