diff --git a/libretroshare/src/grouter/groutermatrix.cc b/libretroshare/src/grouter/groutermatrix.cc index 76ab26488..cb87bec93 100644 --- a/libretroshare/src/grouter/groutermatrix.cc +++ b/libretroshare/src/grouter/groutermatrix.cc @@ -23,6 +23,7 @@ * */ +#include "groutertypes.h" #include "groutermatrix.h" GRouterMatrix::GRouterMatrix() @@ -46,12 +47,43 @@ bool GRouterMatrix::addRoutingClue( const GRouterKeyId& key_id,const GRouterServ rc.time_stamp = now ; rc.friend_id = fid ; - _routing_clues[key_id].push_front(rc) ; // create it if necessary + std::list& lst( _routing_clues[key_id] ) ; + + // Prevent flooding. Happens in two scenarii: + // 1 - a user restarts RS very often => keys get republished for some reason + // 2 - a user intentionnaly floods a key + // + if(!lst.empty() && lst.front().time_stamp + RS_GROUTER_MATRIX_MIN_TIME_BETWEEN_HITS > now) + { + std::cerr << "GRouterMatrix::addRoutingClue(): too clues for key " << key_id.toStdString() << " in a small interval of " << now - lst.front().time_stamp << " seconds. Flooding?" << std::endl; + return false ; + } + + lst.push_front(rc) ; // create it if necessary + + // Remove older elements + // + uint32_t sz = lst.size() ; // O(n)! + + for(uint32_t i=RS_GROUTER_MATRIX_MAX_HIT_ENTRIES;i::const_iterator it = _friend_indices.find(source_friend) ; + if(it == _friend_indices.end()) + return _reverse_friend_indices.size() ; + else + return it->second ; +} uint32_t GRouterMatrix::getFriendId(const SSLIdType& source_friend) { std::map::const_iterator it = _friend_indices.find(source_friend) ; @@ -73,6 +105,7 @@ uint32_t GRouterMatrix::getFriendId(const SSLIdType& source_friend) void GRouterMatrix::debugDump() const { std::cerr << " Proba needs up: " << _proba_need_updating << std::endl; + std::cerr << " Known keys: " << _time_combined_hits.size() << std::endl; std::cerr << " Routing events: " << std::endl; time_t now = time(NULL) ; @@ -84,7 +117,7 @@ void GRouterMatrix::debugDump() const std::cerr << std::endl; } - std::cerr << " Routing probabilities: " << std::endl; + std::cerr << " Routing values: " << std::endl; for(std::map >::const_iterator it(_time_combined_hits.begin());it!=_time_combined_hits.end();++it) { @@ -96,7 +129,7 @@ void GRouterMatrix::debugDump() const } } -bool GRouterMatrix::computeRoutingProbabilities(const GRouterKeyId& id, const std::vector& friends, std::vector& probas) const +bool GRouterMatrix::computeRoutingProbabilities(const GRouterKeyId& key_id, const std::list& friends, std::map& probas) const { // Routing probabilities are computed according to routing clues // @@ -107,6 +140,38 @@ bool GRouterMatrix::computeRoutingProbabilities(const GRouterKeyId& id, const st // Then for a given list of online friends, the weights are computed into probabilities, // that always sum up to 1. // + if(_proba_need_updating) + std::cerr << "GRouterMatrix::computeRoutingProbabilities(): matrix is not up to date. Not a real problem, but still..." << std::endl; + + probas.clear() ; + float total = 0.0f ; + + std::map >::const_iterator it2 = _time_combined_hits.find(key_id) ; + + if(it2 == _time_combined_hits.end()) + { + std::cerr << "GRouterMatrix::computeRoutingProbabilities(): key id " << key_id.toStdString() << " does not exist!" << std::endl; + return false ; + } + const std::vector& w(it2->second) ; + + for(std::list::const_iterator it(friends.begin());it!=friends.end();++it) + { + uint32_t findex = getFriendId_const(*it) ; + + if(findex >= w.size()) + probas[*it] = 0.0f ; + else + { + probas[*it] = w[findex] ; + total += w[findex] ; + } + } + + if(total > 0.0f) + for(std::map::iterator it(probas.begin());it!=probas.end();++it) + it->second /= total ; + return true ; } diff --git a/libretroshare/src/grouter/groutermatrix.h b/libretroshare/src/grouter/groutermatrix.h index a9d8f9a48..90af7f0bd 100644 --- a/libretroshare/src/grouter/groutermatrix.h +++ b/libretroshare/src/grouter/groutermatrix.h @@ -49,11 +49,7 @@ class GRouterMatrix // the computation accounts for the time at which the info was received and the // weight of each routing hit record. // - bool computeRoutingProbabilities(const GRouterKeyId& id, const std::vector& friends, std::vector& probas) const ; - - // Remove oldest entries. - // - bool autoWash() ; + bool computeRoutingProbabilities(const GRouterKeyId& id, const std::list& friends, std::map& probas) const ; // Update routing probabilities for each key, accounting for all received events, but without // activity information @@ -69,12 +65,18 @@ class GRouterMatrix void debugDump() const ; private: + // returns the friend id, possibly creating a new id. + // uint32_t getFriendId(const SSLIdType& id) ; + // returns the friend id. If not exist, returns _reverse_friend_indices.size() + // + uint32_t getFriendId_const(const SSLIdType& id) const; + // List of events received and computed routing probabilities // std::map > _routing_clues ; - std::map > _time_combined_hits ; // hit matrix after time-convolution filter + std::map > _time_combined_hits ; // hit matrix after time-convolution filter // This is used to avoid re-computing probas when new events have been received. // diff --git a/libretroshare/src/grouter/groutertypes.h b/libretroshare/src/grouter/groutertypes.h index 9e165d21b..86839cadf 100644 --- a/libretroshare/src/grouter/groutertypes.h +++ b/libretroshare/src/grouter/groutertypes.h @@ -25,5 +25,20 @@ #pragma once +#include +#include + typedef uint32_t GRouterServiceId ; typedef uint32_t GRouterKeyPropagationId ; + +static const uint32_t RS_GROUTER_MATRIX_MAX_HIT_ENTRIES = 5; +static const uint32_t RS_GROUTER_MATRIX_MIN_TIME_BETWEEN_HITS = 60; // can be set to up to half the publish time interval. Prevents flooding routes. + +static const time_t RS_GROUTER_DEBUG_OUTPUT_PERIOD = 20 ; // Output everything +static const time_t RS_GROUTER_AUTOWASH_PERIOD = 60 ; // Autowash every minute. Not a costly operation. +//static const time_t RS_GROUTER_PUBLISH_CAMPAIGN_PERIOD = 10*60 ; // Check for key advertising every 10 minutes +//static const time_t RS_GROUTER_PUBLISH_KEY_TIME_INTERVAL = 24*60*60 ; // Advertise each key once a day at most. +static const time_t RS_GROUTER_PUBLISH_CAMPAIGN_PERIOD = 1 *60 ; // Check for key advertising every 10 minutes +static const time_t RS_GROUTER_PUBLISH_KEY_TIME_INTERVAL = 2 *60 ; // Advertise each key once a day at most. + + diff --git a/libretroshare/src/grouter/p3grouter.cc b/libretroshare/src/grouter/p3grouter.cc index d787b4339..0dde06840 100644 --- a/libretroshare/src/grouter/p3grouter.cc +++ b/libretroshare/src/grouter/p3grouter.cc @@ -29,13 +29,7 @@ #include "p3grouter.h" #include "grouteritems.h" - -static const time_t RS_GROUTER_DEBUG_OUTPUT_PERIOD = 20 ; // Output everything -static const time_t RS_GROUTER_AUTOWASH_PERIOD = 60 ; // Autowash every minute. Not a costly operation. -//static const time_t RS_GROUTER_PUBLISH_CAMPAIGN_PERIOD = 10*60 ; // Check for key advertising every 10 minutes -//static const time_t RS_GROUTER_PUBLISH_KEY_TIME_INTERVAL = 24*60*60 ; // Advertise each key once a day at most. -static const time_t RS_GROUTER_PUBLISH_CAMPAIGN_PERIOD = 1 *60 ; // Check for key advertising every 10 minutes -static const time_t RS_GROUTER_PUBLISH_KEY_TIME_INTERVAL = 2 *60 ; // Advertise each key once a day at most. +#include "groutertypes.h" p3GRouter::p3GRouter(p3LinkMgr *lm) : p3Service(RS_SERVICE_TYPE_GROUTER), p3Config(CONFIG_TYPE_GROUTER), mLinkMgr(lm), grMtx("GRouter") @@ -321,8 +315,6 @@ void p3GRouter::debugDump() std::cerr << " Routing matrix: " << std::endl; _routing_matrix.debugDump() ; - - std::cerr << " Routing probabilities: " << std::endl; }