fixed gui bits. Improved message handlign logic and notification

git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.6-NewGRouterModel@7854 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2015-01-22 14:33:19 +00:00
parent 15fd4d787a
commit 1998ddd765
11 changed files with 266 additions and 161 deletions

View file

@ -36,6 +36,10 @@
class RsItem ; class RsItem ;
static const uint32_t GROUTER_CLIENT_SERVICE_DATA_STATUS_UNKNOWN = 0x0000 ; // unused.
static const uint32_t GROUTER_CLIENT_SERVICE_DATA_STATUS_RECEIVED = 0x0001 ; // sent when data has been received and a receipt is available.
static const uint32_t GROUTER_CLIENT_SERVICE_DATA_STATUS_FAILED = 0x0002 ; // sent if the global router cannot send after a while
class GRouterClientService class GRouterClientService
{ {
public: public:
@ -55,12 +59,13 @@ class GRouterClientService
std::cerr << " destination key_id = " << destination_key.toStdString() << std::endl; std::cerr << " destination key_id = " << destination_key.toStdString() << std::endl;
} }
// This method is called by the global router when a message has been acknowledged, in order to notify the client. // This method is called by the global router when a message has been received, or cannot be sent, etc.
// //
virtual void acknowledgeDataReceived(const GRouterMsgPropagationId& received_id) virtual void notifyDataStatus(const GRouterMsgPropagationId& received_id,uint32_t data_status)
{ {
std::cerr << "!!!!!! Received Data acknowledge from global router, but the client service is not handling it !!!!!!!!!!" << std::endl ; std::cerr << "!!!!!! Received Data status from global router, but the client service is not handling it !!!!!!!!!!" << std::endl ;
std::cerr << " message ID = " << received_id << std::endl; std::cerr << " message ID = " << received_id << std::endl;
std::cerr << " data status = " << data_status << std::endl;
} }
// This function is mandatory. It should do two things: // This function is mandatory. It should do two things:

View file

