mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-04-01 19:45:52 -04:00
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:
parent
9f358c5480
commit
9efb7f4136
@ -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 ;
|
||||
|
@ -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 ;
|
||||
|
@ -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 ;
|
||||
|
@ -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 ;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) ;
|
||||
|
||||
|
@ -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 ;
|
||||
|
Loading…
x
Reference in New Issue
Block a user