From decb7442bcb54727e378c2b5e1e738fd849b3266 Mon Sep 17 00:00:00 2001 From: csoler Date: Thu, 12 Mar 2009 21:07:00 +0000 Subject: [PATCH] finished turtle router. Needs debugging. Next task: turtle serializer git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@1075 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/services/p3turtle.cc | 94 ++++++++++++-------------- libretroshare/src/services/p3turtle.h | 38 ++++++++--- 2 files changed, 71 insertions(+), 61 deletions(-) diff --git a/libretroshare/src/services/p3turtle.cc b/libretroshare/src/services/p3turtle.cc index f50cea31e..5f01c93a0 100644 --- a/libretroshare/src/services/p3turtle.cc +++ b/libretroshare/src/services/p3turtle.cc @@ -35,9 +35,6 @@ #include #include -const uint8_t RS_TURTLE_SUBTYPE_SEARCH_REQUEST = 0x01; -const uint8_t RS_TURTLE_SUBTYPE_SEARCH_RESULT = 0x02; - #include #include "util/rsdebug.h" @@ -46,20 +43,10 @@ const uint8_t RS_TURTLE_SUBTYPE_SEARCH_RESULT = 0x02; // Operating System specific includes. #include "pqi/pqinetwork.h" -/* DISC FLAGS */ +/* TURTLE FLAGS */ #define P3TURTLE_DEBUG 1 -/*********** NOTE *************** - * - * Only need Mutexs for neighbours information - */ - -/****************************************************************************************** - ****************************** NEW DISCOVERY ******************************************* - ****************************************************************************************** - *****************************************************************************************/ - p3turtle::p3turtle(p3AuthMgr *am, p3ConnectMgr *cm) :p3Service(RS_SERVICE_TYPE_TURTLE), mAuthMgr(am), mConnMgr(cm) { RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ @@ -77,12 +64,14 @@ int p3turtle::tick() if(now > 10+_last_clean_time) { - autoclean() ; // clean old/unused tunnels and search requests. + autoWash() ; // clean old/unused tunnels and search requests. _last_clean_time = now ; } + + return 0 ; } -int p3turtle::autoclean() +void p3turtle::autoWash() { RsStackMutex stack(mTurtleMtx); /********** STACK LOCKED MTX ******/ @@ -93,14 +82,14 @@ TurtleRequestId p3turtle::performSearch(const std::string& string_to_match) { // generate a new search id. - TurtleRequestId = generateRandomRequestId() ; + TurtleRequestId id = generateRandomRequestId() ; // form a request packet // RsTurtleSearchRequestItem *item = new RsTurtleSearchRequestItem ; item->match_string = string_to_match ; - item->request_id = TurtleRequestId ; + item->request_id = id ; item->depth = 0 ; // send it @@ -108,6 +97,8 @@ TurtleRequestId p3turtle::performSearch(const std::string& string_to_match) handleSearchRequest(item) ; delete item ; + + return id ; } int p3turtle::handleIncoming() @@ -126,17 +117,17 @@ int p3turtle::handleIncoming() { nhandled++; - switch(item->subType()) + switch(item->PacketSubType()) { - case RS_TURTLE_SUBTYPE_SEARCH_REQUEST: handleSearchRequest(dynamic_cast(item)) ; + case RS_TURTLE_SUBTYPE_SEARCH_REQUEST: handleSearchRequest(dynamic_cast(item)) ; break ; - case RS_TURTLE_SUBTYPE_SEARCH_RESULT : handleSearchResult(dynamic_cast(item)) ; + case RS_TURTLE_SUBTYPE_SEARCH_RESULT : handleSearchResult(dynamic_cast(item)) ; break ; // Here will also come handling of file transfer requests, tunnel digging/closing, etc. default: - std::cerr << "p3turtle::handleIncoming: Unknown packet subtype " << item->subType() << std::endl ; + std::cerr << "p3turtle::handleIncoming: Unknown packet subtype " << item->PacketSubType() << std::endl ; } delete item; } @@ -151,7 +142,7 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item) #ifdef P3TURTLE_DEBUG std::cerr << "Received search request: " << std::endl ; - item->print() ; + item->print(std::cerr,0) ; #endif // If the item contains an already handled search request, give up. This // happens when the same search request gets relayed by different peers @@ -167,16 +158,16 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item) // This is a new request. Let's add it to the request map, and forward it to // open peers. - requests_origins[item->request_id] = item->peerId() ; + requests_origins[item->request_id] = item->PeerId() ; // If it's not for us, perform a local search. If something found, forward the search result back. - if(item->peerId() != own_peer_id) + if(item->PeerId() != mConnMgr->getOwnId()) { #ifdef P3TURTLE_DEBUG std::cerr << " Request not from us. Performing local search" << std::endl ; #endif - std::map result ; + std::map result ; performLocalSearch(item->match_string,result) ; if(!result.empty()) @@ -190,7 +181,7 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item) res_item->depth = 0 ; res_item->result = result ; res_item->request_id = item->request_id ; - res_item->peer_id = item->peer_id ; // send back to the same guy + res_item->PeerId(item->PeerId()) ; // send back to the same guy #ifdef P3TURTLE_DEBUG std::cerr << " " << result.size() << " matches found. Sending back to origin." << std::endl ; @@ -206,17 +197,17 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item) std::list onlineIds ; mConnMgr->getOnlineList(onlineIds); - for(std::map<>::const_iterator it(inlineIds.begin());it!=inlineIds.end();++it) - if(*it != item->peerId()) + for(std::list::const_iterator it(onlineIds.begin());it!=onlineIds.end();++it) + if(*it != item->PeerId()) { #ifdef P3TURTLE_DEBUG std::cerr << " Forwarding request to peer = " << *it << std::endl ; #endif // Copy current item and modify it. - RsTurtleSearchRequestItem *fwd_item = new RsTurtleSearchRequestItem(item) ; + RsTurtleSearchRequestItem *fwd_item = new RsTurtleSearchRequestItem(*item) ; ++(fwd_item->depth) ; // increase search depth - fwd_item->peerId = *it ; + fwd_item->PeerId(*it) ; sendItem(fwd_item) ; } @@ -227,14 +218,14 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item) #endif } -void p3turtle::handleSearchResult(const RsTurtleSearchResultItem *item) +void p3turtle::handleSearchResult(RsTurtleSearchResultItem *item) { // Find who actually sent the corresponding request. // std::map::const_iterator it = requests_origins.find(item->request_id) ; #ifdef P3TURTLE_DEBUG std::cerr << "Received search result:" << std::endl ; - item->print() ; + item->print(std::cerr,0) ; #endif if(it == requests_origins.end()) { @@ -248,45 +239,48 @@ void p3turtle::handleSearchResult(const RsTurtleSearchResultItem *item) // Is this result's target actually ours ? - if(it->second == own_peer_id) + if(it->second == mConnMgr->getOwnId()) returnSearchResult(item) ; // Yes, so send upward. else { // Nope, so forward it back. #ifdef P3TURTLE_DEBUG std::cerr << " Forwarding result back to " << it->second << std::endl; #endif - RsTurtleSearchResultItem *fwd_item = new RsTurtleSearchResultItem(item) ; // copy the item + RsTurtleSearchResultItem *fwd_item = new RsTurtleSearchResultItem(*item) ; // copy the item ++(fwd_item->depth) ; // increase depth // normally here, we should setup the forward adress, so that the owner's of the files found can be further reached by a tunnel. - fwd_item->peerId = it->second ; + fwd_item->PeerId(it->second) ; sendItem(fwd_item) ; } } -void RsTurtleSearchRequestItem::print() const +std::ostream& RsTurtleSearchRequestItem::print(std::ostream& o, uint16_t) { - std::cout << "Search request:" << std::endl ; + o << "Search request:" << std::endl ; + o << " match string: \"" << match_string << "\"" << std::endl ; + o << " Req. Id: " << request_id << std::endl ; + o << " Depth : " << depth << std::endl ; - std::cout << " match string: \"" << match_string << "\"" << std::endl ; - std::cout << " Req. Id: " << request_id << std::endl ; - std::cout << " Depth : " << depth << std::endl ; + return o ; } -void RsTurtleSearchResultItem::print() const +std::ostream& RsTurtleSearchResultItem::print(std::ostream& o, uint16_t) { - std::cout << "Search result:" << std::endl ; + o << "Search result:" << std::endl ; - std::cout << " Peer id: " << peer_id << std::endl ; - std::cout << " Depth : " << depth << std::endl ; - std::cout << " Req. Id: " << request_id << std::endl ; - std::cout << " Files:" << std::endl ; + o << " Peer id: " << peer_id << std::endl ; + o << " Depth : " << depth << std::endl ; + o << " Req. Id: " << request_id << std::endl ; + o << " Files:" << std::endl ; - for(std::map::const_iterator it(result.begin());it!=result.end();++it) - std::cout << " " << it->first << " " << it->Second << std::endl ; + for(std::map::const_iterator it(result.begin());it!=result.end();++it) + o << " " << it->first << " " << it->second << std::endl ; + + return o ; } void p3turtle::returnSearchResult(RsTurtleSearchResultItem *item) @@ -294,7 +288,7 @@ void p3turtle::returnSearchResult(RsTurtleSearchResultItem *item) // just cout for now, but it should be notified to the gui std::cerr << "Received result for search request: " << std::endl ; - item->print() ; + item->print(std::cerr,0) ; } /************* from pqiMonitor *******************/ diff --git a/libretroshare/src/services/p3turtle.h b/libretroshare/src/services/p3turtle.h index 922314fb4..517530cd5 100644 --- a/libretroshare/src/services/p3turtle.h +++ b/libretroshare/src/services/p3turtle.h @@ -3,7 +3,7 @@ * * Services for RetroShare. * - * Copyright 2004-2008 by Robert Fernie. + * 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 @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. * - * Please report all bugs and problems to "retroshare@lunamutt.com". + * Please report all bugs and problems to "csoler@users.sourceforge.net". * */ @@ -45,16 +45,19 @@ #include #include -// system specific network headers #include "pqi/pqinetwork.h" #include "pqi/pqi.h" #include "pqi/pqimonitor.h" -#include "serialiser/rsdiscitems.h" #include "services/p3service.h" class p3AuthMgr; class p3ConnectMgr; +const uint8_t RS_TURTLE_SUBTYPE_SEARCH_REQUEST = 0x01 ; +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 ; @@ -63,23 +66,27 @@ typedef std::string TurtleFileName ; 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 void print() const = 0 ; + virtual void clear() {} }; class RsTurtleSearchResultItem: public RsTurtleItem { public: + RsTurtleSearchResultItem() : RsTurtleItem(RS_TURTLE_SUBTYPE_SEARCH_RESULT) {} + uint16_t depth ; uint8_t peer_id[16]; // peer id. This will eventually be obfuscated in some way. TurtleRequestId request_id ; // randomly generated request id. std::map result ; - virtual void print() const ; + virtual std::ostream& print(std::ostream& o, uint16_t) ; protected: virtual bool serialize(void *data,uint32_t& size) ; @@ -90,11 +97,13 @@ class RsTurtleSearchResultItem: public RsTurtleItem class RsTurtleSearchRequestItem: public RsTurtleItem { public: + RsTurtleSearchRequestItem() : RsTurtleItem(RS_TURTLE_SUBTYPE_SEARCH_REQUEST) {} + std::string match_string ; // string to match uint32_t request_id ; // randomly generated request id. uint16_t depth ; // Used for limiting search depth. - virtual void print() const = 0 ; + virtual std::ostream& print(std::ostream& o, uint16_t) ; protected: virtual bool serialize(void *data,uint32_t& size) ; @@ -153,16 +162,23 @@ class p3turtle: public p3Service, public pqiMonitor private: inline uint32_t generateRandomRequestId() const { return lrand48() ; } - void autoclean() ; + void autoWash() ; /* Network Input */ int handleIncoming(); int handleOutgoing(); - void handleSearchRequest(RsTurtleSearchRequestItem *item); + // Performs a search calling local cache and search structure. + void performLocalSearch(const std::string& s,std::map& result) {} - std::map request_origins ; // keeps trace of who emmitted a given request - std::map file_tunnels ; // stores adequate tunnels for each file hash. + void handleSearchRequest(RsTurtleSearchRequestItem *item); + void handleSearchResult(RsTurtleSearchResultItem *item); + + // returns a search result upwards (possibly to the gui) + void returnSearchResult(RsTurtleSearchResultItem *item) ; + + 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;