2007-12-11 20:43:17 -05:00
/*
* libretroshare / src / services : p3disc . cc
*
* Services for RetroShare .
*
* Copyright 2004 - 2008 by Robert Fernie .
*
* 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 " retroshare@lunamutt.com " .
*
*/
2010-08-06 05:40:23 -04:00
# include "retroshare/rsiface.h"
# include "retroshare/rsinit.h" /* for PGPSSL flag */
# include "retroshare/rspeers.h"
2007-12-11 20:43:17 -05:00
# include "services/p3disc.h"
2010-01-13 15:56:55 -05:00
# include "pqi/authssl.h"
2010-01-13 16:05:38 -05:00
# include "pqi/authgpg.h"
2008-01-25 02:49:28 -05:00
# include "pqi/p3connmgr.h"
2007-12-11 20:43:17 -05:00
# include <iostream>
# include <errno.h>
# include <cmath>
const uint32_t AUTODISC_LDI_SUBTYPE_PING = 0x01 ;
const uint32_t AUTODISC_LDI_SUBTYPE_RPLY = 0x02 ;
# include <sstream>
2008-02-26 11:52:50 -05:00
2008-07-10 12:29:18 -04:00
# include "util/rsdebug.h"
2008-02-26 11:52:50 -05:00
# include "util/rsprint.h"
2009-06-28 16:57:02 -04:00
# include "util/rsversion.h"
2007-12-11 20:43:17 -05:00
const int pqidisczone = 2482 ;
2010-02-23 16:55:29 -05:00
//static int convertTDeltaToTRange(double tdelta);
//static int convertTRangeToTDelta(int trange);
2007-12-11 20:43:17 -05:00
// Operating System specific includes.
# include "pqi/pqinetwork.h"
2008-02-03 01:29:02 -05:00
/* DISC FLAGS */
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
const uint32_t P3DISC_FLAGS_USE_DISC = 0x0001 ;
const uint32_t P3DISC_FLAGS_USE_DHT = 0x0002 ;
2008-12-23 11:23:54 -05:00
const uint32_t P3DISC_FLAGS_EXTERNAL_ADDR = 0x0004 ;
2008-02-28 10:58:54 -05:00
const uint32_t P3DISC_FLAGS_STABLE_UDP = 0x0008 ;
const uint32_t P3DISC_FLAGS_PEER_ONLINE = 0x0010 ;
const uint32_t P3DISC_FLAGS_OWN_DETAILS = 0x0020 ;
2008-12-23 11:23:54 -05:00
const uint32_t P3DISC_FLAGS_PEER_TRUSTS_ME = 0x0040 ;
2009-06-28 16:57:02 -04:00
const uint32_t P3DISC_FLAGS_ASK_VERSION = 0x0080 ;
2007-12-11 20:43:17 -05:00
2008-03-02 09:25:59 -05:00
/*****
* # define P3DISC_DEBUG 1
* * * */
2007-12-11 20:43:17 -05:00
2010-07-04 11:16:52 -04:00
//#define P3DISC_DEBUG 1
2008-02-04 16:40:34 -05:00
/*********** NOTE ***************
*
* Only need Mutexs for neighbours information
*/
2008-02-03 01:29:02 -05:00
/******************************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * NEW DISCOVERY * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-12-11 20:43:17 -05:00
2010-01-13 15:56:55 -05:00
p3disc : : p3disc ( p3ConnectMgr * cm , pqipersongrp * pqih )
2010-02-23 16:55:29 -05:00
: p3Service ( RS_SERVICE_TYPE_DISC ) ,
p3Config ( CONFIG_TYPE_P3DISC ) ,
mConnMgr ( cm ) ,
mPqiPersonGrp ( pqih )
2007-12-11 20:43:17 -05:00
{
2008-02-04 16:40:34 -05:00
RsStackMutex stack ( mDiscMtx ) ; /********** STACK LOCKED MTX ******/
2008-02-03 01:29:02 -05:00
addSerialType ( new RsDiscSerialiser ( ) ) ;
2010-01-15 16:09:25 -05:00
lastSentHeartbeatTime = time ( NULL ) ;
2009-07-31 14:31:26 -04:00
//add own version to versions map
2010-01-13 15:58:58 -05:00
versions [ AuthSSL : : getAuthSSL ( ) - > OwnId ( ) ] = RsUtil : : retroshareVersion ( ) ;
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
std : : cerr < < " p3disc::p3disc() setup " ;
std : : cerr < < std : : endl ;
# endif
2007-12-11 20:43:17 -05:00
return ;
}
int p3disc : : tick ( )
{
2009-12-22 05:41:19 -05:00
//send a heartbeat to all connected peers
2010-07-04 11:16:52 -04:00
if ( time ( NULL ) - lastSentHeartbeatTime > HEARTBEAT_REPEAT_TIME )
{
# ifdef P3DISC_DEBUG
2009-12-22 05:41:19 -05:00
std : : cerr < < " p3disc::tick() sending heartbeat to all peers " < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2009-12-22 05:41:19 -05:00
lastSentHeartbeatTime = time ( NULL ) ;
std : : list < std : : string > peers ;
mConnMgr - > getOnlineList ( peers ) ;
for ( std : : list < std : : string > : : const_iterator pit = peers . begin ( ) ; pit ! = peers . end ( ) ; + + pit ) {
sendHeartbeat ( * pit ) ;
}
}
2010-09-24 13:06:09 -04:00
2008-02-03 01:29:02 -05:00
return handleIncoming ( ) ;
2007-12-11 20:43:17 -05:00
}
2008-02-03 01:29:02 -05:00
int p3disc : : handleIncoming ( )
2007-12-11 20:43:17 -05:00
{
RsItem * item = NULL ;
2008-02-03 01:29:02 -05:00
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
std : : cerr < < " p3disc::handleIncoming() " < < std : : endl ;
# endif
2007-12-11 20:43:17 -05:00
// if off discard item.
2010-01-15 16:09:25 -05:00
peerConnectState detail ;
2010-07-04 11:16:52 -04:00
if ( ! mConnMgr - > getOwnNetStatus ( detail ) | | ( detail . visState & RS_VIS_STATE_NODISC ) )
{
2007-12-11 20:43:17 -05:00
while ( NULL ! = ( item = recvItem ( ) ) )
{
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
std : : cerr < < " p3disc::handleIncoming() Deleting - Cos RemoteDisc Off! " < < std : : endl ;
item - > print ( std : : cerr ) ;
std : : cerr < < std : : endl ;
# endif
2007-12-11 20:43:17 -05:00
delete item ;
}
return 0 ;
}
int nhandled = 0 ;
// While messages read
while ( NULL ! = ( item = recvItem ( ) ) )
{
2010-06-10 09:42:49 -04:00
RsDiscAskInfo * inf = NULL ;
2007-12-11 20:43:17 -05:00
RsDiscReply * dri = NULL ;
2009-06-28 16:57:02 -04:00
RsDiscVersion * dvi = NULL ;
2010-06-10 09:42:49 -04:00
RsDiscHeartbeat * dta = NULL ;
2007-12-11 20:43:17 -05:00
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-06-10 09:42:49 -04:00
std : : cerr < < " p3disc::handleIncoming() Received Message! " < < std : : endl ;
item - > print ( std : : cerr ) ;
std : : cerr < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
// if discovery reply then respond if haven't already.
2010-01-13 16:33:54 -05:00
if ( NULL ! = ( dri = dynamic_cast < RsDiscReply * > ( item ) ) ) {
2007-12-11 20:43:17 -05:00
2010-10-13 12:15:26 -04:00
RsStackMutex stack ( mDiscMtx ) ; /********** STACK LOCKED MTX ******/
/* search pending item and remove it, when already exist */
std : : list < RsDiscReply * > : : iterator it ;
for ( it = pendingDiscReplyInList . begin ( ) ; it ! = pendingDiscReplyInList . end ( ) ; it + + ) {
if ( ( * it ) - > PeerId ( ) = = dri - > PeerId ( ) & & ( * it ) - > aboutId = = dri - > aboutId ) {
delete ( * it ) ;
pendingDiscReplyInList . erase ( it ) ;
break ;
}
}
2010-09-22 19:45:54 -04:00
// add item to list for later process
2010-10-13 12:15:26 -04:00
pendingDiscReplyInList . push_back ( dri ) ; // no delete
2007-12-11 20:43:17 -05:00
}
2010-01-13 16:33:54 -05:00
else if ( NULL ! = ( dvi = dynamic_cast < RsDiscVersion * > ( item ) ) ) {
2009-06-28 16:57:02 -04:00
recvPeerVersionMsg ( dvi ) ;
nhandled + + ;
2010-09-22 19:45:54 -04:00
delete item ;
2009-06-28 16:57:02 -04:00
}
2010-01-19 14:15:22 -05:00
else if ( NULL ! = ( inf = dynamic_cast < RsDiscAskInfo * > ( item ) ) ) /* Ping */ {
2010-06-10 09:42:49 -04:00
recvAskInfo ( inf ) ;
2009-06-23 17:36:02 -04:00
nhandled + + ;
2010-09-22 19:45:54 -04:00
delete item ;
2007-12-11 20:43:17 -05:00
}
2010-01-13 16:33:54 -05:00
else if ( NULL ! = ( dta = dynamic_cast < RsDiscHeartbeat * > ( item ) ) ) {
2010-06-10 09:42:49 -04:00
recvHeartbeatMsg ( dta ) ;
nhandled + + ;
2010-09-22 19:45:54 -04:00
delete item ;
2010-06-10 09:42:49 -04:00
}
2010-07-04 11:16:52 -04:00
else
{
# ifdef P3DISC_DEBUG
std : : cerr < < " p3disc::handleIncoming() Unknown Received Message! " < < std : : endl ;
item - > print ( std : : cerr ) ;
std : : cerr < < std : : endl ;
# endif
2010-09-22 19:45:54 -04:00
delete item ;
2010-07-04 11:16:52 -04:00
}
2010-09-22 19:45:54 -04:00
}
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-06-10 09:42:49 -04:00
std : : cerr < < " p3disc::handleIncoming() finished. " < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2010-06-10 09:42:49 -04:00
return nhandled ;
2007-12-11 20:43:17 -05:00
}
2008-02-03 01:29:02 -05:00
/************* from pqiMonitor *******************/
void p3disc : : statusChange ( const std : : list < pqipeer > & plist )
2007-12-11 20:43:17 -05:00
{
2010-02-15 10:31:06 -05:00
# ifdef P3DISC_DEBUG
2010-06-10 09:42:49 -04:00
std : : cerr < < " p3disc::statusChange() " < < std : : endl ;
2010-02-15 10:31:06 -05:00
# endif
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
std : : list < pqipeer > : : const_iterator pit ;
/* if any have switched to 'connected' then we notify */
2010-07-04 11:16:52 -04:00
for ( pit = plist . begin ( ) ; pit ! = plist . end ( ) ; pit + + )
{
if ( ( pit - > state & RS_PEER_S_FRIEND ) & & ( pit - > actions & RS_PEER_CONNECTED ) )
{
# ifdef P3DISC_DEBUG
std : : cerr < < " p3disc::statusChange() Starting Disc with: " < < pit - > id < < std : : endl ;
# endif
2010-06-10 09:42:49 -04:00
sendOwnVersion ( pit - > id ) ;
sendAllInfoToJustConnectedPeer ( pit - > id ) ;
sendJustConnectedPeerInfoToAllPeer ( pit - > id ) ;
}
else if ( ! ( pit - > state & RS_PEER_S_FRIEND ) & & ( pit - > actions & RS_PEER_MOVED ) )
2010-07-04 11:16:52 -04:00
{
# ifdef P3DISC_DEBUG
std : : cerr < < " p3disc::statusChange() Removing Friend: " < < pit - > id < < std : : endl ;
# endif
2010-06-10 09:42:49 -04:00
removeFriend ( pit - > id ) ;
2010-07-04 11:16:52 -04:00
}
2010-06-10 09:42:49 -04:00
else if ( ( pit - > state & RS_PEER_S_FRIEND ) & & ( pit - > actions & RS_PEER_NEW ) )
2010-07-04 11:16:52 -04:00
{
# ifdef P3DISC_DEBUG
std : : cerr < < " p3disc::statusChange() Adding Friend: " < < pit - > id < < std : : endl ;
# endif
2010-06-10 09:42:49 -04:00
askInfoToAllPeers ( pit - > id ) ;
2010-07-04 11:16:52 -04:00
}
}
2010-06-10 09:42:49 -04:00
# ifdef P3DISC_DEBUG
std : : cerr < < " p3disc::statusChange() finished. " < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2010-06-10 09:42:49 -04:00
return ;
2007-12-11 20:43:17 -05:00
}
2010-10-13 12:15:26 -04:00
void p3disc : : sendAllInfoToJustConnectedPeer ( const std : : string & id )
2007-12-11 20:43:17 -05:00
{
2008-02-03 01:29:02 -05:00
/* get a peer lists */
2007-12-11 20:43:17 -05:00
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-06-10 09:42:49 -04:00
std : : cerr < < " p3disc::sendAllInfoToJustConnectedPeer() id: " < < id < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2010-06-10 09:42:49 -04:00
RsPeerDetails pd ;
rsPeers - > getPeerDetails ( id , pd ) ;
if ( ! pd . accept_connection | | ( ! pd . ownsign & & pd . gpg_id ! = rsPeers - > getGPGOwnId ( ) ) ) { //only send info when connection is accepted and gpg key is signed or our own key
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-06-10 09:42:49 -04:00
std : : cerr < < " p3disc::sendAllInfoToJustConnectedPeer() we're not sending the info because the destination gpg key is not signed or not accepted. " < < std : : cerr < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2010-06-10 09:42:49 -04:00
return ;
}
2010-02-15 10:31:06 -05:00
2007-12-11 20:43:17 -05:00
2010-06-10 09:42:49 -04:00
std : : list < std : : string > friendIds ;
std : : list < std : : string > : : iterator friendIdsIt ;
2010-09-24 13:06:09 -04:00
std : : set < std : : string > gpgIds ;
2008-02-03 01:29:02 -05:00
2010-06-10 09:42:49 -04:00
rsPeers - > getFriendList ( friendIds ) ;
2008-02-03 01:29:02 -05:00
/* send them a list of all friend's details */
2010-01-13 16:33:54 -05:00
for ( friendIdsIt = friendIds . begin ( ) ; friendIdsIt ! = friendIds . end ( ) ; friendIdsIt + + ) {
2008-02-03 01:29:02 -05:00
/* get details */
peerConnectState detail ;
2010-06-10 09:42:49 -04:00
if ( ! mConnMgr - > getFriendNetStatus ( * friendIdsIt , detail ) ) {
2008-02-03 01:29:02 -05:00
/* major error! */
continue ;
2007-12-11 20:43:17 -05:00
}
2008-02-03 01:29:02 -05:00
2010-06-10 09:42:49 -04:00
if ( ! ( detail . visState & RS_VIS_STATE_NODISC ) ) {
gpgIds . insert ( detail . gpg_id ) ;
2007-12-11 20:43:17 -05:00
}
2010-06-10 09:42:49 -04:00
}
2009-12-18 18:35:40 -05:00
2010-06-10 09:42:49 -04:00
//add own info
gpgIds . insert ( rsPeers - > getGPGOwnId ( ) ) ;
2009-12-18 12:50:53 -05:00
2010-09-24 13:06:09 -04:00
{
RsStackMutex stack ( mDiscMtx ) ; /********** STACK LOCKED MTX ******/
/* append gpg id's to the sending list for the id */
std : : list < std : : string > & idList = sendIdList [ id ] ;
std : : set < std : : string > : : iterator gpgIdsIt ;
for ( gpgIdsIt = gpgIds . begin ( ) ; gpgIdsIt ! = gpgIds . end ( ) ; gpgIdsIt + + ) {
if ( std : : find ( idList . begin ( ) , idList . end ( ) , * gpgIdsIt ) = = idList . end ( ) ) {
idList . push_back ( * gpgIdsIt ) ;
}
}
}
2010-02-15 10:31:06 -05:00
# ifdef P3DISC_DEBUG
2010-06-10 09:42:49 -04:00
std : : cerr < < " p3disc::sendAllInfoToJustConnectedPeer() finished. " < < std : : endl ;
2010-02-15 10:31:06 -05:00
# endif
2007-12-11 20:43:17 -05:00
}
2010-10-13 12:15:26 -04:00
void p3disc : : sendJustConnectedPeerInfoToAllPeer ( const std : : string & connectedPeerId )
2010-01-13 16:34:28 -05:00
{
2010-06-10 09:42:49 -04:00
/* get a peer lists */
2010-01-13 16:34:28 -05:00
# ifdef P3DISC_DEBUG
2010-06-10 09:42:49 -04:00
std : : cerr < < " p3disc::sendJustConnectedPeerInfoToAllPeer() connectedPeerId : " < < connectedPeerId < < std : : endl ;
2010-01-13 16:34:28 -05:00
# endif
2010-06-10 09:42:49 -04:00
std : : string gpg_connectedPeerId = rsPeers - > getGPGId ( connectedPeerId ) ;
std : : list < std : : string > onlineIds ;
2010-01-13 16:34:28 -05:00
2010-06-10 09:42:49 -04:00
rsPeers - > getOnlineList ( onlineIds ) ;
2010-01-13 16:34:28 -05:00
2010-09-24 13:06:09 -04:00
{
RsStackMutex stack ( mDiscMtx ) ; /********** STACK LOCKED MTX ******/
/* append gpg id's of all friend's to the sending list */
std : : list < std : : string > : : iterator onlineIdsIt ;
for ( onlineIdsIt = onlineIds . begin ( ) ; onlineIdsIt ! = onlineIds . end ( ) ; onlineIdsIt + + ) {
std : : list < std : : string > & idList = sendIdList [ * onlineIdsIt ] ;
if ( std : : find ( idList . begin ( ) , idList . end ( ) , gpg_connectedPeerId ) = = idList . end ( ) ) {
idList . push_back ( gpg_connectedPeerId ) ;
}
}
}
2010-01-13 16:34:28 -05:00
}
2008-02-03 01:29:02 -05:00
/* (dest (to), source (cert)) */
2010-10-13 12:15:26 -04:00
RsDiscReply * p3disc : : createDiscReply ( const std : : string & to , const std : : string & about )
2010-07-04 11:16:52 -04:00
{
# ifdef P3DISC_DEBUG
2010-10-13 12:15:26 -04:00
std : : cerr < < " p3disc::createDiscReply() called. Sending details of: " < < about < < " to: " < < to < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2010-02-15 10:31:06 -05:00
2010-06-10 09:42:49 -04:00
RsPeerDetails pd ;
rsPeers - > getPeerDetails ( to , pd ) ;
if ( ! pd . accept_connection | | ! pd . ownsign ) {
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-10-13 12:15:26 -04:00
std : : cerr < < " p3disc::createDiscReply() we're not sending the info because the destination gpg key is not signed or not accepted. " < < std : : cerr < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2010-10-13 12:15:26 -04:00
return NULL ;
2010-06-10 09:42:49 -04:00
}
2010-02-15 10:31:06 -05:00
2007-12-11 20:43:17 -05:00
2010-06-10 09:42:49 -04:00
// if off discard item.
peerConnectState detail ;
2010-01-19 14:15:22 -05:00
if ( ! mConnMgr - > getOwnNetStatus ( detail ) | | ( detail . visState & RS_VIS_STATE_NODISC ) ) {
2010-10-13 12:15:26 -04:00
return NULL ;
2010-01-19 14:15:22 -05:00
}
2010-07-04 11:16:52 -04:00
std : : string aboutGpgId = rsPeers - > getGPGId ( about ) ;
2010-10-13 12:15:26 -04:00
if ( aboutGpgId . empty ( ) ) {
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-10-13 12:15:26 -04:00
std : : cerr < < " p3disc::createDiscReply() no info about this id " < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2010-10-13 12:15:26 -04:00
return NULL ;
2010-06-10 09:42:49 -04:00
}
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
// Construct a message
RsDiscReply * di = new RsDiscReply ( ) ;
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
// Fill the message
// Set Target as input cert.
di - > PeerId ( to ) ;
2010-07-04 11:16:52 -04:00
di - > aboutId = aboutGpgId ;
2007-12-11 20:43:17 -05:00
2010-06-10 09:42:49 -04:00
// set the ip addresse list.
std : : list < std : : string > sslChilds ;
2010-07-04 11:16:52 -04:00
rsPeers - > getSSLChildListOfGPGId ( aboutGpgId , sslChilds ) ;
2010-06-10 09:42:49 -04:00
bool shouldWeSendGPGKey = false ; //the GPG key is send only if we've got a valid friend with DISC enabled
2010-07-04 11:16:52 -04:00
std : : list < std : : string > : : iterator sslChildIt ;
for ( sslChildIt = sslChilds . begin ( ) ; sslChildIt ! = sslChilds . end ( ) ; sslChildIt + + )
2010-12-14 16:56:37 -05:00
if ( ! rsPeers - > isDummyFriend ( * sslChildIt ) )
{
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-12-14 16:56:37 -05:00
std : : cerr < < " p3disc::createDiscReply() Found Child SSL Id: " < < * sslChildIt ;
std : : cerr < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2010-12-14 16:56:37 -05:00
if ( sslChilds . size ( ) = = 1 | | to ! = * sslChildIt ) // We don't send info to a peer about itself, when there are more than one ssl children,
{ // but we allow sending info about peers with the same GPG id. When there is only one ssl child,
// we must send it to transfer the signers of the gpg key. The receiver is skipping the own id.
peerConnectState detail ;
if ( ! mConnMgr - > getFriendNetStatus ( * sslChildIt , detail )
| | detail . visState & RS_VIS_STATE_NODISC )
{
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-12-14 16:56:37 -05:00
std : : cerr < < " p3disc::createDiscReply() Skipping cos No Details or NODISC flag " ;
std : : cerr < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2010-12-14 16:56:37 -05:00
continue ;
}
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-12-14 16:56:37 -05:00
std : : cerr < < " p3disc::createDiscReply() Adding Child SSL Id Details " ;
std : : cerr < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2010-12-14 16:56:37 -05:00
shouldWeSendGPGKey = true ;
RsPeerNetItem * rsPeerNetItem = new RsPeerNetItem ( ) ;
rsPeerNetItem - > clear ( ) ;
2010-06-10 09:42:49 -04:00
2010-12-14 16:56:37 -05:00
rsPeerNetItem - > pid = detail . id ;
rsPeerNetItem - > gpg_id = detail . gpg_id ;
rsPeerNetItem - > location = detail . location ;
rsPeerNetItem - > netMode = detail . netMode ;
rsPeerNetItem - > visState = detail . visState ;
rsPeerNetItem - > lastContact = detail . lastcontact ;
rsPeerNetItem - > currentlocaladdr = detail . currentlocaladdr ;
rsPeerNetItem - > currentremoteaddr = detail . currentserveraddr ;
rsPeerNetItem - > dyndns = detail . dyndns ;
detail . ipAddrs . mLocal . loadTlv ( rsPeerNetItem - > localAddrList ) ;
detail . ipAddrs . mExt . loadTlv ( rsPeerNetItem - > extAddrList ) ;
2010-07-04 06:42:17 -04:00
2010-06-10 09:42:49 -04:00
2010-12-14 16:56:37 -05:00
di - > rsPeerList . push_back ( * rsPeerNetItem ) ;
}
else
{
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-12-14 16:56:37 -05:00
std : : cerr < < " p3disc::createDiscReply() Skipping cos \" to == sslChildId \" " ;
std : : cerr < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2010-12-14 16:56:37 -05:00
}
2010-07-04 11:16:52 -04:00
}
2007-12-11 20:43:17 -05:00
2009-02-22 12:36:39 -05:00
2010-06-10 09:42:49 -04:00
//send own details
if ( about = = rsPeers - > getGPGOwnId ( ) )
{
peerConnectState detail ;
if ( mConnMgr - > getOwnNetStatus ( detail ) )
{
shouldWeSendGPGKey = true ;
RsPeerNetItem * rsPeerNetItem = new RsPeerNetItem ( ) ;
rsPeerNetItem - > clear ( ) ;
rsPeerNetItem - > pid = detail . id ;
rsPeerNetItem - > gpg_id = detail . gpg_id ;
rsPeerNetItem - > location = detail . location ;
rsPeerNetItem - > netMode = detail . netMode ;
rsPeerNetItem - > visState = detail . visState ;
rsPeerNetItem - > lastContact = time ( NULL ) ;
rsPeerNetItem - > currentlocaladdr = detail . currentlocaladdr ;
rsPeerNetItem - > currentremoteaddr = detail . currentserveraddr ;
rsPeerNetItem - > dyndns = detail . dyndns ;
2010-07-04 06:42:17 -04:00
detail . ipAddrs . mLocal . loadTlv ( rsPeerNetItem - > localAddrList ) ;
detail . ipAddrs . mExt . loadTlv ( rsPeerNetItem - > extAddrList ) ;
2010-06-10 09:42:49 -04:00
di - > rsPeerList . push_back ( * rsPeerNetItem ) ;
}
}
if ( ! shouldWeSendGPGKey ) {
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-10-13 12:15:26 -04:00
std : : cerr < < " p3disc::createDiscReply() GPG key should not be send, no friend with disc on found about it. " < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
// cleanup!
delete di ;
2010-10-13 12:15:26 -04:00
return NULL ;
2010-06-10 09:42:49 -04:00
}
2010-07-04 11:16:52 -04:00
2010-10-13 12:15:26 -04:00
return di ;
2009-05-25 07:38:47 -04:00
}
2009-06-28 16:57:02 -04:00
void p3disc : : sendOwnVersion ( std : : string to )
{
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-02-15 10:31:06 -05:00
std : : cerr < < " p3disc::sendOwnVersion() Sending rs version to: " < < to < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2009-06-28 16:57:02 -04:00
RsDiscVersion * di = new RsDiscVersion ( ) ;
di - > PeerId ( to ) ;
di - > version = RsUtil : : retroshareVersion ( ) ;
/* send the message */
sendItem ( di ) ;
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-02-15 10:31:06 -05:00
std : : cerr < < " p3disc::sendOwnVersion() finished. " < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2009-06-28 16:57:02 -04:00
}
2009-05-25 07:38:47 -04:00
2009-12-22 05:41:19 -05:00
void p3disc : : sendHeartbeat ( std : : string to )
{
{
# ifdef P3DISC_DEBUG
std : : ostringstream out ;
out < < " p3disc::sendHeartbeat() " ;
out < < " Sending tick to : " < < to < < std : : endl ;
std : : cerr < < out . str ( ) < < std : : endl ;
# endif
}
RsDiscHeartbeat * di = new RsDiscHeartbeat ( ) ;
di - > PeerId ( to ) ;
/* send the message */
sendItem ( di ) ;
# ifdef P3DISC_DEBUG
std : : cerr < < " Sent tick Message " < < std : : endl ;
# endif
}
2010-01-19 14:15:22 -05:00
void p3disc : : askInfoToAllPeers ( std : : string about )
{
2010-02-15 10:31:06 -05:00
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-02-15 10:31:06 -05:00
std : : cerr < < " p3disc::askInfoToAllPeers() about " < < about < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2010-02-15 10:31:06 -05:00
peerConnectState connectState ;
2010-06-10 09:42:49 -04:00
if ( ! mConnMgr - > getFriendNetStatus ( about , connectState ) ) // || (connectState.visState & RS_VIS_STATE_NODISC)) {
{
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-02-15 10:31:06 -05:00
std : : cerr < < " p3disc::askInfoToAllPeers() friend disc is off, don't send the request. " < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2010-02-15 10:31:06 -05:00
return ;
2010-01-19 14:15:22 -05:00
}
2010-07-04 11:16:52 -04:00
std : : string aboutGpgId = rsPeers - > getGPGId ( about ) ;
if ( aboutGpgId = = " " ) {
# ifdef P3DISC_DEBUG
2010-02-15 10:31:06 -05:00
std : : cerr < < " p3disc::askInfoToAllPeers() no gpg id found " < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2010-01-19 14:15:22 -05:00
}
// if off discard item.
2010-02-15 10:31:06 -05:00
if ( ! mConnMgr - > getOwnNetStatus ( connectState ) | | ( connectState . visState & RS_VIS_STATE_NODISC ) ) {
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
std : : cerr < < " p3disc::askInfoToAllPeers() no gpg id found " < < std : : endl ;
# endif
2010-01-19 14:15:22 -05:00
return ;
}
std : : list < std : : string > onlineIds ;
std : : list < std : : string > : : iterator onlineIdsIt ;
rsPeers - > getOnlineList ( onlineIds ) ;
2010-02-15 10:31:06 -05:00
/* ask info to trusted friends */
2010-07-04 11:16:52 -04:00
for ( onlineIdsIt = onlineIds . begin ( ) ; onlineIdsIt ! = onlineIds . end ( ) ; onlineIdsIt + + )
{
2010-02-15 10:31:06 -05:00
RsPeerDetails details ;
rsPeers - > getPeerDetails ( * onlineIdsIt , details ) ;
2010-07-04 11:16:52 -04:00
if ( ! details . accept_connection | | ! details . ownsign )
{
# ifdef P3DISC_DEBUG
2010-02-15 10:31:06 -05:00
std : : cerr < < " p3disc::askInfoToAllPeers() don't ask info message to untrusted peer. " < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2010-02-15 10:31:06 -05:00
continue ;
}
2010-01-19 14:15:22 -05:00
RsDiscAskInfo * di = new RsDiscAskInfo ( ) ;
di - > PeerId ( * onlineIdsIt ) ;
di - > gpg_id = about ;
sendItem ( di ) ;
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-02-15 10:31:06 -05:00
std : : cerr < < " p3disc::askInfoToAllPeers() question sent to : " < < * onlineIdsIt < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2010-01-19 14:15:22 -05:00
}
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-02-15 10:31:06 -05:00
std : : cerr < < " p3disc::askInfoToAllPeers() finished. " < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2010-01-19 14:15:22 -05:00
}
2010-10-13 12:15:26 -04:00
void p3disc : : recvPeerDetails ( RsDiscReply * item , const std : : string & certGpgId )
2007-12-11 20:43:17 -05:00
{
2010-06-10 09:42:49 -04:00
// discovery is only disabled for sending, not for receiving.
// // if off discard item.
// peerConnectState detail;
// if (!mConnMgr->getOwnNetStatus(detail) || (detail.visState & RS_VIS_STATE_NODISC)) {
// return;
// }
2007-12-11 20:43:17 -05:00
2009-02-22 12:36:39 -05:00
# ifdef P3DISC_DEBUG
2010-06-10 09:42:49 -04:00
std : : cerr < < " p3disc::recvPeerFriendMsg() From: " < < item - > PeerId ( ) < < " About " < < item - > aboutId < < std : : endl ;
2009-02-22 12:36:39 -05:00
# endif
2010-10-13 12:15:26 -04:00
if ( certGpgId . empty ( ) ) {
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-06-10 09:42:49 -04:00
std : : cerr < < " p3disc::recvPeerFriendMsg() gpg cert is not good, aborting " < < std : : endl ;
2010-07-04 11:16:52 -04:00
# endif
2010-06-10 09:42:49 -04:00
return ;
}
2010-03-15 15:10:46 -04:00
if ( item - > aboutId = = " " | | item - > aboutId ! = certGpgId ) {
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-06-10 09:42:49 -04:00
std : : cerr < < " p3disc::recvPeerFriendMsg() Error : about id is not the same as gpg id. " < < std : : endl ;
2010-01-13 16:33:54 -05:00
# endif
2010-06-10 09:42:49 -04:00
return ;
}
2007-12-11 20:43:17 -05:00
2010-11-05 18:46:40 -04:00
bool should_notify_discovery = false ;
2010-06-10 09:42:49 -04:00
for ( std : : list < RsPeerNetItem > : : iterator pitem = item - > rsPeerList . begin ( ) ; pitem ! = item - > rsPeerList . end ( ) ; pitem + + )
2010-12-14 16:56:37 -05:00
if ( ! rsPeers - > isDummyFriend ( pitem - > pid ) )
{
bool new_info ;
addDiscoveryData ( item - > PeerId ( ) , pitem - > pid , rsPeers - > getGPGId ( item - > PeerId ( ) ) , item - > aboutId , pitem - > currentlocaladdr , pitem - > currentremoteaddr , 0 , time ( NULL ) , new_info ) ;
2010-11-05 18:46:40 -04:00
2010-12-14 16:56:37 -05:00
if ( new_info )
should_notify_discovery = true ;
2007-12-11 20:43:17 -05:00
2010-06-15 17:28:27 -04:00
# ifdef P3DISC_DEBUG
2010-12-14 16:56:37 -05:00
std : : cerr < < " p3disc::recvPeerFriendMsg() Peer Config Item: " < < std : : endl ;
2010-03-03 16:09:49 -05:00
2010-12-14 16:56:37 -05:00
pitem - > print ( std : : cerr , 10 ) ;
std : : cerr < < std : : endl ;
2010-06-10 09:42:49 -04:00
# endif
2010-12-14 16:56:37 -05:00
if ( pitem - > pid ! = rsPeers - > getOwnId ( ) )
2010-06-10 09:42:49 -04:00
{
2010-12-14 16:56:37 -05:00
// Apparently, the connect manager won't add a friend if the gpg id is not
// trusted. However, this should be tested here for consistency and security
// in case of modifications in mConnMgr.
2010-06-10 09:42:49 -04:00
//
2010-12-14 16:56:37 -05:00
if ( AuthGPG : : getAuthGPG ( ) - > isGPGAccepted ( pitem - > gpg_id ) | | pitem - > gpg_id = = AuthGPG : : getAuthGPG ( ) - > getGPGOwnId ( ) )
{
// Add with no disc by default. If friend already exists, it will do nothing
2010-06-10 09:42:49 -04:00
//
2010-07-04 11:16:52 -04:00
# ifdef P3DISC_DEBUG
2010-12-14 16:56:37 -05:00
std : : cerr < < " --> Adding to friends list " < < pitem - > pid < < " - " < < pitem - > gpg_id < < std : : endl ;
# endif
mConnMgr - > addFriend ( pitem - > pid , pitem - > gpg_id , pitem - > netMode , 0 , 0 ) ;
RsPeerDetails storedDetails ;
// Update if know this peer
if ( rsPeers - > getPeerDetails ( pitem - > pid , storedDetails ) )
{
// Update if it's fresh info or if it's from the peer itself
// their info is fresher than ours, update ours
//
if ( ! ( storedDetails . state & RS_PEER_CONNECTED ) )
{
# ifdef P3DISC_DEBUG
std : : cerr < < " Friend is not connected -> updating info " < < std : : endl ;
std : : cerr < < " -> network mode: " < < pitem - > netMode < < std : : endl ;
std : : cerr < < " -> location: " < < pitem - > location < < std : : endl ;
# endif
mConnMgr - > setNetworkMode ( pitem - > pid , pitem - > netMode ) ;
mConnMgr - > setLocation ( pitem - > pid , pitem - > location ) ;
}
// The info from the peer itself is ultimately trustable, so we can override some info,
// such as:
// - local and global addresses
// - address list
//
// If we enter here, we're necessarily connected to this peer.
//
if ( item - > PeerId ( ) = = pitem - > pid )
{
# ifdef P3DISC_DEBUG
std : : cerr < < " Info sent by the peer itself -> updating self info: " < < std : : endl ;
std : : cerr < < " -> current local addr = " < < pitem - > currentlocaladdr < < std : : endl ;
std : : cerr < < " -> current remote addr = " < < pitem - > currentremoteaddr < < std : : endl ;
std : : cerr < < " -> clearing NODISC flag " < < std : : endl ;
# endif
// When the peer sends his own list of IPs, the info replaces the existing info, because the
// peer is the primary source of his own IPs.
mConnMgr - > setLocalAddress ( pitem - > pid , pitem - > currentlocaladdr ) ;
mConnMgr - > setExtAddress ( pitem - > pid , pitem - > currentremoteaddr ) ;
pitem - > visState & = ~ RS_VIS_STATE_NODISC ;
mConnMgr - > setVisState ( pitem - > pid , pitem - > visState ) ;
}
2010-06-16 16:18:46 -04:00
}
2010-12-14 16:56:37 -05:00
else
2010-06-10 09:42:49 -04:00
{
2010-12-14 16:56:37 -05:00
std : : cerr < < " p3disc:: ERROR HOW DID WE GET HERE? " < < std : : endl ;
}
pqiIpAddrSet addrsFromPeer ;
addrsFromPeer . mLocal . extractFromTlv ( pitem - > localAddrList ) ;
addrsFromPeer . mExt . extractFromTlv ( pitem - > extAddrList ) ;
2010-06-10 09:42:49 -04:00
# ifdef P3DISC_DEBUG
2010-12-14 16:56:37 -05:00
std : : cerr < < " Setting address list to peer " < < pitem - > pid < < " , to be: " < < std : : endl ;
2010-06-16 16:18:46 -04:00
2010-12-14 16:56:37 -05:00
addrsFromPeer . printAddrs ( std : : cerr ) ;
std : : cerr < < std : : endl ;
# endif
// allways update address list and dns, except if it's ours
if ( pitem - > dyndns ! = " " )
mConnMgr - > setDynDNS ( pitem - > pid , pitem - > dyndns ) ;
2010-07-04 11:16:52 -04:00
2010-12-14 16:56:37 -05:00
mConnMgr - > updateAddressList ( pitem - > pid , addrsFromPeer ) ;
2010-06-10 09:42:49 -04:00
}
2010-12-14 16:56:37 -05:00
# ifdef P3DISC_DEBUG
2010-07-04 11:16:52 -04:00
else
{
2010-12-14 16:56:37 -05:00
std : : cerr < < " skipping unknown gpg id " < < pitem - > gpg_id < < std : : endl ;
2010-07-04 11:16:52 -04:00
}
2010-06-10 09:42:49 -04:00
# endif
}
# ifdef P3DISC_DEBUG
else
2010-07-04 11:16:52 -04:00
{
2010-12-14 16:56:37 -05:00
std : : cerr < < " Skipping info about own id " < < pitem - > pid < < std : : endl ;
2010-07-04 11:16:52 -04:00
}
2010-06-10 09:42:49 -04:00
# endif
2010-12-14 16:56:37 -05:00
}
2009-12-22 13:43:04 -05:00
2009-02-22 12:36:39 -05:00
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_NEIGHBOURS , NOTIFY_TYPE_MOD ) ;
2009-06-28 16:57:02 -04:00
2010-11-05 18:46:40 -04:00
if ( should_notify_discovery )
rsicontrol - > getNotify ( ) . notifyDiscInfoChanged ( ) ;
2010-06-10 09:42:49 -04:00
/* cleanup (handled by caller) */
2007-12-11 20:43:17 -05:00
}
2009-06-28 16:57:02 -04:00
void p3disc : : recvPeerVersionMsg ( RsDiscVersion * item )
{
# ifdef P3DISC_DEBUG
2009-12-22 05:41:19 -05:00
std : : cerr < < " p3disc::recvPeerVersionMsg() From: " < < item - > PeerId ( ) ;
std : : cerr < < std : : endl ;
2009-06-28 16:57:02 -04:00
# endif
2009-12-22 05:41:19 -05:00
// dont need protection
versions [ item - > PeerId ( ) ] = item - > version ;
2009-06-28 16:57:02 -04:00
2009-12-22 05:41:19 -05:00
return ;
}
void p3disc : : recvHeartbeatMsg ( RsDiscHeartbeat * item )
{
# ifdef P3DISC_DEBUG
std : : cerr < < " p3disc::recvHeartbeatMsg() From: " < < item - > PeerId ( ) ;
std : : cerr < < std : : endl ;
# endif
2010-06-25 18:13:52 -04:00
mPqiPersonGrp - > tagHeartbeatRecvd ( item - > PeerId ( ) ) ;
2009-12-22 05:41:19 -05:00
return ;
2009-06-28 16:57:02 -04:00
}
2009-05-25 07:38:47 -04:00
2010-01-19 14:15:22 -05:00
void p3disc : : recvAskInfo ( RsDiscAskInfo * item ) {
# ifdef P3DISC_DEBUG
std : : cerr < < " p3disc::recvAskInfo() From: " < < item - > PeerId ( ) ;
std : : cerr < < std : : endl ;
# endif
2010-10-13 12:15:26 -04:00
std : : list < std : : string > & idList = sendIdList [ item - > PeerId ( ) ] ;
2010-01-19 14:15:22 -05:00
2010-10-13 12:15:26 -04:00
if ( std : : find ( idList . begin ( ) , idList . end ( ) , item - > gpg_id ) = = idList . end ( ) ) {
idList . push_back ( item - > gpg_id ) ;
}
2010-01-19 14:15:22 -05:00
}
2010-01-15 16:09:25 -05:00
void p3disc : : removeFriend ( std : : string ssl_id ) {
# ifdef P3DISC_DEBUG
2010-06-10 09:42:49 -04:00
std : : cerr < < " p3disc::removeFriend() called for : " < < ssl_id < < std : : endl ;
2010-01-15 16:09:25 -05:00
# endif
2010-06-10 09:42:49 -04:00
//if we deleted the gpg_id, don't store the friend deletion as if we add back the gpg_id, we won't have the ssl friends back
std : : string gpg_id = rsPeers - > getGPGId ( ssl_id ) ;
2010-01-15 16:09:25 -05:00
# ifdef P3DISC_DEBUG
2010-06-10 09:42:49 -04:00
std : : cerr < < " p3disc::removeFriend() gpg_id : " < < gpg_id < < std : : endl ;
2010-01-15 16:09:25 -05:00
# endif
2010-06-10 09:42:49 -04:00
if ( gpg_id = = AuthGPG : : getAuthGPG ( ) - > getGPGOwnId ( ) | | rsPeers - > isGPGAccepted ( rsPeers - > getGPGId ( ssl_id ) ) ) {
2010-10-13 12:15:26 -04:00
# ifdef P3DISC_DEBUG
2010-06-10 09:42:49 -04:00
std : : cerr < < " p3disc::removeFriend() storing the friend deletion. " < < ssl_id < < std : : endl ;
2010-01-15 16:09:25 -05:00
# endif
2010-06-10 09:42:49 -04:00
deletedSSLFriendsIds [ ssl_id ] = time ( NULL ) ; //just keep track of the deleted time
IndicateConfigChanged ( ) ;
}
2010-01-15 16:09:25 -05:00
}
2010-10-13 12:15:26 -04:00
/*************************************************************************************/
/* AuthGPGService */
/*************************************************************************************/
AuthGPGOperation * p3disc : : getGPGOperation ( )
{
{
RsStackMutex stack ( mDiscMtx ) ; /********** STACK LOCKED MTX ******/
/* process disc reply in list */
if ( pendingDiscReplyInList . empty ( ) = = false ) {
RsDiscReply * item = pendingDiscReplyInList . front ( ) ;
return new AuthGPGOperationLoadOrSave ( true , item - > certGPG , item ) ;
}
}
/* process disc reply out list */
std : : string destId ;
std : : string srcId ;
{
RsStackMutex stack ( mDiscMtx ) ; /********** STACK LOCKED MTX ******/
while ( ! sendIdList . empty ( ) ) {
std : : map < std : : string , std : : list < std : : string > > : : iterator sendIdIt = sendIdList . begin ( ) ;
if ( ! sendIdIt - > second . empty ( ) & & mConnMgr - > isOnline ( sendIdIt - > first ) ) {
std : : string gpgId = sendIdIt - > second . front ( ) ;
sendIdIt - > second . pop_front ( ) ;
destId = sendIdIt - > first ;
srcId = gpgId ;
break ;
} else {
/* peer is not online anymore ... try next */
sendIdList . erase ( sendIdIt ) ;
}
}
}
if ( ! destId . empty ( ) & & ! srcId . empty ( ) ) {
RsDiscReply * item = createDiscReply ( destId , srcId ) ;
if ( item ) {
return new AuthGPGOperationLoadOrSave ( false , item - > aboutId , item ) ;
}
}
return NULL ;
}
void p3disc : : setGPGOperation ( AuthGPGOperation * operation )
{
AuthGPGOperationLoadOrSave * loadOrSave = dynamic_cast < AuthGPGOperationLoadOrSave * > ( operation ) ;
if ( loadOrSave ) {
if ( loadOrSave - > m_load ) {
/* search in pending in list */
RsDiscReply * item = NULL ;
{
RsStackMutex stack ( mDiscMtx ) ; /********** STACK LOCKED MTX ******/
std : : list < RsDiscReply * > : : iterator it = std : : find ( pendingDiscReplyInList . begin ( ) , pendingDiscReplyInList . end ( ) , loadOrSave - > m_userdata ) ;
if ( it ! = pendingDiscReplyInList . end ( ) ) {
item = * it ;
pendingDiscReplyInList . erase ( it ) ;
}
}
if ( item ) {
recvPeerDetails ( item , loadOrSave - > m_certGpgId ) ;
delete item ;
}
} else {
RsDiscReply * item = ( RsDiscReply * ) loadOrSave - > m_userdata ;
if ( item ) {
if ( loadOrSave - > m_certGpg . empty ( ) ) {
# ifdef P3DISC_DEBUG
std : : cerr < < " p3disc::setGPGOperation() don't send details because the gpg cert is not good " < < std : : endl ;
# endif
delete item ;
return ;
}
// Send off message
item - > certGPG = loadOrSave - > m_certGpg ;
# ifdef P3DISC_DEBUG
std : : cerr < < " p3disc::setGPGOperation() About to Send Message: " < < std : : endl ;
item - > print ( std : : cerr , 5 ) ;
# endif
sendItem ( item ) ;
# ifdef P3DISC_DEBUG
std : : cerr < < " p3disc::cbkGPGOperationSave() discovery reply sent. " < < std : : endl ;
# endif
}
}
return ;
}
/* ignore other operations */
}
2008-02-03 01:29:02 -05:00
/*************************************************************************************/
/* Storing Network Graph */
/*************************************************************************************/
2010-11-14 16:03:36 -05:00
int p3disc : : addDiscoveryData ( const std : : string & fromId , const std : : string & aboutId , const std : : string & from_gpg_id , const std : : string & about_gpg_id , const struct sockaddr_in & laddr , const struct sockaddr_in & raddr , uint32_t flags , time_t ts , bool & new_info )
2008-02-03 01:29:02 -05:00
{
2008-02-04 16:40:34 -05:00
RsStackMutex stack ( mDiscMtx ) ; /********** STACK LOCKED MTX ******/
2007-12-11 20:43:17 -05:00
2010-11-05 18:46:40 -04:00
new_info = false ;
2010-11-14 16:03:36 -05:00
gpg_neighbors [ from_gpg_id ] . insert ( about_gpg_id ) ;
2010-11-19 17:42:29 -05:00
# ifdef P3DISC_DEBUG
2010-11-05 18:46:40 -04:00
std : : cerr < < " Adding discovery data " < < fromId < < " - " < < aboutId < < std : : endl ;
2010-11-19 17:42:29 -05:00
# endif
2008-02-04 16:40:34 -05:00
/* Store Network information */
2008-02-03 01:29:02 -05:00
std : : map < std : : string , autoneighbour > : : iterator it ;
if ( neighbours . end ( ) = = ( it = neighbours . find ( aboutId ) ) )
{
/* doesn't exist */
autoneighbour an ;
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
/* an data */
an . id = aboutId ;
an . validAddrs = false ;
an . discFlags = 0 ;
an . ts = 0 ;
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
neighbours [ aboutId ] = an ;
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
it = neighbours . find ( aboutId ) ;
2010-11-05 18:46:40 -04:00
new_info = true ;
2008-02-03 01:29:02 -05:00
}
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
/* it always valid */
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
/* just update packet */
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
autoserver as ;
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
as . id = fromId ;
as . localAddr = laddr ;
as . remoteAddr = raddr ;
as . discFlags = flags ;
as . ts = ts ;
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
bool authDetails = ( as . id = = it - > second . id ) ;
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
/* KEY decision about address */
2009-06-28 16:57:02 -04:00
if ( ( authDetails ) | |
2008-02-03 01:29:02 -05:00
( ( ! ( it - > second . authoritative ) ) & & ( as . ts > it - > second . ts ) ) )
2007-12-11 20:43:17 -05:00
{
2008-02-03 01:29:02 -05:00
/* copy details to an */
it - > second . authoritative = authDetails ;
it - > second . ts = as . ts ;
it - > second . validAddrs = true ;
it - > second . localAddr = as . localAddr ;
it - > second . remoteAddr = as . remoteAddr ;
it - > second . discFlags = as . discFlags ;
2007-12-11 20:43:17 -05:00
}
2010-11-05 18:46:40 -04:00
if ( it - > second . neighbour_of . find ( fromId ) = = it - > second . neighbour_of . end ( ) )
{
( it - > second ) . neighbour_of [ fromId ] = as ;
new_info = true ;
}
2008-02-03 01:29:02 -05:00
/* do we update network address info??? */
return 1 ;
2007-12-11 20:43:17 -05:00
}
2008-02-03 01:29:02 -05:00
/*************************************************************************************/
/* Extracting Network Graph Details */
/*************************************************************************************/
2010-11-14 16:03:36 -05:00
bool p3disc : : potentialproxies ( const std : : string & id , std : : list < std : : string > & proxyIds )
2008-02-03 01:29:02 -05:00
{
/* find id -> and extract the neighbour_of ids */
2008-02-04 16:40:34 -05:00
2010-11-05 18:46:40 -04:00
if ( id = = rsPeers - > getOwnId ( ) ) // SSL id // This is treated appart, because otherwise we don't receive any disc info about us
return rsPeers - > getFriendList ( proxyIds ) ;
2008-02-04 16:40:34 -05:00
RsStackMutex stack ( mDiscMtx ) ; /********** STACK LOCKED MTX ******/
2008-02-03 01:29:02 -05:00
std : : map < std : : string , autoneighbour > : : iterator it ;
std : : map < std : : string , autoserver > : : iterator sit ;
if ( neighbours . end ( ) = = ( it = neighbours . find ( id ) ) )
2007-12-11 20:43:17 -05:00
{
2008-02-03 01:29:02 -05:00
return false ;
}
2007-12-11 20:43:17 -05:00
2010-11-14 16:03:36 -05:00
for ( sit = it - > second . neighbour_of . begin ( ) ; sit ! = it - > second . neighbour_of . end ( ) ; sit + + )
2008-02-03 01:29:02 -05:00
{
proxyIds . push_back ( sit - > first ) ;
}
return true ;
}
2010-11-14 16:03:36 -05:00
bool p3disc : : potentialGPGproxies ( const std : : string & gpg_id , std : : list < std : : string > & proxyGPGIds )
{
/* find id -> and extract the neighbour_of ids */
if ( gpg_id = = rsPeers - > getGPGOwnId ( ) ) // SSL id // This is treated appart, because otherwise we don't receive any disc info about us
return rsPeers - > getGPGAcceptedList ( proxyGPGIds ) ;
RsStackMutex stack ( mDiscMtx ) ; /********** STACK LOCKED MTX ******/
std : : map < std : : string , std : : set < std : : string > > : : iterator it = gpg_neighbors . find ( gpg_id ) ;
if ( it = = gpg_neighbors . end ( ) )
return false ;
for ( std : : set < std : : string > : : const_iterator sit ( it - > second . begin ( ) ) ; sit ! = it - > second . end ( ) ; + + sit )
proxyGPGIds . push_back ( * sit ) ;
return true ;
}
2007-12-11 20:43:17 -05:00
2009-06-28 16:57:02 -04:00
void p3disc : : getversions ( std : : map < std : : string , std : : string > & versions )
{
versions = this - > versions ;
}
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
int p3disc : : idServers ( )
{
2008-02-04 16:40:34 -05:00
RsStackMutex stack ( mDiscMtx ) ; /********** STACK LOCKED MTX ******/
2008-02-03 01:29:02 -05:00
std : : map < std : : string , autoneighbour > : : iterator nit ;
std : : map < std : : string , autoserver > : : iterator sit ;
int cts = time ( NULL ) ;
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
std : : ostringstream out ;
out < < " ::::AutoDiscovery Neighbours:::: " < < std : : endl ;
for ( nit = neighbours . begin ( ) ; nit ! = neighbours . end ( ) ; nit + + )
{
out < < " Neighbour: " < < ( nit - > second ) . id ;
out < < std : : endl ;
out < < " -> LocalAddr: " ;
2010-07-10 16:34:03 -04:00
out < < rs_inet_ntoa ( nit - > second . localAddr . sin_addr ) ;
2008-02-03 01:29:02 -05:00
out < < " : " < < ntohs ( nit - > second . localAddr . sin_port ) < < std : : endl ;
out < < " -> RemoteAddr: " ;
2010-07-10 16:34:03 -04:00
out < < rs_inet_ntoa ( nit - > second . remoteAddr . sin_addr ) ;
2008-02-03 01:29:02 -05:00
out < < " : " < < ntohs ( nit - > second . remoteAddr . sin_port ) < < std : : endl ;
out < < " Last Contact: " ;
out < < cts - ( nit - > second . ts ) < < " sec ago " ;
out < < std : : endl ;
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
out < < " -->DiscFlags: 0x " < < std : : hex < < nit - > second . discFlags ;
out < < std : : dec < < std : : endl ;
2007-12-11 20:43:17 -05:00
2009-06-28 16:57:02 -04:00
for ( sit = ( nit - > second . neighbour_of ) . begin ( ) ;
2008-02-03 01:29:02 -05:00
sit ! = ( nit - > second . neighbour_of ) . end ( ) ; sit + + )
2007-12-11 20:43:17 -05:00
{
2008-02-03 01:29:02 -05:00
out < < " \t Connected via: " < < ( sit - > first ) ;
2007-12-11 20:43:17 -05:00
out < < std : : endl ;
2008-02-03 01:29:02 -05:00
out < < " \t \t LocalAddr: " ;
2010-07-10 16:34:03 -04:00
out < < rs_inet_ntoa ( sit - > second . localAddr . sin_addr ) ;
2008-02-04 16:40:34 -05:00
out < < " : " < < ntohs ( sit - > second . localAddr . sin_port ) ;
2007-12-11 20:43:17 -05:00
out < < std : : endl ;
2008-02-03 01:29:02 -05:00
out < < " \t \t RemoteAddr: " ;
2010-07-10 16:34:03 -04:00
out < < rs_inet_ntoa ( sit - > second . remoteAddr . sin_addr ) ;
2008-02-03 01:29:02 -05:00
out < < " : " < < ntohs ( sit - > second . remoteAddr . sin_port ) ;
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
out < < std : : endl ;
out < < " \t \t Last Contact: " ;
out < < cts - ( sit - > second . ts ) < < " sec ago " ;
out < < std : : endl ;
out < < " \t \t DiscFlags: 0x " < < std : : hex < < ( sit - > second . discFlags ) ;
out < < std : : dec < < std : : endl ;
2007-12-11 20:43:17 -05:00
}
}
2008-02-03 01:29:02 -05:00
# ifdef P3DISC_DEBUG
std : : cerr < < " p3disc::idServers() " < < std : : endl ;
std : : cerr < < out . str ( ) ;
std : : cerr < < std : : endl ;
# endif
2007-12-11 20:43:17 -05:00
2008-02-03 01:29:02 -05:00
return 1 ;
}
2007-12-11 20:43:17 -05:00
// tdelta -> trange.
// -inf...<0 0 (invalid)
// 0.. <9 1
// 9...<99 2
// 99...<999 3
// 999...<9999 4
// etc...
2010-02-23 16:55:29 -05:00
//int convertTDeltaToTRange(double tdelta)
//{
// if (tdelta < 0)
// return 0;
// int trange = 1 + (int) log10(tdelta + 1.0);
// return trange;
//
//}
2007-12-11 20:43:17 -05:00
// trange -> tdelta
// -inf...0 -1 (invalid)
// 1 8
// 2 98
// 3 998
// 4 9998
// etc...
2010-02-23 16:55:29 -05:00
//int convertTRangeToTDelta(int trange)
//{
// if (trange <= 0)
// return -1;
//
// return (int) (pow(10.0, trange) - 1.5); // (int) xxx98.5 -> xxx98
//}
2007-12-11 20:43:17 -05:00
2010-01-15 16:09:25 -05:00
// -----------------------------------------------------------------------------------//
// -------------------------------- Config functions ------------------------------ //
// -----------------------------------------------------------------------------------//
//
RsSerialiser * p3disc : : setupSerialiser ( )
{
RsSerialiser * rss = new RsSerialiser ;
rss - > addSerialType ( new RsGeneralConfigSerialiser ( ) ) ;
return rss ;
}
std : : list < RsItem * > p3disc : : saveList ( bool & cleanup )
{
2010-02-07 16:28:40 -05:00
# ifdef P3DISC_DEBUG
std : : cerr < < " p3disc::saveList() called " < < std : : endl ;
# endif
2010-01-15 16:09:25 -05:00
cleanup = true ;
std : : list < RsItem * > lst ;
// Now save config for network digging strategies
RsConfigKeyValueSet * vitem = new RsConfigKeyValueSet ;
std : : map < std : : string , time_t > : : iterator mapIt ;
for ( mapIt = deletedSSLFriendsIds . begin ( ) ; mapIt ! = deletedSSLFriendsIds . end ( ) ; mapIt + + ) {
RsTlvKeyValue kv ;
kv . key = mapIt - > first ;
std : : ostringstream time_string ;
time_string < < mapIt - > second ;
kv . value = time_string . str ( ) ;
vitem - > tlvkvs . pairs . push_back ( kv ) ;
2010-02-07 16:28:40 -05:00
# ifdef P3DISC_DEBUG
2010-01-15 16:09:25 -05:00
std : : cerr < < " p3disc::saveList() saving : " < < mapIt - > first < < " ; " < < mapIt - > second < < std : : endl ;
2010-02-07 16:28:40 -05:00
# endif
2010-01-15 16:09:25 -05:00
}
lst . push_back ( vitem ) ;
return lst ;
}
bool p3disc : : loadList ( std : : list < RsItem * > load )
{
2010-02-07 16:28:40 -05:00
# ifdef P3DISC_DEBUG
2010-01-15 16:09:25 -05:00
std : : cerr < < " p3disc::loadList() Item Count: " < < load . size ( ) < < std : : endl ;
2010-02-07 16:28:40 -05:00
# endif
2010-01-15 16:09:25 -05:00
RsStackMutex stack ( mDiscMtx ) ; /****** STACK LOCK MUTEX *******/
/* load the list of accepted gpg keys */
std : : list < RsItem * > : : iterator it ;
for ( it = load . begin ( ) ; it ! = load . end ( ) ; it + + ) {
RsConfigKeyValueSet * vitem = dynamic_cast < RsConfigKeyValueSet * > ( * it ) ;
if ( vitem ) {
2010-02-07 16:28:40 -05:00
# ifdef P3DISC_DEBUG
2010-01-15 16:09:25 -05:00
std : : cerr < < " p3disc::loadList() General Variable Config Item: " < < std : : endl ;
vitem - > print ( std : : cerr , 10 ) ;
std : : cerr < < std : : endl ;
2010-02-07 16:28:40 -05:00
# endif
2010-01-15 16:09:25 -05:00
std : : list < RsTlvKeyValue > : : iterator kit ;
for ( kit = vitem - > tlvkvs . pairs . begin ( ) ; kit ! = vitem - > tlvkvs . pairs . end ( ) ; kit + + ) {
std : : istringstream instream ( kit - > value ) ;
time_t deleted_time_t ;
instream > > deleted_time_t ;
deletedSSLFriendsIds [ kit - > key ] = deleted_time_t ;
}
}
delete ( * it ) ;
}
return true ;
}