implemented a verification for tunnel results. When the network gets heavily loaded, some tunnel results happen to get back twice. This stops the tunnel result sibblings

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@4152 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2011-04-10 19:22:15 +00:00
parent 97b4d5df41
commit 4ea647b78c
2 changed files with 22 additions and 8 deletions

View File

@ -770,7 +770,7 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item)
// We use a random factor on the depth test that is biased by a mix between the session id and the partial tunnel id // We use a random factor on the depth test that is biased by a mix between the session id and the partial tunnel id
// to scramble a possible search-by-depth attack. // to scramble a possible search-by-depth attack.
// //
bool random_bypass = (item->depth == TURTLE_MAX_SEARCH_DEPTH && (_random_bias ^ item->request_id)&0x7==2) ; bool random_bypass = (item->depth == TURTLE_MAX_SEARCH_DEPTH && (((_random_bias ^ item->request_id)&0x7)==2)) ;
if(item->depth < TURTLE_MAX_SEARCH_DEPTH || random_bypass) if(item->depth < TURTLE_MAX_SEARCH_DEPTH || random_bypass)
{ {
@ -1548,11 +1548,12 @@ void p3turtle::handleTunnelRequest(RsTurtleOpenTunnelItem *item)
// //
if(it->second.depth > item->depth && ((item->partial_tunnel_id ^ _random_bias)&0x7)>0) if(it->second.depth > item->depth && ((item->partial_tunnel_id ^ _random_bias)&0x7)>0)
{ {
//#ifdef P3TURTLE_DEBUG #ifdef P3TURTLE_DEBUG
std::cerr << " re-routing tunnel request. Item age difference = " << time(NULL)-it->second.time_stamp << std::endl; std::cerr << " re-routing tunnel request. Item age difference = " << time(NULL)-it->second.time_stamp << std::endl;
std::cerr << " - old source: " << it->second.origin << ", old depth=" << it->second.depth << std::endl ; std::cerr << " - old source: " << it->second.origin << ", old depth=" << it->second.depth << std::endl ;
std::cerr << " - new source: " << item->PeerId() << ", new depth=" << item->depth << std::endl ; std::cerr << " - new source: " << item->PeerId() << ", new depth=" << item->depth << std::endl ;
//#endif std::cerr << " - half id: " << (void*)it->first << std::endl ;
#endif
it->second.origin = item->PeerId() ; it->second.origin = item->PeerId() ;
it->second.depth = item->depth ; it->second.depth = item->depth ;
} }
@ -1637,7 +1638,7 @@ void p3turtle::handleTunnelRequest(RsTurtleOpenTunnelItem *item)
// If search depth not too large, also forward this search request to all other peers. // If search depth not too large, also forward this search request to all other peers.
// //
bool random_bypass = (item->depth == TURTLE_MAX_SEARCH_DEPTH && (_random_bias ^ item->partial_tunnel_id)&0x7==2) ; bool random_bypass = (item->depth == TURTLE_MAX_SEARCH_DEPTH && (((_random_bias ^ item->partial_tunnel_id)&0x7)==2)) ;
if(item->depth < TURTLE_MAX_SEARCH_DEPTH || random_bypass) if(item->depth < TURTLE_MAX_SEARCH_DEPTH || random_bypass)
{ {
@ -1678,19 +1679,30 @@ void p3turtle::handleTunnelResult(RsTurtleTunnelOkItem *item)
// Find who actually sent the corresponding turtle tunnel request. // Find who actually sent the corresponding turtle tunnel request.
// //
std::map<TurtleTunnelRequestId,TurtleRequestInfo>::const_iterator it = _tunnel_requests_origins.find(item->request_id) ; std::map<TurtleTunnelRequestId,TurtleRequestInfo>::iterator it = _tunnel_requests_origins.find(item->request_id) ;
#ifdef P3TURTLE_DEBUG #ifdef P3TURTLE_DEBUG
std::cerr << "Received tunnel result:" << std::endl ; std::cerr << "Received tunnel result:" << std::endl ;
item->print(std::cerr,0) ; item->print(std::cerr,0) ;
#endif #endif
if(it == _tunnel_requests_origins.end()) if(it == _tunnel_requests_origins.end())
{ {
// This is an error: how could we receive a tunnel result corresponding to a tunnel item we // This is an error: how could we receive a tunnel result corresponding to a tunnel item we
// have forwarded but that it not in the list ?? // have forwarded but that it not in the list ?? Actually that happens, when tunnel requests
// get too old, before the tunnelOk item gets back. But this is quite unusual.
#ifdef P3TURTLE_DEBUG
std::cerr << __PRETTY_FUNCTION__ << ": tunnel result has no peer direction!" << std::endl ; std::cerr << __PRETTY_FUNCTION__ << ": tunnel result has no peer direction!" << std::endl ;
#endif
return ; return ;
} }
if(it->second.responses.find(item->tunnel_id) != it->second.responses.end())
{
std::cerr << "p3turtle: ERROR: received a tunnel response twice. That should not happen." << std::endl;
return ;
}
else
it->second.responses.insert(item->tunnel_id) ;
// store tunnel info. // store tunnel info.
bool found = (_local_tunnels.find(item->tunnel_id) != _local_tunnels.end()) ; bool found = (_local_tunnels.find(item->tunnel_id) != _local_tunnels.end()) ;

View File

@ -139,6 +139,7 @@
#include <string> #include <string>
#include <list> #include <list>
#include <set>
#include "pqi/pqinetwork.h" #include "pqi/pqinetwork.h"
#include "pqi/pqi.h" #include "pqi/pqi.h"
@ -165,6 +166,7 @@ class TurtleRequestInfo
TurtlePeerId origin ; // where the request came from. TurtlePeerId origin ; // where the request came from.
uint32_t time_stamp ; // last time the tunnel was actually used. Used for cleaning old tunnels. uint32_t time_stamp ; // last time the tunnel was actually used. Used for cleaning old tunnels.
int depth ; // depth of the request. Used to optimize tunnel length. int depth ; // depth of the request. Used to optimize tunnel length.
std::set<uint32_t> responses; // responses to this request. Useful to avoid spamming tunnel responses.
}; };
class TurtleTunnel class TurtleTunnel