mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-02 06:06:10 -04:00
merged remaining of v0.6-IdCleaning branch (7180->7213) to incorporate global router stuff in trunk
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7214 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
0e6302ac6a
commit
1042744685
53 changed files with 2387 additions and 1904 deletions
|
@ -49,7 +49,7 @@ class GRouterClientService
|
|||
//
|
||||
// GRouter stays owner of the item, so the client should not delete it!
|
||||
//
|
||||
virtual void receiveGRouterData(RsGRouterGenericDataItem * /*item*/,const GRouterKeyId& destination_key)
|
||||
virtual void receiveGRouterData(const GRouterKeyId& destination_key, const RsGRouterGenericDataItem * /*item*/)
|
||||
{
|
||||
std::cerr << "!!!!!! Received Data from global router, but the client service is not handling it !!!!!!!!!!" << std::endl ;
|
||||
std::cerr << " destination key_id = " << destination_key.toStdString() << std::endl;
|
||||
|
|
|
@ -35,11 +35,11 @@ uint32_t RsGRouterPublishKeyItem::serial_size() const
|
|||
uint32_t s = 8 ; // header
|
||||
s += POW_PAYLOAD_SIZE ; // proof of work bytes
|
||||
s += 4 ; // diffusion_id
|
||||
s += 20 ; // sha1 for published_key
|
||||
s += published_key.serial_size() ; // sha1 for published_key
|
||||
s += 4 ; // service id
|
||||
s += 4 ; // randomized distance
|
||||
s += GetTlvStringSize(description_string) ; // description
|
||||
s += PGP_KEY_FINGERPRINT_SIZE ; // fingerprint
|
||||
s += fingerprint.serial_size() ; // fingerprint
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ RsItem *RsGRouterSerialiser::deserialise(void *data, uint32_t *pktsize)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
RsGRouterItem *RsGRouterSerialiser::deserialise_RsGRouterPublishKeyItem(void *data, uint32_t pktsize) const
|
||||
RsGRouterPublishKeyItem *RsGRouterSerialiser::deserialise_RsGRouterPublishKeyItem(void *data, uint32_t pktsize) const
|
||||
{
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
|
@ -197,7 +197,7 @@ RsGRouterItem *RsGRouterSerialiser::deserialise_RsGRouterPublishKeyItem(void *da
|
|||
return item;
|
||||
}
|
||||
|
||||
RsGRouterItem *RsGRouterSerialiser::deserialise_RsGRouterGenericDataItem(void *data, uint32_t pktsize) const
|
||||
RsGRouterGenericDataItem *RsGRouterSerialiser::deserialise_RsGRouterGenericDataItem(void *data, uint32_t pktsize) const
|
||||
{
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
|
@ -205,9 +205,10 @@ RsGRouterItem *RsGRouterSerialiser::deserialise_RsGRouterGenericDataItem(void *d
|
|||
|
||||
RsGRouterGenericDataItem *item = new RsGRouterGenericDataItem() ;
|
||||
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &item->routing_id); // file hash
|
||||
ok &= item->destination_key.deserialise(data, pktsize, offset) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &item->data_size); // file hash
|
||||
ok &= getRawUInt64(data, pktsize, &offset, &item->routing_id);
|
||||
ok &= item->destination_key.deserialise(data, pktsize, offset) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &item->randomized_distance);
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &item->data_size);
|
||||
|
||||
if( NULL == (item->data_bytes = (uint8_t*)malloc(item->data_size)))
|
||||
{
|
||||
|
@ -227,7 +228,7 @@ RsGRouterItem *RsGRouterSerialiser::deserialise_RsGRouterGenericDataItem(void *d
|
|||
return item;
|
||||
}
|
||||
|
||||
RsGRouterItem *RsGRouterSerialiser::deserialise_RsGRouterACKItem(void *data, uint32_t pktsize) const
|
||||
RsGRouterACKItem *RsGRouterSerialiser::deserialise_RsGRouterACKItem(void *data, uint32_t pktsize) const
|
||||
{
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
|
@ -235,7 +236,7 @@ RsGRouterItem *RsGRouterSerialiser::deserialise_RsGRouterACKItem(void *data, uin
|
|||
|
||||
RsGRouterACKItem *item = new RsGRouterACKItem() ;
|
||||
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &item->mid); // file hash
|
||||
ok &= getRawUInt64(data, pktsize, &offset, &item->mid); // file hash
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &item->state); // file hash
|
||||
|
||||
if (offset != rssize || !ok)
|
||||
|
@ -247,7 +248,7 @@ RsGRouterItem *RsGRouterSerialiser::deserialise_RsGRouterACKItem(void *data, uin
|
|||
return item;
|
||||
}
|
||||
|
||||
RsGRouterItem *RsGRouterSerialiser::deserialise_RsGRouterRoutingInfoItem(void *data, uint32_t pktsize) const
|
||||
RsGRouterRoutingInfoItem *RsGRouterSerialiser::deserialise_RsGRouterRoutingInfoItem(void *data, uint32_t pktsize) const
|
||||
{
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
|
@ -256,7 +257,7 @@ RsGRouterItem *RsGRouterSerialiser::deserialise_RsGRouterRoutingInfoItem(void *d
|
|||
RsGRouterRoutingInfoItem *item = new RsGRouterRoutingInfoItem() ;
|
||||
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &item->status_flags);
|
||||
ok &= item->origin.deserialise(data, pktsize, offset) ;
|
||||
ok &= item->origin.deserialise(data, pktsize, offset) ;
|
||||
ok &= getRawTimeT(data, pktsize, &offset, item->received_time);
|
||||
|
||||
uint32_t s = 0 ;
|
||||
|
@ -266,21 +267,15 @@ RsGRouterItem *RsGRouterSerialiser::deserialise_RsGRouterRoutingInfoItem(void *d
|
|||
{
|
||||
FriendTrialRecord ftr ;
|
||||
|
||||
ok &= ftr.friend_id.deserialise(data, pktsize, offset) ;
|
||||
ok &= ftr.friend_id.deserialise(data, pktsize, offset) ;
|
||||
ok &= getRawTimeT(data, pktsize, &offset, ftr.time_stamp) ;
|
||||
ok &= getRawUFloat32(data, pktsize, &offset, ftr.probability) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &ftr.nb_friends) ;
|
||||
|
||||
item->tried_friends.push_back(ftr) ;
|
||||
}
|
||||
|
||||
item->data_item = new RsGRouterGenericDataItem ;
|
||||
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &item->data_item->routing_id);
|
||||
ok &= item->data_item->destination_key.deserialise(data, pktsize, offset) ;
|
||||
ok &= getRawUInt32(data, pktsize, &offset, &item->data_item->data_size) ;
|
||||
|
||||
item->data_item->data_bytes = (uint8_t*)malloc(item->data_item->data_size) ;
|
||||
memcpy(item->data_item->data_bytes,&((uint8_t*)data)[offset],item->data_item->data_size) ;
|
||||
offset += item->data_item->data_size ;
|
||||
item->data_item = deserialise_RsGRouterGenericDataItem(&((uint8_t*)data)[offset],pktsize - offset) ;
|
||||
|
||||
if (offset != rssize || !ok)
|
||||
{
|
||||
|
@ -290,7 +285,7 @@ RsGRouterItem *RsGRouterSerialiser::deserialise_RsGRouterRoutingInfoItem(void *d
|
|||
|
||||
return item;
|
||||
}
|
||||
RsGRouterItem *RsGRouterSerialiser::deserialise_RsGRouterMatrixFriendListItem(void *data, uint32_t pktsize) const
|
||||
RsGRouterMatrixFriendListItem *RsGRouterSerialiser::deserialise_RsGRouterMatrixFriendListItem(void *data, uint32_t pktsize) const
|
||||
{
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
|
@ -314,7 +309,7 @@ RsGRouterItem *RsGRouterSerialiser::deserialise_RsGRouterMatrixFriendListItem(vo
|
|||
|
||||
return item;
|
||||
}
|
||||
RsGRouterItem *RsGRouterSerialiser::deserialise_RsGRouterMatrixCluesItem(void *data, uint32_t pktsize) const
|
||||
RsGRouterMatrixCluesItem *RsGRouterSerialiser::deserialise_RsGRouterMatrixCluesItem(void *data, uint32_t pktsize) const
|
||||
{
|
||||
uint32_t offset = 8; // skip the header
|
||||
uint32_t rssize = getRsItemSize(data);
|
||||
|
@ -357,6 +352,7 @@ RsGRouterGenericDataItem *RsGRouterGenericDataItem::duplicate() const
|
|||
item->routing_id = routing_id ;
|
||||
item->destination_key = destination_key ;
|
||||
item->data_size = data_size ;
|
||||
item->randomized_distance = randomized_distance ;
|
||||
|
||||
// then duplicate the memory chunk
|
||||
|
||||
|
@ -368,11 +364,12 @@ RsGRouterGenericDataItem *RsGRouterGenericDataItem::duplicate() const
|
|||
|
||||
uint32_t RsGRouterGenericDataItem::serial_size() const
|
||||
{
|
||||
uint32_t s = 8 ; // header
|
||||
uint32_t s = 8 ; // header
|
||||
s += sizeof(GRouterMsgPropagationId) ; // routing id
|
||||
s += 20 ; // sha1 for published_key
|
||||
s += 4 ; // data_size
|
||||
s += data_size ; // data_size
|
||||
s += destination_key.serial_size() ; // destination_key
|
||||
s += 4 ; // randomized distance
|
||||
s += 4 ; // data_size
|
||||
s += data_size ; // data
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
@ -393,8 +390,9 @@ bool RsGRouterGenericDataItem::serialise(void *data,uint32_t& size) const
|
|||
return false ;
|
||||
|
||||
/* add mandatory parts first */
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, routing_id);
|
||||
ok &= destination_key.serialise(data, tlvsize, offset) ;
|
||||
ok &= setRawUInt64(data, tlvsize, &offset, routing_id);
|
||||
ok &= destination_key.serialise(data, tlvsize, offset) ;
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, randomized_distance) ;
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, data_size);
|
||||
|
||||
memcpy(&((uint8_t*)data)[offset],data_bytes,data_size) ;
|
||||
|
@ -417,7 +415,7 @@ bool RsGRouterACKItem::serialise(void *data,uint32_t& size) const
|
|||
return false ;
|
||||
|
||||
/* add mandatory parts first */
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, mid);
|
||||
ok &= setRawUInt64(data, tlvsize, &offset, mid);
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, state);
|
||||
|
||||
if (offset != tlvsize)
|
||||
|
@ -434,7 +432,7 @@ uint32_t RsGRouterMatrixCluesItem::serial_size() const
|
|||
{
|
||||
uint32_t s = 8 ; // header
|
||||
|
||||
s += 20 ; // Key size
|
||||
s += destination_key.serial_size() ; // Key size
|
||||
s += 4 ; // list<RoutingMatrixHitEntry>::size()
|
||||
s += (4+4+8) * clues.size() ;
|
||||
|
||||
|
@ -450,18 +448,13 @@ uint32_t RsGRouterMatrixFriendListItem::serial_size() const
|
|||
}
|
||||
uint32_t RsGRouterRoutingInfoItem::serial_size() const
|
||||
{
|
||||
uint32_t s = 8 ; // header
|
||||
uint32_t s = 8 ; // header
|
||||
s += 4 ; // status_flags
|
||||
s += origin.SIZE_IN_BYTES ; // origin
|
||||
s += origin.serial_size() ; // origin
|
||||
s += 8 ; // received_time
|
||||
s += 4 ; // tried_friends.size() ;
|
||||
|
||||
s += tried_friends.size() * ( RsPeerId::SIZE_IN_BYTES + 8 ) ; // FriendTrialRecord
|
||||
|
||||
s += 4; // data_item->routing_id
|
||||
s += data_item->destination_key.SIZE_IN_BYTES; // data_item->destination_key
|
||||
s += 4; // data_item->data_size
|
||||
s += data_item->data_size; // data_item->data_bytes
|
||||
s += tried_friends.size() * ( RsPeerId::SIZE_IN_BYTES + 8 + 4 + 4 ) ; // FriendTrialRecord
|
||||
s += data_item->serial_size(); // data_item
|
||||
|
||||
return s ;
|
||||
}
|
||||
|
@ -515,6 +508,25 @@ bool RsGRouterMatrixCluesItem::serialise(void *data,uint32_t& size) const
|
|||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool FriendTrialRecord::deserialise(void *data,uint32_t& offset,uint32_t size)
|
||||
{
|
||||
bool ok = true ;
|
||||
ok &= friend_id.deserialise(data, size, offset) ;
|
||||
ok &= getRawTimeT(data, size, &offset, time_stamp) ;
|
||||
ok &= getRawUFloat32(data, size, &offset, probability) ;
|
||||
ok &= getRawUInt32(data, size, &offset, &nb_friends) ;
|
||||
return ok ;
|
||||
}
|
||||
bool FriendTrialRecord::serialise(void *data,uint32_t& offset,uint32_t size) const
|
||||
{
|
||||
bool ok = true ;
|
||||
ok &= friend_id.serialise(data, size, offset) ;
|
||||
ok &= setRawTimeT(data, size, &offset, time_stamp) ;
|
||||
ok &= setRawUFloat32(data, size, &offset, probability) ;
|
||||
ok &= setRawUInt32(data, size, &offset, nb_friends) ;
|
||||
return ok ;
|
||||
}
|
||||
bool RsGRouterRoutingInfoItem::serialise(void *data,uint32_t& size) const
|
||||
{
|
||||
uint32_t tlvsize,offset=0;
|
||||
|
@ -529,17 +541,11 @@ bool RsGRouterRoutingInfoItem::serialise(void *data,uint32_t& size) const
|
|||
ok &= setRawUInt32(data, tlvsize, &offset, tried_friends.size()) ;
|
||||
|
||||
for(std::list<FriendTrialRecord>::const_iterator it(tried_friends.begin());it!=tried_friends.end();++it)
|
||||
{
|
||||
ok &= (*it).friend_id.serialise(data, tlvsize, offset ) ;
|
||||
ok &= setRawTimeT(data, tlvsize, &offset, (*it).time_stamp) ;
|
||||
}
|
||||
ok &= (*it).serialise(data,offset,size - offset) ;
|
||||
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, data_item->routing_id) ;
|
||||
ok &= data_item->destination_key.serialise(data, tlvsize, offset) ;
|
||||
ok &= setRawUInt32(data, tlvsize, &offset, data_item->data_size) ;
|
||||
|
||||
memcpy(&((uint8_t*)data)[offset],data_item->data_bytes,data_item->data_size) ;
|
||||
offset += data_item->data_size ;
|
||||
uint32_t ns = size - offset ;
|
||||
ok &= data_item->serialise( &((uint8_t*)data)[offset], ns) ;
|
||||
offset += ns ;
|
||||
|
||||
if (offset != tlvsize)
|
||||
{
|
||||
|
|
|
@ -26,20 +26,19 @@
|
|||
#pragma once
|
||||
|
||||
#include "serialiser/rsserial.h"
|
||||
#include "serialiser/rsserviceids.h"
|
||||
#include "retroshare/rstypes.h"
|
||||
#include "rsgrouter.h"
|
||||
|
||||
#include "retroshare/rsgrouter.h"
|
||||
#include "p3grouter.h"
|
||||
|
||||
// To be put in serialiser/rsserviceids.h
|
||||
static const uint8_t RS_SERVICE_TYPE_GROUTER = 0x0016 ;
|
||||
|
||||
const uint8_t RS_PKT_SUBTYPE_GROUTER_PUBLISH_KEY = 0x01 ; // used to publish a key
|
||||
const uint8_t RS_PKT_SUBTYPE_GROUTER_DATA = 0x02 ; // used to send data to a destination
|
||||
const uint8_t RS_PKT_SUBTYPE_GROUTER_ACK = 0x03 ; // acknowledgement of data received
|
||||
const uint8_t RS_PKT_SUBTYPE_GROUTER_DATA = 0x05 ; // used to send data to a destination
|
||||
|
||||
const uint8_t RS_PKT_SUBTYPE_GROUTER_MATRIX_CLUES = 0x80 ; // item to save matrix clues
|
||||
const uint8_t RS_PKT_SUBTYPE_GROUTER_ROUTING_INFO = 0x81 ; // item to save routing info
|
||||
const uint8_t RS_PKT_SUBTYPE_GROUTER_FRIENDS_LIST = 0x82 ; // item to save friend lists
|
||||
const uint8_t RS_PKT_SUBTYPE_GROUTER_ROUTING_INFO = 0x85 ; // item to save routing info
|
||||
|
||||
const uint8_t QOS_PRIORITY_RS_GROUTER_PUBLISH_KEY = 3 ; // slow items. No need to congest the network with this.
|
||||
const uint8_t QOS_PRIORITY_RS_GROUTER_ACK = 3 ;
|
||||
|
@ -50,6 +49,7 @@ const uint32_t RS_GROUTER_ACK_STATE_RECEIVED_INDIRECTLY = 0x0002 ; // data was
|
|||
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 */
|
||||
|
@ -151,6 +151,7 @@ class RsGRouterGenericDataItem: public RsGRouterItem, public RsGRouterNonCopyabl
|
|||
//
|
||||
GRouterMsgPropagationId routing_id ;
|
||||
GRouterKeyId destination_key ;
|
||||
uint32_t randomized_distance ;
|
||||
|
||||
uint32_t data_size ;
|
||||
uint8_t *data_bytes;
|
||||
|
@ -251,12 +252,12 @@ class RsGRouterSerialiser: public RsSerialType
|
|||
virtual RsItem *deserialise (void *data, uint32_t *size) ;
|
||||
|
||||
private:
|
||||
RsGRouterItem *deserialise_RsGRouterPublishKeyItem(void *data,uint32_t size) const ;
|
||||
RsGRouterItem *deserialise_RsGRouterGenericDataItem(void *data,uint32_t size) const ;
|
||||
RsGRouterItem *deserialise_RsGRouterACKItem(void *data,uint32_t size) const ;
|
||||
RsGRouterItem *deserialise_RsGRouterMatrixCluesItem(void *data,uint32_t size) const ;
|
||||
RsGRouterItem *deserialise_RsGRouterMatrixFriendListItem(void *data,uint32_t size) const ;
|
||||
RsGRouterItem *deserialise_RsGRouterRoutingInfoItem(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 ;
|
||||
RsGRouterMatrixFriendListItem *deserialise_RsGRouterMatrixFriendListItem(void *data,uint32_t size) const ;
|
||||
RsGRouterRoutingInfoItem *deserialise_RsGRouterRoutingInfoItem(void *data,uint32_t size) const ;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -32,8 +32,7 @@ GRouterMatrix::GRouterMatrix()
|
|||
_proba_need_updating = true ;
|
||||
}
|
||||
|
||||
bool GRouterMatrix::addRoutingClue( const GRouterKeyId& key_id,const GRouterServiceId& sid,float distance,
|
||||
const std::string& desc_string,const RsPeerId& source_friend)
|
||||
bool GRouterMatrix::addRoutingClue(const GRouterKeyId& key_id,const RsPeerId& source_friend,float weight)
|
||||
{
|
||||
// 1 - get the friend index.
|
||||
//
|
||||
|
@ -44,7 +43,7 @@ bool GRouterMatrix::addRoutingClue( const GRouterKeyId& key_id,const GRouterServ
|
|||
time_t now = time(NULL) ;
|
||||
|
||||
RoutingMatrixHitEntry rc ;
|
||||
rc.weight = 1.0f / (1.0f + distance) ;
|
||||
rc.weight = weight ;
|
||||
rc.time_stamp = now ;
|
||||
rc.friend_id = fid ;
|
||||
|
||||
|
@ -103,6 +102,14 @@ uint32_t GRouterMatrix::getFriendId(const RsPeerId& source_friend)
|
|||
return it->second ;
|
||||
}
|
||||
|
||||
void GRouterMatrix::getListOfKnownKeys(std::vector<GRouterKeyId>& key_ids) const
|
||||
{
|
||||
key_ids.clear() ;
|
||||
|
||||
for(std::map<GRouterKeyId,std::vector<float> >::const_iterator it(_time_combined_hits.begin());it!=_time_combined_hits.end();++it)
|
||||
key_ids.push_back(it->first) ;
|
||||
}
|
||||
|
||||
void GRouterMatrix::debugDump() const
|
||||
{
|
||||
std::cerr << " Proba needs up: " << _proba_need_updating << std::endl;
|
||||
|
@ -130,7 +137,7 @@ void GRouterMatrix::debugDump() const
|
|||
}
|
||||
}
|
||||
|
||||
bool GRouterMatrix::computeRoutingProbabilities(const GRouterKeyId& key_id, const std::list<RsPeerId>& friends, std::map<RsPeerId,float>& probas) const
|
||||
bool GRouterMatrix::computeRoutingProbabilities(const GRouterKeyId& key_id, const std::vector<RsPeerId>& friends, std::vector<float>& probas) const
|
||||
{
|
||||
// Routing probabilities are computed according to routing clues
|
||||
//
|
||||
|
@ -144,34 +151,41 @@ bool GRouterMatrix::computeRoutingProbabilities(const GRouterKeyId& key_id, cons
|
|||
if(_proba_need_updating)
|
||||
std::cerr << "GRouterMatrix::computeRoutingProbabilities(): matrix is not up to date. Not a real problem, but still..." << std::endl;
|
||||
|
||||
probas.clear() ;
|
||||
probas.resize(friends.size(),0.0f) ;
|
||||
float total = 0.0f ;
|
||||
|
||||
std::map<GRouterKeyId,std::vector<float> >::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;
|
||||
// The key is not known. In this case, we return equal probabilities for all peers.
|
||||
//
|
||||
float p = 1.0f / friends.size() ;
|
||||
|
||||
probas.clear() ;
|
||||
probas.resize(friends.size(),p) ;
|
||||
|
||||
std::cerr << "GRouterMatrix::computeRoutingProbabilities(): key id " << key_id.toStdString() << " does not exist! Returning uniform probabilities." << std::endl;
|
||||
return false ;
|
||||
}
|
||||
const std::vector<float>& w(it2->second) ;
|
||||
|
||||
for(std::list<RsPeerId>::const_iterator it(friends.begin());it!=friends.end();++it)
|
||||
for(uint32_t i=0;i<friends.size();++i)
|
||||
{
|
||||
uint32_t findex = getFriendId_const(*it) ;
|
||||
uint32_t findex = getFriendId_const(friends[i]) ;
|
||||
|
||||
if(findex >= w.size())
|
||||
probas[*it] = 0.0f ;
|
||||
probas[i] = 0.0f ;
|
||||
else
|
||||
{
|
||||
probas[*it] = w[findex] ;
|
||||
probas[i] = w[findex] ;
|
||||
total += w[findex] ;
|
||||
}
|
||||
}
|
||||
|
||||
if(total > 0.0f)
|
||||
for(std::map<RsPeerId,float>::iterator it(probas.begin());it!=probas.end();++it)
|
||||
it->second /= total ;
|
||||
for(int i=0;i<friends.size();++i)
|
||||
probas[i] /= total ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
#include <list>
|
||||
|
||||
#include "pgp/rscertificate.h"
|
||||
#include "retroshare/rsgrouter.h"
|
||||
#include "groutertypes.h"
|
||||
#include "rsgrouter.h"
|
||||
|
||||
class RsItem ;
|
||||
|
||||
|
@ -51,7 +51,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::list<RsPeerId>& friends, std::map<RsPeerId,float>& probas) const ;
|
||||
bool computeRoutingProbabilities(const GRouterKeyId& id, const std::vector<RsPeerId>& friends, std::vector<float>& probas) const ;
|
||||
|
||||
// Update routing probabilities for each key, accounting for all received events, but without
|
||||
// activity information
|
||||
|
@ -60,14 +60,15 @@ class GRouterMatrix
|
|||
|
||||
// Record one routing clue. The events can possibly be merged in time buckets.
|
||||
//
|
||||
bool addRoutingClue(const GRouterKeyId& id,const GRouterServiceId& sid,float distance,const std::string& desc_string,const RsPeerId& source_friend) ;
|
||||
bool addRoutingClue(const GRouterKeyId& id,const RsPeerId& source_friend,float weight) ;
|
||||
|
||||
bool saveList(std::list<RsItem*>& items) ;
|
||||
bool loadList(std::list<RsItem*>& items) ;
|
||||
|
||||
// Dump info in terminal.
|
||||
//
|
||||
void debugDump() const ;
|
||||
|
||||
bool saveList(std::list<RsItem*>& items) ;
|
||||
bool loadList(std::list<RsItem*>& items) ;
|
||||
void getListOfKnownKeys(std::vector<GRouterKeyId>& key_ids) const ;
|
||||
|
||||
private:
|
||||
// returns the friend id, possibly creating a new id.
|
||||
|
|
|
@ -34,7 +34,7 @@ class RsGRouterGenericDataItem ;
|
|||
|
||||
typedef uint32_t GRouterServiceId ;
|
||||
typedef uint32_t GRouterKeyPropagationId ;
|
||||
typedef uint32_t GRouterMsgPropagationId ;
|
||||
typedef uint64_t GRouterMsgPropagationId ;
|
||||
|
||||
static const uint32_t GROUTER_CLIENT_ID_MESSAGES = 0x1001 ;
|
||||
|
||||
|
@ -50,36 +50,35 @@ static const time_t RS_GROUTER_PUBLISH_CAMPAIGN_PERIOD = 1 *60 ; // 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 = 3600 ; // time between two trial of sending a given message
|
||||
static const time_t RS_GROUTER_KEY_DIFFUSION_MAX_KEEP = 7200 ; // time to keep key diffusion items in cache, to avoid multiple diffusion.
|
||||
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.
|
||||
|
||||
static const uint32_t RS_GROUTER_ROUTING_STATE_UNKN = 0x0000 ; // unknown. Unused.
|
||||
static const uint32_t RS_GROUTER_ROUTING_STATE_PEND = 0x0001 ; // item is pending. Should be sent asap.
|
||||
static const uint32_t RS_GROUTER_ROUTING_STATE_SENT = 0x0002 ; // item is sent. Waiting for answer
|
||||
static const uint32_t RS_GROUTER_ROUTING_STATE_ARVD = 0x0003 ; // item is at destination. The cache only holds it to avoid duplication.
|
||||
|
||||
class GRouterPublishedKeyInfo
|
||||
class FriendTrialRecord
|
||||
{
|
||||
public:
|
||||
GRouterServiceId service_id ;
|
||||
std::string description_string ;
|
||||
PGPFingerprintType fpr ;
|
||||
time_t last_published_time ;
|
||||
time_t validity_time ;
|
||||
};
|
||||
|
||||
struct FriendTrialRecord
|
||||
{
|
||||
RsPeerId friend_id ; // id of the friend
|
||||
time_t time_stamp ; // time of the last tried
|
||||
RsPeerId friend_id ; // id of the friend
|
||||
time_t time_stamp ; // time of the last tried
|
||||
float probability ; // probability at which the item was selected
|
||||
uint32_t nb_friends ; // number of friends at the time of sending the item
|
||||
|
||||
bool serialise(void *data,uint32_t& offset,uint32_t size) const ;
|
||||
bool deserialise(void *data,uint32_t& offset,uint32_t size) ;
|
||||
};
|
||||
|
||||
class GRouterRoutingInfo
|
||||
{
|
||||
public:
|
||||
RsGRouterGenericDataItem *data_item ;
|
||||
|
||||
uint32_t status_flags ; // pending, waiting, etc.
|
||||
std::list<FriendTrialRecord> tried_friends ; // list of friends to which the item was sent ordered with time.
|
||||
RsPeerId origin ; // which friend sent us that item
|
||||
time_t received_time ; // time at which the item was received
|
||||
|
||||
std::list<FriendTrialRecord> tried_friends ; // list of friends to which the item was sent ordered with time.
|
||||
|
||||
RsGRouterGenericDataItem *data_item ;
|
||||
};
|
||||
|
||||
|
|
|
@ -68,6 +68,17 @@
|
|||
// * keep the local routing info in a cache that is saved (Which peer issued the msg)
|
||||
// - which probability was used to chose this friend (will be useful
|
||||
// to compute the routing contribution if the msg is ACK-ed)
|
||||
//
|
||||
// Two probabilities are computed:
|
||||
// - routing probabilities among connected friends
|
||||
// * this is computed by the routing matrix
|
||||
// - branching factor N
|
||||
// * depends on the depth of the items
|
||||
// * depends on the distribution of probabilities (min and max)
|
||||
//
|
||||
// Once computed,
|
||||
// - the item is forwarded randomly to N peers drawn from the list of connected peers with the given probabilities.
|
||||
// - the depth of the item is incremented randomly
|
||||
//
|
||||
// - downward: look into routing cache. If info not present, drop the item.
|
||||
// Forward item into stored direction.
|
||||
|
@ -137,6 +148,7 @@
|
|||
// - packet service ID (Can be messenging, channels, etc).
|
||||
// - packet data (void* + size_t)
|
||||
// - flags (such as ACK or response required, and packet direction)
|
||||
// - routed directions and probabilities
|
||||
// * ACK packet.
|
||||
// - packet unique ID (the id of the corresponding data)
|
||||
// - flags (reason for ACK. Could be data delivered, or error, too far, etc)
|
||||
|
@ -179,8 +191,10 @@
|
|||
#include "groutertypes.h"
|
||||
#include "grouterclientservice.h"
|
||||
|
||||
const std::string p3GRouter::SERVICE_INFO_APP_NAME = "Global Router" ;
|
||||
|
||||
p3GRouter::p3GRouter(p3LinkMgr *lm)
|
||||
: p3Service(RS_SERVICE_TYPE_GROUTER), p3Config(CONFIG_TYPE_GROUTER), mLinkMgr(lm), grMtx("GRouter")
|
||||
: p3Service(), p3Config(), mLinkMgr(lm), grMtx("GRouter")
|
||||
{
|
||||
addSerialType(new RsGRouterSerialiser()) ;
|
||||
|
||||
|
@ -215,7 +229,8 @@ int p3GRouter::tick()
|
|||
{
|
||||
last_publish_campaign_time = now ;
|
||||
|
||||
publishKeys() ;
|
||||
//publishKeys() ; // we don't publish keys anymore.
|
||||
//
|
||||
_routing_matrix.updateRoutingProbabilities() ;
|
||||
}
|
||||
|
||||
|
@ -284,135 +299,77 @@ void p3GRouter::routePendingObjects()
|
|||
{
|
||||
RsStackMutex mtx(grMtx) ;
|
||||
|
||||
// Go through list of published keys
|
||||
// broadcast a publishKeyItem for each of them.
|
||||
//
|
||||
// The routing rules are the following:
|
||||
//
|
||||
// Go through list of cached routing objects. For each object:
|
||||
// if(Last try is old)
|
||||
// put the object in pending list
|
||||
//
|
||||
// (This loop is costly (could handle lots of items), so it should be done less often.)
|
||||
//
|
||||
// Add peer to the list of tried routes with time stamp
|
||||
// Keep the list of tried friends
|
||||
//
|
||||
// Go through list of pendign objects. For each object:
|
||||
// Select one route direction
|
||||
// - according to current probabilities from the routing matrix
|
||||
// - according to list of previous attempts
|
||||
//
|
||||
// if(route found)
|
||||
// forward item, update state and time stamp
|
||||
// else
|
||||
// if(I am not the sender)
|
||||
// send back ACK(given up) // if I am the sender, I will keep trying.
|
||||
//
|
||||
// Item has received an ACK
|
||||
//
|
||||
// ACK: given up => change route
|
||||
// ACK: received => Remove item from routed items
|
||||
//
|
||||
// The list in _pending_messages is necessarily short and most of the time empty. Once
|
||||
// treated, objects are stored in _routing_cache, where they wait for an answer.
|
||||
|
||||
time_t now = time(NULL) ;
|
||||
|
||||
std::cerr << "p3GRouter::routeObjects() triage phase:" << std::endl;
|
||||
std::cerr << "Cached Items : " << _pending_messages.size() << std::endl;
|
||||
|
||||
std::list<RsPeerId> lst ;
|
||||
mLinkMgr->getOnlineList(lst) ;
|
||||
mLinkMgr->getOnlineList(lst) ;
|
||||
RsPeerId own_id( mLinkMgr->getOwnId() );
|
||||
|
||||
std::vector<RsPeerId> pids ;
|
||||
for(std::list<RsPeerId>::const_iterator it(lst.begin());it!=lst.end();++it)
|
||||
pids.push_back(*it) ;
|
||||
|
||||
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) || (it->second.status_flags == RS_GROUTER_ROUTING_STATE_SENT && it->second.tried_friends.front().time_stamp+RS_GROUTER_ROUTING_WAITING_TIME < now))
|
||||
{
|
||||
std::cerr << " Msg id: " << std::hex << it->first << std::dec << std::endl;
|
||||
std::cerr << " Origin: " << it->second.origin.toStdString() << std::endl;
|
||||
std::cerr << " Last : " << it->second.tried_friends.front().friend_id.toStdString() << std::endl;
|
||||
std::cerr << " Time : " << it->second.tried_friends.front().time_stamp << 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;
|
||||
|
||||
std::map<RsPeerId,float> probas ; // friends probabilities for online friend list.
|
||||
RsPeerId routed_friend ; // friend chosen for the next hop
|
||||
float best_proba = 0.0f; // temp variable used to select the best proba
|
||||
bool should_remove = false ; // should we remove this from the map?
|
||||
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.
|
||||
// Retrieve probabilities for this key. This call always succeeds. If no route is known, all probabilities become equal.
|
||||
//
|
||||
if(! _routing_matrix.computeRoutingProbabilities(it->second.data_item->destination_key, lst, probas))
|
||||
_routing_matrix.computeRoutingProbabilities(it->second.data_item->destination_key, pids, probas) ;
|
||||
|
||||
// Compute the branching factor.
|
||||
|
||||
int N = computeBranchingFactor(pids,probas,it->second.data_item->randomized_distance) ;
|
||||
|
||||
// Now use this to select N random peers according to the given probabilities
|
||||
|
||||
std::set<uint32_t> routing_friend_indices = computeRoutingFriends(pids,probas,N) ;
|
||||
|
||||
std::cerr << " Routing statistics: " << std::endl;
|
||||
|
||||
// Actually send the item.
|
||||
|
||||
for(std::set<uint32_t>::const_iterator its(routing_friend_indices.begin());its!=routing_friend_indices.end();++its)
|
||||
{
|
||||
// key does not exist in routing matrix => send back an ACK(unknown)
|
||||
std::cerr << " Friend : " << (*its) << std::endl;
|
||||
|
||||
std::cerr << " [Cannot compute. Unknown destination key!!] " << std::endl;
|
||||
|
||||
if(it->second.origin != own_id)
|
||||
{
|
||||
std::cerr << " removing item and notifying the sender (" << it->second.origin.toStdString() << ")" << std::endl;
|
||||
|
||||
sendACK(it->second.origin,it->first,RS_GROUTER_ACK_STATE_UNKNOWN) ;
|
||||
|
||||
// remove item from cache
|
||||
//
|
||||
should_remove = true ;
|
||||
}
|
||||
std::cerr << " item is ours. Keeping it until a route is known." << std::endl;
|
||||
|
||||
// else, select a routing friend at random, or just wait? Wait is probably better.
|
||||
}
|
||||
|
||||
bool friend_found = false ;
|
||||
|
||||
for(std::map<RsPeerId,float>::const_iterator it2(probas.begin());it2!=probas.end();++it2)
|
||||
{
|
||||
std::cerr << " " << it2->first.toStdString() << " : " << it2->second << std::endl;
|
||||
|
||||
// select the peer with highest probability that hasn't yet been tried.
|
||||
|
||||
if(it2->second > best_proba && !(it2->first == it->second.tried_friends.front().friend_id))
|
||||
{
|
||||
routed_friend = it2->first ;
|
||||
best_proba = it2->second ;
|
||||
friend_found = true ;
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << " Best route: " << routed_friend.toStdString() << ", with probability " << best_proba << std::endl;
|
||||
|
||||
// now, send the item.
|
||||
|
||||
if(friend_found)
|
||||
{
|
||||
// make a deep copy of the item
|
||||
RsGRouterGenericDataItem *new_item = it->second.data_item->duplicate() ;
|
||||
|
||||
// update cache entry
|
||||
FriendTrialRecord ftr ;
|
||||
ftr.time_stamp = now ;
|
||||
ftr.friend_id = routed_friend ;
|
||||
ftr.friend_id = pids[*its];
|
||||
ftr.probability = probas[*its] ;
|
||||
ftr.nb_friends = probas.size() ;
|
||||
|
||||
it->second.tried_friends.push_front(ftr) ;
|
||||
it->second.status_flags = RS_GROUTER_ROUTING_STATE_SENT ;
|
||||
|
||||
std::cerr << " Sending..." << std::endl;
|
||||
std::cerr << " Routing probability: " << ftr.probability << std::endl;
|
||||
std::cerr << " Sending..." << std::endl;
|
||||
|
||||
// send
|
||||
new_item->PeerId(routed_friend) ;
|
||||
new_item->PeerId(pids[*its]) ;
|
||||
new_item->randomized_distance += computeRandomDistanceIncrement(pids[*its],new_item->destination_key) ;
|
||||
|
||||
sendItem(new_item) ;
|
||||
}
|
||||
else if(it->second.origin != mLinkMgr->getOwnId() || std::find(lst.begin(),lst.end(),it->second.origin) != lst.end())
|
||||
{
|
||||
// There's no correct friend to send this item to. We keep it for a while. If it's too old,
|
||||
// we discard it. For now, the procedure is to send back an ACK.
|
||||
|
||||
std::cerr << " Item has no route candidate. It's too old. " << std::endl;
|
||||
std::cerr << " sending ACK(no route) to peer " << it->second.origin.toStdString() << std::endl;
|
||||
|
||||
sendACK(it->second.origin,it->first,RS_GROUTER_ACK_STATE_NO_ROUTE) ;
|
||||
|
||||
should_remove = true ;
|
||||
}
|
||||
|
||||
if(should_remove)
|
||||
{
|
||||
|
@ -430,11 +387,56 @@ void p3GRouter::routePendingObjects()
|
|||
++it ;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Skipping " << std::hex << it->first << std::dec << ", dest=" << it->second.data_item->destination_key.toStdString() << ", state = " << it->second.status_flags << ", stamp=" << it->second.tried_friends.front().time_stamp << " - " << it->second.tried_friends.front().friend_id.toStdString() << std::endl;
|
||||
++it ;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t p3GRouter::computeRandomDistanceIncrement(const RsPeerId& pid,const GRouterKeyId& destination_key)
|
||||
{
|
||||
// This computes a consistent random bias between 0 and 255, which only depends on the
|
||||
// destination key and the friend the item is going to be routed through.
|
||||
// Makes it much harder for attakcers to figure out what is going on with
|
||||
// distances in the network, and makes statistics about multiple sending
|
||||
// attempts impossible.
|
||||
//
|
||||
static uint64_t random_salt = RSRandom::random_u64() ;
|
||||
static const int total_size = RsPeerId::SIZE_IN_BYTES + GRouterKeyId::SIZE_IN_BYTES + sizeof(random_salt) ;
|
||||
|
||||
unsigned char tmpmem[total_size] ;
|
||||
*(uint64_t*)&tmpmem[0] = random_salt ;
|
||||
memcpy(&tmpmem[sizeof(random_salt)],pid.toByteArray(),RsPeerId::SIZE_IN_BYTES) ;
|
||||
memcpy(&tmpmem[sizeof(random_salt) + RsPeerId::SIZE_IN_BYTES],destination_key.toByteArray(),GRouterKeyId::SIZE_IN_BYTES) ;
|
||||
|
||||
return RsDirUtil::sha1sum(tmpmem,total_size).toByteArray()[5] ;
|
||||
}
|
||||
|
||||
uint32_t p3GRouter::computeBranchingFactor(const std::vector<RsPeerId>& friends,const std::vector<float>& probas,uint32_t dist)
|
||||
{
|
||||
// This should be made a bit more adaptive ;-)
|
||||
//
|
||||
return 1 ;
|
||||
}
|
||||
|
||||
std::set<uint32_t> p3GRouter::computeRoutingFriends(const std::vector<RsPeerId>& pids,const std::vector<float>& probas,uint32_t N)
|
||||
{
|
||||
// We draw N friends according to the routing probabilitites that are passed as parameter.
|
||||
//
|
||||
|
||||
std::set<uint32_t> res ;
|
||||
|
||||
if(probas.empty())
|
||||
return res ;
|
||||
|
||||
res.insert(0) ;
|
||||
|
||||
return res ;
|
||||
}
|
||||
|
||||
void p3GRouter::publishKeys()
|
||||
{
|
||||
#ifdef SUSPENDED
|
||||
RsStackMutex mtx(grMtx) ;
|
||||
|
||||
// Go through list of published keys
|
||||
|
@ -454,14 +456,13 @@ void p3GRouter::publishKeys()
|
|||
std::cerr << " Key id : " << it->first.toStdString() << std::endl;
|
||||
std::cerr << " Service id : " << std::hex << info.service_id << std::dec << std::endl;
|
||||
std::cerr << " Description : " << info.description_string << std::endl;
|
||||
std::cerr << " Fingerprint : " << info.fpr.toStdString() << std::endl;
|
||||
|
||||
RsGRouterPublishKeyItem item ;
|
||||
item.diffusion_id = RSRandom::random_u32() ;
|
||||
item.published_key = it->first ;
|
||||
item.service_id = info.service_id ;
|
||||
item.randomized_distance = drand48() ;
|
||||
item.fingerprint = info.fpr;
|
||||
item.fingerprint.clear() ; // not set
|
||||
item.description_string = info.description_string ;
|
||||
item.PeerId(RsPeerId()) ; // no peer id => key is forwarded to all friends.
|
||||
|
||||
|
@ -471,6 +472,7 @@ void p3GRouter::publishKeys()
|
|||
info.last_published_time = now ;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void p3GRouter::locked_forwardKey(const RsGRouterPublishKeyItem& item)
|
||||
|
@ -497,16 +499,20 @@ void p3GRouter::locked_forwardKey(const RsGRouterPublishKeyItem& item)
|
|||
else
|
||||
std::cerr << " Not forwarding to source id " << item.PeerId() << std::endl;
|
||||
}
|
||||
bool p3GRouter::registerKey(const GRouterKeyId& key,const PGPFingerprintType& fps,const GRouterServiceId& client_id,const std::string& description)
|
||||
bool p3GRouter::registerKey(const GRouterKeyId& key,const GRouterServiceId& client_id,const std::string& description)
|
||||
{
|
||||
RsStackMutex mtx(grMtx) ;
|
||||
|
||||
if(_registered_services.find(client_id) == _registered_services.end())
|
||||
{
|
||||
std::cerr << __PRETTY_FUNCTION__ << ": unable to register key " << key << " for client id " << client_id << ": client id is not known." << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
GRouterPublishedKeyInfo info ;
|
||||
info.service_id = client_id ;
|
||||
info.fpr = fps ;
|
||||
info.description_string = description.substr(0,20);
|
||||
info.validity_time = 0 ; // not used yet.
|
||||
info.last_published_time = 0 ; // means never published, se it will be re-published soon.
|
||||
//info.last_published_time = 0 ; // means never published, se it will be re-published soon.
|
||||
|
||||
_owned_key_ids[key] = info ;
|
||||
|
||||
|
@ -575,7 +581,7 @@ void p3GRouter::handleRecvPublishKeyItem(RsGRouterPublishKeyItem *item)
|
|||
|
||||
// update the route matrix
|
||||
|
||||
_routing_matrix.addRoutingClue(item->published_key,item->service_id,item->randomized_distance,item->description_string,RsPeerId(item->PeerId())) ;
|
||||
_routing_matrix.addRoutingClue(item->published_key,RsPeerId(item->PeerId()),1) ;
|
||||
|
||||
// forward the key to other peers according to key forwarding cache
|
||||
|
||||
|
@ -602,7 +608,7 @@ void p3GRouter::handleRecvPublishKeyItem(RsGRouterPublishKeyItem *item)
|
|||
void p3GRouter::handleRecvACKItem(RsGRouterACKItem *item)
|
||||
{
|
||||
RsStackMutex mtx(grMtx) ;
|
||||
std::cerr << "Received ACK item, mid=" << std::hex << item->mid << std::dec << std::endl;
|
||||
std::cerr << "Received ACK item, mid=" << std::hex << item->mid << std::dec << ", ACK type = "<< item->state << std::endl;
|
||||
|
||||
// find the item in the pendign list,
|
||||
// - if not found, drop.
|
||||
|
@ -624,44 +630,81 @@ void p3GRouter::handleRecvACKItem(RsGRouterACKItem *item)
|
|||
switch(item->state)
|
||||
{
|
||||
case RS_GROUTER_ACK_STATE_RECEIVED_INDIRECTLY:
|
||||
// Do nothing. It was indirectly received: fine. We don't need to notify the origin
|
||||
// otherwise lots of ACKs will flow to the origin.
|
||||
break ;
|
||||
case RS_GROUTER_ACK_STATE_RECEIVED:
|
||||
// Notify the origin. This is the main route and it was successful.
|
||||
|
||||
std::cerr << " forwarding ACK to origin: " << it->second.origin.toStdString() << std::endl;
|
||||
std::cerr << " updating routing matrix." << std::endl;
|
||||
|
||||
sendACK(it->second.origin,item->mid,RS_GROUTER_ACK_STATE_RECEIVED) ;
|
||||
it->second.status_flags = RS_GROUTER_ROUTING_STATE_ARVD ;
|
||||
|
||||
{
|
||||
#warning UNFINISHED code.
|
||||
|
||||
// Now compute the weight for that particular item. See with what probabilities it was chosen.
|
||||
//
|
||||
float weight = (item->state == RS_GROUTER_ACK_STATE_RECEIVED)?1.0f : 0.5;
|
||||
std::cerr << " weight = " << weight << std::endl;
|
||||
|
||||
|
||||
_routing_matrix.addRoutingClue(it->second.data_item->destination_key,item->PeerId(),weight) ;
|
||||
}
|
||||
|
||||
if(it->second.origin != mLinkMgr->getOwnId())
|
||||
{
|
||||
std::cerr << " forwarding ACK to origin: " << it->second.origin.toStdString() << std::endl;
|
||||
sendACK(it->second.origin,item->mid,item->state) ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case RS_GROUTER_ACK_STATE_GIVEN_UP: // route is bad. We forward back and update the routing matrix.
|
||||
break ;
|
||||
}
|
||||
|
||||
if(it->second.origin == mLinkMgr->getOwnId())
|
||||
if(it->second.origin == mLinkMgr->getOwnId())
|
||||
{
|
||||
// find the client service and notify it.
|
||||
std::cerr << " We're owner: should notify client id" << std::endl;
|
||||
}
|
||||
|
||||
// Always remove the item.
|
||||
// Just decrement the list of tried friends
|
||||
//
|
||||
delete it->second.data_item ;
|
||||
_pending_messages.erase(it) ;
|
||||
for(std::list<FriendTrialRecord>::iterator it2(it->second.tried_friends.begin());it2!=it->second.tried_friends.end();++it2)
|
||||
if( (*it2).friend_id == item->PeerId())
|
||||
{
|
||||
std::cerr << " Removing friend try for peer " << item->PeerId() << ". " << it->second.tried_friends.size() << " tries left." << std::endl;
|
||||
it->second.tried_friends.erase(it2) ;
|
||||
break ;
|
||||
}
|
||||
|
||||
if(it->second.tried_friends.empty())
|
||||
{
|
||||
delete it->second.data_item ;
|
||||
_pending_messages.erase(it) ;
|
||||
|
||||
std::cerr << " No tries left. Removing item from pending list." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void p3GRouter::handleRecvDataItem(RsGRouterGenericDataItem *item)
|
||||
{
|
||||
RsStackMutex mtx(grMtx) ;
|
||||
std::cerr << "Received data item for key " << item->destination_key << std::endl;
|
||||
std::cerr << "Received data item for key " << item->destination_key << ", distance = " << item->randomized_distance << std::endl;
|
||||
|
||||
// check the item depth. If too large, send a ACK back.
|
||||
|
||||
if(item->randomized_distance > GROUTER_ITEM_MAX_TRAVEL_DISTANCE)
|
||||
{
|
||||
std::cerr << " Distance is too large: " << item->randomized_distance << " units. Item is dropped." << std::endl;
|
||||
sendACK(item->PeerId(),item->routing_id,RS_GROUTER_ACK_STATE_TOO_FAR) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
// Do we have this item in the cache already?
|
||||
// - if not, add in the pending items
|
||||
// - if yet. Ignore, or send ACK for shorter route.
|
||||
|
||||
std::map<GRouterKeyId,GRouterPublishedKeyInfo>::const_iterator it = _owned_key_ids.find(item->destination_key) ;
|
||||
std::map<GRouterMsgPropagationId,GRouterRoutingInfo>::const_iterator itr = _pending_messages.find(item->routing_id) ;
|
||||
std::map<GRouterMsgPropagationId,GRouterRoutingInfo>::iterator itr = _pending_messages.find(item->routing_id) ;
|
||||
RsGRouterGenericDataItem *item_copy = NULL;
|
||||
|
||||
if(itr != _pending_messages.end())
|
||||
|
@ -670,7 +713,7 @@ void p3GRouter::handleRecvDataItem(RsGRouterGenericDataItem *item)
|
|||
|
||||
item_copy = itr->second.data_item ;
|
||||
}
|
||||
else // item is now known. Store it into pending msgs. We make a copy, since the item will be deleted otherwise.
|
||||
else // item is not known. Store it into pending msgs. We make a copy, since the item will be deleted otherwise.
|
||||
{
|
||||
std::cerr << " Item is new. Storing in cache as pending messages." << std::endl;
|
||||
|
||||
|
@ -679,38 +722,40 @@ void p3GRouter::handleRecvDataItem(RsGRouterGenericDataItem *item)
|
|||
info.data_item = item->duplicate() ;
|
||||
item_copy = info.data_item ;
|
||||
|
||||
if(it != _owned_key_ids.end())
|
||||
info.status_flags = RS_GROUTER_ROUTING_STATE_ARVD ;
|
||||
else
|
||||
info.status_flags = RS_GROUTER_ROUTING_STATE_PEND ;
|
||||
|
||||
info.origin = RsPeerId(item->PeerId()) ;
|
||||
info.received_time = time(NULL) ;
|
||||
|
||||
_pending_messages[item->routing_id] = info ;
|
||||
itr = _pending_messages.find(item->routing_id) ;
|
||||
}
|
||||
|
||||
// Is the item for us? If so, find the client service and send the item back.
|
||||
|
||||
//
|
||||
if(it != _owned_key_ids.end())
|
||||
if(time(NULL) < it->second.validity_time)
|
||||
{
|
||||
if(itr->second.status_flags == RS_GROUTER_ROUTING_STATE_ARVD)
|
||||
sendACK(item->PeerId(), item->routing_id, RS_GROUTER_ACK_STATE_RECEIVED_INDIRECTLY) ;
|
||||
else
|
||||
{
|
||||
// test validity time. If too old, we don't forward.
|
||||
sendACK(item->PeerId(), item->routing_id, RS_GROUTER_ACK_STATE_RECEIVED) ;
|
||||
itr->second.status_flags = RS_GROUTER_ROUTING_STATE_ARVD ;
|
||||
|
||||
std::map<GRouterServiceId,GRouterClientService*>::const_iterator its = _registered_services.find(it->second.service_id) ;
|
||||
|
||||
if(its != _registered_services.end())
|
||||
{
|
||||
std::cerr << " Key is owned by us. Notifying service for this item." << std::endl;
|
||||
its->second->receiveGRouterData(item_copy,it->first) ;
|
||||
its->second->receiveGRouterData(it->first,item_copy) ;
|
||||
}
|
||||
else
|
||||
std::cerr << " (EE) weird situation. No service registered for a key that we own. Key id = " << item->destination_key.toStdString() << ", service id = " << it->second.service_id << std::endl;
|
||||
}
|
||||
else
|
||||
std::cerr << " (WW) key is outdated. Dropping this item." << std::endl;
|
||||
}
|
||||
else
|
||||
std::cerr << " Item is not for us. Leaving in pending msgs to be routed later." << std::endl;
|
||||
{
|
||||
std::cerr << " item is not for us. Storing in pending mode." << std::endl;
|
||||
itr->second.status_flags = RS_GROUTER_ROUTING_STATE_PEND ;
|
||||
}
|
||||
|
||||
_changed = true ;
|
||||
}
|
||||
|
@ -732,17 +777,22 @@ 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.received_time = time(NULL) ;
|
||||
info.data_item->randomized_distance = 0 ;
|
||||
|
||||
// Make sure we have a unique id (at least locally).
|
||||
//
|
||||
GRouterMsgPropagationId propagation_id ;
|
||||
do { propagation_id = RSRandom::random_u32(); } while(_pending_messages.find(propagation_id) != _pending_messages.end()) ;
|
||||
|
||||
item->destination_key = destination ;
|
||||
item->routing_id = propagation_id ;
|
||||
|
||||
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 << " status = " << info.status_flags << std::endl;
|
||||
std::cerr << " distance = " << info.data_item->randomized_distance << std::endl;
|
||||
std::cerr << " origin = " << info.origin.toStdString() << std::endl;
|
||||
std::cerr << " Recv time = " << info.received_time << std::endl;
|
||||
|
||||
|
@ -821,6 +871,54 @@ bool p3GRouter::saveList(bool& cleanup,std::list<RsItem*>& items)
|
|||
return true ;
|
||||
}
|
||||
|
||||
bool p3GRouter::getRoutingMatrixInfo(RsGRouter::GRouterRoutingMatrixInfo& info)
|
||||
{
|
||||
info.per_friend_probabilities.clear() ;
|
||||
info.friend_ids.clear() ;
|
||||
info.published_keys.clear() ;
|
||||
|
||||
std::list<RsPeerId> ids ;
|
||||
mLinkMgr->getOnlineList(ids) ;
|
||||
|
||||
RsStackMutex mtx(grMtx) ;
|
||||
|
||||
info.published_keys = _owned_key_ids ;
|
||||
|
||||
for(std::list<RsPeerId>::const_iterator it(ids.begin());it!=ids.end();++it)
|
||||
info.friend_ids.push_back(*it) ;
|
||||
|
||||
std::vector<GRouterKeyId> known_keys ;
|
||||
std::vector<float> probas ;
|
||||
_routing_matrix.getListOfKnownKeys(known_keys) ;
|
||||
|
||||
for(uint32_t i=0;i<known_keys.size();++i)
|
||||
{
|
||||
_routing_matrix.computeRoutingProbabilities(known_keys[i],info.friend_ids,probas) ;
|
||||
info.per_friend_probabilities[known_keys[i]] = probas ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
bool p3GRouter::getRoutingCacheInfo(std::vector<GRouterRoutingCacheInfo>& infos)
|
||||
{
|
||||
RsStackMutex mtx(grMtx) ;
|
||||
infos.clear() ;
|
||||
|
||||
for(std::map<GRouterMsgPropagationId,GRouterRoutingInfo>::const_iterator it(_pending_messages.begin());it!=_pending_messages.end();++it)
|
||||
{
|
||||
infos.push_back(GRouterRoutingCacheInfo()) ;
|
||||
GRouterRoutingCacheInfo& cinfo(infos.back()) ;
|
||||
|
||||
cinfo.mid = it->first ;
|
||||
cinfo.local_origin = it->second.origin ;
|
||||
cinfo.destination = it->second.data_item->destination_key ;
|
||||
cinfo.time_stamp = it->second.received_time ;
|
||||
cinfo.status = it->second.status_flags ;
|
||||
cinfo.data_size = it->second.data_item->data_size ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
// Dump everything
|
||||
//
|
||||
void p3GRouter::debugDump()
|
||||
|
@ -837,7 +935,7 @@ void p3GRouter::debugDump()
|
|||
std::cerr << " Key id : " << it->first.toStdString() << std::endl;
|
||||
std::cerr << " Service id : " << std::hex << it->second.service_id << std::dec << std::endl;
|
||||
std::cerr << " Description : " << it->second.description_string << std::endl;
|
||||
std::cerr << " Last published: " << now - it->second.last_published_time << " secs ago" << std::endl;
|
||||
//std::cerr << " Last published: " << now - it->second.last_published_time << " secs ago" << std::endl;
|
||||
}
|
||||
|
||||
std::cerr << " Registered services: " << std::endl;
|
||||
|
@ -854,7 +952,18 @@ void p3GRouter::debugDump()
|
|||
std::cerr << " [Not shown yet] " << std::endl;
|
||||
|
||||
std::cerr << " Data items: " << std::endl;
|
||||
std::cerr << " [Not shown yet] " << std::endl;
|
||||
|
||||
static std::string statusString[4] = { "Unkn","Pend","Sent","Ackn" };
|
||||
|
||||
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()
|
||||
<< " Destination: " << it->second.data_item->destination_key
|
||||
<< " Time : " << now - it->second.tried_friends.front().time_stamp << " secs ago."
|
||||
<< " Status: " << statusString[it->second.status_flags] << std::endl;
|
||||
|
||||
// << " Last : " << it->second.tried_friends.front().friend_id.toStdString() << std::endl;
|
||||
// << " Probabilities: " << std::endl;
|
||||
|
||||
std::cerr << " Routing matrix: " << std::endl;
|
||||
|
||||
|
|
|
@ -28,15 +28,16 @@
|
|||
#include <map>
|
||||
#include <queue>
|
||||
|
||||
#include "rsgrouter.h"
|
||||
#include "retroshare/rsgrouter.h"
|
||||
#include "retroshare/rstypes.h"
|
||||
|
||||
#include "services/p3service.h"
|
||||
#include "pqi/p3cfgmgr.h"
|
||||
#include "retroshare/rstypes.h"
|
||||
|
||||
#include "groutertypes.h"
|
||||
#include "groutermatrix.h"
|
||||
#include "groutercache.h"
|
||||
#include "grouteritems.h"
|
||||
//#include "groutercache.h"
|
||||
|
||||
// To be put in pqi/p3cfgmgr.h
|
||||
//
|
||||
|
@ -75,9 +76,7 @@ class p3GRouter: public RsGRouter, public p3Service, public p3Config
|
|||
// Unregistering a key might not have an instantaneous effect, so the client is responsible for
|
||||
// discarding traffic that might later come for this key.
|
||||
//
|
||||
bool registerKey(const GRouterKeyId& key,const PGPFingerprintType& pgp_fingerprint,
|
||||
const GRouterServiceId& client_id,const std::string& description_string) ;
|
||||
|
||||
bool registerKey(const GRouterKeyId& key, const GRouterServiceId& client_id,const std::string& description_string) ;
|
||||
bool unregisterKey(const GRouterKeyId& key) ;
|
||||
|
||||
//===================================================//
|
||||
|
@ -103,7 +102,7 @@ class p3GRouter: public RsGRouter, public p3Service, public p3Config
|
|||
// - list of clues/time_stamp for each key.
|
||||
// - real time routing probabilities
|
||||
//
|
||||
virtual bool getRoutingMatrixInfo(RoutingMatrixInfo& info) { return false ;}
|
||||
virtual bool getRoutingMatrixInfo(GRouterRoutingMatrixInfo& info) ;
|
||||
|
||||
// debug info from routing cache
|
||||
// - Cache Items
|
||||
|
@ -113,8 +112,21 @@ class p3GRouter: public RsGRouter, public p3Service, public p3Config
|
|||
// * message type
|
||||
// - Cache state (memory size, etc)
|
||||
//
|
||||
virtual bool getRoutingCacheInfo(RoutingCacheInfo& info) { return false ;}
|
||||
virtual bool getRoutingCacheInfo(std::vector<GRouterRoutingCacheInfo>& info) ;
|
||||
|
||||
//===================================================//
|
||||
// Derived from p3Service //
|
||||
//===================================================//
|
||||
|
||||
virtual RsServiceInfo getServiceInfo()
|
||||
{
|
||||
return RsServiceInfo(RS_SERVICE_TYPE_GROUTER,
|
||||
SERVICE_INFO_APP_NAME,
|
||||
SERVICE_INFO_APP_MAJOR_VERSION,
|
||||
SERVICE_INFO_APP_MINOR_VERSION,
|
||||
SERVICE_INFO_MIN_MAJOR_VERSION,
|
||||
SERVICE_INFO_MIN_MINOR_VERSION) ;
|
||||
}
|
||||
protected:
|
||||
//===================================================//
|
||||
// Routing method handling //
|
||||
|
@ -127,6 +139,12 @@ class p3GRouter: public RsGRouter, public p3Service, public p3Config
|
|||
//
|
||||
virtual int tick() ;
|
||||
|
||||
static const std::string SERVICE_INFO_APP_NAME ;
|
||||
static const uint16_t SERVICE_INFO_APP_MAJOR_VERSION = 1;
|
||||
static const uint16_t SERVICE_INFO_APP_MINOR_VERSION = 0;
|
||||
static const uint16_t SERVICE_INFO_MIN_MAJOR_VERSION = 1;
|
||||
static const uint16_t SERVICE_INFO_MIN_MINOR_VERSION = 0;
|
||||
|
||||
private:
|
||||
void autoWash() ;
|
||||
void routePendingObjects() ;
|
||||
|
@ -135,6 +153,12 @@ class p3GRouter: public RsGRouter, public p3Service, public p3Config
|
|||
void debugDump() ;
|
||||
void locked_forwardKey(const RsGRouterPublishKeyItem&) ;
|
||||
|
||||
// utility functions
|
||||
//
|
||||
static uint32_t computeBranchingFactor(const std::vector<RsPeerId>& friends,const std::vector<float>& probas,uint32_t dist) ;
|
||||
static std::set<uint32_t> computeRoutingFriends(const std::vector<RsPeerId>& friends,const std::vector<float>& probas,uint32_t N) ;
|
||||
static uint32_t computeRandomDistanceIncrement(const RsPeerId& pid,const GRouterKeyId& destination_id) ;
|
||||
|
||||
//===================================================//
|
||||
// p3Config methods //
|
||||
//===================================================//
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
/*
|
||||
* libretroshare/src/services: rsgrouter.h
|
||||
*
|
||||
* Services for RetroShare.
|
||||
*
|
||||
* Copyright 2013 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
|
||||
* License Version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA.
|
||||
*
|
||||
* Please report all bugs and problems to "csoler@users.sourceforge.net".
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "util/rsdir.h"
|
||||
#include "grouter/groutertypes.h"
|
||||
|
||||
typedef Sha1CheckSum GRouterKeyId ; // we use sha1. Gives sufficient entropy.
|
||||
class GRouterClientService ;
|
||||
class RsGRouterGenericDataItem ;
|
||||
|
||||
// This is the interface file for the global router service.
|
||||
//
|
||||
struct RoutingCacheInfo
|
||||
{
|
||||
// what do we want to show here?
|
||||
// - recently routed items
|
||||
// - ongoing routing info
|
||||
// - pending items, waiting for an answer
|
||||
// -
|
||||
};
|
||||
|
||||
struct RoutingMatrixInfo
|
||||
{
|
||||
// Probabilities of reaching a given key for each friend.
|
||||
// This concerns all known keys.
|
||||
//
|
||||
std::map<GRouterKeyId, std::vector<float> > per_friend_probabilities ;
|
||||
|
||||
// List of own published keys, with associated service ID
|
||||
//
|
||||
std::map<GRouterKeyId, GRouterClientService *> published_keys ;
|
||||
};
|
||||
|
||||
class RsGRouter
|
||||
{
|
||||
public:
|
||||
//===================================================//
|
||||
// Debugging info //
|
||||
//===================================================//
|
||||
|
||||
virtual bool getRoutingCacheInfo(RoutingCacheInfo& info) =0;
|
||||
virtual bool getRoutingMatrixInfo(RoutingMatrixInfo& info) =0;
|
||||
|
||||
// retrieve the routing probabilities
|
||||
|
||||
//===================================================//
|
||||
// Communication to other services. //
|
||||
//===================================================//
|
||||
|
||||
virtual void sendData(const GRouterKeyId& destination, RsGRouterGenericDataItem *item) =0;
|
||||
virtual bool registerKey(const GRouterKeyId& key,const PGPFingerprintType& fps,const GRouterServiceId& client_id,const std::string& description_string) =0;
|
||||
|
||||
};
|
||||
|
||||
// To access the GRouter from anywhere
|
||||
//
|
||||
extern RsGRouter *rsGRouter ;
|
Loading…
Add table
Add a link
Reference in a new issue