improved routing algorithm. Fixed several bugs.

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7269 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2014-04-12 19:58:45 +00:00
parent 9f358c5480
commit 9efb7f4136
7 changed files with 231 additions and 202 deletions

View File

@ -30,46 +30,46 @@ bool RsGRouterItem::serialise_header(void *data,uint32_t& pktsize,uint32_t& tlvs
}
/* serialise the data to the buffer */
uint32_t RsGRouterPublishKeyItem::serial_size() const
{
uint32_t s = 8 ; // header
s += POW_PAYLOAD_SIZE ; // proof of work bytes
s += 4 ; // diffusion_id
s += published_key.serial_size() ; // sha1 for published_key
s += 4 ; // service id
s += 4 ; // randomized distance
s += GetTlvStringSize(description_string) ; // description
s += fingerprint.serial_size() ; // fingerprint
return s ;
}
bool RsGRouterPublishKeyItem::serialise(void *data, uint32_t& pktsize) const
{
uint32_t tlvsize,offset=0;
bool ok = true;
if(!serialise_header(data,pktsize,tlvsize,offset))
return false ;
memcpy(&((uint8_t*)data)[offset],pow_bytes,POW_PAYLOAD_SIZE) ;
offset += 8 ;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, diffusion_id);
ok &= published_key.serialise(data, tlvsize, offset) ;
ok &= setRawUInt32(data, tlvsize, &offset, service_id);
ok &= setRawUFloat32(data, tlvsize, &offset, randomized_distance);
ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, description_string);
ok &= fingerprint.serialise(data, tlvsize, offset) ;
if (offset != tlvsize)
{
ok = false;
std::cerr << "RsFileItemSerialiser::serialiseData() Size Error! " << std::endl;
}
return ok;
}
// uint32_t RsGRouterPublishKeyItem::serial_size() const
// {
// uint32_t s = 8 ; // header
// s += POW_PAYLOAD_SIZE ; // proof of work bytes
// s += 4 ; // diffusion_id
// s += published_key.serial_size() ; // sha1 for published_key
// s += 4 ; // service id
// s += 4 ; // randomized distance
// s += GetTlvStringSize(description_string) ; // description
// s += fingerprint.serial_size() ; // fingerprint
//
// return s ;
// }
//bool RsGRouterPublishKeyItem::serialise(void *data, uint32_t& pktsize) const
//{
// uint32_t tlvsize,offset=0;
// bool ok = true;
//
// if(!serialise_header(data,pktsize,tlvsize,offset))
// return false ;
//
// memcpy(&((uint8_t*)data)[offset],pow_bytes,POW_PAYLOAD_SIZE) ;
// offset += 8 ;
//
// /* add mandatory parts first */
// ok &= setRawUInt32(data, tlvsize, &offset, diffusion_id);
// ok &= published_key.serialise(data, tlvsize, offset) ;
// ok &= setRawUInt32(data, tlvsize, &offset, service_id);
// ok &= setRawUFloat32(data, tlvsize, &offset, randomized_distance);
// ok &= SetTlvString(data, tlvsize, &offset, TLV_TYPE_STR_VALUE, description_string);
// ok &= fingerprint.serialise(data, tlvsize, offset) ;
//
// if (offset != tlvsize)
// {
// ok = false;
// std::cerr << "RsFileItemSerialiser::serialiseData() Size Error! " << std::endl;
// }
//
// return ok;
//}
/**********************************************************************************************/
/* PROOF OF WORK STUFF */
@ -157,7 +157,7 @@ RsItem *RsGRouterSerialiser::deserialise(void *data, uint32_t *pktsize)
switch(getRsItemSubType(rstype))
{
case RS_PKT_SUBTYPE_GROUTER_PUBLISH_KEY: return deserialise_RsGRouterPublishKeyItem(data, *pktsize);
//case RS_PKT_SUBTYPE_GROUTER_PUBLISH_KEY: return deserialise_RsGRouterPublishKeyItem(data, *pktsize);
case RS_PKT_SUBTYPE_GROUTER_DATA: return deserialise_RsGRouterGenericDataItem(data, *pktsize);
case RS_PKT_SUBTYPE_GROUTER_ACK: return deserialise_RsGRouterACKItem(data, *pktsize);
case RS_PKT_SUBTYPE_GROUTER_MATRIX_CLUES: return deserialise_RsGRouterMatrixCluesItem(data, *pktsize);
@ -170,32 +170,32 @@ RsItem *RsGRouterSerialiser::deserialise(void *data, uint32_t *pktsize)
return NULL;
}
RsGRouterPublishKeyItem *RsGRouterSerialiser::deserialise_RsGRouterPublishKeyItem(void *data, uint32_t pktsize) const
{
uint32_t offset = 8; // skip the header
uint32_t rssize = getRsItemSize(data);
bool ok = true ;
RsGRouterPublishKeyItem *item = new RsGRouterPublishKeyItem() ;
memcpy(&((uint8_t*)data)[offset],item->pow_bytes,RsGRouterProofOfWorkObject::POW_PAYLOAD_SIZE) ;
offset += 8 ;
ok &= getRawUInt32(data, pktsize, &offset, &item->diffusion_id); // file hash
ok &= item->published_key.deserialise(data, pktsize, offset) ;
ok &= getRawUInt32(data, pktsize, &offset, &item->service_id); // file hash
ok &= getRawUFloat32(data, pktsize, &offset, item->randomized_distance); // file hash
ok &= GetTlvString(data, pktsize, &offset, TLV_TYPE_STR_VALUE,item->description_string);
ok &= item->fingerprint.deserialise(data,pktsize,offset) ;
if (offset != rssize || !ok)
{
std::cerr << __PRETTY_FUNCTION__ << ": error while deserialising! Item will be dropped." << std::endl;
return NULL ;
}
return item;
}
//RsGRouterPublishKeyItem *RsGRouterSerialiser::deserialise_RsGRouterPublishKeyItem(void *data, uint32_t pktsize) const
//{
// uint32_t offset = 8; // skip the header
// uint32_t rssize = getRsItemSize(data);
// bool ok = true ;
//
// RsGRouterPublishKeyItem *item = new RsGRouterPublishKeyItem() ;
//
// memcpy(&((uint8_t*)data)[offset],item->pow_bytes,RsGRouterProofOfWorkObject::POW_PAYLOAD_SIZE) ;
// offset += 8 ;
//
// ok &= getRawUInt32(data, pktsize, &offset, &item->diffusion_id); // file hash
// ok &= item->published_key.deserialise(data, pktsize, offset) ;
// ok &= getRawUInt32(data, pktsize, &offset, &item->service_id); // file hash
// ok &= getRawUFloat32(data, pktsize, &offset, item->randomized_distance); // file hash
// ok &= GetTlvString(data, pktsize, &offset, TLV_TYPE_STR_VALUE,item->description_string);
// ok &= item->fingerprint.deserialise(data,pktsize,offset) ;
//
// if (offset != rssize || !ok)
// {
// std::cerr << __PRETTY_FUNCTION__ << ": error while deserialising! Item will be dropped." << std::endl;
// return NULL ;
// }
//
// return item;
//}
RsGRouterGenericDataItem *RsGRouterSerialiser::deserialise_RsGRouterGenericDataItem(void *data, uint32_t pktsize) const
{
@ -560,20 +560,20 @@ bool RsGRouterRoutingInfoItem::serialise(void *data,uint32_t& size) const
// ------------------------------------- IO --------------------------------------- //
// -----------------------------------------------------------------------------------//
//
std::ostream& RsGRouterPublishKeyItem::print(std::ostream& o, uint16_t)
{
o << "GRouterPublishKeyItem:" << std::endl ;
o << " POW bytes : \""<< RsPgpId(pow_bytes).toStdString() << "\"" << std::endl ;
o << " direct origin: \""<< PeerId() << "\"" << std::endl ;
o << " Key: " << published_key.toStdString() << std::endl ;
o << " Req. Id: " << std::hex << diffusion_id << std::dec << std::endl ;
o << " Srv. Id: " << std::hex << service_id << std::dec << std::endl ;
o << " Distance: " << randomized_distance << std::endl ;
o << " Description: " << description_string << std::endl ;
o << " Fingerprint: " << fingerprint.toStdString() << std::endl ;
return o ;
}
//std::ostream& RsGRouterPublishKeyItem::print(std::ostream& o, uint16_t)
//{
// o << "GRouterPublishKeyItem:" << std::endl ;
// o << " POW bytes : \""<< RsPgpId(pow_bytes).toStdString() << "\"" << std::endl ;
// o << " direct origin: \""<< PeerId() << "\"" << std::endl ;
// o << " Key: " << published_key.toStdString() << std::endl ;
// o << " Req. Id: " << std::hex << diffusion_id << std::dec << std::endl ;
// o << " Srv. Id: " << std::hex << service_id << std::dec << std::endl ;
// o << " Distance: " << randomized_distance << std::endl ;
// o << " Description: " << description_string << std::endl ;
// o << " Fingerprint: " << fingerprint.toStdString() << std::endl ;
//
// return o ;
//}
std::ostream& RsGRouterACKItem::print(std::ostream& o, uint16_t)
{
o << "RsGRouterACKItem:" << std::endl ;

View File

@ -44,12 +44,6 @@ const uint8_t QOS_PRIORITY_RS_GROUTER_PUBLISH_KEY = 3 ; // slow items. No nee
const uint8_t QOS_PRIORITY_RS_GROUTER_ACK = 3 ;
const uint8_t QOS_PRIORITY_RS_GROUTER_DATA = 3 ;
const uint32_t RS_GROUTER_ACK_STATE_RECEIVED = 0x0001 ; // data was received, directly
const uint32_t RS_GROUTER_ACK_STATE_RECEIVED_INDIRECTLY = 0x0002 ; // data was received indirectly
const uint32_t RS_GROUTER_ACK_STATE_GIVEN_UP = 0x0003 ; // data was given up. No route.
const uint32_t RS_GROUTER_ACK_STATE_NO_ROUTE = 0x0004 ; // data was given up. No route.
const uint32_t RS_GROUTER_ACK_STATE_UNKNOWN = 0x0005 ; // unknown destination key
const uint32_t RS_GROUTER_ACK_STATE_TOO_FAR = 0x0006 ; // dropped because of distance
/***********************************************************************************/
/* Basic GRouter Item Class */
@ -107,27 +101,27 @@ class RsGRouterProofOfWorkObject
/* Specific packets */
/***********************************************************************************/
class RsGRouterPublishKeyItem: public RsGRouterItem, public RsGRouterProofOfWorkObject
{
public:
RsGRouterPublishKeyItem() : RsGRouterItem(RS_PKT_SUBTYPE_GROUTER_PUBLISH_KEY) { setPriorityLevel(QOS_PRIORITY_RS_GROUTER_PUBLISH_KEY) ; }
virtual bool serialise(void *data,uint32_t& size) const ;
virtual uint32_t serial_size() const ;
virtual void clear() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0) ;
// packet data
//
GRouterKeyPropagationId diffusion_id ;
GRouterKeyId published_key ;
uint32_t service_id ;
float randomized_distance ;
std::string description_string ;
PGPFingerprintType fingerprint ;
};
//class RsGRouterPublishKeyItem: public RsGRouterItem, public RsGRouterProofOfWorkObject
//{
// public:
// RsGRouterPublishKeyItem() : RsGRouterItem(RS_PKT_SUBTYPE_GROUTER_PUBLISH_KEY) { setPriorityLevel(QOS_PRIORITY_RS_GROUTER_PUBLISH_KEY) ; }
//
// virtual bool serialise(void *data,uint32_t& size) const ;
// virtual uint32_t serial_size() const ;
//
// virtual void clear() {}
// virtual std::ostream& print(std::ostream &out, uint16_t indent = 0) ;
//
// // packet data
// //
// GRouterKeyPropagationId diffusion_id ;
// GRouterKeyId published_key ;
// uint32_t service_id ;
// float randomized_distance ;
// std::string description_string ;
// PGPFingerprintType fingerprint ;
//
//};
class RsGRouterGenericDataItem: public RsGRouterItem, public RsGRouterNonCopyableObject
{
@ -252,7 +246,7 @@ class RsGRouterSerialiser: public RsSerialType
virtual RsItem *deserialise (void *data, uint32_t *size) ;
private:
RsGRouterPublishKeyItem *deserialise_RsGRouterPublishKeyItem(void *data,uint32_t size) const ;
//RsGRouterPublishKeyItem *deserialise_RsGRouterPublishKeyItem(void *data,uint32_t size) const ;
RsGRouterGenericDataItem *deserialise_RsGRouterGenericDataItem(void *data,uint32_t size) const ;
RsGRouterACKItem *deserialise_RsGRouterACKItem(void *data,uint32_t size) const ;
RsGRouterMatrixCluesItem *deserialise_RsGRouterMatrixCluesItem(void *data,uint32_t size) const ;

View File

@ -184,7 +184,7 @@ bool GRouterMatrix::computeRoutingProbabilities(const GRouterKeyId& key_id, cons
}
if(total > 0.0f)
for(int i=0;i<friends.size();++i)
for(uint32_t i=0;i<friends.size();++i)
probas[i] /= total ;
return true ;

View File

@ -29,13 +29,10 @@
#include <time.h>
#include <list>
#include "pgp/rscertificate.h"
#include "retroshare/rsgrouter.h"
class RsGRouterGenericDataItem ;
typedef uint32_t GRouterServiceId ;
typedef uint32_t GRouterKeyPropagationId ;
typedef uint64_t GRouterMsgPropagationId ;
static const uint32_t GROUTER_CLIENT_ID_MESSAGES = 0x1001 ;
static const uint32_t RS_GROUTER_MATRIX_MAX_HIT_ENTRIES = 5;
@ -50,6 +47,7 @@ static const time_t RS_GROUTER_MATRIX_UPDATE_PERIOD = 1 *10 ; // Check
static const time_t RS_GROUTER_PUBLISH_KEY_TIME_INTERVAL = 2 *60 ; // Advertise each key once a day at most.
static const time_t RS_GROUTER_ROUTING_WAITING_TIME = 2 *60 ; // time between two trial of sending a given message
//static const time_t RS_GROUTER_ROUTING_WAITING_TIME = 3600 ; // time between two trial of sending a given message
static const time_t RS_GROUTER_MEAN_EXPECTED_RTT = 30 ; // reference RTT time for a message.
static const uint32_t GROUTER_ITEM_DISTANCE_UNIT = 256 ; // One unit of distance between two peers
static const uint32_t GROUTER_ITEM_MAX_TRAVEL_DISTANCE = 16*256 ; // 16 distance units. That is a lot.
@ -85,10 +83,11 @@ class GRouterRoutingInfo
public:
uint32_t status_flags ; // pending, waiting, etc.
RsPeerId origin ; // which friend sent us that item
time_t received_time ; // time at which the item was received
time_t last_activity ; // time at which the item was received
time_t received_time ; // time at which the item was originally received
time_t last_sent ; // last time the item was sent to friends
std::list<FriendTrialRecord> tried_friends ; // list of friends to which the item was sent ordered with time.
GRouterKeyId destination_key ; // ultimate destination for this key
RsGRouterGenericDataItem *data_item ;
};

View File

@ -235,8 +235,10 @@ int p3GRouter::tick()
//
if(now > _last_matrix_update_time + RS_GROUTER_MATRIX_UPDATE_PERIOD)
{
RsStackMutex mtx(grMtx) ;
_last_matrix_update_time = now ;
_routing_matrix.updateRoutingProbabilities() ;
_routing_matrix.updateRoutingProbabilities() ; // This should be locked.
}
#ifdef GROUTER_DEBUG
@ -289,10 +291,10 @@ void p3GRouter::autoWash()
time_t now = time(NULL) ;
for(std::map<GRouterMsgPropagationId,GRouterRoutingInfo>::iterator it(_pending_messages.begin());it!=_pending_messages.end();)
if(it->second.last_activity + GROUTER_ITEM_MAX_CACHE_KEEP_TIME < now)
if(it->second.received_time + GROUTER_ITEM_MAX_CACHE_KEEP_TIME < now) // is the item too old for cache
{
#ifdef GROUTER_DEBUG
std::cerr << " Removing cache item " << std::hex << it->first << std::dec << " for key id " << it->second.data_item->destination_key << std::endl;
std::cerr << " Removing cache item " << std::hex << it->first << std::dec << std::endl;
#endif
delete it->second.data_item ;
std::map<GRouterMsgPropagationId,GRouterRoutingInfo>::iterator tmp(it) ;
@ -300,6 +302,14 @@ void p3GRouter::autoWash()
_pending_messages.erase(it) ;
it = tmp ;
}
else if(it->second.data_item != NULL && it->second.status_flags == RS_GROUTER_ROUTING_STATE_SENT && it->second.last_sent+RS_GROUTER_ROUTING_WAITING_TIME < now)
{
it->second.status_flags = RS_GROUTER_ROUTING_STATE_PEND ;
#ifdef GROUTER_DEBUG
std::cerr << " Scheduling the item " << std::hex << it->first << std::dec << " for sending again." << std::endl;
#endif
++it ;
}
else
++it ;
@ -325,35 +335,56 @@ void p3GRouter::routePendingObjects()
mServiceControl->getPeersConnected(RS_SERVICE_TYPE_GROUTER,lst) ;
RsPeerId own_id( mServiceControl->getOwnId() );
std::vector<RsPeerId> pids ;
for(std::set<RsPeerId>::const_iterator it(lst.begin());it!=lst.end();++it)
pids.push_back(*it) ;
// The policy is the following:
//
// - all pending messages should be handled. A msg is pending when it is waiting for routage.
// A pending message should always have a non NULL data item attached.
//
for(std::map<GRouterMsgPropagationId, GRouterRoutingInfo>::iterator it(_pending_messages.begin());it!=_pending_messages.end();)
if((it->second.status_flags == RS_GROUTER_ROUTING_STATE_PEND) || (it->second.status_flags == RS_GROUTER_ROUTING_STATE_SENT && it->second.tried_friends.front().time_stamp+RS_GROUTER_ROUTING_WAITING_TIME < now))
if(it->second.status_flags == RS_GROUTER_ROUTING_STATE_PEND)
{
// make sure we have data to send.
//
if(it->second.data_item == NULL)
{
std::cerr << " (EE) Pending item has no data!!" << std::endl;
++it ;
continue ;
}
#ifdef GROUTER_DEBUG
std::cerr << " Msg id: " << std::hex << it->first << std::dec << std::endl;
std::cerr << " Origin: " << it->second.origin.toStdString() << std::endl;
if(!it->second.tried_friends.empty())
{
std::cerr << " Last : " << it->second.tried_friends.front().friend_id.toStdString() << std::endl;
std::cerr << " R Time: " << it->second.tried_friends.front().time_stamp << std::endl;
std::cerr << " S Time: " << it->second.tried_friends.front().time_stamp << std::endl;
}
std::cerr << " Recvd : " << it->second.received_time << std::endl;
std::cerr << " Last M: " << it->second.last_activity << std::endl;
std::cerr << " Recvd : " << now - it->second.received_time << " secs ago." << std::endl;
std::cerr << " Sent : " << now - it->second.last_sent << " secs ago." << std::endl;
std::cerr << " Flags : " << it->second.status_flags << std::endl;
std::cerr << " Dist : " << it->second.data_item->randomized_distance<< std::endl;
std::cerr << " Probabilities: " << std::endl;
#endif
std::vector<RsPeerId> pids ;
for(std::set<RsPeerId>::const_iterator its(lst.begin());its!=lst.end();++its)
if(*its != it->second.origin)
pids.push_back(*its) ;
if(pids.empty()) // no friends to send to!! Send back a give up signal.
{
sendACK(it->second.origin,it->first,RS_GROUTER_ACK_STATE_GVNP) ;
it->second.status_flags = RS_GROUTER_ROUTING_STATE_DEAD ;
delete it->second.data_item ;
it->second.data_item = NULL ;
++it ;
continue ;
}
std::vector<float> probas ; // friends probabilities for online friend list.
RsPeerId routed_friend ; // friend chosen for the next hop
bool should_remove = false ; // should we remove this from the map?
// Retrieve probabilities for this key. This call always succeeds. If no route is known, all probabilities become equal.
//
_routing_matrix.computeRoutingProbabilities(it->second.data_item->destination_key, pids, probas) ;
_routing_matrix.computeRoutingProbabilities(it->second.destination_key, pids, probas) ;
// Compute the maximum branching factor.
@ -386,7 +417,6 @@ void p3GRouter::routePendingObjects()
ftr.nb_friends = probas.size() ;
it->second.tried_friends.push_front(ftr) ;
it->second.status_flags = RS_GROUTER_ROUTING_STATE_SENT ;
#ifdef GROUTER_DEBUG
std::cerr << " Routing probability: " << ftr.probability << std::endl;
@ -400,28 +430,13 @@ void p3GRouter::routePendingObjects()
sendItem(new_item) ;
}
if(should_remove)
{
// We remove from the map. That means the RsItem* has been transfered to somewhere else.
//
#ifdef GROUTER_DEBUG
std::cerr << " Removing item from pending items" << std::endl;
#endif
std::map<GRouterMsgPropagationId, GRouterRoutingInfo>::iterator tmp(it) ;
delete it->second.data_item ;
++tmp ;
_pending_messages.erase(it) ;
it = tmp ;
}
else
++it ;
it->second.status_flags = RS_GROUTER_ROUTING_STATE_SENT ;
it->second.last_sent = now ;
}
else
{
#ifdef GROUTER_DEBUG
std::cerr << "Skipping " << std::hex << it->first << std::dec << ", dest=" << it->second.data_item->destination_key.toStdString() << ", state = " << it->second.status_flags ;
std::cerr << "Skipping " << std::hex << it->first << std::dec << ", state = " << it->second.status_flags ;
if(!it->second.tried_friends.empty())
std::cerr << ", stamp=" << it->second.tried_friends.front().time_stamp << " - " << it->second.tried_friends.front().friend_id.toStdString() << std::endl;
else
@ -467,21 +482,23 @@ uint32_t p3GRouter::computeBranchingFactor(const std::vector<RsPeerId>& friends,
uint32_t dist_index = std::min( (uint32_t)(dist / (float)GROUTER_ITEM_DISTANCE_UNIT), MAX_DIST_INDEX-1) ;
return std::max(2, (int)(friends.size()*branching_factors[dist_index])) ;
}
//// Now temper the branching factor by how likely we are to already have a good guess from the probabilities:
//// - if the largest probability is much larger than the second one
//
//std::vector<float> probs(probas) ;
//std::sort(probs.begin(),probs.end()) ;
//int n=0 ;
//for(int i=probs.size()-1;i>=0;--i)
// if(probs[i] > 0.5 * probs.back())
// ++n ;
//// send the final value
//return std::max(1, std::min(n, (int)(friends.size()*branching_factors[dist_index]))) ;
float p3GRouter::computeMatrixContribution(float base,uint32_t time_shift,float probability)
{
// This function computes the contribution to the routing matrix for an ACK that was
// received. The different variables are:
// base : base contribution. 1.0 for directly received items, 0.5 for indirectly received items.
// time_shift : time in seconds between when the item was sent and when the item was ACKed. This is a clue of
// how far the destination is, and is used to favor fast routes.
// probability : probability with which the item was sent. This should be used for importance-sampling the resulting weight
if(probability == 0.0f)
{
std::cerr << "Probability is NULL !!!!! This should not happen." << std::endl;
return 0.0f ;
}
return base * exp(-float(time_shift) / float(RS_GROUTER_MEAN_EXPECTED_RTT)) / probability ;
}
class peer_comparison_function
@ -604,7 +621,6 @@ std::set<uint32_t> p3GRouter::computeRoutingFriends_old(const std::vector<RsPeer
//
return res ;
}
#endif
void p3GRouter::locked_forwardKey(const RsGRouterPublishKeyItem& item)
{
@ -636,6 +652,8 @@ void p3GRouter::locked_forwardKey(const RsGRouterPublishKeyItem& item)
std::cerr << " Not forwarding to source id " << item.PeerId() << std::endl;
#endif
}
#endif
bool p3GRouter::registerKey(const GRouterKeyId& key,const GRouterServiceId& client_id,const std::string& description)
{
RsStackMutex mtx(grMtx) ;
@ -761,8 +779,11 @@ void p3GRouter::handleRecvACKItem(RsGRouterACKItem *item)
#endif
return ;
}
uint32_t next_state ;
uint32_t forward_state = RS_GROUTER_ACK_STATE_UNKNOWN ;
uint32_t next_state = it->second.status_flags;
uint32_t forward_state = RS_GROUTER_ACK_STATE_UNKN ;
bool update_routing_matrix = false ;
time_t now = time(NULL) ;
switch(item->state)
{
@ -779,26 +800,11 @@ void p3GRouter::handleRecvACKItem(RsGRouterACKItem *item)
next_state = RS_GROUTER_ROUTING_STATE_ARVD ;
{
#warning UNFINISHED code.
update_routing_matrix = true ;
break ;
// Now compute the weight for that particular item. See with what probabilities it was chosen.
//
// The real formula should be:
// weight = w(ACK type) / probability
//
// ... where probability is the probability with whitch the item was sent in the first place.
//
// The time should also be set so that the routing clue has less importance.
//
float weight = (item->state == RS_GROUTER_ACK_STATE_RCVD)?1.0f : 0.5;
#ifdef GROUTER_DEBUG
std::cerr << " weight = " << weight << std::endl;
#endif
_routing_matrix.addRoutingClue(it->second.data_item->destination_key,item->PeerId(),weight) ;
}
case RS_GROUTER_ACK_STATE_GIVEN_UP: // route is bad. We forward back and update the routing matrix.
case RS_GROUTER_ACK_STATE_GVNP: // route is bad. We forward back and update the routing matrix.
break ;
}
@ -812,16 +818,46 @@ void p3GRouter::handleRecvACKItem(RsGRouterACKItem *item)
// Just decrement the list of tried friends
//
bool found = false ;
for(std::list<FriendTrialRecord>::iterator it2(it->second.tried_friends.begin());it2!=it->second.tried_friends.end();++it2)
if( (*it2).friend_id == item->PeerId())
{
if(update_routing_matrix)
{
// Now compute the weight for that particular item. See with what probabilities it was chosen.
//
// The real formula should be:
// weight = w(ACK type) / probability
//
// ... where probability is the probability with whitch the item was sent in the first place.
//
// The time should also be set so that the routing clue has less importance.
//
float base = (item->state == RS_GROUTER_ACK_STATE_RCVD)?1.0f : 0.5 ;
uint32_t time_shift = now - (*it2).time_stamp ;
float probability = (*it2).probability;
float weight = computeMatrixContribution(base,time_shift,probability) ;
#ifdef GROUTER_DEBUG
std::cerr << " base contrib = " << base << std::endl;
std::cerr << " time shift = " << time_shift << std::endl;
std::cerr << " sendind proba = " << probability << std::endl;
std::cerr << " ==> final weight : " << weight << std::endl;
#endif
_routing_matrix.addRoutingClue(it->second.destination_key,item->PeerId(),weight) ;
}
#ifdef GROUTER_DEBUG
std::cerr << " Removing friend try for peer " << item->PeerId() << ". " << it->second.tried_friends.size() << " tries left." << std::endl;
#endif
it->second.tried_friends.erase(it2) ;
found = true ;
break ;
}
if(!found)
std::cerr << " (EE) friend try not found!! This should not happen. Needs debugging." << std::endl;
if(it->second.tried_friends.empty())
{
delete it->second.data_item ;
@ -838,7 +874,6 @@ void p3GRouter::handleRecvACKItem(RsGRouterACKItem *item)
forward_state = RS_GROUTER_ACK_STATE_GVNP ;
}
}
it->second.last_activity = time(NULL) ;
// Now send an ACK if necessary.
//
@ -849,13 +884,14 @@ void p3GRouter::handleRecvACKItem(RsGRouterACKItem *item)
std::cerr << "ACK triage phase ended. Next state = " << statusString[next_state] << ", forwarded ack=" << ackString[forward_state] << std::endl;
#endif
if(forward_state != RS_GROUTER_ACK_STATE_UNKNOWN && it->second.origin != mLinkMgr->getOwnId())
if(forward_state != RS_GROUTER_ACK_STATE_UNKN && it->second.origin != mLinkMgr->getOwnId())
{
#ifdef GROUTER_DEBUG
std::cerr << " forwarding ACK to origin: " << it->second.origin.toStdString() << std::endl;
#endif
sendACK(it->second.origin,item->mid,item->state) ;
}
it->second.status_flags = next_state ;
}
void p3GRouter::handleRecvDataItem(RsGRouterGenericDataItem *item)
@ -929,9 +965,10 @@ void p3GRouter::handleRecvDataItem(RsGRouterGenericDataItem *item)
info.data_item = item->duplicate() ;
item_copy = info.data_item ;
info.origin = RsPeerId(item->PeerId()) ;
info.origin = item->PeerId() ;
info.received_time = time(NULL) ;
info.last_activity = info.received_time ;
info.last_sent = 0 ;
info.destination_key = item->destination_key ;
info.status_flags = RS_GROUTER_ROUTING_STATE_PEND ;
_pending_messages[item->routing_id] = info ;
@ -981,7 +1018,6 @@ void p3GRouter::handleRecvDataItem(RsGRouterGenericDataItem *item)
if(returned_ack != RS_GROUTER_ACK_STATE_UNKN)
sendACK(item->PeerId(),item->routing_id,returned_ack) ;
itr->second.last_activity = now ;
_changed = true ;
}
@ -1003,10 +1039,11 @@ void p3GRouter::sendData(const GRouterKeyId& destination, RsGRouterGenericDataIt
info.data_item = item ;
info.status_flags = RS_GROUTER_ROUTING_STATE_PEND ;
info.origin = RsPeerId(mLinkMgr->getOwnId()) ;
info.origin = mLinkMgr->getOwnId() ;
info.data_item->randomized_distance = 0 ;
info.last_activity = now ;
info.last_sent = 0 ;
info.received_time = now ;
info.destination_key = destination ;
// Make sure we have a unique id (at least locally).
//
@ -1019,8 +1056,8 @@ void p3GRouter::sendData(const GRouterKeyId& destination, RsGRouterGenericDataIt
#ifdef GROUTER_DEBUG
std::cerr << "p3GRouter::sendGRouterData(): pushing the followign item in the msg pending list:" << std::endl;
std::cerr << " data_item.size = " << info.data_item->data_size << std::endl;
std::cerr << " data_item.byte = " << info.data_item->data_bytes << std::endl;
std::cerr << " destination = " << info.data_item->destination_key << std::endl;
std::cerr << " data_item.byte = " << RsDirUtil::sha1sum(info.data_item->data_bytes,info.data_item->data_size) << std::endl;
std::cerr << " destination = " << info.destination_key << std::endl;
std::cerr << " status = " << info.status_flags << std::endl;
std::cerr << " distance = " << info.data_item->randomized_distance << std::endl;
std::cerr << " origin = " << info.origin.toStdString() << std::endl;
@ -1150,10 +1187,10 @@ bool p3GRouter::getRoutingCacheInfo(std::vector<GRouterRoutingCacheInfo>& infos)
cinfo.mid = it->first ;
cinfo.local_origin = it->second.origin ;
cinfo.destination = it->second.data_item->destination_key ;
cinfo.destination = it->second.destination_key ;
cinfo.time_stamp = it->second.received_time ;
cinfo.status = it->second.status_flags ;
cinfo.data_size = it->second.data_item->data_size ;
cinfo.data_size = (it->second.data_item==NULL)?0:(it->second.data_item->data_size) ;
}
return true ;
}
@ -1197,12 +1234,9 @@ void p3GRouter::debugDump()
for(std::map<GRouterMsgPropagationId, GRouterRoutingInfo>::iterator it(_pending_messages.begin());it!=_pending_messages.end();++it)
{
std::cerr << " Msg id: " << std::hex << it->first << std::dec
<< " Local Origin: " << it->second.origin.toStdString() ;
if(it->second.data_item != NULL)
std::cerr << " Destination: " << it->second.data_item->destination_key ;
if(!it->second.tried_friends.empty())
std::cerr << " Time : " << now - it->second.tried_friends.front().time_stamp << " secs ago.";
std::cerr << " Msg id: " << std::hex << it->first << std::dec << " Local Origin: " << it->second.origin.toStdString() ;
std::cerr << " Destination: " << it->second.destination_key ;
std::cerr << " Time : " << now - it->second.last_sent << " secs ago.";
std::cerr << " Status: " << statusString[it->second.status_flags] << std::endl;
}

View File

@ -156,6 +156,7 @@ class p3GRouter: public RsGRouter, public p3Service, public p3Config
//
static uint32_t computeBranchingFactor(const std::vector<RsPeerId>& friends,uint32_t dist) ;
static std::set<uint32_t> computeRoutingFriends(const std::vector<RsPeerId>& friends,const std::vector<float>& probas,uint32_t N) ;
static float computeMatrixContribution(float base,uint32_t time_shift,float probability) ;
uint32_t computeRandomDistanceIncrement(const RsPeerId& pid,const GRouterKeyId& destination_id) ;

View File

@ -26,10 +26,11 @@
#pragma once
#include "util/rsdir.h"
#include "grouter/groutertypes.h"
#include "retroshare/rsids.h"
typedef GRouterKeyIdType GRouterKeyId ; // we use SSLIds, so that it's easier in the GUI to mix up peer ids with grouter ids.
typedef uint32_t GRouterServiceId ;
typedef uint64_t GRouterMsgPropagationId ;
class GRouterClientService ;
class RsGRouterGenericDataItem ;