@ -194,6 +194,8 @@ RsGRouterRoutingInfoItem *RsGRouterSerialiser::deserialise_RsGRouterRoutingInfoI
ok &= getRawUInt32(data, pktsize, &offset, &item->tunnel_status); ok &= getRawUInt32(data, pktsize, &offset, &item->tunnel_status);
ok &= getRawTimeT(data, pktsize, &offset, item->received_time_TS); ok &= getRawTimeT(data, pktsize, &offset, item->received_time_TS);
ok &= getRawTimeT(data, pktsize, &offset, item->last_sent_TS); ok &= getRawTimeT(data, pktsize, &offset, item->last_sent_TS);
ok &= getRawTimeT(data, pktsize, &offset, item->last_tunnel_request_TS);
ok &= getRawUInt32(data, pktsize, &offset, &item->sending_attempts); ok &= getRawUInt32(data, pktsize, &offset, &item->sending_attempts);
ok &= getRawUInt32(data, pktsize, &offset, &item->client_id); ok &= getRawUInt32(data, pktsize, &offset, &item->client_id);
@ -205,11 +207,16 @@ RsGRouterRoutingInfoItem *RsGRouterSerialiser::deserialise_RsGRouterRoutingInfoI
else else
ok = false ; ok = false ;
// receipt item is optional.
if(offset < pktsize)
{
item->receipt_item = deserialise_RsGRouterSignedReceiptItem(&((uint8_t*)data)[offset],pktsize - offset) ; item->receipt_item = deserialise_RsGRouterSignedReceiptItem(&((uint8_t*)data)[offset],pktsize - offset) ;
if(item->receipt_item != NULL) if(item->receipt_item != NULL)
offset += item->receipt_item->serial_size() ; offset += item->receipt_item->serial_size() ;
else else
ok = false ; ok = false ;
}
if (offset != rssize || !ok) if (offset != rssize || !ok)
@ -278,25 +285,29 @@ RsGRouterMatrixCluesItem *RsGRouterSerialiser::deserialise_RsGRouterMatrixCluesI
return item; return item;
} }
RsGRouterGenericDataItem *RsGRouterGenericDataItem::duplicate() const RsGRouterGenericDataItem *RsGRouterGenericDataItem::duplicate() const
{ {
RsGRouterGenericDataItem *item = new RsGRouterGenericDataItem ; RsGRouterGenericDataItem *item = new RsGRouterGenericDataItem ;
item->routing_id = routing_id ; // copy all members
item->destination_key = destination_key ;
item->data_size = data_size ; *item = *this ;
// then duplicate the memory chunk // then duplicate the memory chunk
item->data_bytes = (uint8_t*)malloc(data_size) ; item->data_bytes = (uint8_t*)malloc(data_size) ;
memcpy(item->data_bytes,data_bytes,data_size) ; memcpy(item->data_bytes,data_bytes,data_size) ;
item->signature = signature ; return item ;
}
item->randomized_distance = randomized_distance ; RsGRouterSignedReceiptItem *RsGRouterSignedReceiptItem::duplicate() const
item->flags = flags ; {
RsGRouterSignedReceiptItem *item = new RsGRouterSignedReceiptItem ;
// copy all members
*item = *this ;
return item ; return item ;
} }
@ -525,10 +536,12 @@ uint32_t RsGRouterRoutingInfoItem::serial_size() const
{ {
uint32_t s = 8 ; // header uint32_t s = 8 ; // header
s += PeerId().serial_size() ; s += PeerId().serial_size() ;
s += 4 ; // data status_flags s += 4 ; // data status_flags
s += 4 ; // tunnel status_flags s += 4 ; // tunnel status_flags
s += 8 ; // received_time s += 8 ; // received_time
s += 8 ; // last_sent s += 8 ; // last_sent
s += 8 ; // last_TR_TS s += 8 ; // last_TR_TS
s += 4 ; // sending attempts s += 4 ; // sending attempts
@ -536,6 +549,8 @@ uint32_t RsGRouterRoutingInfoItem::serial_size() const
s += tunnel_hash.serial_size() ; s += tunnel_hash.serial_size() ;
s += data_item->serial_size(); // data_item s += data_item->serial_size(); // data_item
if(receipt_item != NULL)
s += receipt_item->serial_size(); // receipt_item s += receipt_item->serial_size(); // receipt_item
return s ; return s ;

View file

@ -77,7 +77,7 @@ class RsGRouterNonCopyableObject
{ {
public: public:
RsGRouterNonCopyableObject() {} RsGRouterNonCopyableObject() {}
private: protected:
RsGRouterNonCopyableObject(const RsGRouterNonCopyableObject&) {} RsGRouterNonCopyableObject(const RsGRouterNonCopyableObject&) {}
RsGRouterNonCopyableObject operator=(const RsGRouterNonCopyableObject&) { return *this ;} RsGRouterNonCopyableObject operator=(const RsGRouterNonCopyableObject&) { return *this ;}
}; };
@ -145,6 +145,8 @@ class RsGRouterSignedReceiptItem: public RsGRouterAbstractMsgItem
virtual void clear() {} virtual void clear() {}
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0) ; virtual std::ostream& print(std::ostream &out, uint16_t indent = 0) ;
RsGRouterSignedReceiptItem *duplicate() const ;
// packet data // packet data
// //
Sha1CheckSum data_hash ; // avoids an attacker to re-use a given signed receipt. This is the hash of the enceypted data. Sha1CheckSum data_hash ; // avoids an attacker to re-use a given signed receipt. This is the hash of the enceypted data.
@ -237,9 +239,11 @@ class RsGRouterRoutingInfoItem: public RsGRouterItem, public GRouterRoutingInfo,
virtual void clear() virtual void clear()
{ {
if(data_item != NULL) if(data_item != NULL) delete data_item ;
delete data_item ; if(receipt_item != NULL) delete receipt_item ;
data_item = NULL ; data_item = NULL ;
receipt_item = NULL ;
} }
virtual std::ostream& print(std::ostream &out, uint16_t indent = 0) ; virtual std::ostream& print(std::ostream &out, uint16_t indent = 0) ;
}; };

View file

