added routing methods for data in grouter.

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6961 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2013-12-24 16:41:07 +00:00
parent beedc07de8
commit 7edfa21ffd
5 changed files with 89 additions and 17 deletions

View file

@ -45,4 +45,4 @@ static const time_t RS_GROUTER_PUBLISH_KEY_TIME_INTERVAL = 2 *60 ; // Adverti
static const uint32_t RS_GROUTER_ROUTING_STATE_UNKN = 0x0000 ; // unknown. Unused. 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_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_SENT = 0x0002 ; // item is sent. Waiting for answer
static const uint32_t RS_GROUTER_ROUTING_STATE_OWND = 0x0003 ; // item is origined here. Needed for retry policy. static const uint32_t RS_GROUTER_ROUTING_STATE_ARVD = 0x0003 ; // item is at destination. The cache only holds it to avoid duplication.

View file

@ -30,6 +30,7 @@
#include "p3grouter.h" #include "p3grouter.h"
#include "grouteritems.h" #include "grouteritems.h"
#include "groutertypes.h" #include "groutertypes.h"
#include "grouterclientservice.h"
static const uint32_t RS_GROUTER_ROUTING_WAITING_TIME = 3600 ; // time between two trial of sending a message static const uint32_t RS_GROUTER_ROUTING_WAITING_TIME = 3600 ; // time between two trial of sending a message
@ -223,14 +224,14 @@ void p3GRouter::routePendingObjects()
ftr.time_stamp = now ; ftr.time_stamp = now ;
ftr.friend_id = routed_friend ; ftr.friend_id = routed_friend ;
it->second.tried_friends.push_front(ftr) ; it->second.tried_friends.push_front(ftr) ;
it->second.status_flags |= RS_GROUTER_ROUTING_STATE_SENT ; it->second.status_flags = RS_GROUTER_ROUTING_STATE_SENT ;
std::cerr << " Sending..." << std::endl; std::cerr << " Sending..." << std::endl;
// send // send
new_item->PeerId(routed_friend.toStdString()) ; new_item->PeerId(routed_friend.toStdString()) ;
sendItem(new_item) ; sendItem(new_item) ;
} }
else if(!(it->second.status_flags & RS_GROUTER_ROUTING_STATE_OWND) || std::find(lst.begin(),lst.end(),it->second.origin) != lst.end()) else if(it->second.origin.toStdString() != 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, // 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. // we discard it. For now, the procedure is to send back an ACK.
@ -423,7 +424,7 @@ void p3GRouter::handleRecvACKItem(RsGRouterACKItem *item)
break ; break ;
} }
if(it->second.status_flags & RS_GROUTER_ROUTING_STATE_OWND) if(it->second.origin.toStdString() == mLinkMgr->getOwnId())
{ {
// find the client service and notify it. // find the client service and notify it.
std::cerr << " We're owner: should notify client id" << std::endl; std::cerr << " We're owner: should notify client id" << std::endl;
@ -437,20 +438,89 @@ void p3GRouter::handleRecvACKItem(RsGRouterACKItem *item)
void p3GRouter::handleRecvDataItem(RsGRouterGenericDataItem *item) void p3GRouter::handleRecvDataItem(RsGRouterGenericDataItem *item)
{ {
std::cerr << "Received data item from key " << item->destination_key.toStdString() << std::endl; std::cerr << "Received data item for key " << item->destination_key.toStdString() << std::endl;
// update the local cache // Do we have this item in the cache already?
// 1 - do we have a sensible route for the item? // - if not, add in the pending items
// // - if yet. Ignore, or send ACK for shorter route.
// 1.1 - select the best guess, send the item
// 1.2 - keep track of origin and update list of tried directions 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) ;
// 2 - no route. Keep the item for a while. Will be retried later. RsGRouterGenericDataItem *item_copy = NULL;
if(itr != _pending_messages.end())
{
std::cerr << " Item is already there. Nothing to do. Should we update the cache?" << std::endl;
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.
{
std::cerr << " Item is new. Storing in cache as pending messages." << std::endl;
GRouterRoutingInfo info ;
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 = SSLIdType(item->PeerId()) ;
info.received_time = time(NULL) ;
_pending_messages[item->routing_id] = info ;
}
// 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)
{
// test validity time. If too old, we don't forward.
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) ;
}
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;
} }
void p3GRouter::sendData(const GRouterKeyId& destination, void *& item_data,uint32_t item_size) void p3GRouter::sendData(const GRouterKeyId& destination, RsGRouterGenericDataItem *item)
{ {
std::cerr << "(WW) " << __PRETTY_FUNCTION__ << ": not implemented." << std::endl; // push the item into pending messages.
//
GRouterRoutingInfo info ;
info.data_item = item ;
info.status_flags = RS_GROUTER_ROUTING_STATE_PEND ;
info.origin = SSLIdType(mLinkMgr->getOwnId()) ;
info.received_time = time(NULL) ;
// 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()) ;
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 << " status = " << info.status_flags << std::endl;
std::cerr << " origin = " << info.origin.toStdString() << std::endl;
std::cerr << " Recv time = " << info.received_time << std::endl;
_pending_messages[propagation_id] = info ;
} }
void p3GRouter::sendACK(const SSLIdType& peer, GRouterMsgPropagationId mid, uint32_t ack_flags) void p3GRouter::sendACK(const SSLIdType& peer, GRouterMsgPropagationId mid, uint32_t ack_flags)

View file

@ -103,7 +103,7 @@ class p3GRouter: public RsGRouter, public p3Service, public p3Config
// Sends an item to the given destination. The router takes ownership of // Sends an item to the given destination. The router takes ownership of
// the memory. That means item_data will be erase on return. // the memory. That means item_data will be erase on return.
// //
void sendData(const GRouterKeyId& destination, void *& item_data,uint32_t item_size) ; void sendData(const GRouterKeyId& destination, RsGRouterGenericDataItem *item) ;
// Sends an ACK to the origin of the msg. This is used to notify for // Sends an ACK to the origin of the msg. This is used to notify for
// unfound route, or message correctly received, depending on the particular situation. // unfound route, or message correctly received, depending on the particular situation.

View file

@ -30,6 +30,7 @@
typedef Sha1CheckSum GRouterKeyId ; // we use sha1. Gives sufficient entropy. typedef Sha1CheckSum GRouterKeyId ; // we use sha1. Gives sufficient entropy.
class GRouterClientService ; class GRouterClientService ;
class RsGRouterGenericDataItem ;
// This is the interface file for the global router service. // This is the interface file for the global router service.
// //
@ -70,7 +71,7 @@ class RsGRouter
// Communication to other services. // // Communication to other services. //
//===================================================// //===================================================//
virtual void sendData(const GRouterKeyId& destination, void *& item_data,uint32_t item_size) =0; virtual void sendData(const GRouterKeyId& destination, RsGRouterGenericDataItem *item) =0;
virtual bool registerKey(const GRouterKeyId& key,const GRouterServiceId& client_id,const std::string& description_string) =0; virtual bool registerKey(const GRouterKeyId& key,const GRouterServiceId& client_id,const std::string& description_string) =0;
}; };

View file

@ -24,6 +24,7 @@
*/ */
#include <iostream> #include <iostream>
#include <math.h>
#include "util/rsrandom.h" #include "util/rsrandom.h"
#include "grouter/grouteritems.h" #include "grouter/grouteritems.h"
@ -81,7 +82,7 @@ bool operator ==(const RsGRouterPublishKeyItem& cmiLeft,const RsGRouterPublishK
if(cmiLeft.diffusion_id != cmiRight.diffusion_id) return false; if(cmiLeft.diffusion_id != cmiRight.diffusion_id) return false;
if(!(cmiLeft.published_key == cmiRight.published_key)) return false; if(!(cmiLeft.published_key == cmiRight.published_key)) return false;
if(cmiLeft.service_id != cmiRight.service_id) return false; if(cmiLeft.service_id != cmiRight.service_id) return false;
// if(cmiLeft.randomized_distance != cmiRight.randomized_distance) return false; if(fabs(cmiLeft.randomized_distance - cmiRight.randomized_distance) > 0.001) return false;
if(cmiLeft.description_string != cmiRight.description_string) return false; if(cmiLeft.description_string != cmiRight.description_string) return false;
return true ; return true ;