2008-01-25 01:36:40 -05:00
/*
* libretroshare / src / pqi : p3connmgr . cc
*
* 3 P / PQI network interface for RetroShare .
*
* Copyright 2007 - 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 " .
*
*/
# include "pqi/p3connmgr.h"
2008-08-16 11:02:24 -04:00
# include "pqi/p3dhtmgr.h" // Only need it for constants.
2008-01-25 01:36:40 -05:00
# include "tcponudp/tou.h"
2009-04-03 05:21:20 -04:00
# include "tcponudp/extaddrfinder.h"
2009-11-11 11:47:10 -05:00
# include "util/rsnet.h"
2008-07-10 12:29:18 -04:00
2008-01-25 01:36:40 -05:00
# include "util/rsprint.h"
2008-07-10 12:29:18 -04:00
# include "util/rsdebug.h"
const int p3connectzone = 3431 ;
2008-01-25 01:36:40 -05:00
2008-02-07 11:18:34 -05:00
# include "serialiser/rsconfigitems.h"
2008-03-31 10:06:59 -04:00
# include "pqi/pqinotify.h"
2008-02-07 11:18:34 -05:00
2008-07-10 12:29:18 -04:00
# include <sstream>
2008-01-25 01:36:40 -05:00
/* Network setup States */
2009-10-29 20:36:56 -04:00
const uint32_t RS_NET_NEED_RESET = 0x0000 ;
2008-01-25 01:36:40 -05:00
const uint32_t RS_NET_UNKNOWN = 0x0001 ;
const uint32_t RS_NET_UPNP_INIT = 0x0002 ;
2009-10-29 20:44:44 -04:00
const uint32_t RS_NET_UPNP_SETUP = 0x0004 ;
const uint32_t RS_NET_DONE = 0x0005 ;
const uint32_t RS_NET_LOOPBACK = 0x0006 ;
const uint32_t RS_NET_MODE_DOWN = 0x0007 ;
2008-01-25 01:36:40 -05:00
/* Stun modes (TODO) */
const uint32_t RS_STUN_DHT = 0x0001 ;
const uint32_t RS_STUN_DONE = 0x0002 ;
const uint32_t RS_STUN_LIST_MIN = 100 ;
2008-03-05 11:32:18 -05:00
const uint32_t RS_STUN_FOUND_MIN = 10 ;
2008-01-25 01:36:40 -05:00
2009-11-16 05:53:17 -05:00
const uint32_t MAX_UPNP_INIT = 60 ; /* seconds UPnP timeout */
const uint32_t MAX_NETWORK_INIT = 70 ; /* timeout before network reset */
2009-10-29 20:35:12 -04:00
2009-10-29 20:37:45 -04:00
const uint32_t MIN_TIME_BETWEEN_NET_RESET = 5 ;
2008-01-25 01:36:40 -05:00
2009-12-13 16:59:26 -05:00
const uint32_t PEER_IP_CONNECT_STATE_MAX_LIST_SIZE = 6 ;
2009-11-11 11:47:10 -05:00
2008-03-03 09:01:52 -05:00
/****
* # define CONN_DEBUG 1
* * */
/****
* # define P3CONNMGR_NO_TCP_CONNECTIONS 1
* * */
2008-03-02 09:25:59 -05:00
/****
* # define P3CONNMGR_NO_AUTO_CONNECTION 1
* * */
2008-03-26 11:35:09 -04:00
const uint32_t P3CONNMGR_TCP_DEFAULT_DELAY = 2 ; /* 2 Seconds? is it be enough! */
2009-12-13 16:59:26 -05:00
const uint32_t P3CONNMGR_UDP_DEFAULT_DELAY = 2 ; /* 2 Seconds? is it be enough! */
2009-12-14 16:20:17 -05:00
const uint32_t P3CONNMGR_UDP_DEFAULT_PERIOD = 20 ; //a random timeout is set between P3CONNMGR_UDP_DEFAULT_PERIOD and 2 * P3CONNMGR_UDP_DEFAULT_PERIOD in the implementation
2008-03-03 09:01:52 -05:00
2009-12-13 16:59:26 -05:00
# define MAX_AVAIL_PERIOD 180 //times a peer stay in available state when not connected
# define MIN_RETRY_PERIOD 90
2008-01-25 01:36:40 -05:00
2008-02-08 12:05:55 -05:00
void printConnectState ( peerConnectState & peer ) ;
2008-01-25 01:36:40 -05:00
peerConnectAddress : : peerConnectAddress ( )
2008-02-26 21:32:20 -05:00
: delay ( 0 ) , period ( 0 ) , type ( 0 ) , ts ( 0 )
2008-01-25 01:36:40 -05:00
{
2008-02-03 07:07:59 -05:00
sockaddr_clear ( & addr ) ;
2008-01-25 01:36:40 -05:00
}
peerAddrInfo : : peerAddrInfo ( )
: found ( false ) , type ( 0 ) , ts ( 0 )
{
2008-02-03 07:07:59 -05:00
sockaddr_clear ( & laddr ) ;
sockaddr_clear ( & raddr ) ;
2008-01-25 01:36:40 -05:00
}
peerConnectState : : peerConnectState ( )
2008-02-07 11:18:34 -05:00
: id ( " unknown " ) ,
2008-01-25 01:36:40 -05:00
netMode ( RS_NET_MODE_UNKNOWN ) , visState ( RS_VIS_STATE_STD ) ,
2008-02-07 11:18:34 -05:00
lastcontact ( 0 ) ,
2008-03-26 11:35:09 -04:00
connecttype ( 0 ) ,
2008-03-02 09:25:59 -05:00
lastavailable ( 0 ) ,
lastattempt ( 0 ) ,
2008-02-07 11:18:34 -05:00
name ( " nameless " ) , state ( 0 ) , actions ( 0 ) ,
source ( 0 ) ,
2008-03-02 09:25:59 -05:00
inConnAttempt ( 0 )
2008-01-25 01:36:40 -05:00
{
2009-11-11 11:43:51 -05:00
sockaddr_clear ( & currentlocaladdr ) ;
sockaddr_clear ( & currentserveraddr ) ;
2008-01-25 01:36:40 -05:00
return ;
}
2009-08-04 19:22:44 -04:00
std : : string textPeerConnectState ( peerConnectState & state )
{
std : : ostringstream out ;
out < < " Id: " < < state . id < < std : : endl ;
out < < " NetMode: " < < state . netMode < < std : : endl ;
out < < " VisState: " < < state . visState < < std : : endl ;
2009-11-11 11:43:51 -05:00
out < < " laddr: " < < inet_ntoa ( state . currentlocaladdr . sin_addr )
< < " : " < < ntohs ( state . currentlocaladdr . sin_port ) < < std : : endl ;
out < < " eaddr: " < < inet_ntoa ( state . currentserveraddr . sin_addr )
< < " : " < < ntohs ( state . currentserveraddr . sin_port ) < < std : : endl ;
2009-08-04 19:22:44 -04:00
std : : string output = out . str ( ) ;
return output ;
}
2008-02-07 11:18:34 -05:00
p3ConnectMgr : : p3ConnectMgr ( p3AuthMgr * am )
: p3Config ( CONFIG_TYPE_PEERS ) ,
2008-08-16 11:02:24 -04:00
mAuthMgr ( am ) , mNetStatus ( RS_NET_UNKNOWN ) ,
2008-03-05 11:32:18 -05:00
mStunStatus ( 0 ) , mStunFound ( 0 ) , mStunMoreRequired ( true ) ,
mStatusChanged ( false )
2008-02-07 11:18:34 -05:00
{
/* setup basics of own state */
if ( am )
{
ownState . id = mAuthMgr - > OwnId ( ) ;
ownState . name = mAuthMgr - > getName ( ownState . id ) ;
ownState . netMode = RS_NET_MODE_UDP ;
}
2009-05-23 11:07:35 -04:00
//use_extr_addr_finder = true ;
use_extr_addr_finder = false ;
2009-12-13 16:59:26 -05:00
allow_tunnel_connection = true ;
2009-04-05 09:04:18 -04:00
mExtAddrFinder = new ExtAddrFinder ;
2008-02-07 11:18:34 -05:00
return ;
}
2009-04-05 09:04:18 -04:00
void p3ConnectMgr : : getIPServersList ( std : : list < std : : string > & ip_servers )
{
mExtAddrFinder - > getIPServersList ( ip_servers ) ;
}
void p3ConnectMgr : : setIPServersEnabled ( bool b )
{
use_extr_addr_finder = b ;
2009-04-09 17:13:48 -04:00
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2009-04-05 09:04:18 -04:00
std : : cerr < < " p3ConnectMgr: setIPServers to " < < b < < std : : endl ;
}
2008-02-07 11:18:34 -05:00
2009-12-13 16:59:26 -05:00
void p3ConnectMgr : : setTunnelConnection ( bool b )
{
allow_tunnel_connection = b ;
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
}
2008-02-07 11:18:34 -05:00
void p3ConnectMgr : : setOwnNetConfig ( uint32_t netMode , uint32_t visState )
{
2008-02-26 11:14:13 -05:00
/* only change TRY flags */
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::setOwnNetConfig() " < < std : : endl ;
std : : cerr < < " Existing netMode: " < < ownState . netMode < < " vis: " < < ownState . visState ;
std : : cerr < < std : : endl ;
std : : cerr < < " Input netMode: " < < netMode < < " vis: " < < visState ;
std : : cerr < < std : : endl ;
# endif
ownState . netMode & = ~ ( RS_NET_MODE_TRYMODE ) ;
# ifdef CONN_DEBUG
std : : cerr < < " After Clear netMode: " < < ownState . netMode < < " vis: " < < ownState . visState ;
std : : cerr < < std : : endl ;
# endif
switch ( netMode & RS_NET_MODE_ACTUAL )
{
case RS_NET_MODE_EXT :
ownState . netMode | = RS_NET_MODE_TRY_EXT ;
break ;
case RS_NET_MODE_UPNP :
ownState . netMode | = RS_NET_MODE_TRY_UPNP ;
break ;
default :
case RS_NET_MODE_UDP :
ownState . netMode | = RS_NET_MODE_TRY_UDP ;
break ;
}
2008-02-07 11:18:34 -05:00
ownState . visState = visState ;
2008-02-26 11:14:13 -05:00
# ifdef CONN_DEBUG
std : : cerr < < " Final netMode: " < < ownState . netMode < < " vis: " < < ownState . visState ;
std : : cerr < < std : : endl ;
# endif
2008-02-07 11:18:34 -05:00
/* if we've started up - then tweak Dht On/Off */
if ( mNetStatus ! = RS_NET_UNKNOWN )
{
2009-12-14 08:46:38 -05:00
//enableNetAssistConnect(!(ownState.visState & RS_VIS_STATE_NODHT));
//DHT disabled
2008-02-07 11:18:34 -05:00
}
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
}
2008-01-25 01:36:40 -05:00
/***** Framework / initial implementation for a connection manager.
*
* This needs a state machine for Initialisation .
*
* Network state :
* RS_NET_UNKNOWN
* RS_NET_EXT_UNKNOWN * forwarded port ( but Unknown Ext IP ) *
* RS_NET_EXT_KNOWN * forwarded port with known IP / Port . *
*
* RS_NET_UPNP_CHECK * checking for UPnP *
* RS_NET_UPNP_KNOWN * confirmed UPnP ext Ip / port *
*
* RS_NET_UDP_UNKNOWN * not Ext / UPnP - to determine Ext IP / Port *
* RS_NET_UDP_KNOWN * have Stunned for Ext Addr *
*
* Transitions :
*
* RS_NET_UNKNOWN - ( config ) - > RS_NET_EXT_UNKNOWN
* RS_NET_UNKNOWN - ( config ) - > RS_NET_UPNP_UNKNOWN
* RS_NET_UNKNOWN - ( config ) - > RS_NET_UDP_UNKNOWN
*
* RS_NET_EXT_UNKNOWN - ( DHT ( ip ) / Stun ) - > RS_NET_EXT_KNOWN
*
* RS_NET_UPNP_UNKNOWN - ( Upnp ) - > RS_NET_UPNP_KNOWN
* RS_NET_UPNP_UNKNOWN - ( timout / Upnp ) - > RS_NET_UDP_UNKNOWN
*
* RS_NET_UDP_UNKNOWN - ( stun ) - > RS_NET_UDP_KNOWN
*
*
* STUN state :
* RS_STUN_INIT * done nothing *
* RS_STUN_DHT * looking up peers *
* RS_STUN_DONE * found active peer and stunned *
*
*
* Steps .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* ( 1 ) Startup .
* - UDP port setup .
* - DHT setup .
* - Get Stun Keys - > add to DHT .
* - Feedback from DHT - > ask UDP to stun .
*
* ( 1 ) determine Network mode .
* If external Port . . . . Done :
* ( 2 )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Stable operation :
* ( 1 ) tick and check peers .
* ( 2 ) handle callback .
* ( 3 ) notify of new / failed connections .
*
*
*/
2009-08-04 19:22:44 -04:00
/* Called to reseet the whole network stack. this call is
* triggered by udp stun address tracking .
*
* must :
* - reset UPnP and DHT .
* -
*/
void p3ConnectMgr : : netReset ( )
{
2009-10-29 20:35:12 -04:00
2009-08-04 19:22:44 -04:00
std : : cerr < < " p3ConnectMgr::netReset() " < < std : : endl ;
2009-10-29 20:35:12 -04:00
//don't do a net reset if the MIN_TIME_BETWEEN_NET_RESET is not reached
time_t delta = time ( NULL ) - mNetInitTS ;
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr time since last reset : " < < delta < < std : : endl ;
# endif
if ( delta < MIN_TIME_BETWEEN_NET_RESET ) {
2009-10-29 20:36:56 -04:00
{
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
mNetStatus = RS_NET_NEED_RESET ;
}
2009-10-29 20:35:12 -04:00
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::netStartup() don't do a net reset if the MIN_TIME_BETWEEN_NET_RESET is not reached " < < std : : endl ;
# endif
return ;
}
2009-08-04 19:22:44 -04:00
std : : cerr < < " p3ConnectMgr::netReset() shutdown " < < std : : endl ;
shutdown ( ) ; /* blocking shutdown call */
2009-11-06 17:12:58 -05:00
// Will initiate a new call for determining the external ip.
mExtAddrFinder - > reset ( ) ;
2009-08-04 19:22:44 -04:00
std : : cerr < < " p3ConnectMgr::netReset() reset NetStatus " < < std : : endl ;
{
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
mNetStatus = RS_NET_UNKNOWN ;
2009-10-29 20:37:12 -04:00
netStatusReset ( ) ;
2009-08-04 19:22:44 -04:00
}
std : : cerr < < " p3ConnectMgr::netReset() checkNetAddress " < < std : : endl ;
/* check Network Address */
checkNetAddress ( ) ;
/* reset udp network - handled by tou_init! */
/* reset tcp network - if necessary */
{
/* NOTE: nNetListeners should be protected via the Mutex.
* HOWEVER , as we NEVER change this list - once its setup
* we can get away without it - and assume its constant .
*
* NB : ( * it ) - > reset_listener must be out of the mutex ,
* as it calls back to p3ConnMgr .
*/
std : : cerr < < " p3ConnectMgr::netReset() resetting listeners " < < std : : endl ;
std : : list < pqiNetListener * > : : const_iterator it ;
for ( it = mNetListeners . begin ( ) ; it ! = mNetListeners . end ( ) ; it + + )
{
std : : cerr < < " p3ConnectMgr::netReset() reset listener " < < std : : endl ;
( * it ) - > reset_listener ( ) ;
}
}
std : : cerr < < " p3ConnectMgr::netReset() done " < < std : : endl ;
}
/* to allow resets of network stuff */
void p3ConnectMgr : : addNetListener ( pqiNetListener * listener )
{
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
mNetListeners . push_back ( listener ) ;
}
2008-10-18 12:02:06 -04:00
void p3ConnectMgr : : netStatusReset ( )
{
2009-10-29 20:41:24 -04:00
//std::cerr << "p3ConnectMgr::netStatusReset()" << std::endl;;
netFlagExtraAddressCheckOk = false ;
netFlagLocalOk = false ;
2008-10-18 12:02:06 -04:00
netFlagUpnpOk = false ;
netFlagDhtOk = false ;
2009-10-29 20:41:24 -04:00
netFlagStunOk = false ;
2009-11-06 17:42:41 -05:00
for ( std : : map < std : : string , peerConnectState > : : iterator it = mFriendList . begin ( ) ; it ! = mFriendList . end ( ) ; it + + )
{
it - > second . state & = ~ RS_PEER_S_CONNECTED ;
2009-11-06 17:56:01 -05:00
it - > second . lastattempt = time ( NULL ) - MIN_RETRY_PERIOD + 5 ; // forces immediate re-connexion in 5 seconds
2009-11-06 17:42:41 -05:00
}
2009-10-29 20:38:02 -04:00
IndicateConfigChanged ( ) ;
2008-10-18 12:02:06 -04:00
}
2008-01-25 01:36:40 -05:00
void p3ConnectMgr : : netStartup ( )
{
/* startup stuff */
/* StunInit gets a list of peers, and asks the DHT to find them...
* This is needed for all systems so startup straight away
*/
2008-02-28 05:43:33 -05:00
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::netStartup() " < < std : : endl ;
# endif
2008-01-25 01:36:40 -05:00
2009-12-14 08:46:38 -05:00
//netDhtInit(); //DHT disabled
2008-01-25 01:36:40 -05:00
netUdpInit ( ) ;
netStunInit ( ) ;
/* decide which net setup mode we're going into
*/
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2009-10-29 20:38:52 -04:00
netStatusReset ( ) ;
2008-01-25 01:36:40 -05:00
mNetInitTS = time ( NULL ) ;
2008-02-28 05:43:33 -05:00
# ifdef CONN_DEBUG
2009-10-29 20:35:12 -04:00
std : : cerr < < " p3ConnectMgr::netStartup() resetting mNetInitTS timestamp " < < std : : endl ;
2008-02-28 05:43:33 -05:00
std : : cerr < < " p3ConnectMgr::netStartup() tou_stunkeepalive() enabled " < < std : : endl ;
# endif
tou_stunkeepalive ( 1 ) ;
2009-08-04 19:22:44 -04:00
mStunMoreRequired = true ;
2008-02-28 05:43:33 -05:00
2008-02-26 11:14:13 -05:00
ownState . netMode & = ~ ( RS_NET_MODE_ACTUAL ) ;
switch ( ownState . netMode & RS_NET_MODE_TRYMODE )
2008-01-25 01:36:40 -05:00
{
2009-11-18 12:46:38 -05:00
case RS_NET_MODE_TRY_EXT : /* v similar to UDP */
ownState . netMode | = RS_NET_MODE_EXT ;
mNetStatus = RS_NET_DONE ;
break ;
2008-02-26 11:14:13 -05:00
case RS_NET_MODE_TRY_UDP :
ownState . netMode | = RS_NET_MODE_UDP ;
2009-10-29 20:41:24 -04:00
mNetStatus = RS_NET_DONE ;
2008-01-25 01:36:40 -05:00
break ;
2008-03-02 09:25:59 -05:00
case RS_NET_MODE_TRY_UPNP :
default :
2008-03-03 09:01:52 -05:00
/* Force it here (could be default!) */
ownState . netMode | = RS_NET_MODE_TRY_UPNP ;
2008-03-23 18:27:43 -04:00
ownState . netMode | = RS_NET_MODE_UDP ; /* set to UDP, upgraded is UPnP is Okay */
2008-03-02 09:25:59 -05:00
mNetStatus = RS_NET_UPNP_INIT ;
break ;
2008-01-25 01:36:40 -05:00
}
}
void p3ConnectMgr : : tick ( )
{
netTick ( ) ;
2008-03-02 09:25:59 -05:00
statusTick ( ) ;
2008-01-25 01:36:40 -05:00
tickMonitors ( ) ;
}
2008-04-09 08:54:15 -04:00
bool p3ConnectMgr : : shutdown ( ) /* blocking shutdown call */
{
2009-10-29 20:37:45 -04:00
{
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
mNetStatus = RS_NET_UNKNOWN ;
mNetInitTS = time ( NULL ) ;
netStatusReset ( ) ;
}
2009-10-29 20:37:12 -04:00
netAssistFirewallShutdown ( ) ;
2008-08-16 11:02:24 -04:00
netAssistConnectShutdown ( ) ;
2008-04-09 08:54:15 -04:00
return true ;
}
2008-03-02 09:25:59 -05:00
void p3ConnectMgr : : statusTick ( )
{
/* iterate through peers ...
* if been available for long time . . . remove flag
* if last attempt a while - retryConnect .
* etc .
*/
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::statusTick() " < < std : : endl ;
2008-03-02 09:25:59 -05:00
# endif
std : : list < std : : string > retryIds ;
std : : list < std : : string > : : iterator it2 ;
time_t now = time ( NULL ) ;
time_t oldavail = now - MAX_AVAIL_PERIOD ;
time_t retry = now - MIN_RETRY_PERIOD ;
{
RsStackMutex stack ( connMtx ) ; /****** LOCK MUTEX ******/
std : : map < std : : string , peerConnectState > : : iterator it ;
for ( it = mFriendList . begin ( ) ; it ! = mFriendList . end ( ) ; it + + )
{
if ( it - > second . state & RS_PEER_S_CONNECTED )
{
continue ;
}
if ( ( it - > second . state & RS_PEER_S_ONLINE ) & &
( it - > second . lastavailable < oldavail ) )
{
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::statusTick() ONLINE TIMEOUT for: " ;
std : : cerr < < it - > first ;
std : : cerr < < std : : endl ;
# endif
it - > second . state & = ( ~ RS_PEER_S_ONLINE ) ;
}
if ( it - > second . lastattempt < retry )
{
retryIds . push_back ( it - > first ) ;
}
}
}
# ifndef P3CONNMGR_NO_AUTO_CONNECTION
for ( it2 = retryIds . begin ( ) ; it2 ! = retryIds . end ( ) ; it2 + + )
{
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::statusTick() RETRY TIMEOUT for: " ;
std : : cerr < < * it2 ;
std : : cerr < < std : : endl ;
# endif
/* retry it! */
2008-03-03 09:01:52 -05:00
retryConnectTCP ( * it2 ) ;
2008-03-02 09:25:59 -05:00
}
# endif
}
2008-01-25 01:36:40 -05:00
void p3ConnectMgr : : netTick ( )
{
# ifdef CONN_DEBUG
2008-02-03 01:29:02 -05:00
//std::cerr << "p3ConnectMgr::netTick()" << std::endl;
2008-01-25 01:36:40 -05:00
# endif
2009-04-09 17:13:48 -04:00
// Check whether we are stuck on loopback. This happens if RS starts when
// the computer is not yet connected to the internet. In such a case we
// periodically check for a local net address.
//
2009-10-29 20:36:56 -04:00
checkNetAddress ( ) ;
2009-10-29 20:41:24 -04:00
networkConsistencyCheck ( ) ; /* check consistency. If not consistent, do a reset inside networkConsistencyCheck() */
2009-04-09 17:13:48 -04:00
2008-01-25 01:36:40 -05:00
connMtx . lock ( ) ; /* LOCK MUTEX */
uint32_t netStatus = mNetStatus ;
connMtx . unlock ( ) ; /* UNLOCK MUTEX */
switch ( netStatus )
{
2009-10-29 20:36:56 -04:00
case RS_NET_NEED_RESET :
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::netTick() STATUS: NEED_RESET " < < std : : endl ;
# endif
netReset ( ) ;
break ;
2008-01-25 01:36:40 -05:00
2009-10-29 20:36:56 -04:00
case RS_NET_UNKNOWN :
2008-01-25 01:36:40 -05:00
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::netTick() STATUS: UNKNOWN " < < std : : endl ;
# endif
netStartup ( ) ;
break ;
case RS_NET_UPNP_INIT :
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::netTick() STATUS: UPNP_INIT " < < std : : endl ;
# endif
2009-11-12 17:19:45 -05:00
netExtFinderAddressCheck ( ) ;
2008-01-25 01:36:40 -05:00
netUpnpInit ( ) ;
break ;
case RS_NET_UPNP_SETUP :
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::netTick() STATUS: UPNP_SETUP " < < std : : endl ;
# endif
netUpnpCheck ( ) ;
break ;
case RS_NET_DONE :
# ifdef CONN_DEBUG
2008-02-03 01:29:02 -05:00
//std::cerr << "p3ConnectMgr::netTick() STATUS: DONE" << std::endl;
2008-01-25 01:36:40 -05:00
# endif
2009-10-29 20:41:24 -04:00
2009-10-29 20:36:56 -04:00
break ;
case RS_NET_LOOPBACK :
2009-12-14 08:46:23 -05:00
//don't do a shutdown because a client in a computer without local network might be usefull for debug.
2009-11-16 05:53:17 -05:00
//shutdown();
2009-10-29 20:36:56 -04:00
# ifdef CONN_DEBUG
2009-11-16 05:53:17 -05:00
std : : cerr < < " p3ConnectMgr::netTick() STATUS: RS_NET_LOOPBACK " < < std : : endl ;
2009-10-29 20:36:56 -04:00
# endif
2008-01-25 01:36:40 -05:00
default :
break ;
}
return ;
}
void p3ConnectMgr : : netUdpInit ( )
{
2008-02-28 05:43:33 -05:00
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::netUdpInit() " < < std : : endl ;
# endif
2008-01-25 01:36:40 -05:00
connMtx . lock ( ) ; /* LOCK MUTEX */
2009-11-11 11:43:51 -05:00
struct sockaddr_in iaddr = ownState . currentlocaladdr ;
2008-01-25 01:36:40 -05:00
connMtx . unlock ( ) ; /* UNLOCK MUTEX */
/* open our udp port */
tou_init ( ( struct sockaddr * ) & iaddr , sizeof ( iaddr ) ) ;
}
void p3ConnectMgr : : netDhtInit ( )
{
2008-02-28 05:43:33 -05:00
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::netDhtInit() " < < std : : endl ;
# endif
2008-01-25 01:36:40 -05:00
connMtx . lock ( ) ; /* LOCK MUTEX */
uint32_t vs = ownState . visState ;
connMtx . unlock ( ) ; /* UNLOCK MUTEX */
2009-12-14 08:46:38 -05:00
//enableNetAssistConnect(!(vs & RS_VIS_STATE_NODHT));
//DHT disabled
2008-01-25 01:36:40 -05:00
}
void p3ConnectMgr : : netUpnpInit ( )
{
2008-02-28 05:43:33 -05:00
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::netUpnpInit() " < < std : : endl ;
# endif
2008-01-25 01:36:40 -05:00
uint16_t eport , iport ;
connMtx . lock ( ) ; /* LOCK MUTEX */
/* get the ports from the configuration */
mNetStatus = RS_NET_UPNP_SETUP ;
2009-11-11 11:43:51 -05:00
iport = ntohs ( ownState . currentlocaladdr . sin_port ) ;
eport = ntohs ( ownState . currentserveraddr . sin_port ) ;
2008-02-11 18:27:17 -05:00
if ( ( eport < 1000 ) | | ( eport > 30000 ) )
2008-02-11 11:27:55 -05:00
{
eport = iport ;
}
2008-01-25 01:36:40 -05:00
connMtx . unlock ( ) ; /* UNLOCK MUTEX */
2008-08-16 11:02:24 -04:00
netAssistFirewallPorts ( iport , eport ) ;
enableNetAssistFirewall ( true ) ;
2008-01-25 01:36:40 -05:00
}
void p3ConnectMgr : : netUpnpCheck ( )
{
/* grab timestamp */
connMtx . lock ( ) ; /* LOCK MUTEX */
time_t delta = time ( NULL ) - mNetInitTS ;
2009-10-29 20:35:12 -04:00
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr time since last reset : " < < delta < < std : : endl ;
# endif
2008-01-25 01:36:40 -05:00
connMtx . unlock ( ) ; /* UNLOCK MUTEX */
struct sockaddr_in extAddr ;
2008-08-16 11:02:24 -04:00
int upnpState = netAssistFirewallActive ( ) ;
2008-01-25 01:36:40 -05:00
2009-10-29 20:39:26 -04:00
if ( ( upnpState = = 0 ) & & ( delta > MAX_UPNP_INIT ) )
2008-01-25 01:36:40 -05:00
{
2009-10-29 20:35:12 -04:00
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::netUpnpCheck() " ;
std : : cerr < < " Upnp Check failed. " < < std : : endl ;
# endif
2008-01-25 01:36:40 -05:00
/* fallback to UDP startup */
connMtx . lock ( ) ; /* LOCK MUTEX */
2008-02-26 11:14:13 -05:00
/* UPnP Failed us! */
2009-10-29 20:41:24 -04:00
mNetStatus = RS_NET_DONE ;
2008-01-25 01:36:40 -05:00
connMtx . unlock ( ) ; /* UNLOCK MUTEX */
}
2009-04-09 17:13:48 -04:00
else if ( ( upnpState > 0 ) & & netAssistExtAddress ( extAddr ) )
2008-01-25 01:36:40 -05:00
{
2009-10-29 20:35:12 -04:00
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::netUpnpCheck() " ;
std : : cerr < < " Upnp Check successed. " < < std : : endl ;
# endif
2008-01-25 01:36:40 -05:00
/* switch to UDP startup */
connMtx . lock ( ) ; /* LOCK MUTEX */
2008-10-18 12:02:06 -04:00
/* Set Net Status flags ....
* we now have external upnp address . Golden !
* don ' t set netOk flag until have seen some traffic .
*/
netFlagUpnpOk = true ;
2009-10-29 20:41:24 -04:00
mNetStatus = RS_NET_DONE ;
2008-02-26 11:14:13 -05:00
/* Fix netMode & Clear others! */
ownState . netMode = RS_NET_MODE_TRY_UPNP | RS_NET_MODE_UPNP ;
2008-01-25 01:36:40 -05:00
connMtx . unlock ( ) ; /* UNLOCK MUTEX */
}
}
2009-10-29 20:41:24 -04:00
void p3ConnectMgr : : networkConsistencyCheck ( )
2008-01-25 01:36:40 -05:00
{
2009-10-29 20:41:24 -04:00
time_t delta ;
2008-02-28 10:58:54 -05:00
# ifdef CONN_DEBUG
2009-10-29 20:41:24 -04:00
delta = time ( NULL ) - mNetInitTS ;
2009-11-16 05:53:17 -05:00
std : : cerr < < " p3ConnectMgr::networkConsistencyCheck() time since last reset : " < < delta < < std : : endl ;
2008-02-28 10:58:54 -05:00
# endif
2009-10-29 20:44:04 -04:00
2009-10-29 20:41:24 -04:00
bool doNetReset = false ;
//if one of the flag is degrated from true to false during last tick, let's do a reset
2009-10-29 20:41:55 -04:00
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::networkConsistencyCheck() net flags : " < < std : : endl ;
std : : cerr < < " oldnetFlagLocalOk : " < < oldnetFlagLocalOk < < " . netFlagLocalOk : " < < netFlagLocalOk < < " . " < < std : : endl ;
std : : cerr < < " oldnetFlagUpnpOk : " < < oldnetFlagUpnpOk < < " . netFlagUpnpOk : " < < netFlagUpnpOk < < " . " < < std : : endl ;
std : : cerr < < " oldnetFlagDhtOk : " < < oldnetFlagDhtOk < < " . netFlagDhtOk : " < < netFlagDhtOk < < " . " < < std : : endl ;
std : : cerr < < " oldnetFlagStunOk : " < < oldnetFlagStunOk < < " . netFlagStunOk : " < < netFlagStunOk < < " . " < < std : : endl ;
std : : cerr < < " oldnetFlagExtraAddressCheckOk : " < < oldnetFlagExtraAddressCheckOk < < " . netFlagExtraAddressCheckOk : " < < netFlagExtraAddressCheckOk < < " . " < < std : : endl ;
# endif
2009-11-16 05:53:17 -05:00
if ( ! netFlagLocalOk
2009-10-29 20:41:24 -04:00
| | ( ! netFlagUpnpOk & & oldnetFlagUpnpOk )
| | ( ! netFlagDhtOk & & oldnetFlagDhtOk )
| | ( ! netFlagStunOk & & oldnetFlagStunOk )
| | ( ! netFlagExtraAddressCheckOk & & oldnetFlagExtraAddressCheckOk )
) {
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::networkConsistencyCheck() A net flag went down. " < < std : : endl ;
# endif
2009-10-29 20:41:55 -04:00
//don't do a normal shutdown for upnp as it might hang up.
2009-11-12 17:19:25 -05:00
//With a 0 port it will just dereference and not attemps to communicate for shutting down upnp session.
2009-10-29 20:41:55 -04:00
netAssistFirewallPorts ( 0 , 0 ) ;
2009-10-29 20:41:24 -04:00
doNetReset = true ;
}
2008-07-10 12:29:18 -04:00
2009-10-29 20:41:24 -04:00
connMtx . lock ( ) ; /* LOCK MUTEX */
//storing old flags
oldnetFlagLocalOk = netFlagLocalOk ;
oldnetFlagUpnpOk = netFlagUpnpOk ;
oldnetFlagDhtOk = netFlagDhtOk ;
oldnetFlagStunOk = netFlagStunOk ;
oldnetFlagExtraAddressCheckOk = netFlagExtraAddressCheckOk ;
2008-02-28 10:58:54 -05:00
2009-11-16 05:53:17 -05:00
if ( ! doNetReset ) { //set an external address. if ip adresses are different, let's use the stun address, then the extaddrfinder and then the upnp address.
2009-11-14 06:59:50 -05:00
struct sockaddr_in extAddr ;
2009-12-14 16:59:15 -05:00
if ( getUpnpExtAddress ( extAddr ) ) {
2009-11-14 06:59:50 -05:00
# ifdef CONN_DEBUG
2009-12-14 16:59:15 -05:00
std : : cerr < < " p3ConnectMgr::networkConsistencyCheck() using getUpnpExtAddress for ownState.serveraddr. " < < std : : endl ;
# endif
ownState . currentserveraddr = extAddr ;
} else if ( getExtFinderExtAddress ( extAddr ) ) {
netExtFinderAddressCheck ( ) ; //so we put the extra address flag ok.
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::networkConsistencyCheck() using getExtFinderExtAddress for ownState.serveraddr. " < < std : : endl ;
2009-11-14 06:59:50 -05:00
# endif
ownState . currentserveraddr = extAddr ;
} else {
2009-12-14 16:59:15 -05:00
//check if a peer is connected, if yes don't do a net reset
bool is_connected = false ;
std : : map < std : : string , peerConnectState > : : iterator it ;
for ( it = mFriendList . begin ( ) ; it ! = mFriendList . end ( ) & & ! is_connected ; it + + )
{
/* get last contact detail */
is_connected = it - > second . state & RS_PEER_S_CONNECTED ;
}
# ifdef CONN_DEBUG
if ( is_connected ) {
std : : cerr < < " p3ConnectMgr::networkConsistencyCheck() not doing a net reset because a peer is connected. " < < std : : endl ;
2009-11-14 06:59:50 -05:00
} else {
2009-12-14 16:59:15 -05:00
std : : cerr < < " p3ConnectMgr::networkConsistencyCheck() no peer is connected. " < < std : : endl ;
2009-11-14 06:59:50 -05:00
}
2009-12-14 16:59:15 -05:00
# endif
doNetReset = ! is_connected ;
2009-11-14 06:59:50 -05:00
}
}
2009-10-29 20:41:24 -04:00
connMtx . unlock ( ) ; /* UNLOCK MUTEX */
2008-01-25 01:36:40 -05:00
2009-11-16 05:53:17 -05:00
if ( ! doNetReset ) {
//extAddr found,update ip address list
IpAddressTimed ipAddressTimed ;
ipAddressTimed . ipAddr = ownState . currentserveraddr ;
ipAddressTimed . seenTime = time ( NULL ) ;
ownState . updateIpAddressList ( ipAddressTimed ) ;
}
//let's do a net reset
2009-10-29 20:41:24 -04:00
if ( doNetReset ) {
//don't do a reset it if the network init is not finished
delta = time ( NULL ) - mNetInitTS ;
if ( delta > MAX_NETWORK_INIT ) {
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::networkConsistencyCheck() doing a net reset. " < < std : : endl ;
# endif
netReset ( ) ;
} else {
2009-10-29 20:44:04 -04:00
# ifdef CONN_DEBUG
2009-10-29 20:41:24 -04:00
std : : cerr < < " p3ConnectMgr::networkConsistencyCheck() reset delayed : p3ConnectMgr time since last reset : " < < delta ;
std : : cerr < < " . Cannot reset before : " < < MAX_NETWORK_INIT < < " sec " < < std : : endl ;
2009-10-29 20:44:04 -04:00
# endif
2008-01-25 01:36:40 -05:00
}
2009-11-16 05:53:17 -05:00
}
2009-10-29 20:41:24 -04:00
}
2009-11-12 17:19:45 -05:00
void p3ConnectMgr : : netExtFinderAddressCheck ( )
2009-10-29 20:41:24 -04:00
{ struct sockaddr_in tmpip ;
2009-11-12 17:19:25 -05:00
if ( getExtFinderExtAddress ( tmpip ) ) {
2009-10-29 20:44:04 -04:00
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::netExtraAddressCheck() return true " < < std : : endl ;
# endif
2009-10-29 20:41:24 -04:00
netFlagExtraAddressCheckOk = true ;
2009-10-29 20:38:37 -04:00
} else {
2009-10-29 20:44:04 -04:00
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::netExtraAddressCheck() return false " < < std : : endl ;
# endif
2009-10-29 20:41:24 -04:00
netFlagExtraAddressCheckOk = false ;
2008-01-25 01:36:40 -05:00
}
}
2008-03-02 09:25:59 -05:00
void p3ConnectMgr : : netUnreachableCheck ( )
{
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::netUnreachableCheck() " < < std : : endl ;
# endif
std : : map < std : : string , peerConnectState > : : iterator it ;
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-03-02 09:25:59 -05:00
for ( it = mFriendList . begin ( ) ; it ! = mFriendList . end ( ) ; it + + )
{
/* get last contact detail */
if ( it - > second . state & RS_PEER_S_CONNECTED )
{
# ifdef CONN_DEBUG
std : : cerr < < " NUC() Ignoring Connected Peer " < < std : : endl ;
# endif
continue ;
}
peerAddrInfo details ;
switch ( it - > second . source )
{
case RS_CB_DHT :
details = it - > second . dht ;
# ifdef CONN_DEBUG
std : : cerr < < " NUC() Using DHT data " < < std : : endl ;
# endif
break ;
case RS_CB_DISC :
details = it - > second . disc ;
# ifdef CONN_DEBUG
std : : cerr < < " NUC() Using DISC data " < < std : : endl ;
# endif
break ;
case RS_CB_PERSON :
details = it - > second . peer ;
# ifdef CONN_DEBUG
std : : cerr < < " NUC() Using PEER data " < < std : : endl ;
# endif
break ;
default :
continue ;
break ;
}
std : : cerr < < " NUC() Peer: " < < it - > first < < std : : endl ;
/* Determine Reachability (only advisory) */
// if (ownState.netMode == RS_NET_MODE_UNREACHABLE) // MUST BE TRUE!
{
if ( details . type & RS_NET_CONN_TCP_EXTERNAL )
{
/* reachable! */
it - > second . state & = ( ~ RS_PEER_S_UNREACHABLE ) ;
# ifdef CONN_DEBUG
std : : cerr < < " NUC() Peer EXT TCP - reachable " < < std : : endl ;
# endif
}
else
{
/* unreachable */
it - > second . state | = RS_PEER_S_UNREACHABLE ;
# ifdef CONN_DEBUG
std : : cerr < < " NUC() Peer !EXT TCP - unreachable " < < std : : endl ;
# endif
}
}
}
}
2008-01-25 01:36:40 -05:00
/******************************* UDP MAINTAINANCE ********************************
* Interaction with the UDP is mainly for determining the External Port .
*
*/
void p3ConnectMgr : : udpStunPeer ( std : : string id , struct sockaddr_in & addr )
{
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::udpStunPeer() " < < std : : endl ;
# endif
/* add it into udp stun list */
tou_stunpeer ( ( struct sockaddr * ) & addr , sizeof ( addr ) , id . c_str ( ) ) ;
}
/********************************** STUN SERVERS ***********************************
* We maintain a list of stun servers . This is initialised with a set of random keys .
*
* This is gradually rolled over with time . We update with friends / friends of friends ,
* and the lists that they provide ( part of AutoDisc ) .
*
* max 100 entries ?
*/
void p3ConnectMgr : : netStunInit ( )
{
stunInit ( ) ;
}
void p3ConnectMgr : : stunInit ( )
{
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
2008-08-16 11:02:24 -04:00
netAssistStun ( true ) ;
2008-01-25 01:36:40 -05:00
/* push stun list to DHT */
std : : list < std : : string > : : iterator it ;
for ( it = mStunList . begin ( ) ; it ! = mStunList . end ( ) ; it + + )
{
2008-08-16 11:02:24 -04:00
netAssistAddStun ( * it ) ;
2008-01-25 01:36:40 -05:00
}
mStunStatus = RS_STUN_DHT ;
2008-03-05 11:32:18 -05:00
mStunFound = 0 ;
mStunMoreRequired = true ;
2008-01-25 01:36:40 -05:00
}
2009-08-04 19:22:44 -04:00
/* This is continually called
*
* checks whether the ext address is consistent
*
* checks if UDP needs more stun peers - or not
* The status is passed onto the DHT .
*
*/
2008-01-25 01:36:40 -05:00
bool p3ConnectMgr : : stunCheck ( )
{
# ifdef CONN_DEBUG
2009-08-04 19:22:44 -04:00
std : : cerr < < " p3ConnectMgr::stunCheck() " < < std : : endl ;
2008-01-25 01:36:40 -05:00
# endif
2009-08-04 19:22:44 -04:00
/* check udp address stability */
bool netDone = false ;
2008-01-25 01:36:40 -05:00
2008-03-05 11:32:18 -05:00
{
2009-08-04 19:22:44 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
mStunStatus = RS_STUN_DHT ;
netDone = ( mNetStatus = = RS_NET_DONE ) ;
}
struct sockaddr_in raddr ;
socklen_t rlen = sizeof ( raddr ) ;
uint8_t stable ;
if ( netDone )
{
if ( 0 < tou_extaddr ( ( struct sockaddr * ) & raddr , & rlen , & stable ) )
{
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
# ifdef CONN_DEBUG
2009-10-29 20:44:44 -04:00
std : : cerr < < " p3ConnectMgr::stunCheck() mStunExtAddr.sin_addr.s_addr : " < < inet_ntoa ( mStunExtAddr . sin_addr ) < < std : : endl ;
std : : cerr < < " p3ConnectMgr::stunCheck() raddr.sin_addr.s_addr : " < < inet_ntoa ( raddr . sin_addr ) < < std : : endl ;
std : : cerr < < " p3ConnectMgr::stunCheck() stable : " < < ( stable ! = 0 ) < < std : : endl ;
2009-08-04 19:22:44 -04:00
# endif
2009-10-29 20:41:24 -04:00
if ( ( mStunExtAddr . sin_addr . s_addr ! = raddr . sin_addr . s_addr ) | |
( stable = = 0 ) )
{
netFlagStunOk = false ;
mStunExtAddr = raddr ;
2009-08-04 19:22:44 -04:00
}
else
{
2009-10-29 20:41:24 -04:00
netFlagStunOk = true ;
2009-08-04 19:22:44 -04:00
# ifdef CONN_DEBUG
2009-10-29 20:41:24 -04:00
std : : cerr < < " p3ConnectMgr::stunCheck() Stun ext : ok ! " < < std : : endl ;
2009-08-04 19:22:44 -04:00
# endif
}
}
else
{
2009-10-29 20:41:24 -04:00
netFlagStunOk = false ;
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::stunCheck() Stun : No Ext Address. " < < std : : endl ;
# endif
}
}
//#ifdef CONN_DEBUG
// uint32_t failCount;
// time_t lastSent;
// time_t now = time(NULL);
// struct sockaddr_in eaddr;
// socklen_t elen = sizeof(eaddr);
// int i = 0;
// for(i = 0; tou_getstunpeer(i, (struct sockaddr *) &raddr, &rlen,
// (struct sockaddr *) &eaddr, &elen,
// &failCount, &lastSent); i++)
// {
// std::cerr << "STUN PEERS: ";
// std::cerr << " raddr: " << inet_ntoa(raddr.sin_addr) << ":" << ntohs(raddr.sin_port);
// std::cerr << " eaddr: " << inet_ntoa(eaddr.sin_addr) << ":" << ntohs(eaddr.sin_port);
// if (lastSent)
// {
// std::cerr << " failCount: " << failCount << " lastSent: " << now-lastSent;
// }
// else
// {
// std::cerr << " Unused ";
// }
// std::cerr << std::endl;
// }
//#endif
2008-03-05 11:32:18 -05:00
2009-08-04 19:22:44 -04:00
/* pass on udp status to dht */
if ( tou_needstunpeers ( ) )
2008-01-25 01:36:40 -05:00
{
2009-08-04 19:22:44 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
if ( ! mStunMoreRequired )
{
# ifdef CONN_DEBUG
std : : cerr < < " Telling DHT More Stun Required " < < std : : endl ;
# endif
2008-01-25 01:36:40 -05:00
2009-08-04 19:22:44 -04:00
netAssistStun ( true ) ;
mStunMoreRequired = true ;
}
}
else
{
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
2009-08-04 19:22:44 -04:00
if ( mStunMoreRequired )
{
# ifdef CONN_DEBUG
std : : cerr < < " Telling DHT No More Stun Required " < < std : : endl ;
# endif
2008-01-25 01:36:40 -05:00
2009-08-04 19:22:44 -04:00
netAssistStun ( false ) ;
mStunMoreRequired = false ;
}
2008-01-25 01:36:40 -05:00
}
2009-08-04 19:22:44 -04:00
return true ;
2008-01-25 01:36:40 -05:00
}
2008-02-25 18:56:23 -05:00
void p3ConnectMgr : : stunStatus ( std : : string id , struct sockaddr_in raddr , uint32_t type , uint32_t flags )
2008-01-25 01:36:40 -05:00
{
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::stunStatus() id: " < < RsUtil : : BinToHex ( id ) < < " raddr: " < < inet_ntoa ( raddr . sin_addr ) ;
std : : cerr < < " : " < < ntohs ( raddr . sin_port ) < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-01-25 01:36:40 -05:00
connMtx . lock ( ) ; /* LOCK MUTEX */
bool stillStunning = ( mStunStatus = = RS_STUN_DHT ) ;
connMtx . unlock ( ) ; /* UNLOCK MUTEX */
2009-12-14 13:11:19 -05:00
/* only useful if they have an exposed TCP/UDP port */
2008-02-25 18:56:23 -05:00
if ( type & RS_NET_CONN_TCP_EXTERNAL )
2008-01-25 01:36:40 -05:00
{
2008-02-25 18:56:23 -05:00
if ( stillStunning )
{
2008-03-05 11:32:18 -05:00
connMtx . lock ( ) ; /* LOCK MUTEX */
mStunFound + + ;
connMtx . unlock ( ) ; /* UNLOCK MUTEX */
2008-02-25 18:56:23 -05:00
2008-01-25 01:36:40 -05:00
# ifdef CONN_DEBUG
2008-02-25 18:56:23 -05:00
std : : cerr < < " p3ConnectMgr::stunStatus() Sending to UDP " < < std : : endl ;
2008-01-25 01:36:40 -05:00
# endif
2008-02-25 18:56:23 -05:00
/* push to the UDP */
udpStunPeer ( id , raddr ) ;
2008-03-05 11:32:18 -05:00
2008-02-25 18:56:23 -05:00
}
2008-01-25 01:36:40 -05:00
2008-02-25 18:56:23 -05:00
/* push to the stunCollect */
stunCollect ( id , raddr , flags ) ;
}
2008-01-25 01:36:40 -05:00
}
/* FLAGS
ONLINE
EXT
UPNP
UDP
FRIEND
FRIEND_OF_FRIEND
OTHER
*/
void p3ConnectMgr : : stunCollect ( std : : string id , struct sockaddr_in addr , uint32_t flags )
{
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::stunCollect() id: " < < RsUtil : : BinToHex ( id ) < < std : : endl ;
# endif
std : : list < std : : string > : : iterator it ;
it = std : : find ( mStunList . begin ( ) , mStunList . end ( ) , id ) ;
if ( it = = mStunList . end ( ) )
{
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::stunCollect() Id not in List " < < std : : endl ;
# endif
/* add it in:
* if FRIEND / ONLINE or if list is short .
*/
2008-03-05 11:32:18 -05:00
if ( ( flags & RS_STUN_ONLINE ) | | ( flags & RS_STUN_FRIEND ) )
2008-01-25 01:36:40 -05:00
{
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::stunCollect() Id added to Front " < < std : : endl ;
# endif
/* push to the front */
mStunList . push_front ( id ) ;
2008-02-07 11:18:34 -05:00
2008-03-05 11:32:18 -05:00
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
}
else if ( mStunList . size ( ) < RS_STUN_LIST_MIN )
{
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::stunCollect() Id added to Back " < < std : : endl ;
# endif
/* push to the front */
mStunList . push_back ( id ) ;
2008-02-07 11:18:34 -05:00
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2008-01-25 01:36:40 -05:00
}
}
else
{
/* if they're online ... move to the front
*/
if ( flags & RS_STUN_ONLINE )
{
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::stunCollect() Id moved to Front " < < std : : endl ;
# endif
/* move to front */
mStunList . erase ( it ) ;
mStunList . push_front ( id ) ;
2008-02-07 11:18:34 -05:00
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2008-01-25 01:36:40 -05:00
}
}
}
/******************************** Network Status *********************************
* Configuration Loading / Saving .
*/
void p3ConnectMgr : : addMonitor ( pqiMonitor * mon )
{
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
std : : list < pqiMonitor * > : : iterator it ;
it = std : : find ( clients . begin ( ) , clients . end ( ) , mon ) ;
if ( it ! = clients . end ( ) )
{
return ;
}
mon - > setConnectionMgr ( this ) ;
clients . push_back ( mon ) ;
return ;
}
void p3ConnectMgr : : removeMonitor ( pqiMonitor * mon )
{
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
std : : list < pqiMonitor * > : : iterator it ;
it = std : : find ( clients . begin ( ) , clients . end ( ) , mon ) ;
if ( it = = clients . end ( ) )
{
return ;
}
( * it ) - > setConnectionMgr ( NULL ) ;
clients . erase ( it ) ;
return ;
}
void p3ConnectMgr : : tickMonitors ( )
{
2008-05-13 11:41:40 -04:00
bool doStatusChange = false ;
2008-01-25 01:36:40 -05:00
std : : list < pqipeer > actionList ;
std : : map < std : : string , peerConnectState > : : iterator it ;
2008-05-13 11:41:40 -04:00
{
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
if ( mStatusChanged )
{
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::tickMonitors() StatusChanged! List: " < < std : : endl ;
# endif
/* assemble list */
for ( it = mFriendList . begin ( ) ; it ! = mFriendList . end ( ) ; it + + )
{
if ( it - > second . actions )
{
/* add in */
pqipeer peer ;
peer . id = it - > second . id ;
peer . name = it - > second . name ;
peer . state = it - > second . state ;
peer . actions = it - > second . actions ;
/* reset action */
it - > second . actions = 0 ;
actionList . push_back ( peer ) ;
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " Friend: " < < peer . name < < " Id: " < < peer . id < < " State: " < < peer . state ;
2008-01-25 01:36:40 -05:00
if ( peer . state & RS_PEER_S_FRIEND )
std : : cerr < < " S:RS_PEER_S_FRIEND " ;
if ( peer . state & RS_PEER_S_ONLINE )
std : : cerr < < " S:RS_PEER_S_ONLINE " ;
if ( peer . state & RS_PEER_S_CONNECTED )
std : : cerr < < " S:RS_PEER_S_CONNECTED " ;
std : : cerr < < " Actions: " < < peer . actions ;
if ( peer . actions & RS_PEER_NEW )
std : : cerr < < " A:RS_PEER_NEW " ;
if ( peer . actions & RS_PEER_MOVED )
std : : cerr < < " A:RS_PEER_MOVED " ;
if ( peer . actions & RS_PEER_CONNECTED )
std : : cerr < < " A:RS_PEER_CONNECTED " ;
if ( peer . actions & RS_PEER_DISCONNECTED )
std : : cerr < < " A:RS_PEER_DISCONNECTED " ;
if ( peer . actions & RS_PEER_CONNECT_REQ )
std : : cerr < < " A:RS_PEER_CONNECT_REQ " ;
std : : cerr < < std : : endl ;
# endif
2008-03-05 11:32:18 -05:00
/* notify GUI */
2008-03-31 10:06:59 -04:00
if ( peer . actions & RS_PEER_CONNECTED )
2008-03-05 11:32:18 -05:00
{
2008-03-31 10:06:59 -04:00
pqiNotify * notify = getPqiNotify ( ) ;
if ( notify )
{
notify - > AddPopupMessage ( RS_POPUP_CONNECT ,
2008-11-16 22:03:23 -05:00
peer . id , " Online: " ) ;
2008-06-20 08:38:11 -04:00
notify - > AddFeedItem ( RS_FEED_ITEM_PEER_CONNECT , peer . id , " " , " " ) ;
}
}
2008-01-25 01:36:40 -05:00
}
}
/* do the Others as well! */
for ( it = mOthersList . begin ( ) ; it ! = mOthersList . end ( ) ; it + + )
{
if ( it - > second . actions )
{
/* add in */
pqipeer peer ;
peer . id = it - > second . id ;
peer . name = it - > second . name ;
peer . state = it - > second . state ;
peer . actions = it - > second . actions ;
/* reset action */
it - > second . actions = 0 ;
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " Other: " < < peer . name < < " Id: " < < peer . id < < " State: " < < peer . state ;
2008-01-25 01:36:40 -05:00
if ( peer . state & RS_PEER_S_FRIEND )
std : : cerr < < " S:RS_PEER_S_FRIEND " ;
if ( peer . state & RS_PEER_S_ONLINE )
std : : cerr < < " S:RS_PEER_S_ONLINE " ;
if ( peer . state & RS_PEER_S_CONNECTED )
std : : cerr < < " S:RS_PEER_S_CONNECTED " ;
std : : cerr < < " Actions: " < < peer . actions ;
if ( peer . actions & RS_PEER_NEW )
std : : cerr < < " A:RS_PEER_NEW " ;
if ( peer . actions & RS_PEER_MOVED )
std : : cerr < < " A:RS_PEER_MOVED " ;
if ( peer . actions & RS_PEER_CONNECTED )
std : : cerr < < " A:RS_PEER_CONNECTED " ;
if ( peer . actions & RS_PEER_DISCONNECTED )
std : : cerr < < " A:RS_PEER_DISCONNECTED " ;
if ( peer . actions & RS_PEER_CONNECT_REQ )
std : : cerr < < " A:RS_PEER_CONNECT_REQ " ;
std : : cerr < < std : : endl ;
# endif
actionList . push_back ( peer ) ;
}
}
mStatusChanged = false ;
2008-05-13 11:41:40 -04:00
doStatusChange = true ;
2008-01-25 01:36:40 -05:00
2008-05-13 11:41:40 -04:00
}
} /****** UNLOCK STACK MUTEX ******/
/* NOTE - clients is accessed without mutex protection!!!!
* At the moment this is okay - as they are only added at the start .
* IF this changes - - - - must fix with second Mutex .
*/
if ( doStatusChange )
{
2008-01-25 01:36:40 -05:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " Sending to " < < clients . size ( ) < < " monitorClients " < < std : : endl ;
2008-01-25 01:36:40 -05:00
# endif
/* send to all monitors */
std : : list < pqiMonitor * > : : iterator mit ;
for ( mit = clients . begin ( ) ; mit ! = clients . end ( ) ; mit + + )
{
( * mit ) - > statusChange ( actionList ) ;
}
}
}
const std : : string p3ConnectMgr : : getOwnId ( )
{
if ( mAuthMgr )
{
return mAuthMgr - > OwnId ( ) ;
}
else
{
std : : string nullStr ;
return nullStr ;
}
}
bool p3ConnectMgr : : getOwnNetStatus ( peerConnectState & state )
{
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
state = ownState ;
return true ;
}
bool p3ConnectMgr : : isFriend ( std : : string id )
{
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
return ( mFriendList . end ( ) ! = mFriendList . find ( id ) ) ;
}
2008-08-17 11:23:11 -04:00
bool p3ConnectMgr : : isOnline ( std : : string id )
{
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
std : : map < std : : string , peerConnectState > : : iterator it ;
if ( mFriendList . end ( ) ! = ( it = mFriendList . find ( id ) ) )
{
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::isOnline( " < < id < < " ) is Friend, Online: " < < ( it - > second . state & RS_PEER_S_CONNECTED ) < < std : : endl ;
2008-08-17 11:23:11 -04:00
# endif
return ( it - > second . state & RS_PEER_S_CONNECTED ) ;
}
else
{
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::isOnline( " < < id < < " ) is Not Friend " < < std : : endl < < " p3ConnectMgr::isOnline() OwnId: " < < mAuthMgr - > OwnId ( ) < < std : : endl ;
2008-08-17 11:23:11 -04:00
# endif
/* not a friend */
}
return false ;
}
2008-01-25 01:36:40 -05:00
bool p3ConnectMgr : : getFriendNetStatus ( std : : string id , peerConnectState & state )
{
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
/* check for existing */
std : : map < std : : string , peerConnectState > : : iterator it ;
it = mFriendList . find ( id ) ;
if ( it = = mFriendList . end ( ) )
{
return false ;
}
state = it - > second ;
return true ;
}
bool p3ConnectMgr : : getOthersNetStatus ( std : : string id , peerConnectState & state )
{
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
/* check for existing */
std : : map < std : : string , peerConnectState > : : iterator it ;
it = mOthersList . find ( id ) ;
if ( it = = mOthersList . end ( ) )
{
return false ;
}
state = it - > second ;
return true ;
}
void p3ConnectMgr : : getOnlineList ( std : : list < std : : string > & peers )
{
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
/* check for existing */
std : : map < std : : string , peerConnectState > : : iterator it ;
for ( it = mFriendList . begin ( ) ; it ! = mFriendList . end ( ) ; it + + )
{
2008-02-03 01:29:02 -05:00
if ( it - > second . state & RS_PEER_S_CONNECTED )
2008-01-25 01:36:40 -05:00
{
peers . push_back ( it - > first ) ;
}
}
return ;
}
void p3ConnectMgr : : getFriendList ( std : : list < std : : string > & peers )
{
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
/* check for existing */
std : : map < std : : string , peerConnectState > : : iterator it ;
for ( it = mFriendList . begin ( ) ; it ! = mFriendList . end ( ) ; it + + )
{
peers . push_back ( it - > first ) ;
}
return ;
}
void p3ConnectMgr : : getOthersList ( std : : list < std : : string > & peers )
{
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
/* check for existing */
std : : map < std : : string , peerConnectState > : : iterator it ;
for ( it = mOthersList . begin ( ) ; it ! = mOthersList . end ( ) ; it + + )
{
peers . push_back ( it - > first ) ;
}
return ;
}
2008-02-26 21:32:20 -05:00
bool p3ConnectMgr : : connectAttempt ( std : : string id , struct sockaddr_in & addr ,
uint32_t & delay , uint32_t & period , uint32_t & type )
2008-01-25 01:36:40 -05:00
{
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
/* check for existing */
std : : map < std : : string , peerConnectState > : : iterator it ;
it = mFriendList . find ( id ) ;
if ( it = = mFriendList . end ( ) )
{
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::connectAttempt() FAILED Not in FriendList! id: " < < id < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-02-08 12:05:55 -05:00
2008-01-25 01:36:40 -05:00
return false ;
}
if ( it - > second . connAddrs . size ( ) < 1 )
{
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::connectAttempt() FAILED No ConnectAddresses id: " < < id < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-01-25 01:36:40 -05:00
return false ;
}
2009-12-13 16:59:26 -05:00
it - > second . lastattempt = time ( NULL ) + ( ( time ( NULL ) * 1664525 + 1013904223 ) % 3 ) ; //add a random perturbation between 0 and 2 sec. pseudo random number generator from Wikipedia/Numerical Recipies.
2008-01-25 01:36:40 -05:00
it - > second . inConnAttempt = true ;
2009-11-11 11:43:51 -05:00
it - > second . currentConnAddrAttempt = it - > second . connAddrs . front ( ) ;
2008-01-25 01:36:40 -05:00
it - > second . connAddrs . pop_front ( ) ;
2009-11-11 11:43:51 -05:00
addr = it - > second . currentConnAddrAttempt . addr ;
delay = it - > second . currentConnAddrAttempt . delay ;
period = it - > second . currentConnAddrAttempt . period ;
type = it - > second . currentConnAddrAttempt . type ;
2009-11-11 11:49:11 -05:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::connectAttempt() Success: id: " < < id < < std : : endl ;
std : : cerr < < " laddr: " < < inet_ntoa ( addr . sin_addr ) < < " lport: " < < ntohs ( addr . sin_port ) < < " delay: " < < delay < < " period: " < < period ;
std : : cerr < < " type: " < < type < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-02-08 12:05:55 -05:00
2008-01-25 01:36:40 -05:00
return true ;
}
/****************************
* Update state ,
* trigger retry if necessary ,
*
* remove from DHT ?
*
*/
2009-12-14 13:11:19 -05:00
bool p3ConnectMgr : : connectResult ( std : : string id , bool success , uint32_t flags , struct sockaddr_in remote_peer_address )
2008-01-25 01:36:40 -05:00
{
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2009-12-13 16:59:26 -05:00
rslog ( RSL_WARNING , p3connectzone , " p3ConnectMgr::connectResult() called Connect!: id: " + id ) ;
if ( success ) {
rslog ( RSL_WARNING , p3connectzone , " p3ConnectMgr::connectResult() called with SUCCESS. " ) ;
} else {
rslog ( RSL_WARNING , p3connectzone , " p3ConnectMgr::connectResult() called with FAILED. " ) ;
}
2008-01-25 01:36:40 -05:00
/* check for existing */
std : : map < std : : string , peerConnectState > : : iterator it ;
it = mFriendList . find ( id ) ;
if ( it = = mFriendList . end ( ) )
{
2008-08-16 11:02:24 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::connectResult() Failed, missing Friend " < < " id: " < < id < < std : : endl ;
2008-08-16 11:02:24 -04:00
# endif
2008-01-25 01:36:40 -05:00
return false ;
}
2009-12-14 13:11:19 -05:00
it - > second . inConnAttempt = false ;
2008-01-25 01:36:40 -05:00
if ( success )
{
2009-12-14 13:11:19 -05:00
/* remove other attempts */
it - > second . inConnAttempt = false ;
netAssistFriend ( id , false ) ;
2008-01-25 01:36:40 -05:00
2009-12-14 13:11:19 -05:00
/* update address (will come although through from DISC) */
2008-01-25 01:36:40 -05:00
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::connectResult() Connect!: id: " < < id < < std : : endl ;
std : : cerr < < " Success: " < < success < < " flags: " < < flags < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-02-08 12:05:55 -05:00
2009-12-13 16:59:26 -05:00
rslog ( RSL_WARNING , p3connectzone , " p3ConnectMgr::connectResult() Success " ) ;
2008-02-08 12:05:55 -05:00
2008-01-25 01:36:40 -05:00
/* change state */
it - > second . state | = RS_PEER_S_CONNECTED ;
it - > second . actions | = RS_PEER_CONNECTED ;
2008-02-03 01:29:02 -05:00
it - > second . lastcontact = time ( NULL ) ; /* time of connect */
2009-12-14 13:11:19 -05:00
it - > second . connecttype = flags ;
2009-12-14 13:46:08 -05:00
if ( remote_peer_address . sin_addr . s_addr ! = 0
& & ! ( remote_peer_address . sin_addr . s_addr = = ownState . currentlocaladdr . sin_addr . s_addr )
& & ( ! isLoopbackNet ( & remote_peer_address . sin_addr ) )
) {
2009-12-14 13:11:19 -05:00
IpAddressTimed ipLocalAddressTimed ;
ipLocalAddressTimed . ipAddr = remote_peer_address ;
ipLocalAddressTimed . seenTime = time ( NULL ) ;
it - > second . updateIpAddressList ( ipLocalAddressTimed ) ;
it - > second . purgeIpAddressList ( ) ;
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::connectResult() adding current peer adress in list. " < < std : : endl ;
it - > second . printIpAddressList ( ) ;
# endif
}
2009-11-11 11:44:51 -05:00
2009-12-14 13:11:19 -05:00
mStatusChanged = true ;
return true ;
}
2008-01-25 01:36:40 -05:00
2008-08-16 11:02:24 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::connectResult() Disconnect/Fail: id: " < < id < < std : : endl ;
std : : cerr < < " Success: " < < success < < " flags: " < < flags < < std : : endl ;
2008-08-16 11:02:24 -04:00
# endif
2008-01-25 01:36:40 -05:00
/* if currently connected -> flag as failed */
if ( it - > second . state & RS_PEER_S_CONNECTED )
{
2008-02-08 12:05:55 -05:00
it - > second . state & = ( ~ RS_PEER_S_CONNECTED ) ;
2008-01-25 01:36:40 -05:00
it - > second . actions | = RS_PEER_DISCONNECTED ;
2008-02-03 01:29:02 -05:00
it - > second . lastcontact = time ( NULL ) ; /* time of disconnect */
2008-08-16 11:02:24 -04:00
netAssistFriend ( id , true ) ;
2008-01-25 01:36:40 -05:00
}
if ( it - > second . connAddrs . size ( ) < 1 )
{
return true ;
}
it - > second . actions | = RS_PEER_CONNECT_REQ ;
mStatusChanged = true ;
return true ;
}
2009-12-13 16:59:26 -05:00
bool p3ConnectMgr : : doNextAttempt ( std : : string id )
{
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
rslog ( RSL_WARNING , p3connectzone , " p3ConnectMgr::doNextAttempt() called id : " + id ) ;
/* check for existing */
std : : map < std : : string , peerConnectState > : : iterator it ;
it = mFriendList . find ( id ) ;
if ( it = = mFriendList . end ( ) )
{
2009-12-15 16:50:45 -05:00
rslog ( RSL_WARNING , p3connectzone , " p3ConnectMgr::connectResult() Failed, missing Friend " ) ;
2009-12-13 16:59:26 -05:00
return false ;
}
2008-01-25 01:36:40 -05:00
2009-12-13 16:59:26 -05:00
it - > second . inConnAttempt = false ;
2009-12-15 17:04:50 -05:00
if ( ( it - > second . state & RS_PEER_S_CONNECTED ) & & ! ( it - > second . connecttype & RS_NET_CONN_TUNNEL ) ) {
2009-12-15 16:50:45 -05:00
rslog ( RSL_WARNING , p3connectzone , " p3ConnectMgr::doNextAttempt() peer is already connected and not in tunnel mode, don't do next attempt. " ) ;
return true ;
}
2009-12-13 16:59:26 -05:00
if ( it - > second . connAddrs . size ( ) < 1 )
{
return true ;
}
it - > second . actions | = RS_PEER_CONNECT_REQ ;
mStatusChanged = true ;
return true ;
}
2008-01-25 01:36:40 -05:00
/******************************** Feedback ...... *********************************
* From various sources
*/
2008-03-02 09:25:59 -05:00
2008-01-25 01:36:40 -05:00
void p3ConnectMgr : : peerStatus ( std : : string id ,
2009-11-11 11:49:11 -05:00
struct sockaddr_in laddr , struct sockaddr_in raddr , std : : list < IpAddressTimed > ipDiscAddressList ,
2008-02-03 01:29:02 -05:00
uint32_t type , uint32_t flags , uint32_t source )
2008-01-25 01:36:40 -05:00
{
2008-05-13 11:41:40 -04:00
std : : map < std : : string , peerConnectState > : : iterator it ;
bool isFriend = true ;
time_t now = time ( NULL ) ;
peerAddrInfo details ;
details . type = type ;
details . found = true ;
details . laddr = laddr ;
details . raddr = raddr ;
details . ts = now ;
{
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::peerStatus() " < < " id: " < < id < < " laddr: " < < inet_ntoa ( laddr . sin_addr ) < < " lport: " < < ntohs ( laddr . sin_port ) ;
std : : cerr < < " raddr: " < < inet_ntoa ( raddr . sin_addr ) < < " rport: " < < ntohs ( raddr . sin_port ) < < " type: " < < type < < " flags: " < < flags ;
std : : cerr < < " source: " < < source < < std : : endl ;
2009-11-11 11:49:11 -05:00
peerConnectState : : printIpAddressList ( ipDiscAddressList ) ;
2008-07-09 05:55:09 -04:00
# endif
2008-07-10 12:29:18 -04:00
{
/* Log */
std : : ostringstream out ;
2009-11-18 12:46:38 -05:00
out < < " p3ConnectMgr::peerStatus() " < < " id: " < < id < < " laddr: " < < inet_ntoa ( laddr . sin_addr ) < < " lport: " < < ntohs ( laddr . sin_port ) ;
out < < " raddr: " < < inet_ntoa ( raddr . sin_addr ) < < " rport: " < < ntohs ( raddr . sin_port ) < < " type: " < < type < < " flags: " < < flags < < " source: " < < source ;
2008-07-10 12:29:18 -04:00
rslog ( RSL_WARNING , p3connectzone , out . str ( ) ) ;
}
2008-01-25 01:36:40 -05:00
/* look up the id */
it = mFriendList . find ( id ) ;
if ( it = = mFriendList . end ( ) )
{
/* check Others list */
isFriend = false ;
it = mOthersList . find ( id ) ;
if ( it = = mOthersList . end ( ) )
{
/* not found - ignore */
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::peerStatus() Peer Not Found - Ignore " < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-01-25 01:36:40 -05:00
return ;
}
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::peerStatus() Peer is in mOthersList " < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-01-25 01:36:40 -05:00
}
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2008-02-08 12:05:55 -05:00
std : : cerr < < " p3ConnectMgr::peerStatus() Current Peer State: " < < std : : endl ;
printConnectState ( it - > second ) ;
std : : cerr < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-01-25 01:36:40 -05:00
/* update the status */
/* if source is DHT */
if ( source = = RS_CB_DHT )
{
/* DHT can tell us about
* 1 ) connect type ( UDP / TCP / etc )
* 2 ) local / external address
*/
it - > second . source = RS_CB_DHT ;
it - > second . dht = details ;
2008-02-03 01:29:02 -05:00
/* If we get a info -> then they are online */
it - > second . state | = RS_PEER_S_ONLINE ;
2008-03-02 09:25:59 -05:00
it - > second . lastavailable = now ;
2008-10-18 12:02:06 -04:00
/* if we are recieving these - the dht is definitely up.
*/
netFlagDhtOk = true ;
2008-01-25 01:36:40 -05:00
}
else if ( source = = RS_CB_DISC )
{
/* DISC can tell us about
* 1 ) connect type ( UDP / TCP / etc )
* 2 ) local / external addresses
*/
it - > second . source = RS_CB_DISC ;
it - > second . disc = details ;
2008-02-03 01:29:02 -05:00
2009-11-11 11:49:11 -05:00
it - > second . updateIpAddressList ( ipDiscAddressList ) ;
2009-12-15 12:48:48 -05:00
it - > second . currentlocaladdr = laddr ;
it - > second . currentserveraddr = raddr ;
//add the given address to the address list
IpAddressTimed laddrTimed ;
laddrTimed . ipAddr = laddr ;
laddrTimed . seenTime = time ( NULL ) ;
it - > second . updateIpAddressList ( laddrTimed ) ;
IpAddressTimed raddrTimed ;
raddrTimed . ipAddr = raddr ;
raddrTimed . seenTime = time ( NULL ) ;
it - > second . updateIpAddressList ( raddrTimed ) ;
2008-02-03 01:29:02 -05:00
if ( flags & RS_NET_FLAGS_ONLINE )
{
it - > second . actions | = RS_PEER_ONLINE ;
it - > second . state | = RS_PEER_S_ONLINE ;
2008-03-02 09:25:59 -05:00
it - > second . lastavailable = now ;
2008-02-03 01:29:02 -05:00
mStatusChanged = true ;
}
/* not updating VIS status??? */
2008-02-07 11:18:34 -05:00
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2008-01-25 01:36:40 -05:00
}
else if ( source = = RS_CB_PERSON )
{
/* PERSON can tell us about
* 1 ) online / offline
* 2 ) connect address
2008-02-03 01:29:02 -05:00
* - > update all !
2008-01-25 01:36:40 -05:00
*/
it - > second . source = RS_CB_PERSON ;
it - > second . peer = details ;
2008-02-03 01:29:02 -05:00
2009-11-11 11:49:11 -05:00
it - > second . updateIpAddressList ( ipDiscAddressList ) ;
2008-03-02 09:25:59 -05:00
2009-12-15 12:48:48 -05:00
it - > second . currentlocaladdr = laddr ;
it - > second . currentserveraddr = raddr ;
//add the given address to the address list
IpAddressTimed laddrTimed ;
laddrTimed . ipAddr = laddr ;
laddrTimed . seenTime = time ( NULL ) ;
it - > second . updateIpAddressList ( laddrTimed ) ;
IpAddressTimed raddrTimed ;
raddrTimed . ipAddr = raddr ;
raddrTimed . seenTime = time ( NULL ) ;
it - > second . updateIpAddressList ( raddrTimed ) ;
2008-02-03 01:29:02 -05:00
it - > second . state | = RS_PEER_S_ONLINE ;
2008-03-02 09:25:59 -05:00
it - > second . lastavailable = now ;
2008-02-03 01:29:02 -05:00
/* must be online to recv info (should be connected too!)
* but no need for action as should be connected already
*/
2008-02-26 11:14:13 -05:00
it - > second . netMode & = ( ~ RS_NET_MODE_ACTUAL ) ; /* clear actual flags */
2008-02-03 01:29:02 -05:00
if ( flags & RS_NET_FLAGS_EXTERNAL_ADDR )
{
it - > second . netMode = RS_NET_MODE_EXT ;
}
2008-02-28 10:58:54 -05:00
else if ( flags & RS_NET_FLAGS_STABLE_UDP )
2008-02-03 01:29:02 -05:00
{
it - > second . netMode = RS_NET_MODE_UDP ;
}
2008-02-28 10:58:54 -05:00
else
{
it - > second . netMode = RS_NET_MODE_UNREACHABLE ;
}
2008-02-03 01:29:02 -05:00
/* always update VIS status */
if ( flags & RS_NET_FLAGS_USE_DISC )
{
it - > second . visState & = ( ~ RS_VIS_STATE_NODISC ) ;
}
else
{
it - > second . visState | = RS_VIS_STATE_NODISC ;
}
if ( flags & RS_NET_FLAGS_USE_DHT )
{
it - > second . visState & = ( ~ RS_VIS_STATE_NODHT ) ;
}
else
{
it - > second . visState | = RS_VIS_STATE_NODHT ;
}
2008-02-07 11:18:34 -05:00
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2008-01-25 01:36:40 -05:00
}
2008-02-28 10:58:54 -05:00
/* Determine Reachability (only advisory) */
2008-03-02 09:25:59 -05:00
if ( ownState . netMode & RS_NET_MODE_UDP )
2008-02-28 10:58:54 -05:00
{
2009-12-13 16:59:26 -05:00
if ( ( details . type & RS_NET_CONN_UDP ) | |
2008-02-28 10:58:54 -05:00
( details . type & RS_NET_CONN_TCP_EXTERNAL ) )
{
/* reachable! */
it - > second . state & = ( ~ RS_PEER_S_UNREACHABLE ) ;
}
else
{
/* unreachable */
it - > second . state | = RS_PEER_S_UNREACHABLE ;
}
}
2008-03-02 09:25:59 -05:00
else if ( ownState . netMode & RS_NET_MODE_UNREACHABLE )
2008-02-28 10:58:54 -05:00
{
if ( details . type & RS_NET_CONN_TCP_EXTERNAL )
{
/* reachable! */
it - > second . state & = ( ~ RS_PEER_S_UNREACHABLE ) ;
}
else
{
/* unreachable */
it - > second . state | = RS_PEER_S_UNREACHABLE ;
}
}
else
{
it - > second . state & = ( ~ RS_PEER_S_UNREACHABLE ) ;
}
2008-01-25 01:36:40 -05:00
if ( ! isFriend )
{
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::peerStatus() NOT FRIEND " < < " id: " < < id < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-02-08 12:05:55 -05:00
2008-07-10 12:29:18 -04:00
{
2009-11-18 12:46:38 -05:00
rslog ( RSL_WARNING , p3connectzone , " p3ConnectMgr::peerStatus() NO CONNECT (not friend) " ) ;
2008-07-10 12:29:18 -04:00
}
2008-01-25 01:36:40 -05:00
return ;
}
/* if already connected -> done */
if ( it - > second . state & RS_PEER_S_CONNECTED )
{
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::peerStatus() PEER ONLINE ALREADY " < < " id: " < < id < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-07-10 12:29:18 -04:00
{
/* Log */
2009-11-18 12:46:38 -05:00
rslog ( RSL_WARNING , p3connectzone , " p3ConnectMgr::peerStatus() NO CONNECT (already connected!) " ) ;
2008-07-10 12:29:18 -04:00
}
2008-02-08 12:05:55 -05:00
2008-01-25 01:36:40 -05:00
return ;
}
2009-11-18 12:46:38 -05:00
} /****** STACK UNLOCK MUTEX *******/
2008-02-08 12:05:55 -05:00
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::peerStatus() " < < " id: " < < id < < " laddr: " < < inet_ntoa ( laddr . sin_addr ) < < " lport: " < < ntohs ( laddr . sin_port ) ;
std : : cerr < < " raddr: " < < inet_ntoa ( raddr . sin_addr ) < < " rport: " < < ntohs ( raddr . sin_port ) < < " type: " < < type < < " flags: " < < flags ;
std : : cerr < < " source: " < < source < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-02-26 21:32:20 -05:00
2008-03-02 09:25:59 -05:00
# ifndef P3CONNMGR_NO_AUTO_CONNECTION
2008-02-26 21:32:20 -05:00
# ifndef P3CONNMGR_NO_TCP_CONNECTIONS
2009-11-18 12:46:38 -05:00
retryConnectTCP ( id ) ;
2008-03-02 09:25:59 -05:00
# endif // P3CONNMGR_NO_TCP_CONNECTIONS
2009-12-13 16:59:26 -05:00
retryConnectNotify ( id ) ;
2008-05-13 11:41:40 -04:00
# else
2008-03-02 09:25:59 -05:00
2009-11-18 12:46:38 -05:00
# endif // P3CONNMGR_NO_AUTO_CONNECTION
2008-02-26 21:32:20 -05:00
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2008-03-03 09:01:52 -05:00
std : : cerr < < " p3ConnectMgr::peerStatus() Resulting Peer State: " < < std : : endl ;
printConnectState ( it - > second ) ;
std : : cerr < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-03-03 09:01:52 -05:00
2008-02-26 21:32:20 -05:00
}
2008-01-25 01:36:40 -05:00
2008-02-26 21:32:20 -05:00
void p3ConnectMgr : : peerConnectRequest ( std : : string id , struct sockaddr_in raddr ,
uint32_t source )
2008-01-25 01:36:40 -05:00
{
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::peerConnectRequest() id: " < < id < < " raddr: " < < inet_ntoa ( raddr . sin_addr ) < < " : " < < ntohs ( raddr . sin_port ) ;
std : : cerr < < " source: " < < source < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-07-10 12:29:18 -04:00
{
/* Log */
std : : ostringstream out ;
2009-11-18 12:46:38 -05:00
out < < " p3ConnectMgr::peerConnectRequest() id: " < < id < < " raddr: " < < inet_ntoa ( raddr . sin_addr ) ;
out < < " : " < < ntohs ( raddr . sin_port ) < < " source: " < < source ;
2008-07-10 12:29:18 -04:00
rslog ( RSL_WARNING , p3connectzone , out . str ( ) ) ;
}
2008-01-25 01:36:40 -05:00
2008-03-02 09:25:59 -05:00
/******************** TCP PART *****************************/
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::peerConnectRequest() Try TCP first " < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2009-12-13 16:59:26 -05:00
retryConnect ( id ) ;
2008-01-25 01:36:40 -05:00
}
/*******************************************************************/
/*******************************************************************/
2008-02-07 11:18:34 -05:00
bool p3ConnectMgr : : addFriend ( std : : string id , uint32_t netMode , uint32_t visState , time_t lastContact )
2008-01-25 01:36:40 -05:00
{
/* so three possibilities
* ( 1 ) already exists as friend - > do nothing .
* ( 2 ) is in others list - > move over .
* ( 3 ) is non - existant - > create new one .
*/
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::addFriend() " < < id < < std : : endl ;
2008-01-25 01:36:40 -05:00
# endif
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
std : : map < std : : string , peerConnectState > : : iterator it ;
if ( mFriendList . end ( ) ! = mFriendList . find ( id ) )
{
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::addFriend() Already Exists " < < std : : endl ;
2008-01-25 01:36:40 -05:00
# endif
/* (1) already exists */
return true ;
}
/* check with the AuthMgr if its authorised */
if ( ! mAuthMgr - > isAuthenticated ( id ) )
{
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::addFriend() Failed Authentication " < < std : : endl ;
2008-01-25 01:36:40 -05:00
# endif
/* no auth */
return false ;
}
/* check if it is in others */
if ( mOthersList . end ( ) ! = ( it = mOthersList . find ( id ) ) )
{
/* (2) in mOthersList -> move over */
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::addFriend() Move from Others " < < std : : endl ;
2008-01-25 01:36:40 -05:00
# endif
mFriendList [ id ] = it - > second ;
mOthersList . erase ( it ) ;
it = mFriendList . find ( id ) ;
/* setup state */
it - > second . state = RS_PEER_S_FRIEND ;
it - > second . actions = RS_PEER_NEW ;
2008-02-07 11:18:34 -05:00
/* setup connectivity parameters */
it - > second . visState = visState ;
it - > second . netMode = netMode ;
it - > second . lastcontact = lastContact ;
2008-01-25 01:36:40 -05:00
mStatusChanged = true ;
/* add peer to DHT (if not dark) */
if ( it - > second . visState & RS_VIS_STATE_NODHT )
{
/* hidden from DHT world */
2008-08-16 11:02:24 -04:00
netAssistFriend ( id , false ) ;
2008-01-25 01:36:40 -05:00
}
else
{
2008-08-16 11:02:24 -04:00
netAssistFriend ( id , true ) ;
2008-01-25 01:36:40 -05:00
}
2008-02-07 11:18:34 -05:00
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2008-01-25 01:36:40 -05:00
return true ;
}
/* get details from AuthMgr */
pqiAuthDetails detail ;
if ( ! mAuthMgr - > getDetails ( id , detail ) )
{
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::addFriend() Failed to get Details " < < std : : endl ;
2008-01-25 01:36:40 -05:00
# endif
/* ERROR: no details */
return false ;
}
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::addFriend() Creating New Entry " < < std : : endl ;
2008-01-25 01:36:40 -05:00
# endif
/* create a new entry */
peerConnectState pstate ;
pstate . id = id ;
pstate . name = detail . name ;
pstate . state = RS_PEER_S_FRIEND ;
pstate . actions = RS_PEER_NEW ;
2008-02-07 11:18:34 -05:00
pstate . visState = visState ;
pstate . netMode = netMode ;
pstate . lastcontact = lastContact ;
2008-01-25 01:36:40 -05:00
/* addr & timestamps -> auto cleared */
mFriendList [ id ] = pstate ;
mStatusChanged = true ;
/* expect it to be a standard DHT */
2008-08-16 11:02:24 -04:00
netAssistFriend ( id , true ) ;
2008-01-25 01:36:40 -05:00
2008-02-07 11:18:34 -05:00
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2008-01-25 01:36:40 -05:00
return true ;
}
bool p3ConnectMgr : : removeFriend ( std : : string id )
{
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::removeFriend() " < < id < < std : : endl ;
2008-01-25 01:36:40 -05:00
# endif
2008-08-16 11:02:24 -04:00
netAssistFriend ( id , false ) ;
2008-01-25 01:36:40 -05:00
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
/* move to othersList */
bool success = false ;
std : : map < std : : string , peerConnectState > : : iterator it ;
if ( mFriendList . end ( ) ! = ( it = mFriendList . find ( id ) ) )
{
peerConnectState peer = it - > second ;
mFriendList . erase ( it ) ;
peer . state & = ( ~ RS_PEER_S_FRIEND ) ;
peer . state & = ( ~ RS_PEER_S_CONNECTED ) ;
peer . state & = ( ~ RS_PEER_S_ONLINE ) ;
peer . actions = RS_PEER_MOVED ;
peer . inConnAttempt = false ;
mOthersList [ id ] = peer ;
mStatusChanged = true ;
success = true ;
}
2008-02-07 11:18:34 -05:00
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2008-01-25 01:36:40 -05:00
return success ;
}
bool p3ConnectMgr : : addNeighbour ( std : : string id )
{
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::addNeighbour() " < < id < < std : : endl ;
2008-01-25 01:36:40 -05:00
# endif
/* so three possibilities
* ( 1 ) already exists as friend - > do nothing .
* ( 2 ) already in others list - > do nothing .
* ( 3 ) is non - existant - > create new one .
*/
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
std : : map < std : : string , peerConnectState > : : iterator it ;
if ( mFriendList . end ( ) = = mFriendList . find ( id ) )
{
/* (1) already exists */
return false ;
}
if ( mOthersList . end ( ) = = mOthersList . find ( id ) )
{
/* (2) already exists */
return true ;
}
/* check with the AuthMgr if its valid */
if ( ! mAuthMgr - > isValid ( id ) )
{
/* no auth */
return false ;
}
/* get details from AuthMgr */
pqiAuthDetails detail ;
if ( ! mAuthMgr - > getDetails ( id , detail ) )
{
/* no details */
return false ;
}
/* create a new entry */
peerConnectState pstate ;
pstate . id = id ;
pstate . name = detail . name ;
pstate . state = 0 ;
pstate . actions = 0 ; //RS_PEER_NEW;
pstate . visState = RS_VIS_STATE_STD ;
pstate . netMode = RS_NET_MODE_UNKNOWN ;
/* addr & timestamps -> auto cleared */
mOthersList [ id ] = pstate ;
return true ;
}
/*******************************************************************/
/*******************************************************************/
/*************** External Control ****************/
bool p3ConnectMgr : : retryConnect ( std : : string id )
2008-03-02 09:25:59 -05:00
{
retryConnectTCP ( id ) ;
retryConnectNotify ( id ) ;
return true ;
}
bool p3ConnectMgr : : retryConnectTCP ( std : : string id )
2008-01-25 01:36:40 -05:00
{
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
/* push addresses onto stack */
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::retryConnectTCP() id: " < < id < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-01-25 01:36:40 -05:00
/* look up the id */
std : : map < std : : string , peerConnectState > : : iterator it ;
if ( mFriendList . end ( ) = = ( it = mFriendList . find ( id ) ) )
{
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-12-13 16:59:26 -05:00
std : : cerr < < " p3ConnectMgr::retryConnectTCP() Peer is not Friend " < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-01-25 01:36:40 -05:00
return false ;
}
/* if already connected -> done */
2009-12-13 16:59:26 -05:00
if ( it - > second . state & RS_PEER_S_CONNECTED )
2008-01-25 01:36:40 -05:00
{
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::retryConnectTCP() Peer Already Connected " < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2009-12-13 16:59:26 -05:00
if ( it - > second . currentConnAddrAttempt . type & RS_NET_CONN_TUNNEL ) {
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::retryConnectTCP() Peer Connected through a tunnel connection, let's try a normal connection. " < < std : : endl ;
# endif
} else {
return true ;
}
2008-01-25 01:36:40 -05:00
}
2009-12-13 16:59:26 -05:00
//add the ips off the ipAdressList for TCP
2009-11-11 11:47:54 -05:00
std : : list < IpAddressTimed > ipList = it - > second . getIpAddressList ( ) ;
for ( std : : list < IpAddressTimed > : : iterator ipListIt = ipList . begin ( ) ; ipListIt ! = ( ipList . end ( ) ) ; ipListIt + + ) {
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::retryConnectTCP() adding ip : " < < inet_ntoa ( ipListIt - > ipAddr . sin_addr ) ;
std : : cerr < < " : " < < ntohs ( ipListIt - > ipAddr . sin_port ) < < std : : endl ;
2009-11-11 11:47:54 -05:00
# endif
2009-11-12 06:51:27 -05:00
//check that the address doens't exist already in the connAddrs
bool found = false ;
for ( std : : list < peerConnectAddress > : : iterator cit = it - > second . connAddrs . begin ( ) ; cit ! = it - > second . connAddrs . end ( ) ; cit + + ) {
2009-12-13 16:59:26 -05:00
if ( cit - > addr . sin_addr . s_addr = = ipListIt - > ipAddr . sin_addr . s_addr & &
cit - > addr . sin_port = = ipListIt - > ipAddr . sin_port & &
cit - > type = = RS_NET_CONN_TCP_UNKNOW_TOPOLOGY ) {
2009-11-12 06:51:27 -05:00
# ifdef CONN_DEBUG
2009-12-13 16:59:26 -05:00
std : : cerr < < " p3ConnectMgr::retryConnectTCP() tcp attempt already in list. " < < std : : endl ;
2009-11-12 06:51:27 -05:00
# endif
found = true ;
break ;
}
}
2009-12-13 16:59:26 -05:00
if ( ! found ) {
# ifdef CONN_DEBUG
std : : cerr < < " Adding tcp connection attempt list. " < < std : : endl ;
# endif
2009-12-14 16:20:17 -05:00
peerConnectAddress pca ;
2009-12-13 16:59:26 -05:00
pca . addr = ipListIt - > ipAddr ;
pca . type = RS_NET_CONN_TCP_UNKNOW_TOPOLOGY ;
pca . delay = P3CONNMGR_TCP_DEFAULT_DELAY ;
pca . ts = time ( NULL ) ;
pca . period = 0 ;
it - > second . connAddrs . push_back ( pca ) ;
}
}
2009-12-15 11:56:58 -05:00
//add the supposed external address UDP
IpAddressTimed extractedAddress ;
if ( peerConnectState : : extractExtAddress ( it - > second . getIpAddressList ( ) , extractedAddress ) ) {
# ifdef CONN_DEBUG
rslog ( RSL_DEBUG_BASIC , p3connectzone , " p3ConnectMgr::retryConnectTCP() got a valid external address for UDP connection " ) ;
# endif
//check that the UDP attempt doens't exist already in the connAddrs
bool found = false ;
for ( std : : list < peerConnectAddress > : : iterator cit = it - > second . connAddrs . begin ( ) ; cit ! = it - > second . connAddrs . end ( ) ; cit + + ) {
if ( cit - > type = = RS_NET_CONN_UDP ) {
# ifdef CONN_DEBUG
rslog ( RSL_DEBUG_BASIC , p3connectzone , " p3ConnectMgr::retryConnectTCP() udp attempt already in list. " ) ;
# endif
found = true ;
break ;
2009-12-13 16:59:26 -05:00
}
2009-12-15 11:56:58 -05:00
}
if ( ! found ) {
# ifdef CONN_DEBUG
rslog ( RSL_DEBUG_BASIC , p3connectzone , " p3ConnectMgr::retryConnectTCP() Adding udp connection attempt. " ) ;
# endif
peerConnectAddress pca ;
pca . addr = extractedAddress . ipAddr ;
pca . type = RS_NET_CONN_UDP ;
pca . delay = P3CONNMGR_UDP_DEFAULT_DELAY ;
pca . ts = time ( NULL ) ;
// pseudo random number generator from Wikipedia/Numerical Recipies.
pca . period = P3CONNMGR_UDP_DEFAULT_PERIOD + ( ( time ( NULL ) * 1664525 + 1013904223 ) % P3CONNMGR_UDP_DEFAULT_PERIOD ) ; //add a random period between 1 and 2 times P3CONNMGR_UDP_DEFAULT_PERIOD
it - > second . connAddrs . push_back ( pca ) ;
}
} else {
# ifdef CONN_DEBUG
rslog ( RSL_DEBUG_BASIC , p3connectzone , " p3ConnectMgr::retryConnectTCP() no valid external address found for udp connection. " ) ;
# endif
2009-12-13 16:59:26 -05:00
}
//ad the tunnel attempt
bool found = false ;
for ( std : : list < peerConnectAddress > : : iterator cit = it - > second . connAddrs . begin ( ) ; cit ! = it - > second . connAddrs . end ( ) ; cit + + ) {
if ( cit - > type = = RS_NET_CONN_TUNNEL ) {
2009-12-15 11:56:58 -05:00
# ifdef CONN_DEBUG
rslog ( RSL_DEBUG_BASIC , p3connectzone , " p3ConnectMgr::retryConnectTCP() tunnel is already in the list. " ) ;
# endif
2009-12-13 16:59:26 -05:00
found = true ;
break ;
}
}
if ( ! ( it - > second . state & RS_PEER_S_CONNECTED ) & & ! found & & allow_tunnel_connection )
{
2009-12-15 11:56:58 -05:00
# ifdef CONN_DEBUG
rslog ( RSL_DEBUG_BASIC , p3connectzone , " p3ConnectMgr::retryConnectTCP() Add the tunnel connection attempt. " ) ;
# endif
2009-12-13 16:59:26 -05:00
peerConnectAddress pca ;
pca . type = RS_NET_CONN_TUNNEL ;
pca . ts = time ( NULL ) ;
pca . period = 0 ;
it - > second . connAddrs . push_back ( pca ) ;
}
2008-03-02 09:25:59 -05:00
/* flag as last attempt to prevent loop */
2009-12-13 16:59:26 -05:00
it - > second . lastattempt = time ( NULL ) + ( ( time ( NULL ) * 1664525 + 1013904223 ) % 3 ) ; //add a random perturbation between 0 and 2 sec. pseudo random number generator from Wikipedia/Numerical Recipies.
2008-03-02 09:25:59 -05:00
2009-12-15 11:56:58 -05:00
if ( it - > second . inConnAttempt ) {
/* -> it'll automatically use the addresses we added */
2008-03-02 09:25:59 -05:00
return true ;
}
/* start a connection attempt */
2009-12-15 11:56:58 -05:00
if ( it - > second . connAddrs . size ( ) > 0 ) {
# ifdef CONN_DEBUG
std : : ostringstream out ;
out < < " p3ConnectMgr::retryConnectTCP() Started CONNECT ATTEMPT! " < < " id: " < < id ;
rslog ( RSL_DEBUG_ALERT , p3connectzone , out . str ( ) ) ;
# endif
2008-02-26 21:32:20 -05:00
2009-12-15 11:56:58 -05:00
it - > second . actions | = RS_PEER_CONNECT_REQ ;
mStatusChanged = true ;
} else {
# ifdef CONN_DEBUG
std : : ostringstream out ;
out < < " p3ConnectMgr::retryConnectTCP() No addr in the connect attempt list. Not suitable for CONNECT ATTEMPT! " < < " id: " < < id ;
rslog ( RSL_DEBUG_ALERT , p3connectzone , out . str ( ) ) ;
# endif
2008-02-26 21:32:20 -05:00
}
2008-03-02 09:25:59 -05:00
return true ;
}
2008-01-25 01:36:40 -05:00
2008-03-02 09:25:59 -05:00
bool p3ConnectMgr : : retryConnectNotify ( std : : string id )
{
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-03-02 09:25:59 -05:00
/* push addresses onto stack */
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::retryConnectNotify() id: " < < id < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-03-02 09:25:59 -05:00
/* look up the id */
std : : map < std : : string , peerConnectState > : : iterator it ;
if ( mFriendList . end ( ) = = ( it = mFriendList . find ( id ) ) )
2008-01-25 01:36:40 -05:00
{
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::retryConnectNotify() Peer is not Friend " < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-03-02 09:25:59 -05:00
return false ;
}
/* if already connected -> done */
if ( it - > second . state & RS_PEER_S_CONNECTED )
{
2009-12-13 16:59:26 -05:00
if ( it - > second . currentConnAddrAttempt . type & RS_NET_CONN_TUNNEL ) {
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-12-13 16:59:26 -05:00
std : : cerr < < " p3ConnectMgr::retryConnectNotify() Peer Connected through a tunnel connection, let's try a normal connection. " < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2009-12-13 16:59:26 -05:00
} else {
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::retryConnectNotify() Peer Already Connected, aborting retryConnect " < < std : : endl ;
# endif
return true ;
}
2008-01-25 01:36:40 -05:00
}
2008-03-02 09:25:59 -05:00
/* flag as last attempt to prevent loop */
2009-12-13 16:59:26 -05:00
it - > second . lastattempt = time ( NULL ) + ( ( time ( NULL ) * 1664525 + 1013904223 ) % 3 ) ; //add a random perturbation between 0 and 2 sec. pseudo random number generator from Wikipedia/Numerical Recipies.
2008-03-02 09:25:59 -05:00
if ( ownState . netMode & RS_NET_MODE_UNREACHABLE )
2008-01-28 00:40:32 -05:00
{
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::retryConnectNotify() UNREACHABLE so no Notify! id: " < < id < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-01-28 00:40:32 -05:00
}
2008-02-26 21:32:20 -05:00
else
{
2008-07-09 05:55:09 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::retryConnectNotify() Notifying Peer id: " < < id < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2008-07-10 12:29:18 -04:00
{
/* Log */
std : : ostringstream out ;
out < < " p3ConnectMgr::retryConnectNotify() Notifying Peer " ;
out < < " id: " < < id ;
rslog ( RSL_WARNING , p3connectzone , out . str ( ) ) ;
}
2008-03-02 09:25:59 -05:00
/* attempt UDP connection */
2008-08-16 11:02:24 -04:00
netAssistNotify ( id ) ;
2008-02-26 21:32:20 -05:00
}
2008-03-02 09:25:59 -05:00
2008-01-25 01:36:40 -05:00
return true ;
}
bool p3ConnectMgr : : setLocalAddress ( std : : string id , struct sockaddr_in addr )
{
2008-05-13 11:41:40 -04:00
2008-01-25 01:36:40 -05:00
if ( id = = mAuthMgr - > OwnId ( ) )
{
2009-12-14 08:46:23 -05:00
{
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
ownState . currentlocaladdr = addr ;
}
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
if ( ( ownState . netMode & RS_NET_MODE_ACTUAL ) = = RS_NET_MODE_EXT | |
( ownState . netMode & RS_NET_MODE_ACTUAL ) = = RS_NET_MODE_UDP ) {
netReset ( ) ;
}
return true ;
2008-01-25 01:36:40 -05:00
}
2009-12-14 08:46:23 -05:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
/* check if it is a friend */
2008-01-25 01:36:40 -05:00
std : : map < std : : string , peerConnectState > : : iterator it ;
if ( mFriendList . end ( ) = = ( it = mFriendList . find ( id ) ) )
{
if ( mOthersList . end ( ) = = ( it = mOthersList . find ( id ) ) )
{
2009-09-06 15:52:48 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::setLocalAddress() cannot add addres info : peer id not found in friend list id: " < < id < < std : : endl ;
2009-09-06 15:52:48 -04:00
# endif
2008-01-25 01:36:40 -05:00
return false ;
}
}
/* "it" points to peer */
2009-11-11 11:43:51 -05:00
it - > second . currentlocaladdr = addr ;
2009-11-11 11:47:54 -05:00
//update ip address list
IpAddressTimed ipAddressTimed ;
ipAddressTimed . ipAddr = addr ;
ipAddressTimed . seenTime = time ( NULL ) ;
it - > second . updateIpAddressList ( ipAddressTimed ) ;
2008-02-07 11:18:34 -05:00
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2008-01-25 01:36:40 -05:00
return true ;
}
bool p3ConnectMgr : : setExtAddress ( std : : string id , struct sockaddr_in addr )
{
if ( id = = mAuthMgr - > OwnId ( ) )
{
2009-12-14 13:11:19 -05:00
if ( ownState . currentserveraddr . sin_addr . s_addr ! = addr . sin_addr . s_addr | |
ownState . currentserveraddr . sin_port ! = addr . sin_port ) {
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
ownState . currentserveraddr = addr ;
}
2009-12-14 08:46:23 -05:00
return true ;
2009-12-14 13:11:19 -05:00
}
2008-01-25 01:36:40 -05:00
2009-12-14 08:46:23 -05:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
/* check if it is a friend */
std : : map < std : : string , peerConnectState > : : iterator it ;
if ( mFriendList . end ( ) = = ( it = mFriendList . find ( id ) ) )
{
if ( mOthersList . end ( ) = = ( it = mOthersList . find ( id ) ) )
{
2009-09-06 15:52:48 -04:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::setLocalAddress() cannot add addres info : peer id not found in friend list id: " < < id < < std : : endl ;
2009-09-06 15:52:48 -04:00
# endif
2008-01-25 01:36:40 -05:00
return false ;
}
}
/* "it" points to peer */
2009-11-11 11:43:51 -05:00
it - > second . currentserveraddr = addr ;
2009-11-11 11:47:54 -05:00
//update ip address list
IpAddressTimed ipAddressTimed ;
ipAddressTimed . ipAddr = addr ;
ipAddressTimed . seenTime = time ( NULL ) ;
it - > second . updateIpAddressList ( ipAddressTimed ) ;
2008-02-07 11:18:34 -05:00
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2008-01-25 01:36:40 -05:00
return true ;
}
2009-11-11 11:44:51 -05:00
bool p3ConnectMgr : : setAddressList ( std : : string id , std : : list < IpAddressTimed > IpAddressTimedList )
{
2009-12-14 13:11:19 -05:00
/* check if it is our own ip */
if ( id = = getOwnId ( ) ) {
2009-12-14 16:59:15 -05:00
struct sockaddr_in extAddr ;
if ( getUpnpExtAddress ( extAddr ) | | getExtFinderExtAddress ( extAddr ) ) {
2009-12-15 11:56:58 -05:00
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::setAddressList() received own ip address list, but already got an external address with upnp or extaddrfinder. " < < std : : endl ;
# endif
return false ;
}
IpAddressTimed extractedAddress ;
if ( peerConnectState : : extractExtAddress ( IpAddressTimedList , extractedAddress ) ) {
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::setAddressList() got a valid own external address. " < < std : : endl ;
# endif
setExtAddress ( getOwnId ( ) , extractedAddress . ipAddr ) ;
IndicateConfigChanged ( ) ;
return true ;
} else {
# ifdef CONN_DEBUG
rslog ( RSL_DEBUG_BASIC , p3connectzone , " p3ConnectMgr::setAddressList() no valid external address found for own address " ) ;
# endif
2009-12-14 16:59:15 -05:00
return false ;
}
2009-12-14 13:11:19 -05:00
}
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
/* check if it is a friend */
2009-11-11 11:44:51 -05:00
std : : map < std : : string , peerConnectState > : : iterator it ;
if ( mFriendList . end ( ) = = ( it = mFriendList . find ( id ) ) )
{
if ( mOthersList . end ( ) = = ( it = mOthersList . find ( id ) ) )
{
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::setLocalAddress() cannot add addres info : peer id not found in friend list id: " < < id < < std : : endl ;
2009-11-11 11:44:51 -05:00
# endif
return false ;
}
}
/* "it" points to peer */
2009-11-11 11:47:10 -05:00
it - > second . updateIpAddressList ( IpAddressTimedList ) ;
2009-11-11 11:44:51 -05:00
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
return true ;
}
2008-01-25 01:36:40 -05:00
bool p3ConnectMgr : : setNetworkMode ( std : : string id , uint32_t netMode )
{
2008-02-07 11:18:34 -05:00
if ( id = = mAuthMgr - > OwnId ( ) )
{
uint32_t visState = ownState . visState ;
setOwnNetConfig ( netMode , visState ) ;
2009-12-14 08:46:23 -05:00
if ( ( netMode & RS_NET_MODE_ACTUAL ) ! = ( ownState . netMode & RS_NET_MODE_ACTUAL ) ) {
netReset ( ) ;
}
2008-02-07 11:18:34 -05:00
return true ;
}
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-02-07 11:18:34 -05:00
/* check if it is a friend */
std : : map < std : : string , peerConnectState > : : iterator it ;
if ( mFriendList . end ( ) = = ( it = mFriendList . find ( id ) ) )
{
if ( mOthersList . end ( ) = = ( it = mOthersList . find ( id ) ) )
{
return false ;
}
}
/* "it" points to peer */
it - > second . netMode = netMode ;
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
return false ;
}
bool p3ConnectMgr : : setVisState ( std : : string id , uint32_t visState )
{
if ( id = = mAuthMgr - > OwnId ( ) )
{
uint32_t netMode = ownState . netMode ;
setOwnNetConfig ( netMode , visState ) ;
return true ;
}
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-02-07 11:18:34 -05:00
/* check if it is a friend */
std : : map < std : : string , peerConnectState > : : iterator it ;
bool isFriend = false ;
if ( mFriendList . end ( ) = = ( it = mFriendList . find ( id ) ) )
{
if ( mOthersList . end ( ) = = ( it = mOthersList . find ( id ) ) )
{
return false ;
}
}
else
{
isFriend = true ;
}
/* "it" points to peer */
it - > second . visState = visState ;
if ( isFriend )
{
/* toggle DHT state */
if ( it - > second . visState & RS_VIS_STATE_NODHT )
{
/* hidden from DHT world */
2008-08-16 11:02:24 -04:00
netAssistFriend ( id , false ) ;
2008-02-07 11:18:34 -05:00
}
else
{
2008-08-16 11:02:24 -04:00
netAssistFriend ( id , true ) ;
2008-02-07 11:18:34 -05:00
}
}
IndicateConfigChanged ( ) ; /**** INDICATE MSG CONFIG CHANGED! *****/
2008-01-25 01:36:40 -05:00
return false ;
}
2008-02-07 11:18:34 -05:00
2008-01-25 01:36:40 -05:00
/*******************************************************************/
2009-11-06 17:12:58 -05:00
bool p3ConnectMgr : : checkNetAddress ( )
{
2009-11-11 11:43:51 -05:00
in_addr_t old_in_addr = ownState . currentlocaladdr . sin_addr . s_addr ;
int old_in_port = ownState . currentlocaladdr . sin_port ;
2009-11-06 17:12:58 -05:00
{
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
// GetPreferredInterface now chooses the best local ilterface for you. So it's the default function to use now.
//
2009-11-11 11:43:51 -05:00
ownState . currentlocaladdr . sin_addr = getPreferredInterface ( ) ;
2009-11-06 17:12:58 -05:00
2009-11-16 05:53:17 -05:00
if ( ownState . currentlocaladdr . sin_addr . s_addr ! = 0 & & ! isLoopbackNet ( & ( ownState . currentlocaladdr . sin_addr ) ) )
2009-11-06 17:12:58 -05:00
{
if ( netFlagLocalOk ! = true )
{
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::checkNetAddress() changing netFlagOk to true. " < < std : : endl ;
2009-11-06 17:12:58 -05:00
# endif
netFlagLocalOk = true ;
IndicateConfigChanged ( ) ;
}
2009-11-16 05:53:17 -05:00
} else {
if ( netFlagLocalOk ! = false )
{
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::checkNetAddress() changing netFlagOk to false. " < < std : : endl ;
2009-11-16 05:53:17 -05:00
# endif
netFlagLocalOk = false ;
netFlagExtraAddressCheckOk = false ;
netFlagUpnpOk = false ;
netFlagDhtOk = false ;
netFlagStunOk = false ;
IndicateConfigChanged ( ) ;
}
}
2009-11-06 17:12:58 -05:00
2009-11-11 11:43:51 -05:00
if ( isLoopbackNet ( & ( ownState . currentlocaladdr . sin_addr ) ) )
2009-11-06 17:12:58 -05:00
mNetStatus = RS_NET_LOOPBACK ;
2009-11-11 11:43:51 -05:00
int port = ntohs ( ownState . currentlocaladdr . sin_port ) ;
2009-11-06 17:12:58 -05:00
if ( ( port < PQI_MIN_PORT ) | | ( port > PQI_MAX_PORT ) )
2009-11-11 11:43:51 -05:00
ownState . currentlocaladdr . sin_port = htons ( PQI_DEFAULT_PORT ) ;
2009-11-06 17:12:58 -05:00
/* if localaddr = serveraddr, then ensure that the ports
* are the same ( modify server ) . . . this mismatch can
* occur when the local port is changed . . . .
*/
2009-11-11 11:43:51 -05:00
if ( ownState . currentlocaladdr . sin_addr . s_addr = = ownState . currentserveraddr . sin_addr . s_addr )
ownState . currentserveraddr . sin_port = ownState . currentlocaladdr . sin_port ;
2009-11-06 17:12:58 -05:00
// ensure that address family is set, otherwise windows Barfs.
2009-11-11 11:43:51 -05:00
ownState . currentlocaladdr . sin_family = AF_INET ;
ownState . currentserveraddr . sin_family = AF_INET ;
2009-11-06 17:12:58 -05:00
2009-11-11 11:47:10 -05:00
//update ip address list
IpAddressTimed ipAddressTimed ;
ipAddressTimed . ipAddr = ownState . currentlocaladdr ;
ipAddressTimed . seenTime = time ( NULL ) ;
ownState . updateIpAddressList ( ipAddressTimed ) ;
2009-11-06 17:12:58 -05:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::checkNetAddress() Final Local Address: " < < inet_ntoa ( ownState . currentlocaladdr . sin_addr ) ;
std : : cerr < < " : " < < ntohs ( ownState . currentlocaladdr . sin_port ) < < std : : endl ;
2009-11-06 17:12:58 -05:00
# endif
}
2009-11-11 11:43:51 -05:00
if ( ( old_in_addr ! = ownState . currentlocaladdr . sin_addr . s_addr ) | | ( old_in_port ! = ownState . currentlocaladdr . sin_port ) )
2009-11-06 17:12:58 -05:00
{
# ifdef CONN_DEBUG
std : : cerr < < " p3ConnectMgr::checkNetAddress() local address changed, resetting network. " < < std : : endl ;
# endif
netReset ( ) ;
}
return 1 ;
}
2008-01-25 01:36:40 -05:00
/************************* p3config functions **********************/
/*******************************************************************/
/* Key Functions to be overloaded for Full Configuration */
RsSerialiser * p3ConnectMgr : : setupSerialiser ( )
{
RsSerialiser * rss = new RsSerialiser ( ) ;
2008-02-07 11:18:34 -05:00
rss - > addSerialType ( new RsPeerConfigSerialiser ( ) ) ;
2009-04-09 17:13:48 -04:00
rss - > addSerialType ( new RsGeneralConfigSerialiser ( ) ) ;
2008-01-25 01:36:40 -05:00
return rss ;
}
std : : list < RsItem * > p3ConnectMgr : : saveList ( bool & cleanup )
{
/* create a list of current peers */
std : : list < RsItem * > saveData ;
cleanup = true ;
2008-02-07 11:18:34 -05:00
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-01-25 01:36:40 -05:00
2008-02-07 11:18:34 -05:00
RsPeerNetItem * item = new RsPeerNetItem ( ) ;
item - > clear ( ) ;
2008-01-25 01:36:40 -05:00
2008-02-07 11:18:34 -05:00
item - > pid = getOwnId ( ) ;
2008-02-26 11:14:13 -05:00
if ( ownState . netMode & RS_NET_MODE_TRY_EXT )
{
item - > netMode = RS_NET_MODE_EXT ;
}
else if ( ownState . netMode & RS_NET_MODE_TRY_UPNP )
{
item - > netMode = RS_NET_MODE_UPNP ;
}
else
{
item - > netMode = RS_NET_MODE_UDP ;
}
2008-02-07 11:18:34 -05:00
item - > visState = ownState . visState ;
item - > lastContact = ownState . lastcontact ;
2009-11-11 11:43:51 -05:00
2009-11-11 11:45:46 -05:00
item - > currentlocaladdr = ownState . currentlocaladdr ;
item - > currentremoteaddr = ownState . currentserveraddr ;
2009-11-11 11:47:10 -05:00
item - > ipAddressList = ownState . getIpAddressList ( ) ;
2008-01-25 01:36:40 -05:00
2008-02-07 11:18:34 -05:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::saveList() Own Config Item: " < < std : : endl ;
2008-02-07 11:18:34 -05:00
item - > print ( std : : cerr , 10 ) ;
std : : cerr < < std : : endl ;
# endif
2008-01-25 01:36:40 -05:00
2008-02-07 11:18:34 -05:00
saveData . push_back ( item ) ;
2008-01-25 01:36:40 -05:00
2008-02-07 11:18:34 -05:00
/* iterate through all friends and save */
std : : map < std : : string , peerConnectState > : : iterator it ;
for ( it = mFriendList . begin ( ) ; it ! = mFriendList . end ( ) ; it + + )
{
item = new RsPeerNetItem ( ) ;
item - > clear ( ) ;
2008-01-25 01:36:40 -05:00
2008-02-07 11:18:34 -05:00
item - > pid = it - > first ;
item - > netMode = ( it - > second ) . netMode ;
item - > visState = ( it - > second ) . visState ;
item - > lastContact = ( it - > second ) . lastcontact ;
2009-11-11 11:43:51 -05:00
item - > currentlocaladdr = ( it - > second ) . currentlocaladdr ;
2009-11-11 11:45:46 -05:00
item - > currentremoteaddr = ( it - > second ) . currentserveraddr ;
2009-11-11 11:47:10 -05:00
item - > ipAddressList = ( it - > second ) . getIpAddressList ( ) ;
2008-01-25 01:36:40 -05:00
2008-02-07 11:18:34 -05:00
saveData . push_back ( item ) ;
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::saveList() Peer Config Item: " < < std : : endl ;
2008-02-07 11:18:34 -05:00
item - > print ( std : : cerr , 10 ) ;
std : : cerr < < std : : endl ;
# endif
}
2008-01-25 01:36:40 -05:00
2008-02-07 11:18:34 -05:00
RsPeerStunItem * sitem = new RsPeerStunItem ( ) ;
2008-01-25 01:36:40 -05:00
2008-02-07 11:18:34 -05:00
std : : list < std : : string > : : iterator sit ;
2008-02-26 13:55:16 -05:00
uint32_t count = 0 ;
for ( sit = mStunList . begin ( ) ; ( sit ! = mStunList . end ( ) ) & &
( count < RS_STUN_LIST_MIN ) ; sit + + , count + + )
2008-02-07 11:18:34 -05:00
{
sitem - > stunList . ids . push_back ( * sit ) ;
}
2008-02-26 11:14:13 -05:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::saveList() Peer Stun Item: " < < std : : endl ;
2008-02-26 11:14:13 -05:00
sitem - > print ( std : : cerr , 10 ) ;
std : : cerr < < std : : endl ;
# endif
2008-02-07 11:18:34 -05:00
saveData . push_back ( sitem ) ;
2008-01-25 01:36:40 -05:00
2009-04-09 17:13:48 -04:00
// Now save config for network digging strategies
RsConfigKeyValueSet * vitem = new RsConfigKeyValueSet ;
RsTlvKeyValue kv ;
kv . key = " USE_EXTR_IP_FINDER " ;
kv . value = ( use_extr_addr_finder ) ? " TRUE " : " FALSE " ;
vitem - > tlvkvs . pairs . push_back ( kv ) ;
std : : cout < < " Pushing item for use_extr_addr_finder = " < < use_extr_addr_finder < < std : : endl ;
saveData . push_back ( vitem ) ;
2009-12-13 16:59:26 -05:00
// Now save config for network digging strategies
RsConfigKeyValueSet * vitem2 = new RsConfigKeyValueSet ;
RsTlvKeyValue kv2 ;
kv2 . key = " ALLOW_TUNNEL_CONNECTION " ;
kv2 . value = ( allow_tunnel_connection ) ? " TRUE " : " FALSE " ;
vitem2 - > tlvkvs . pairs . push_back ( kv2 ) ;
std : : cout < < " Pushing item for allow_tunnel_connection = " < < allow_tunnel_connection < < std : : endl ;
saveData . push_back ( vitem2 ) ;
2008-02-07 11:18:34 -05:00
return saveData ;
}
2008-01-25 01:36:40 -05:00
2008-02-07 11:18:34 -05:00
bool p3ConnectMgr : : loadList ( std : : list < RsItem * > load )
{
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::loadList() Item Count: " < < load . size ( ) < < std : : endl ;
2008-02-07 11:18:34 -05:00
# endif
2008-01-25 01:36:40 -05:00
2008-02-07 11:18:34 -05:00
/* load the list of peers */
std : : list < RsItem * > : : iterator it ;
for ( it = load . begin ( ) ; it ! = load . end ( ) ; it + + )
2008-01-25 01:36:40 -05:00
{
2008-02-07 11:18:34 -05:00
RsPeerNetItem * pitem = dynamic_cast < RsPeerNetItem * > ( * it ) ;
RsPeerStunItem * sitem = dynamic_cast < RsPeerStunItem * > ( * it ) ;
2009-04-09 17:13:48 -04:00
RsConfigKeyValueSet * vitem = dynamic_cast < RsConfigKeyValueSet * > ( * it ) ;
2008-01-25 01:36:40 -05:00
2008-02-07 11:18:34 -05:00
if ( pitem )
2008-01-25 01:36:40 -05:00
{
2008-02-07 11:18:34 -05:00
if ( pitem - > pid = = getOwnId ( ) )
2008-01-25 01:36:40 -05:00
{
2008-02-07 11:18:34 -05:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::loadList() Own Config Item: " < < std : : endl ;
2008-02-07 11:18:34 -05:00
pitem - > print ( std : : cerr , 10 ) ;
std : : cerr < < std : : endl ;
# endif
/* add ownConfig */
setOwnNetConfig ( pitem - > netMode , pitem - > visState ) ;
2009-11-11 11:43:51 -05:00
setLocalAddress ( pitem - > pid , pitem - > currentlocaladdr ) ;
setExtAddress ( pitem - > pid , pitem - > currentremoteaddr ) ;
2008-01-25 01:36:40 -05:00
}
2008-02-07 11:18:34 -05:00
else
2008-01-25 01:36:40 -05:00
{
2008-02-07 11:18:34 -05:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::loadList() Peer Config Item: " < < std : : endl ;
2008-02-07 11:18:34 -05:00
pitem - > print ( std : : cerr , 10 ) ;
std : : cerr < < std : : endl ;
# endif
/* ************* */
addFriend ( pitem - > pid , pitem - > netMode , pitem - > visState , pitem - > lastContact ) ;
2009-11-11 11:43:51 -05:00
setLocalAddress ( pitem - > pid , pitem - > currentlocaladdr ) ;
setExtAddress ( pitem - > pid , pitem - > currentremoteaddr ) ;
2009-11-11 11:45:46 -05:00
setAddressList ( pitem - > pid , pitem - > ipAddressList ) ;
2008-01-25 01:36:40 -05:00
}
2008-02-07 11:18:34 -05:00
}
else if ( sitem )
{
2008-05-13 11:41:40 -04:00
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
2008-02-07 11:18:34 -05:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::loadList() Stun Config Item: " < < std : : endl ;
2008-02-07 11:18:34 -05:00
sitem - > print ( std : : cerr , 10 ) ;
std : : cerr < < std : : endl ;
# endif
std : : list < std : : string > : : iterator sit ;
for ( sit = sitem - > stunList . ids . begin ( ) ;
sit ! = sitem - > stunList . ids . end ( ) ; sit + + )
2008-01-25 01:36:40 -05:00
{
2008-02-07 11:18:34 -05:00
mStunList . push_back ( * sit ) ;
2008-01-25 01:36:40 -05:00
}
}
2009-04-09 17:13:48 -04:00
else if ( vitem )
{
RsStackMutex stack ( connMtx ) ; /****** STACK LOCK MUTEX *******/
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " p3ConnectMgr::loadList() General Variable Config Item: " < < std : : endl ;
2009-04-09 17:13:48 -04:00
vitem - > print ( std : : cerr , 10 ) ;
std : : cerr < < std : : endl ;
# endif
if ( vitem - > tlvkvs . pairs . front ( ) . key = = " USE_EXTR_IP_FINDER " )
{
use_extr_addr_finder = ( vitem - > tlvkvs . pairs . front ( ) . value = = " TRUE " ) ;
std : : cerr < < " setting use_extr_addr_finder to " < < use_extr_addr_finder < < std : : endl ;
2009-12-13 16:59:26 -05:00
} else if ( vitem - > tlvkvs . pairs . front ( ) . key = = " ALLOW_TUNNEL_CONNECTION " )
{
allow_tunnel_connection = ( vitem - > tlvkvs . pairs . front ( ) . value = = " TRUE " ) ;
std : : cerr < < " setting allow_tunnel_connection to " < < allow_tunnel_connection < < std : : endl ;
}
2009-04-09 17:13:48 -04:00
}
2008-01-25 01:36:40 -05:00
2008-02-07 11:18:34 -05:00
delete ( * it ) ;
2008-01-25 01:36:40 -05:00
}
2008-02-07 11:18:34 -05:00
return true ;
2008-01-25 01:36:40 -05:00
}
2008-02-08 12:05:55 -05:00
void printConnectState ( peerConnectState & peer )
{
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " Friend: " < < peer . name < < " Id: " < < peer . id < < " State: " < < peer . state ;
2008-02-08 12:05:55 -05:00
if ( peer . state & RS_PEER_S_FRIEND )
std : : cerr < < " S:RS_PEER_S_FRIEND " ;
if ( peer . state & RS_PEER_S_ONLINE )
std : : cerr < < " S:RS_PEER_S_ONLINE " ;
if ( peer . state & RS_PEER_S_CONNECTED )
std : : cerr < < " S:RS_PEER_S_CONNECTED " ;
std : : cerr < < " Actions: " < < peer . actions ;
if ( peer . actions & RS_PEER_NEW )
std : : cerr < < " A:RS_PEER_NEW " ;
if ( peer . actions & RS_PEER_MOVED )
std : : cerr < < " A:RS_PEER_MOVED " ;
if ( peer . actions & RS_PEER_CONNECTED )
std : : cerr < < " A:RS_PEER_CONNECTED " ;
if ( peer . actions & RS_PEER_DISCONNECTED )
std : : cerr < < " A:RS_PEER_DISCONNECTED " ;
if ( peer . actions & RS_PEER_CONNECT_REQ )
std : : cerr < < " A:RS_PEER_CONNECT_REQ " ;
std : : cerr < < std : : endl ;
# endif
return ;
}
2008-03-03 09:01:52 -05:00
bool p3ConnectMgr : : addBootstrapStunPeers ( )
{
std : : string id ;
2008-03-05 11:32:18 -05:00
struct sockaddr_in dummyaddr ;
uint32_t flags = 0 ;
2008-03-03 09:01:52 -05:00
2008-03-26 11:35:09 -04:00
/* only use the Bootstrap system now */
2008-03-03 09:01:52 -05:00
2008-03-05 11:32:18 -05:00
return true ;
2008-03-03 09:01:52 -05:00
}
2008-08-16 11:02:24 -04:00
/************************ INTERFACES ***********************/
2008-08-16 11:40:47 -04:00
void p3ConnectMgr : : addNetAssistFirewall ( uint32_t id , pqiNetAssistFirewall * fwAgent )
{
mFwAgents [ id ] = fwAgent ;
}
2008-08-16 11:02:24 -04:00
bool p3ConnectMgr : : enableNetAssistFirewall ( bool on )
{
std : : map < uint32_t , pqiNetAssistFirewall * > : : iterator it ;
for ( it = mFwAgents . begin ( ) ; it ! = mFwAgents . end ( ) ; it + + )
{
( it - > second ) - > enable ( on ) ;
}
return true ;
}
bool p3ConnectMgr : : netAssistFirewallEnabled ( )
{
std : : map < uint32_t , pqiNetAssistFirewall * > : : iterator it ;
for ( it = mFwAgents . begin ( ) ; it ! = mFwAgents . end ( ) ; it + + )
{
if ( ( it - > second ) - > getEnabled ( ) )
{
return true ;
}
}
return false ;
}
bool p3ConnectMgr : : netAssistFirewallActive ( )
{
std : : map < uint32_t , pqiNetAssistFirewall * > : : iterator it ;
for ( it = mFwAgents . begin ( ) ; it ! = mFwAgents . end ( ) ; it + + )
{
if ( ( it - > second ) - > getActive ( ) )
{
return true ;
}
}
return false ;
}
bool p3ConnectMgr : : netAssistFirewallShutdown ( )
{
std : : map < uint32_t , pqiNetAssistFirewall * > : : iterator it ;
for ( it = mFwAgents . begin ( ) ; it ! = mFwAgents . end ( ) ; it + + )
{
( it - > second ) - > shutdown ( ) ;
}
return true ;
}
bool p3ConnectMgr : : netAssistFirewallPorts ( uint16_t iport , uint16_t eport )
{
std : : map < uint32_t , pqiNetAssistFirewall * > : : iterator it ;
for ( it = mFwAgents . begin ( ) ; it ! = mFwAgents . end ( ) ; it + + )
{
( it - > second ) - > setInternalPort ( iport ) ;
( it - > second ) - > setExternalPort ( eport ) ;
}
return true ;
}
bool p3ConnectMgr : : netAssistExtAddress ( struct sockaddr_in & extAddr )
{
std : : map < uint32_t , pqiNetAssistFirewall * > : : iterator it ;
for ( it = mFwAgents . begin ( ) ; it ! = mFwAgents . end ( ) ; it + + )
{
if ( ( it - > second ) - > getActive ( ) )
{
if ( ( it - > second ) - > getExternalAddress ( extAddr ) )
{
return true ;
}
}
}
return false ;
}
2008-08-16 11:40:47 -04:00
void p3ConnectMgr : : addNetAssistConnect ( uint32_t id , pqiNetAssistConnect * dht )
{
mDhts [ id ] = dht ;
}
2008-08-16 11:02:24 -04:00
bool p3ConnectMgr : : enableNetAssistConnect ( bool on )
{
std : : map < uint32_t , pqiNetAssistConnect * > : : iterator it ;
for ( it = mDhts . begin ( ) ; it ! = mDhts . end ( ) ; it + + )
{
( it - > second ) - > enable ( on ) ;
}
return true ;
}
bool p3ConnectMgr : : netAssistConnectEnabled ( )
{
std : : map < uint32_t , pqiNetAssistConnect * > : : iterator it ;
for ( it = mDhts . begin ( ) ; it ! = mDhts . end ( ) ; it + + )
{
if ( ( it - > second ) - > getEnabled ( ) )
{
return true ;
}
}
return false ;
}
bool p3ConnectMgr : : netAssistConnectActive ( )
{
std : : map < uint32_t , pqiNetAssistConnect * > : : iterator it ;
for ( it = mDhts . begin ( ) ; it ! = mDhts . end ( ) ; it + + )
{
if ( ( it - > second ) - > getActive ( ) )
{
return true ;
}
}
return false ;
}
bool p3ConnectMgr : : netAssistConnectShutdown ( )
{
std : : map < uint32_t , pqiNetAssistConnect * > : : iterator it ;
for ( it = mDhts . begin ( ) ; it ! = mDhts . end ( ) ; it + + )
{
( it - > second ) - > shutdown ( ) ;
}
return true ;
}
bool p3ConnectMgr : : netAssistFriend ( std : : string id , bool on )
{
std : : map < uint32_t , pqiNetAssistConnect * > : : iterator it ;
for ( it = mDhts . begin ( ) ; it ! = mDhts . end ( ) ; it + + )
{
if ( on )
{
( it - > second ) - > findPeer ( id ) ;
}
else
{
( it - > second ) - > dropPeer ( id ) ;
}
}
return true ;
}
bool p3ConnectMgr : : netAssistAddStun ( std : : string id )
{
std : : map < uint32_t , pqiNetAssistConnect * > : : iterator it ;
for ( it = mDhts . begin ( ) ; it ! = mDhts . end ( ) ; it + + )
{
( it - > second ) - > addStun ( id ) ;
}
return true ;
}
bool p3ConnectMgr : : netAssistStun ( bool on )
{
std : : map < uint32_t , pqiNetAssistConnect * > : : iterator it ;
for ( it = mDhts . begin ( ) ; it ! = mDhts . end ( ) ; it + + )
{
( it - > second ) - > enableStun ( on ) ;
}
return true ;
}
bool p3ConnectMgr : : netAssistNotify ( std : : string id )
{
std : : map < uint32_t , pqiNetAssistConnect * > : : iterator it ;
for ( it = mDhts . begin ( ) ; it ! = mDhts . end ( ) ; it + + )
{
( it - > second ) - > notifyPeer ( id ) ;
}
return true ;
}
bool p3ConnectMgr : : netAssistSetAddress ( struct sockaddr_in & laddr ,
struct sockaddr_in & eaddr ,
uint32_t mode )
{
std : : map < uint32_t , pqiNetAssistConnect * > : : iterator it ;
for ( it = mDhts . begin ( ) ; it ! = mDhts . end ( ) ; it + + )
{
( it - > second ) - > setExternalInterface ( laddr , eaddr , mode ) ;
}
return true ;
}
2008-08-16 11:40:47 -04:00
bool p3ConnectMgr : : getUPnPState ( )
{
return netAssistFirewallActive ( ) ;
}
bool p3ConnectMgr : : getUPnPEnabled ( )
{
return netAssistFirewallEnabled ( ) ;
}
bool p3ConnectMgr : : getDHTEnabled ( )
{
return netAssistConnectEnabled ( ) ;
}
2008-03-03 09:01:52 -05:00
2009-10-29 20:41:24 -04:00
bool p3ConnectMgr : : getNetStatusLocalOk ( )
2008-10-18 12:02:06 -04:00
{
2009-10-29 20:41:24 -04:00
return netFlagLocalOk ;
2008-10-18 12:02:06 -04:00
}
bool p3ConnectMgr : : getNetStatusUpnpOk ( )
{
return netFlagUpnpOk ;
}
bool p3ConnectMgr : : getNetStatusDhtOk ( )
{
return netFlagDhtOk ;
}
2009-10-29 20:41:24 -04:00
bool p3ConnectMgr : : getNetStatusStunOk ( )
2008-10-18 12:02:06 -04:00
{
2009-10-29 20:41:24 -04:00
return netFlagStunOk ;
2008-10-18 12:02:06 -04:00
}
2009-10-29 20:41:24 -04:00
bool p3ConnectMgr : : getNetStatusExtraAddressCheckOk ( )
2008-10-18 12:02:06 -04:00
{
2009-10-29 20:41:24 -04:00
return netFlagExtraAddressCheckOk ;
2008-10-18 12:02:06 -04:00
}
2009-10-29 20:41:24 -04:00
bool p3ConnectMgr : : getUpnpExtAddress ( struct sockaddr_in & addr ) {
return netAssistExtAddress ( addr ) ;
}
2008-10-18 12:02:06 -04:00
2009-10-29 20:41:24 -04:00
bool p3ConnectMgr : : getStunExtAddress ( struct sockaddr_in & addr ) {
struct sockaddr_in temp_addr ;
socklen_t len = sizeof ( temp_addr ) ;
uint8_t stable ;
if ( 0 < tou_extaddr ( ( struct sockaddr * ) & temp_addr , & len , & stable ) )
{
addr = temp_addr ;
2008-10-18 12:02:06 -04:00
2009-10-29 20:41:24 -04:00
//#ifdef CONN_DEBUG
// std::cerr << "p3ConnectMgr::getStunExtAddress() Got ";
// std::cerr << " addr: " << inet_ntoa(addr.sin_addr);
// std::cerr << ":" << ntohs(addr.sin_port);
// std::cerr << std::endl;
//#endif
return true ;
}
//#ifdef CONN_DEBUG
// std::cerr << "p3ConnectMgr::getStunExtAddress() No ext address found." << std::endl;
//#endif
return false ;
2008-03-03 09:01:52 -05:00
2009-10-29 20:41:24 -04:00
}
2008-03-03 09:01:52 -05:00
2009-10-29 20:41:24 -04:00
bool p3ConnectMgr : : getExtFinderExtAddress ( struct sockaddr_in & addr ) {
return ( use_extr_addr_finder & & mExtAddrFinder - > hasValidIP ( & addr ) ) ;
}
2009-11-11 11:46:28 -05:00
2009-11-11 11:47:10 -05:00
bool peerConnectState : : compare_seen_time ( IpAddressTimed first , IpAddressTimed second ) { //Sort the ip list ordering by seen time
return ( first . seenTime < second . seenTime ) ;
2009-11-11 11:46:28 -05:00
}
2009-11-11 11:47:10 -05:00
bool peerConnectState : : is_same_address ( IpAddressTimed first , IpAddressTimed second ) { //Sort the ip list ordering by seen time
return ( first . ipAddr . sin_addr . s_addr = = second . ipAddr . sin_addr . s_addr & & first . ipAddr . sin_port = = second . ipAddr . sin_port ) ;
2009-11-11 11:46:28 -05:00
}
2009-11-11 11:47:10 -05:00
void peerConnectState : : sortIpAddressListBySeenTime ( ) { //Sort the ip list ordering by seen time
2009-12-15 11:56:58 -05:00
sortIpAddressListBySeenTime ( this - > ipAddressList ) ;
}
void peerConnectState : : sortIpAddressListBySeenTime ( std : : list < IpAddressTimed > & ipTimedListInput ) { //Sort the ip list ordering by seen time
2009-11-11 11:47:10 -05:00
# ifdef CONN_DEBUG
std : : cerr < < " peerConnectState::sortIpAdressListBySeenTime() called " < < std : : endl ;
# endif
2009-12-15 11:56:58 -05:00
ipTimedListInput . sort ( peerConnectState : : compare_seen_time ) ;
ipTimedListInput . reverse ( ) ;
2009-11-11 11:47:10 -05:00
}
2009-12-15 11:56:58 -05:00
2009-11-11 11:47:10 -05:00
std : : list < IpAddressTimed > peerConnectState : : getIpAddressList ( ) {
# ifdef CONN_DEBUG
std : : cerr < < " peerConnectState::getIpAddressList() called " < < std : : endl ;
# endif
purgeIpAddressList ( ) ;
# ifdef CONN_DEBUG
printIpAddressList ( ) ;
# endif
return ipAddressList ;
}
void peerConnectState : : purgeIpAddressList ( ) { //purge old and useless addresses to keep a small list
# ifdef CONN_DEBUG
std : : cerr < < " peerConnectState::purgeIpAdressList() called. " < < std : : endl ;
# endif
std : : list < IpAddressTimed > : : iterator ipListIt ;
for ( ipListIt = ipAddressList . begin ( ) ; ipListIt ! = ( ipAddressList . end ( ) ) ; ) {
2009-11-16 05:53:17 -05:00
if ( ipListIt - > ipAddr . sin_addr . s_addr = = 0 ) {
2009-11-11 11:47:10 -05:00
ipAddressList . erase ( ipListIt + + ) ;
} else {
+ + ipListIt ;
}
}
printIpAddressList ( ) ;
//purge duplicates
for ( ipListIt = ipAddressList . begin ( ) ; ipListIt ! = ( ipAddressList . end ( ) ) ; ipListIt + + ) {
std : : list < IpAddressTimed > : : iterator ipListIt2 = ipListIt ;
+ + ipListIt2 ;
while ( ipListIt2 ! = ( ipAddressList . end ( ) ) ) {
if ( is_same_address ( * ipListIt2 , * ipListIt ) ) {
ipAddressList . erase ( ipListIt2 + + ) ;
} else {
+ + ipListIt2 ;
}
}
}
sortIpAddressListBySeenTime ( ) ;
//keep only a limited number of addresses
2009-11-16 05:53:17 -05:00
if ( ipAddressList . size ( ) > PEER_IP_CONNECT_STATE_MAX_LIST_SIZE ) {
ipAddressList . resize ( PEER_IP_CONNECT_STATE_MAX_LIST_SIZE ) ;
2009-11-11 11:47:10 -05:00
}
}
void peerConnectState : : updateIpAddressList ( std : : list < IpAddressTimed > ipTimedList ) { //purge old addresses to keep a small list
std : : list < IpAddressTimed > : : iterator ipListIt ;
for ( ipListIt = ipTimedList . begin ( ) ; ipListIt ! = ( ipTimedList . end ( ) ) ; ipListIt + + ) {
updateIpAddressList ( * ipListIt ) ;
}
}
void peerConnectState : : updateIpAddressList ( IpAddressTimed ipTimed ) { //purge old addresses to keep a small list
2009-11-11 11:49:11 -05:00
# ifdef CONN_DEBUG
std : : cerr < < " peerConnectState::updateIpAdressList() ip " < < inet_ntoa ( ipTimed . ipAddr . sin_addr ) ;
std : : cerr < < " : " < < ntohs ( ipTimed . ipAddr . sin_port ) ;
std : : cerr < < std : : endl ;
# endif
2009-11-12 06:51:27 -05:00
if ( ipTimed . ipAddr . sin_addr . s_addr = = 0 | | ipTimed . ipAddr . sin_port = = 0 | |
std : : string ( inet_ntoa ( ipTimed . ipAddr . sin_addr ) ) = = " 1.1.1.1 " ) {
2009-11-11 11:47:10 -05:00
# ifdef CONN_DEBUG
2009-11-12 06:51:27 -05:00
std : : cerr < < " peerConnectState::updateIpAdressList() ip parameter is 0.0.0.0, 1.1.1.1 or port is 0, ignoring. " < < std : : endl ;
2009-11-11 11:47:10 -05:00
# endif
return ;
}
//check if the ip list contains the current remote address of the connected peer
bool found = false ;
std : : list < IpAddressTimed > : : iterator ipListIt ;
2009-11-11 11:49:11 -05:00
for ( ipListIt = ipAddressList . begin ( ) ; ipListIt ! = ( ipAddressList . end ( ) ) & & ! found ; ipListIt + + ) {
if ( is_same_address ( * ipListIt , ipTimed ) ) {
2009-11-11 11:47:10 -05:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " peerConnectState::updateIpAdressList() ip found in the list. " < < std : : endl ;
2009-11-11 11:47:10 -05:00
# endif
found = true ;
//update the seen time
if ( ipListIt - > seenTime < ipTimed . seenTime ) {
ipListIt - > seenTime = ipTimed . seenTime ;
2009-11-11 11:49:11 -05:00
# ifdef CONN_DEBUG
std : : cerr < < " peerConnectState::updateIpAdressList() Update seen time to : " < < ipTimed . seenTime < < std : : endl ;
# endif
2009-11-11 11:47:10 -05:00
}
}
}
2009-11-11 11:49:11 -05:00
if ( ! found ) {
2009-11-11 11:47:10 -05:00
//add the current addresses to the ip list
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " peerConnectState::updateIpAdressList() adding to the ip list the current remote addr : " < < id < < " address : " < < inet_ntoa ( ipTimed . ipAddr . sin_addr ) ;
2009-11-11 11:47:10 -05:00
std : : cerr < < " : " < < ntohs ( ipTimed . ipAddr . sin_port ) ;
std : : cerr < < std : : endl ;
# endif
ipAddressList . push_back ( ipTimed ) ;
}
}
2009-11-11 11:49:11 -05:00
void peerConnectState : : printIpAddressList ( ) {
2009-11-11 11:47:10 -05:00
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < " peerConnectState::printIpAdressList() current ip list for the peer : " < < id < < " , size : " < < ipAddressList . size ( ) < < " , adresses : " < < std : : endl ;
2009-11-11 11:47:10 -05:00
# endif
for ( std : : list < IpAddressTimed > : : iterator ipListIt = ipAddressList . begin ( ) ; ipListIt ! = ( ipAddressList . end ( ) ) ; ipListIt + + ) {
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < inet_ntoa ( ipListIt - > ipAddr . sin_addr ) < < " : " < < ntohs ( ipListIt - > ipAddr . sin_port ) < < " seenTime : " < < ipListIt - > seenTime < < std : : endl ;
2009-11-11 11:47:10 -05:00
# endif
}
2009-11-11 11:46:28 -05:00
}
2009-11-11 11:49:11 -05:00
2009-12-15 11:56:58 -05:00
bool peerConnectState : : extractExtAddress ( std : : list < IpAddressTimed > IpAddressTimedList , IpAddressTimed & resultAddress ) { //extract first address that is not the same as local address
sortIpAddressListBySeenTime ( IpAddressTimedList ) ;
//check if the ip list contains the current remote address of the connected peer
std : : list < IpAddressTimed > : : iterator ipListIt ;
for ( ipListIt = IpAddressTimedList . begin ( ) ; ipListIt ! = ( IpAddressTimedList . end ( ) ) ; + + ipListIt ) {
//assume address is valid if not private, is not 0 and is not loopback
if ( ( ipListIt - > ipAddr . sin_addr . s_addr ! = 0 )
& & ( ! isLoopbackNet ( & ipListIt - > ipAddr . sin_addr ) )
& & ( ! isPrivateNet ( & ipListIt - > ipAddr . sin_addr ) )
) {
resultAddress = * ipListIt ;
return true ;
}
}
return false ;
}
2009-11-11 11:49:11 -05:00
void peerConnectState : : printIpAddressList ( std : : list < IpAddressTimed > ipTimedList ) {
# ifdef CONN_DEBUG
std : : cerr < < " peerConnectState::printIpAdressList() " < < std : : endl ;
# endif
for ( std : : list < IpAddressTimed > : : iterator ipListIt = ipTimedList . begin ( ) ; ipListIt ! = ( ipTimedList . end ( ) ) ; ipListIt + + ) {
# ifdef CONN_DEBUG
2009-11-18 12:46:38 -05:00
std : : cerr < < inet_ntoa ( ipListIt - > ipAddr . sin_addr ) < < " : " < < ntohs ( ipListIt - > ipAddr . sin_port ) < < " seenTime : " < < ipListIt - > seenTime < < std : : endl ;
2009-11-11 11:49:11 -05:00
# endif
}
}
2009-12-13 16:59:26 -05:00
p3tunnel * p3ConnectMgr : : getP3tunnel ( ) {
return mP3tunnel ;
}
void p3ConnectMgr : : setP3tunnel ( p3tunnel * p3tun ) {
mP3tunnel = p3tun ;
}