@ -80,7 +80,15 @@ class FriendTrialRecord
class GRouterRoutingInfo class GRouterRoutingInfo
{ {
// There's no destructor to this class, because the memory is managed elsewhere, which
// ovoids lots of duplications if the class is copied.
public: public:
GRouterRoutingInfo()
{
data_item = NULL ;
receipt_item = NULL ;
}
uint32_t data_status ; // pending, waiting, etc. uint32_t data_status ; // pending, waiting, etc.
uint32_t tunnel_status ; // status of tunnel handling. uint32_t tunnel_status ; // status of tunnel handling.
time_t received_time_TS ; // time at which the item was originally received time_t received_time_TS ; // time at which the item was originally received

View file

@ -200,9 +200,9 @@
//#define GROUTER_DEBUG //#define GROUTER_DEBUG
/**********************/ /**********************/
#define GROUTER_DEBUG #define GROUTER_DEBUG
#define NOT_IMPLEMENTED std::cerr << __PRETTY_FUNCTION__ << ": not implemented!" << std::endl;
static const uint32_t MAX_TUNNEL_WAIT_TIME = 60 ; // wait for 60 seconds at most for a tunnel response. static const uint32_t MAX_TUNNEL_WAIT_TIME = 60 ; // wait for 60 seconds at most for a tunnel response.
static const uint32_t MAX_TUNNEL_UNMANAGED_TIME = 600 ; // min time before retry tunnels for that msg.
static const uint32_t MAX_DELAY_BETWEEN_TWO_SEND = 120 ; // wait for 120 seconds before re-sending. static const uint32_t MAX_DELAY_BETWEEN_TWO_SEND = 120 ; // wait for 120 seconds before re-sending.
static const uint32_t TUNNEL_OK_WAIT_TIME = 10 ; // wait for 10 seconds after last tunnel ok, so that we have a complete set of tunnels. static const uint32_t TUNNEL_OK_WAIT_TIME = 10 ; // wait for 10 seconds after last tunnel ok, so that we have a complete set of tunnels.
static const uint32_t MAX_GROUTER_DATA_SIZE = 2*1024*1024 ; // 2MB size limit. This is of course arbitrary. static const uint32_t MAX_GROUTER_DATA_SIZE = 2*1024*1024 ; // 2MB size limit. This is of course arbitrary.
@ -305,6 +305,9 @@ RsSerialiser *p3GRouter::setupSerialiser()
} }
void p3GRouter::autoWash() void p3GRouter::autoWash()
{
std::map<GRouterMsgPropagationId,GRouterClientService *> cancelled_msgs ;
{ {
RsStackMutex mtx(grMtx) ; RsStackMutex mtx(grMtx) ;
@ -322,6 +325,16 @@ void p3GRouter::autoWash()
#ifdef GROUTER_DEBUG #ifdef GROUTER_DEBUG
grouter_debug() << " Removing cached item " << std::hex << it->first << std::dec << std::endl; grouter_debug() << " Removing cached item " << std::hex << it->first << std::dec << std::endl;
#endif #endif
GRouterClientService *client = NULL ;
GRouterServiceId service_id = 0;
if(!locked_getClientAndServiceId(it->second.tunnel_hash,it->second.data_item->destination_key,client,service_id))
{
std::cerr << " ERROR: cannot find client for cancelled message " << it->first << std::endl;
}
else
cancelled_msgs[it->first] = client ;
delete it->second.data_item ; delete it->second.data_item ;
std::map<GRouterMsgPropagationId,GRouterRoutingInfo>::iterator tmp(it) ; std::map<GRouterMsgPropagationId,GRouterRoutingInfo>::iterator tmp(it) ;
++tmp ; ++tmp ;
@ -338,6 +351,10 @@ void p3GRouter::autoWash()
#endif #endif
} }
for(std::map<GRouterMsgPropagationId,GRouterClientService*>::const_iterator it(cancelled_msgs.begin());it!=cancelled_msgs.end();++it)
it->second->notifyDataStatus(it->first, GROUTER_CLIENT_SERVICE_DATA_STATUS_FAILED) ;
}
bool p3GRouter::registerKey(const RsGxsId& authentication_key,const GRouterServiceId& client_id,const std::string& description) bool p3GRouter::registerKey(const RsGxsId& authentication_key,const GRouterServiceId& client_id,const std::string& description)
{ {
RS_STACK_MUTEX(grMtx) ; RS_STACK_MUTEX(grMtx) ;
@ -402,15 +419,11 @@ bool p3GRouter::handleTunnelRequest(const RsFileHash& hash,const RsPeerId& /*pee
// - we know the destination and have a route (according to matrix) => accept with high probability // - we know the destination and have a route (according to matrix) => accept with high probability
// - we don't know the destination => accept with very low probability // - we don't know the destination => accept with very low probability
#ifdef GROUTER_DEBUG
std::cerr << "p3GRouter::handleTunnelRequest(). Got req for hash " << hash << ", responding OK" << std::endl;
#endif
if(_owned_key_ids.find(hash) == _owned_key_ids.end()) if(_owned_key_ids.find(hash) == _owned_key_ids.end())
return false ; return false ;
#ifdef GROUTER_DEBUG #ifdef GROUTER_DEBUG
std::cerr << " responding ok." << std::endl; std::cerr << "p3GRouter::handleTunnelRequest(). Got req for hash " << hash << ", responding OK" << std::endl;
#endif #endif
return true ; return true ;
} }
@ -750,12 +763,14 @@ if(!_pending_messages.empty())
for(std::map<GRouterMsgPropagationId, GRouterRoutingInfo>::iterator it=_pending_messages.begin();it!=_pending_messages.end();++it) for(std::map<GRouterMsgPropagationId, GRouterRoutingInfo>::iterator it=_pending_messages.begin();it!=_pending_messages.end();++it)
{ {
#ifdef GROUTER_DEBUG #ifdef GROUTER_DEBUG
grouter_debug() << " " << std::hex << it->first << std::dec << " data_status=" << it->second.data_status << ", tunnel_status=" << it->second.tunnel_status; grouter_debug() << " " << std::hex << it->first << std::dec
<< " data_status=" << it->second.data_status << ", tunnel_status=" << it->second.tunnel_status
<< " last tried: "<< now - it->second.last_tunnel_request_TS << " (secs ago)" << ", last sent: " << now - it->second.last_sent_TS << " (secs ago) " ;
#endif #endif
if(it->second.data_status == RS_GROUTER_DATA_STATUS_PENDING) if(it->second.data_status == RS_GROUTER_DATA_STATUS_PENDING)
{ {
if(it->second.tunnel_status == RS_GROUTER_TUNNEL_STATUS_UNMANAGED) if(it->second.tunnel_status == RS_GROUTER_TUNNEL_STATUS_UNMANAGED && it->second.last_tunnel_request_TS + MAX_TUNNEL_UNMANAGED_TIME < now)
{ {
uint32_t item_delay = now - it->second.last_tunnel_request_TS ; uint32_t item_delay = now - it->second.last_tunnel_request_TS ;
int item_priority = item_delay - send_retry_time_delays[std::min(5u,it->second.sending_attempts)] ; int item_priority = item_delay - send_retry_time_delays[std::min(5u,it->second.sending_attempts)] ;
@ -786,6 +801,13 @@ if(!_pending_messages.empty())
grouter_debug() << std::endl; grouter_debug() << std::endl;
#endif #endif
} }
else if(it->second.data_status == RS_GROUTER_DATA_STATUS_RECEIPT_OK)
{
#ifdef GROUTER_DEBUG
std::cerr << " closing pending tunnels." << std::endl;
#endif
mTurtle->stopMonitoringTunnels(it->second.tunnel_hash) ;
}
#ifdef GROUTER_DEBUG #ifdef GROUTER_DEBUG
else else
std::cerr << " doing nothing." << std::endl; std::cerr << " doing nothing." << std::endl;
@ -823,12 +845,12 @@ void p3GRouter::routePendingObjects()
time_t now = time(NULL) ; time_t now = time(NULL) ;
#ifdef GROUTER_DEBUG #ifdef GROUTER_DEBUG
if(!_pending_messages.empty())
std::cerr << "p3GRouter::routePendingObjects()" << std::endl; std::cerr << "p3GRouter::routePendingObjects()" << std::endl;
#endif #endif
for(std::map<GRouterMsgPropagationId, GRouterRoutingInfo>::iterator it=_pending_messages.begin();it!=_pending_messages.end();++it) for(std::map<GRouterMsgPropagationId, GRouterRoutingInfo>::iterator it=_pending_messages.begin();it!=_pending_messages.end();++it)
if(it->second.data_status == RS_GROUTER_DATA_STATUS_PENDING && it->second.tunnel_status == RS_GROUTER_TUNNEL_STATUS_READY if(it->second.data_status == RS_GROUTER_DATA_STATUS_PENDING && it->second.tunnel_status == RS_GROUTER_TUNNEL_STATUS_READY && now > it->second.last_sent_TS + MAX_DELAY_BETWEEN_TWO_SEND)
&& now > it->second.last_sent_TS + MAX_DELAY_BETWEEN_TWO_SEND)
{ {
#ifdef GROUTER_DEBUG #ifdef GROUTER_DEBUG
std::cerr << " routing id: " << std::hex << it->first << std::dec ; std::cerr << " routing id: " << std::hex << it->first << std::dec ;
@ -987,6 +1009,7 @@ void p3GRouter::handleIncoming(const TurtleFileHash& hash,RsGRouterAbstractMsgIt
void p3GRouter::handleIncomingReceiptItem(const TurtleFileHash& hash,RsGRouterSignedReceiptItem *receipt_item) void p3GRouter::handleIncomingReceiptItem(const TurtleFileHash& hash,RsGRouterSignedReceiptItem *receipt_item)
{ {
bool changed = false ;
#ifdef GROUTER_DEBUG #ifdef GROUTER_DEBUG
std::cerr << "Handling incoming signed receipt item." << std::endl; std::cerr << "Handling incoming signed receipt item." << std::endl;
std::cerr << "Item content:" << std::endl; std::cerr << "Item content:" << std::endl;
@ -1032,27 +1055,35 @@ void p3GRouter::handleIncomingReceiptItem(const TurtleFileHash& hash,RsGRouterSi
//delete it->second.receipt_item ; //delete it->second.receipt_item ;
_pending_messages.erase(it) ; _pending_messages.erase(it) ;
//it->second.data_status = RS_GROUTER_DATA_STATUS_RECEIPT_OK; it->second.data_status = RS_GROUTER_DATA_STATUS_RECEIPT_OK;
changed = true ;
//it->second.receipt_item = signed_receipt_item ; //it->second.receipt_item = signed_receipt_item ;
} }
#ifdef GROUTER_DEBUG #ifdef GROUTER_DEBUG
std::cerr << " notifying client that the msg was received." << std::endl; std::cerr << " notifying client that the msg was received." << std::endl;
#endif #endif
if(changed)
IndicateConfigChanged() ;
GRouterClientService *client = NULL ; GRouterClientService *client = NULL ;
GRouterServiceId service_id = 0; GRouterServiceId service_id = 0;
if(!getClientAndServiceId(hash,receipt_item->signature.keyId,client,service_id)) {
RS_STACK_MUTEX (grMtx) ;
if(!locked_getClientAndServiceId(hash,receipt_item->signature.keyId,client,service_id))
{ {
std::cerr << " ERROR: cannot find client service for this hash/key combination." << std::endl; std::cerr << " ERROR: cannot find client service for this hash/key combination." << std::endl;
return ; return ;
} }
}
#ifdef GROUTER_DEBUG #ifdef GROUTER_DEBUG
std::cerr << " retrieved client " << (void*)client << ", service_id=" << std::hex << service_id << std::dec << std::endl; std::cerr << " retrieved client " << (void*)client << ", service_id=" << std::hex << service_id << std::dec << std::endl;
std::cerr << " acknowledging client for data received" << std::endl; std::cerr << " acknowledging client for data received" << std::endl;
#endif #endif
client->acknowledgeDataReceived(receipt_item->routing_id) ; client->notifyDataStatus(receipt_item->routing_id,GROUTER_CLIENT_SERVICE_DATA_STATUS_RECEIVED) ;
} }
void p3GRouter::handleIncomingDataItem(const TurtleFileHash& hash,RsGRouterGenericDataItem *generic_item) void p3GRouter::handleIncomingDataItem(const TurtleFileHash& hash,RsGRouterGenericDataItem *generic_item)
@ -1066,11 +1097,15 @@ void p3GRouter::handleIncomingDataItem(const TurtleFileHash& hash,RsGRouterGener
GRouterClientService *client = NULL ; GRouterClientService *client = NULL ;
GRouterServiceId service_id = 0; GRouterServiceId service_id = 0;
if(!getClientAndServiceId(hash,generic_item->destination_key,client,service_id)) {
RS_STACK_MUTEX(grMtx) ;
if(!locked_getClientAndServiceId(hash,generic_item->destination_key,client,service_id))
{ {
std::cerr << " ERROR: cannot find client service for this hash/key combination." << std::endl; std::cerr << " ERROR: cannot find client service for this hash/key combination." << std::endl;
return ; return ;
} }
}
// We don't do proxy yet, so the item is necessarily for us. // We don't do proxy yet, so the item is necessarily for us.
// The item's signature must be checked, and the item needs to be decrypted. // The item's signature must be checked, and the item needs to be decrypted.
@ -1143,7 +1178,7 @@ void p3GRouter::handleIncomingDataItem(const TurtleFileHash& hash,RsGRouterGener
#endif #endif
} }
bool p3GRouter::getClientAndServiceId(const TurtleFileHash& hash, const RsGxsId& destination_key, GRouterClientService *& client, GRouterServiceId& service_id) bool p3GRouter::locked_getClientAndServiceId(const TurtleFileHash& hash, const RsGxsId& destination_key, GRouterClientService *& client, GRouterServiceId& service_id)
{ {
client = NULL ; client = NULL ;
service_id = 0; service_id = 0;
@ -1157,9 +1192,6 @@ bool p3GRouter::getClientAndServiceId(const TurtleFileHash& hash, const RsGxsId&
return false; return false;
} }
{
RS_STACK_MUTEX (grMtx) ;
// now find the client given its id. // now find the client given its id.
std::map<GRouterServiceId,GRouterClientService*>::const_iterator its = _registered_services.find(service_id) ; std::map<GRouterServiceId,GRouterClientService*>::const_iterator its = _registered_services.find(service_id) ;
@ -1171,7 +1203,6 @@ bool p3GRouter::getClientAndServiceId(const TurtleFileHash& hash, const RsGxsId&
} }
client = its->second ; client = its->second ;
}
return true ; return true ;
} }
@ -1352,7 +1383,7 @@ bool p3GRouter::verifySignedDataItem(RsGRouterAbstractMsgItem *item)
#ifdef GROUTER_DEBUG #ifdef GROUTER_DEBUG
std::cerr << " Validating signature for data hash: " << RsDirUtil::sha1sum(data,data_size) << " and key_id = " << item->signature.keyId << std::endl; std::cerr << " Validating signature for data hash: " << RsDirUtil::sha1sum(data,data_size) << " and key_id = " << item->signature.keyId << std::endl;
std::cerr << " First bytes of encrypted data: " << RsUtil::BinToHex((const char *)data,std::min(data_size,30u)) << "..."<< std::endl; std::cerr << " First bytes of signed data: " << RsUtil::BinToHex((const char *)data,std::min(data_size,30u)) << "..."<< std::endl;
#endif #endif
if(!GxsSecurity::validateSignature((char*)data,data_size,signature_key,item->signature)) if(!GxsSecurity::validateSignature((char*)data,data_size,signature_key,item->signature))
@ -1370,6 +1401,35 @@ bool p3GRouter::verifySignedDataItem(RsGRouterAbstractMsgItem *item)
} }
} }
bool p3GRouter::cancel(GRouterMsgPropagationId mid)
{
{
RS_STACK_MUTEX(grMtx) ;
#ifdef GROUTER_DEBUG
std::cerr << "p3GRouter::cancel(). Canceling message ID " << mid << std::endl;
#endif
std::map<GRouterMsgPropagationId,GRouterRoutingInfo>::iterator it = _pending_messages.find(mid) ;
if(it == _pending_messages.end())
{
std::cerr << " ERROR: message ID is unknown." << std::endl;
return false ;
}
delete it->second.data_item ;
if(it->second.receipt_item)
delete it->second.receipt_item;
_pending_messages.erase(it) ;
}
IndicateConfigChanged() ;
return true ;
}
bool p3GRouter::sendData(const RsGxsId& destination,const GRouterServiceId& client_id,uint8_t *data, uint32_t data_size,const RsGxsId& signing_id, GRouterMsgPropagationId &propagation_id) bool p3GRouter::sendData(const RsGxsId& destination,const GRouterServiceId& client_id,uint8_t *data, uint32_t data_size,const RsGxsId& signing_id, GRouterMsgPropagationId &propagation_id)
{ {
if(data_size > MAX_GROUTER_DATA_SIZE) if(data_size > MAX_GROUTER_DATA_SIZE)
@ -1454,6 +1514,8 @@ bool p3GRouter::sendData(const RsGxsId& destination,const GRouterServiceId& clie
RS_STACK_MUTEX(grMtx) ; RS_STACK_MUTEX(grMtx) ;
_pending_messages[propagation_id] = info ; _pending_messages[propagation_id] = info ;
} }
IndicateConfigChanged() ;
return true ; return true ;
} }
@ -1549,6 +1611,9 @@ bool p3GRouter::saveList(bool& cleanup,std::list<RsItem*>& items)
*(GRouterRoutingInfo*)item = it->second ; // copy all members *(GRouterRoutingInfo*)item = it->second ; // copy all members
item->data_item = it->second.data_item->duplicate() ; // deep copy, because we call delete on the object, and the item might be removed before we handle it in the client. item->data_item = it->second.data_item->duplicate() ; // deep copy, because we call delete on the object, and the item might be removed before we handle it in the client.
if(it->second.receipt_item != NULL)
item->receipt_item = it->second.receipt_item->duplicate() ;
items.push_back(item) ; items.push_back(item) ;
} }

View file

@ -123,12 +123,11 @@ public:
// remembered by the client, so that he knows when the data has been received. // remembered by the client, so that he knows when the data has been received.
// The client id is supplied so that the client can be notified when the data has been received. // The client id is supplied so that the client can be notified when the data has been received.
// //
virtual bool sendData( const RsGxsId& destination, virtual bool sendData(const RsGxsId& destination, const GRouterServiceId& client_id, uint8_t *data, uint32_t data_size, const RsGxsId& signing_id, GRouterMsgPropagationId& id) ;
const GRouterServiceId& client_id,
uint8_t *data, // Cancels a given sending order. If called too late, the message might already have left. But this will remove the item from the
uint32_t data_size, // re-try list.
const RsGxsId& signing_id, virtual bool cancel(GRouterMsgPropagationId mid) ;
GRouterMsgPropagationId& id) ;
//===================================================// //===================================================//
// Interface with RsGRouter // // Interface with RsGRouter //
@ -214,7 +213,7 @@ private:
void handleIncomingReceiptItem(const TurtleFileHash &hash, RsGRouterSignedReceiptItem *receipt_item) ; void handleIncomingReceiptItem(const TurtleFileHash &hash, RsGRouterSignedReceiptItem *receipt_item) ;
void handleIncomingDataItem(const TurtleFileHash &hash, RsGRouterGenericDataItem *data_item) ; void handleIncomingDataItem(const TurtleFileHash &hash, RsGRouterGenericDataItem *data_item) ;
bool getClientAndServiceId(const TurtleFileHash& hash, const RsGxsId& destination_key, GRouterClientService *& client, GRouterServiceId& service_id); bool locked_getClientAndServiceId(const TurtleFileHash& hash, const RsGxsId& destination_key, GRouterClientService *& client, GRouterServiceId& service_id);
// utility functions // utility functions

View file

@ -87,12 +87,8 @@ class RsGRouter
// Communication to other services. // // Communication to other services. //
//===================================================// //===================================================//
virtual bool sendData( const RsGxsId& destination, virtual bool sendData(const RsGxsId& destination, const GRouterServiceId& client_id, uint8_t *data, uint32_t data_size, const RsGxsId& signing_id, GRouterMsgPropagationId& id) =0;
const GRouterServiceId& client_id, virtual bool cancel(GRouterMsgPropagationId mid) =0;
uint8_t *data,
uint32_t data_size,
const RsGxsId& signing_id,
GRouterMsgPropagationId& id) =0;
virtual bool registerKey(const RsGxsId& authentication_id, const GRouterServiceId& client_id,const std::string& description_string)=0 ; virtual bool registerKey(const RsGxsId& authentication_id, const GRouterServiceId& client_id,const std::string& description_string)=0 ;

View file

@ -2155,8 +2155,19 @@ void p3MsgService::manageDistantPeers()
enableDistantMessaging(mDistantMessagingEnabled) ; enableDistantMessaging(mDistantMessagingEnabled) ;
} }
void p3MsgService::acknowledgeDataReceived(const GRouterMsgPropagationId& id) void p3MsgService::notifyDataStatus(const GRouterMsgPropagationId& id,uint32_t data_status)
{ {
if(data_status == GROUTER_CLIENT_SERVICE_DATA_STATUS_FAILED)
{
std::cerr << __PRETTY_FUNCTION__ << ": Not fully implemented. The global router fails to send apacket, but we don't deal with it. Please remind the devs to do it" << std::endl;
return ;
}
if(data_status != GROUTER_CLIENT_SERVICE_DATA_STATUS_RECEIVED)
{
std::cerr << "p3MsgService: unhandled data status info from global router for msg ID " << id << ": this is a bug." << std::endl;
return ;
}
RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/ RsStackMutex stack(mMsgMtx); /********** STACK LOCKED MTX ******/
#ifdef DEBUG_DISTANT_MSG #ifdef DEBUG_DISTANT_MSG
std::cerr << "p3MsgService::acknowledgeDataReceived(): acknowledging data received for msg propagation id " << id << std::endl; std::cerr << "p3MsgService::acknowledgeDataReceived(): acknowledging data received for msg propagation id " << id << std::endl;

View file

@ -137,7 +137,7 @@ class p3MsgService: public p3Service, public p3Config, public pqiServiceMonitor,
// Overloaded from GRouterClientService // Overloaded from GRouterClientService
virtual void receiveGRouterData(const RsGxsId& destination_key,const RsGxsId& signing_key, GRouterServiceId &client_id, uint8_t *data, uint32_t data_size) ; virtual void receiveGRouterData(const RsGxsId& destination_key,const RsGxsId& signing_key, GRouterServiceId &client_id, uint8_t *data, uint32_t data_size) ;
virtual void acknowledgeDataReceived(const GRouterMsgPropagationId& msg_id) ; virtual void notifyDataStatus(const GRouterMsgPropagationId& msg_id,uint32_t data_status) ;
// Utility functions // Utility functions

View file

@ -59,6 +59,8 @@ public:
void setDefaultId(RsGxsId defId) {mDefaultId=defId;} void setDefaultId(RsGxsId defId) {mDefaultId=defId;}
void setDefaultId(std::string defIdName) {mDefaultIdName=defIdName;} void setDefaultId(std::string defIdName) {mDefaultIdName=defIdName;}
bool hasAvailableIds() const { return !mDefaultId.isNull() ; }
bool setChosenId(RsGxsId &gxsId); bool setChosenId(RsGxsId &gxsId);
ChosenId_Ret getChosenId(RsGxsId &gxsId); ChosenId_Ret getChosenId(RsGxsId &gxsId);

View file

@ -2352,7 +2352,7 @@ void MessageComposer::addContact(enumType type)
std::list<RsGxsId> gxsIds ; std::list<RsGxsId> gxsIds ;
ui.friendSelectionWidget->selectedIds<RsGxsId,FriendSelectionWidget::IDTYPE_GXS>(gxsIds, false); ui.friendSelectionWidget->selectedIds<RsGxsId,FriendSelectionWidget::IDTYPE_GXS>(gxsIds, false);
if(!gxsIds.empty() && ui.respond_to_CB->count() == 0) if(!gxsIds.empty() && ui.respond_to_CB->hasAvailableIds())
{ {
QMessageBox::warning(NULL,tr("Cannot send distant messages"),tr("In order to send distant messages, you need an identity to sign with. Please go to the Identities tab and create one first.")); QMessageBox::warning(NULL,tr("Cannot send distant messages"),tr("In order to send distant messages, you need an identity to sign with. Please go to the Identities tab and create one first."));
return ; return ;