2007-11-14 22:18:48 -05:00
/*
2007-12-11 20:29:14 -05:00
* libretroshare / src / pqi pqiperson . cc
2007-11-14 22:18:48 -05:00
*
* 3 P / PQI network interface for RetroShare .
*
* Copyright 2004 - 2006 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/pqi.h"
# include "pqi/pqiperson.h"
2008-01-25 01:36:40 -05:00
# include "pqi/pqipersongrp.h"
2013-09-10 15:31:44 -04:00
# include "pqi/pqissl.h"
2014-02-01 09:16:15 -05:00
2007-11-14 22:18:48 -05:00
const int pqipersonzone = 82371 ;
2008-07-10 12:29:18 -04:00
# include "util/rsdebug.h"
2012-04-13 20:30:23 -04:00
# include "util/rsstring.h"
2013-09-10 15:31:44 -04:00
# include "retroshare/rspeers.h"
2007-11-14 22:18:48 -05:00
2008-07-09 05:55:09 -04:00
/****
2013-09-13 10:35:19 -04:00
* # define PERSON_DEBUG 1
2008-07-09 05:55:09 -04:00
* * * */
2007-11-14 22:18:48 -05:00
2014-03-17 16:56:06 -04:00
pqiperson : : pqiperson ( const RsPeerId & id , pqipersongrp * pg )
2013-10-01 23:21:04 -04:00
: PQInterface ( id ) , mNotifyMtx ( " pqiperson-notify " ) , mPersonMtx ( " pqiperson " ) ,
active ( false ) , activepqi ( NULL ) ,
2008-01-25 01:36:40 -05:00
inConnectAttempt ( false ) , waittimes ( 0 ) ,
pqipg ( pg )
2007-11-14 22:18:48 -05:00
{
2008-01-25 01:36:40 -05:00
/* must check id! */
2007-11-14 22:18:48 -05:00
return ;
}
pqiperson : : ~ pqiperson ( )
{
2013-10-01 23:21:04 -04:00
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
2007-11-14 22:18:48 -05:00
// clean up the children.
2008-01-25 01:36:40 -05:00
std : : map < uint32_t , pqiconnect * > : : iterator it ;
2014-10-24 18:07:26 -04:00
for ( it = kids . begin ( ) ; it ! = kids . end ( ) ; + + it )
2007-11-14 22:18:48 -05:00
{
2008-01-25 01:36:40 -05:00
pqiconnect * pc = ( it - > second ) ;
2007-11-14 22:18:48 -05:00
delete pc ;
}
2008-01-25 01:36:40 -05:00
kids . clear ( ) ;
2007-11-14 22:18:48 -05:00
}
// The PQInterface interface.
2011-09-04 16:01:30 -04:00
int pqiperson : : SendItem ( RsItem * i , uint32_t & serialized_size )
2007-11-14 22:18:48 -05:00
{
2013-10-01 23:21:04 -04:00
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
2007-11-14 22:18:48 -05:00
if ( active )
{
2015-03-08 04:48:00 -04:00
// every outgoing item goes through this function, so try to not waste cpu cycles
// check if debug output is wanted, to avoid unecessary work
// getZoneLevel() locks a global mutex and does a lookup in a map or returns a default value
// (not sure if this is a performance problem)
if ( PQL_DEBUG_BASIC < = getZoneLevel ( pqipersonzone ) )
{
std : : string out = " pqiperson::SendItem() Active: Sending On \n " ;
i - > print_string ( out , 5 ) ; // this can be very expensive
2009-12-13 16:59:26 -05:00
# ifdef PERSON_DEBUG
2015-03-08 04:48:00 -04:00
std : : cerr < < out < < std : : endl ;
2009-12-13 16:59:26 -05:00
# endif
2015-03-08 04:48:00 -04:00
pqioutput ( PQL_DEBUG_BASIC , pqipersonzone , out ) ;
}
2011-09-04 16:01:30 -04:00
return activepqi - > SendItem ( i , serialized_size ) ;
2007-11-14 22:18:48 -05:00
}
else
{
2015-03-08 04:48:00 -04:00
if ( PQL_DEBUG_BASIC < = getZoneLevel ( pqipersonzone ) )
{
std : : string out = " pqiperson::SendItem() " ;
out + = " Not Active: Used to put in ToGo Store \n " ;
out + = " Now deleting... " ;
pqioutput ( PQL_DEBUG_BASIC , pqipersonzone , out ) ;
}
2007-11-14 22:18:48 -05:00
delete i ;
}
return 0 ; // queued.
}
2007-12-11 20:29:14 -05:00
RsItem * pqiperson : : GetItem ( )
2007-11-14 22:18:48 -05:00
{
2013-10-01 23:21:04 -04:00
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
2007-11-14 22:18:48 -05:00
if ( active )
return activepqi - > GetItem ( ) ;
// else not possible.
return NULL ;
}
2013-10-01 23:21:04 -04:00
bool pqiperson : : RecvItem ( RsItem * item )
{
2014-03-17 16:56:06 -04:00
# ifdef PERSON_DEBUG
2013-10-01 23:21:04 -04:00
std : : cerr < < " pqiperson::RecvItem() " ;
std : : cerr < < std : : endl ;
2014-03-17 16:56:06 -04:00
# endif
2013-10-01 23:21:04 -04:00
return pqipg - > recvItem ( ( RsRawItem * ) item ) ;
}
2007-11-14 22:18:48 -05:00
int pqiperson : : status ( )
{
2013-10-01 23:21:04 -04:00
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
2007-11-14 22:18:48 -05:00
if ( active )
return activepqi - > status ( ) ;
return - 1 ;
}
2009-12-22 05:41:19 -05:00
int pqiperson : : receiveHeartbeat ( )
{
2013-10-01 23:21:04 -04:00
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
2014-03-17 16:56:06 -04:00
pqioutput ( PQL_WARNING , pqipersonzone , " pqiperson::receiveHeartbeat() from peer : " + PeerId ( ) . toStdString ( ) ) ;
2009-12-22 05:41:19 -05:00
lastHeartbeatReceived = time ( NULL ) ;
2010-01-27 03:24:39 -05:00
return true ;
2009-12-22 05:41:19 -05:00
}
2007-11-14 22:18:48 -05:00
// tick......
int pqiperson : : tick ( )
{
2013-10-01 23:21:04 -04:00
int activeTick = 0 ;
2011-07-18 20:06:09 -04:00
{
2013-10-01 23:21:04 -04:00
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
//if lastHeartbeatReceived is 0, it might be not activated so don't do a net reset.
if ( active & & ( lastHeartbeatReceived ! = 0 ) & &
( time ( NULL ) - lastHeartbeatReceived ) > HEARTBEAT_REPEAT_TIME * 5 )
2012-01-19 11:23:57 -05:00
{
2013-10-01 23:21:04 -04:00
int ageLastIncoming = time ( NULL ) - activepqi - > getLastIncomingTS ( ) ;
2014-03-17 16:56:06 -04:00
std : : string out = " pqiperson::tick() WARNING No heartbeat from: " + PeerId ( ) . toStdString ( ) ;
2013-10-01 23:21:04 -04:00
//out << " assume dead. calling pqissl::reset(), LastHeartbeat was: ";
rs_sprintf_append ( out , " LastHeartbeat was: %ld secs ago " , time ( NULL ) - lastHeartbeatReceived ) ;
rs_sprintf_append ( out , " LastIncoming was: %d secs ago " , ageLastIncoming ) ;
2012-04-13 20:30:23 -04:00
pqioutput ( PQL_WARNING , pqipersonzone , out ) ;
2013-10-01 23:21:04 -04:00
# define NO_PACKET_TIMEOUT 60
if ( ageLastIncoming > NO_PACKET_TIMEOUT )
{
2014-03-17 16:56:06 -04:00
out = " pqiperson::tick() " + PeerId ( ) . toStdString ( ) ;
2013-10-01 23:21:04 -04:00
out + = " No Heartbeat & No Packets -> assume dead. calling pqissl::reset() " ;
pqioutput ( PQL_WARNING , pqipersonzone , out ) ;
2014-01-20 06:42:27 -05:00
this - > reset_locked ( ) ;
2013-10-01 23:21:04 -04:00
}
2012-01-19 11:23:57 -05:00
}
2013-10-01 23:21:04 -04:00
{
2014-03-17 16:56:06 -04:00
std : : string out = " pqiperson::tick() Id: " + PeerId ( ) . toStdString ( ) + " " ;
2013-10-01 23:21:04 -04:00
if ( active )
out + = " ***Active*** " ;
else
out + = " >>InActive<< " ;
out + = " \n " ;
rs_sprintf_append ( out , " Activepqi: %p inConnectAttempt: " , activepqi ) ;
if ( inConnectAttempt )
out + = " In Connection Attempt " ;
else
out + = " Not Connecting " ;
out + = " \n " ;
// tick the children.
std : : map < uint32_t , pqiconnect * > : : iterator it ;
2014-10-24 18:07:26 -04:00
for ( it = kids . begin ( ) ; it ! = kids . end ( ) ; + + it )
2013-10-01 23:21:04 -04:00
{
if ( 0 < ( it - > second ) - > tick ( ) )
{
activeTick = 1 ;
}
rs_sprintf_append ( out , " \t Ticking Child: %d \n " , it - > first ) ;
}
pqioutput ( PQL_DEBUG_ALL , pqipersonzone , out ) ;
} // end of pqioutput.
2012-01-19 11:23:57 -05:00
}
2013-10-01 23:21:04 -04:00
// handle Notify Events that were generated.
processNotifyEvents ( ) ;
return activeTick ;
}
2007-11-14 22:18:48 -05:00
2013-10-01 23:21:04 -04:00
// callback function for the child - notify of a change.
// This is only used for out-of-band info....
// otherwise could get dangerous loops.
// - Actually, now we have - must store and process later.
int pqiperson : : notifyEvent ( NetInterface * ni , int newState , const struct sockaddr_storage & remote_peer_address )
{
2015-05-25 10:02:45 -04:00
# ifdef PERSON_DEBUG
std : : cerr < < " pqiperson::notifyEvent() adding event to Queue. newState= " < < newState < < " from IP = " < < sockaddr_storage_tostring ( remote_peer_address ) < < std : : endl ;
# endif
if ( mPersonMtx . trylock ( ) )
2007-11-14 22:18:48 -05:00
{
2013-10-01 23:21:04 -04:00
handleNotifyEvent_locked ( ni , newState , remote_peer_address ) ;
2007-11-14 22:18:48 -05:00
2013-10-01 23:21:04 -04:00
mPersonMtx . unlock ( ) ;
return 1 ;
}
2007-11-14 22:18:48 -05:00
2013-10-01 23:21:04 -04:00
RsStackMutex stack ( mNotifyMtx ) ; /**** LOCK MUTEX ****/
mNotifyQueue . push_back ( NotifyData ( ni , newState , remote_peer_address ) ) ;
return 1 ;
}
void pqiperson : : processNotifyEvents ( )
{
NetInterface * ni ;
int state ;
struct sockaddr_storage addr ;
while ( 1 )
{
2007-11-14 22:18:48 -05:00
{
2013-10-01 23:21:04 -04:00
RsStackMutex stack ( mNotifyMtx ) ; /**** LOCK MUTEX ****/
if ( mNotifyQueue . empty ( ) )
2012-04-13 20:30:23 -04:00
{
2013-10-01 23:21:04 -04:00
return ;
2012-04-13 20:30:23 -04:00
}
2013-10-01 23:21:04 -04:00
NotifyData & data = mNotifyQueue . front ( ) ;
ni = data . mNi ;
state = data . mState ;
addr = data . mAddr ;
2007-11-14 22:18:48 -05:00
2013-10-01 23:21:04 -04:00
mNotifyQueue . pop_front ( ) ;
}
2007-11-14 22:18:48 -05:00
2013-10-01 23:21:04 -04:00
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
handleNotifyEvent_locked ( ni , state , addr ) ;
}
return ;
2007-11-14 22:18:48 -05:00
}
2013-10-01 23:21:04 -04:00
int pqiperson : : handleNotifyEvent_locked ( NetInterface * ni , int newState , const struct sockaddr_storage & remote_peer_address )
2007-11-14 22:18:48 -05:00
{
2013-10-01 23:21:04 -04:00
2007-11-14 22:18:48 -05:00
{
2014-03-17 16:56:06 -04:00
std : : string out = " pqiperson::notifyEvent() Id: " + PeerId ( ) . toStdString ( ) + " \n " ;
2012-04-13 20:30:23 -04:00
rs_sprintf_append ( out , " Message: %d from: %p \n " , newState , ni ) ;
rs_sprintf_append ( out , " Active pqi : %p " , activepqi ) ;
2007-11-14 22:18:48 -05:00
2012-04-13 20:30:23 -04:00
pqioutput ( PQL_DEBUG_BASIC , pqipersonzone , out ) ;
2007-11-14 22:18:48 -05:00
}
/* find the pqi, */
2010-06-25 18:00:38 -04:00
pqiconnect * pqi = NULL ;
2008-03-26 11:35:09 -04:00
uint32_t type = 0 ;
2008-01-25 01:36:40 -05:00
std : : map < uint32_t , pqiconnect * > : : iterator it ;
2007-11-14 22:18:48 -05:00
/* start again */
int i = 0 ;
2014-10-24 18:07:26 -04:00
for ( it = kids . begin ( ) ; it ! = kids . end ( ) ; + + it )
2007-11-14 22:18:48 -05:00
{
2012-04-13 20:30:23 -04:00
std : : string out ;
rs_sprintf ( out , " pqiperson::connectattempt() Kid# %d of %u \n " , i , kids . size ( ) ) ;
rs_sprintf_append ( out , " type: %u in_ni: %p " , it - > first , ni ) ;
pqioutput ( PQL_DEBUG_BASIC , pqipersonzone , out ) ;
2010-06-25 18:00:38 -04:00
i + + ;
2007-11-14 22:18:48 -05:00
2008-01-25 01:36:40 -05:00
if ( ( it - > second ) - > thisNetInterface ( ni ) )
2007-11-14 22:18:48 -05:00
{
2010-06-25 18:00:38 -04:00
pqi = ( it - > second ) ;
2008-03-26 11:35:09 -04:00
type = ( it - > first ) ;
2007-11-14 22:18:48 -05:00
}
}
if ( ! pqi )
2014-12-18 15:09:04 -05:00
{
2007-11-14 22:18:48 -05:00
pqioutput ( PQL_WARNING , pqipersonzone , " Unknown notfyEvent Source! " ) ;
return - 1 ;
}
2010-06-25 18:00:38 -04:00
2007-11-14 22:18:48 -05:00
switch ( newState )
{
case CONNECT_RECEIVED :
case CONNECT_SUCCESS :
2008-01-25 01:36:40 -05:00
/* notify */
2015-05-16 07:19:53 -04:00
if ( pqipg )
{
pqissl * ssl = dynamic_cast < pqissl * > ( ni ) ;
if ( ssl ! = NULL )
pqipg - > notifyConnect ( PeerId ( ) , type , true , ssl - > actAsServer ( ) , remote_peer_address ) ;
else
pqipg - > notifyConnect ( PeerId ( ) , type , true , false , remote_peer_address ) ;
}
2008-01-25 01:36:40 -05:00
2007-11-14 22:18:48 -05:00
if ( ( active ) & & ( activepqi ! = pqi ) ) // already connected - trouble
{
2014-03-17 16:56:06 -04:00
pqioutput ( PQL_WARNING , pqipersonzone , " pqiperson::notifyEvent() Id: " + PeerId ( ) . toStdString ( ) + " CONNECT_SUCCESS+active-> activing new connection, shutting others " ) ;
2007-11-14 22:18:48 -05:00
// This is the RESET that's killing the connections.....
2009-12-13 16:59:26 -05:00
//activepqi -> reset();
2007-11-14 22:18:48 -05:00
// this causes a recursive call back into this fn.
// which cleans up state.
// we only do this if its not going to mess with new conn.
}
/* now install a new one. */
2014-12-16 17:16:14 -05:00
{
2007-11-14 22:18:48 -05:00
2014-03-17 16:56:06 -04:00
pqioutput ( PQL_WARNING , pqipersonzone , " pqiperson::notifyEvent() Id: " + PeerId ( ) . toStdString ( ) + " CONNECT_SUCCESS->marking so! (resetting others) " ) ;
2012-01-18 17:51:38 -05:00
2010-06-25 18:00:38 -04:00
// mark as active.
2007-11-14 22:18:48 -05:00
active = true ;
2009-12-22 05:41:19 -05:00
lastHeartbeatReceived = 0 ;
2007-11-14 22:18:48 -05:00
activepqi = pqi ;
2010-06-25 18:00:38 -04:00
inConnectAttempt = false ;
2008-03-26 11:35:09 -04:00
2013-10-01 23:21:04 -04:00
activepqi - > start ( ) ; // STARTUP THREAD.
2008-03-26 11:35:09 -04:00
/* reset all other children? (clear up long UDP attempt) */
2014-10-24 18:07:26 -04:00
for ( it = kids . begin ( ) ; it ! = kids . end ( ) ; + + it )
2008-03-26 11:35:09 -04:00
{
2012-04-13 20:30:23 -04:00
if ( ! ( it - > second ) - > thisNetInterface ( ni ) )
{
std : : string out ;
rs_sprintf ( out , " Resetting pqi ref : %p " , & ( it - > second ) ) ;
pqioutput ( PQL_DEBUG_BASIC , pqipersonzone , out ) ;
it - > second - > reset ( ) ;
} else {
//std::cerr << "Active pqi : not resetting." << std::endl;
}
2008-03-26 11:35:09 -04:00
}
2007-11-14 22:18:48 -05:00
return 1 ;
2014-12-18 15:09:04 -05:00
}
2007-11-14 22:18:48 -05:00
break ;
case CONNECT_UNREACHABLE :
case CONNECT_FIREWALLED :
case CONNECT_FAILED :
2008-01-25 01:36:40 -05:00
2007-11-14 22:18:48 -05:00
if ( active )
{
2010-06-25 18:00:38 -04:00
if ( activepqi = = pqi )
2007-11-14 22:18:48 -05:00
{
2014-03-17 16:56:06 -04:00
pqioutput ( PQL_WARNING , pqipersonzone , " pqiperson::notifyEvent() Id: " + PeerId ( ) . toStdString ( ) + " CONNECT_FAILED->marking so! " ) ;
2012-01-18 17:51:38 -05:00
2015-03-10 17:16:41 -04:00
activepqi - > shutdown ( ) ; // STOP THREAD.
2007-11-14 22:18:48 -05:00
active = false ;
activepqi = NULL ;
2012-04-13 20:30:23 -04:00
}
2012-01-18 17:51:38 -05:00
else
2011-07-11 08:11:58 -04:00
{
2014-03-17 16:56:06 -04:00
pqioutput ( PQL_WARNING , pqipersonzone , " pqiperson::notifyEvent() Id: " + PeerId ( ) . toStdString ( ) + " CONNECT_FAILED-> from an unactive connection, don't flag the peer as not connected, just try next attempt ! " ) ;
2012-04-13 20:30:23 -04:00
}
}
2007-11-14 22:18:48 -05:00
else
{
2014-03-17 16:56:06 -04:00
pqioutput ( PQL_WARNING , pqipersonzone , " pqiperson::notifyEvent() Id: " + PeerId ( ) . toStdString ( ) + " CONNECT_FAILED+NOT active -> try connect again " ) ;
2007-11-14 22:18:48 -05:00
}
2008-03-21 15:06:34 -04:00
2011-07-11 08:11:58 -04:00
/* notify up */
2010-06-25 18:00:38 -04:00
if ( pqipg )
{
2015-05-16 07:19:53 -04:00
pqipg - > notifyConnect ( PeerId ( ) , type , false , false , remote_peer_address ) ;
2010-06-25 18:00:38 -04:00
}
2008-03-21 15:06:34 -04:00
return 1 ;
2007-11-14 22:18:48 -05:00
break ;
default :
break ;
}
return - 1 ;
}
/***************** Not PQInterface Fns ***********************/
int pqiperson : : reset ( )
{
2013-10-01 23:21:04 -04:00
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
2014-01-20 06:42:27 -05:00
return reset_locked ( ) ;
}
int pqiperson : : reset_locked ( )
2007-11-14 22:18:48 -05:00
{
2014-03-17 16:56:06 -04:00
pqioutput ( PQL_WARNING , pqipersonzone , " pqiperson::reset() resetting all pqiconnect for Id: " + PeerId ( ) . toStdString ( ) ) ;
2007-11-14 22:18:48 -05:00
2008-01-25 01:36:40 -05:00
std : : map < uint32_t , pqiconnect * > : : iterator it ;
2014-10-24 18:07:26 -04:00
for ( it = kids . begin ( ) ; it ! = kids . end ( ) ; + + it )
2007-11-14 22:18:48 -05:00
{
2015-03-10 17:16:41 -04:00
( it - > second ) - > shutdown ( ) ; // STOP THREAD.
2008-01-25 01:36:40 -05:00
( it - > second ) - > reset ( ) ;
2007-11-14 22:18:48 -05:00
}
activepqi = NULL ;
active = false ;
2012-04-13 20:30:23 -04:00
lastHeartbeatReceived = 0 ;
2007-11-14 22:18:48 -05:00
return 1 ;
}
2013-10-01 23:21:04 -04:00
int pqiperson : : fullstopthreads ( )
{
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
2014-03-17 16:56:06 -04:00
pqioutput ( PQL_WARNING , pqipersonzone , " pqiperson::fullstopthreads() for Id: " + PeerId ( ) . toStdString ( ) ) ;
2013-10-01 23:21:04 -04:00
std : : map < uint32_t , pqiconnect * > : : iterator it ;
2014-10-24 18:07:26 -04:00
for ( it = kids . begin ( ) ; it ! = kids . end ( ) ; + + it )
2013-10-01 23:21:04 -04:00
{
( it - > second ) - > fullstop ( ) ; // WAIT FOR THREAD TO STOP.
}
activepqi = NULL ;
active = false ;
lastHeartbeatReceived = 0 ;
return 1 ;
}
2008-01-25 01:36:40 -05:00
int pqiperson : : addChildInterface ( uint32_t type , pqiconnect * pqi )
2007-11-14 22:18:48 -05:00
{
2013-10-01 23:21:04 -04:00
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
2007-11-14 22:18:48 -05:00
{
2012-04-13 20:30:23 -04:00
std : : string out ;
2014-03-17 16:56:06 -04:00
rs_sprintf ( out , " pqiperson::addChildInterface() : Id %s %u " , PeerId ( ) . toStdString ( ) . c_str ( ) , type ) ;
2012-04-13 20:30:23 -04:00
pqioutput ( PQL_DEBUG_BASIC , pqipersonzone , out ) ;
2007-11-14 22:18:48 -05:00
}
2008-01-25 01:36:40 -05:00
kids [ type ] = pqi ;
2007-11-14 22:18:48 -05:00
return 1 ;
}
/***************** PRIVATE FUNCTIONS ***********************/
// functions to iterate over the connects and change state.
int pqiperson : : listen ( )
{
2013-10-01 23:21:04 -04:00
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
2014-03-17 16:56:06 -04:00
pqioutput ( PQL_DEBUG_BASIC , pqipersonzone , " pqiperson::listen() Id: " + PeerId ( ) . toStdString ( ) ) ;
2007-11-14 22:18:48 -05:00
if ( ! active )
{
2008-01-25 01:36:40 -05:00
std : : map < uint32_t , pqiconnect * > : : iterator it ;
2014-10-24 18:07:26 -04:00
for ( it = kids . begin ( ) ; it ! = kids . end ( ) ; + + it )
2007-11-14 22:18:48 -05:00
{
// set them all listening.
2008-01-25 01:36:40 -05:00
( it - > second ) - > listen ( ) ;
2007-11-14 22:18:48 -05:00
}
}
return 1 ;
}
int pqiperson : : stoplistening ( )
{
2013-10-01 23:21:04 -04:00
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
2014-03-17 16:56:06 -04:00
pqioutput ( PQL_DEBUG_BASIC , pqipersonzone , " pqiperson::stoplistening() Id: " + PeerId ( ) . toStdString ( ) ) ;
2007-11-14 22:18:48 -05:00
2008-01-25 01:36:40 -05:00
std : : map < uint32_t , pqiconnect * > : : iterator it ;
2014-10-24 18:07:26 -04:00
for ( it = kids . begin ( ) ; it ! = kids . end ( ) ; + + it )
2007-11-14 22:18:48 -05:00
{
// set them all listening.
2008-01-25 01:36:40 -05:00
( it - > second ) - > stoplistening ( ) ;
2007-11-14 22:18:48 -05:00
}
return 1 ;
}
2013-09-13 10:35:19 -04:00
int pqiperson : : connect ( uint32_t type , const struct sockaddr_storage & raddr ,
const struct sockaddr_storage & proxyaddr , const struct sockaddr_storage & srcaddr ,
2013-09-03 09:35:39 -04:00
uint32_t delay , uint32_t period , uint32_t timeout , uint32_t flags , uint32_t bandwidth ,
const std : : string & domain_addr , uint16_t domain_port )
2007-11-14 22:18:48 -05:00
{
2013-10-01 23:21:04 -04:00
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
2008-07-09 05:55:09 -04:00
# ifdef PERSON_DEBUG
2011-08-06 08:27:23 -04:00
# endif
2007-11-14 22:18:48 -05:00
{
2014-03-17 16:56:06 -04:00
std : : string out = " pqiperson::connect() Id: " + PeerId ( ) . toStdString ( ) ;
2012-04-13 20:30:23 -04:00
rs_sprintf_append ( out , " type: %u " , type ) ;
2013-09-13 10:35:19 -04:00
out + = " addr: " ;
out + = sockaddr_storage_tostring ( raddr ) ;
out + = " proxyaddr: " ;
out + = sockaddr_storage_tostring ( proxyaddr ) ;
out + = " srcaddr: " ;
out + = sockaddr_storage_tostring ( srcaddr ) ;
2012-04-13 20:30:23 -04:00
rs_sprintf_append ( out , " delay: %u " , delay ) ;
rs_sprintf_append ( out , " period: %u " , period ) ;
rs_sprintf_append ( out , " timeout: %u " , timeout ) ;
rs_sprintf_append ( out , " flags: %u " , flags ) ;
rs_sprintf_append ( out , " bandwidth: %u " , bandwidth ) ;
//std::cerr << out.str();
pqioutput ( PQL_WARNING , pqipersonzone , out ) ;
2007-11-14 22:18:48 -05:00
}
2008-01-25 01:36:40 -05:00
std : : map < uint32_t , pqiconnect * > : : iterator it ;
it = kids . find ( type ) ;
2007-11-14 22:18:48 -05:00
if ( it = = kids . end ( ) )
{
2008-07-09 05:55:09 -04:00
# ifdef PERSON_DEBUG
2012-04-13 20:30:23 -04:00
//pqioutput(PQL_DEBUG_BASIC, pqipersonzone, "pqiperson::connect() missing pqiconnect");
2008-07-09 05:55:09 -04:00
# endif
2010-07-04 06:35:38 -04:00
/* notify of fail! */
2015-05-16 07:19:53 -04:00
pqipg - > notifyConnect ( PeerId ( ) , type , false , false , raddr ) ;
2010-07-04 06:35:38 -04:00
2008-02-26 21:32:20 -05:00
return 0 ;
2007-11-14 22:18:48 -05:00
}
2008-02-26 21:32:20 -05:00
2011-07-13 18:23:40 -04:00
# ifdef PERSON_DEBUG
2012-01-20 10:13:50 -05:00
std : : cerr < < " pqiperson::connect() WARNING, resetting for new connection attempt " < < std : : endl ;
2011-07-13 18:23:40 -04:00
# endif
2008-02-26 21:32:20 -05:00
/* set the parameters */
2011-08-06 08:27:23 -04:00
pqioutput ( PQL_WARNING , pqipersonzone , " pqiperson::connect reset() before connection attempt " ) ;
2008-03-21 15:06:34 -04:00
( it - > second ) - > reset ( ) ;
2008-03-26 11:35:09 -04:00
2012-01-20 10:13:50 -05:00
# ifdef PERSON_DEBUG
2012-01-08 13:40:09 -05:00
std : : cerr < < " pqiperson::connect() WARNING, clearing rate cap " < < std : : endl ;
2012-01-20 10:13:50 -05:00
# endif
2013-10-01 23:21:04 -04:00
setRateCap_locked ( 0 , 0 ) ;
2012-01-08 13:40:09 -05:00
2008-07-09 05:55:09 -04:00
# ifdef PERSON_DEBUG
2008-03-26 11:35:09 -04:00
std : : cerr < < " pqiperson::connect() setting connect_parameters " < < std : : endl ;
2008-07-09 05:55:09 -04:00
# endif
2013-09-03 09:35:39 -04:00
// These two are universal.
2008-02-26 21:32:20 -05:00
( it - > second ) - > connect_parameter ( NET_PARAM_CONNECT_DELAY , delay ) ;
2008-03-26 11:35:09 -04:00
( it - > second ) - > connect_parameter ( NET_PARAM_CONNECT_TIMEOUT , timeout ) ;
2013-09-03 09:35:39 -04:00
// these 5 are only used by UDP connections.
( it - > second ) - > connect_parameter ( NET_PARAM_CONNECT_PERIOD , period ) ;
2011-07-13 18:23:40 -04:00
( it - > second ) - > connect_parameter ( NET_PARAM_CONNECT_FLAGS , flags ) ;
2011-07-14 10:56:33 -04:00
( it - > second ) - > connect_parameter ( NET_PARAM_CONNECT_BANDWIDTH , bandwidth ) ;
2008-03-26 11:35:09 -04:00
2013-09-13 10:35:19 -04:00
( it - > second ) - > connect_additional_address ( NET_PARAM_CONNECT_PROXY , proxyaddr ) ;
( it - > second ) - > connect_additional_address ( NET_PARAM_CONNECT_SOURCE , srcaddr ) ;
2011-07-14 10:56:33 -04:00
2013-09-03 09:35:39 -04:00
// These are used by Proxy/Hidden
( it - > second ) - > connect_parameter ( NET_PARAM_CONNECT_DOMAIN_ADDRESS , domain_addr ) ;
( it - > second ) - > connect_parameter ( NET_PARAM_CONNECT_REMOTE_PORT , domain_port ) ;
2011-07-14 10:56:33 -04:00
( it - > second ) - > connect ( raddr ) ;
2007-11-14 22:18:48 -05:00
// flag if we started a new connectionAttempt.
2008-01-25 01:36:40 -05:00
inConnectAttempt = true ;
2007-11-14 22:18:48 -05:00
return 1 ;
}
2012-06-21 21:35:32 -04:00
void pqiperson : : getRates ( RsBwRates & rates )
{
2013-10-01 23:21:04 -04:00
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
2012-06-21 21:35:32 -04:00
// get the rate from the active one.
if ( ( ! active ) | | ( activepqi = = NULL ) )
return ;
activepqi - > getRates ( rates ) ;
}
2014-10-31 17:24:42 -04:00
int pqiperson : : gatherOutQueueStatistics ( std : : vector < uint32_t > & per_service , std : : vector < uint32_t > & per_priority )
{
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
2012-06-21 21:35:32 -04:00
2014-10-31 17:24:42 -04:00
// get the rate from the active one.
if ( ( ! active ) | | ( activepqi = = NULL ) )
return 0 ;
return activepqi - > gatherOutQueueStatistics ( per_service , per_priority ) ;
}
2012-06-21 21:35:32 -04:00
int pqiperson : : getQueueSize ( bool in )
{
2013-10-01 23:21:04 -04:00
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
2012-06-21 21:35:32 -04:00
// get the rate from the active one.
if ( ( ! active ) | | ( activepqi = = NULL ) )
return 0 ;
return activepqi - > getQueueSize ( in ) ;
}
2013-09-10 15:31:44 -04:00
bool pqiperson : : getCryptoParams ( RsPeerCryptoParams & params )
{
2014-02-01 09:16:15 -05:00
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
2013-09-10 15:31:44 -04:00
if ( active & & activepqi ! = NULL )
return activepqi - > getCryptoParams ( params ) ;
else
{
params . connexion_state = 0 ;
params . cipher_name . clear ( ) ;
params . cipher_bits_1 = 0 ;
params . cipher_bits_2 = 0 ;
params . cipher_version . clear ( ) ;
return false ;
}
}
bool pqiconnect : : getCryptoParams ( RsPeerCryptoParams & params )
{
pqissl * ssl = dynamic_cast < pqissl * > ( ni ) ;
if ( ssl ! = NULL )
{
ssl - > getCryptoParams ( params ) ;
return true ;
}
else
{
params . connexion_state = 0 ;
params . cipher_name . clear ( ) ;
params . cipher_bits_1 = 0 ;
params . cipher_bits_2 = 0 ;
params . cipher_version . clear ( ) ;
return false ;
}
}
2012-06-21 21:35:32 -04:00
2007-11-14 22:18:48 -05:00
float pqiperson : : getRate ( bool in )
{
2013-10-01 23:21:04 -04:00
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
2007-11-14 22:18:48 -05:00
// get the rate from the active one.
if ( ( ! active ) | | ( activepqi = = NULL ) )
return 0 ;
return activepqi - > getRate ( in ) ;
}
void pqiperson : : setMaxRate ( bool in , float val )
{
2013-10-01 23:21:04 -04:00
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
2007-11-14 22:18:48 -05:00
// set to all of them. (and us)
PQInterface : : setMaxRate ( in , val ) ;
// clean up the children.
2008-01-25 01:36:40 -05:00
std : : map < uint32_t , pqiconnect * > : : iterator it ;
2014-10-24 18:07:26 -04:00
for ( it = kids . begin ( ) ; it ! = kids . end ( ) ; + + it )
2007-11-14 22:18:48 -05:00
{
2008-01-25 01:36:40 -05:00
( it - > second ) - > setMaxRate ( in , val ) ;
2007-11-14 22:18:48 -05:00
}
}
2012-01-08 13:40:09 -05:00
void pqiperson : : setRateCap ( float val_in , float val_out )
2013-10-01 23:21:04 -04:00
{
2014-09-12 17:52:13 -04:00
// This methods might be called all the way down from pqiperson::tick() down
// to pqissludp while completing a UDP connexion, causing a deadlock.
//
// We need to make sure the mutex is not already locked by current thread. If so, we call the
// locked version directly if not, we lock, call, and unlock, possibly waiting if the
// lock is already acquired by another thread.
//
// The lock cannot be locked by the same thread between the first test and
// the "else" statement, so there is no possibility for this code to fail.
//
// We could actually put that code in RsMutex::lock()
if ( pthread_equal ( mPersonMtx . owner ( ) , pthread_self ( ) ) ) // 1 - unlocked, or already locked by same thread
return setRateCap_locked ( val_in , val_out ) ; // -> do nothing
else
{ // 2 - lock was free or locked by different thread => wait.
RsStackMutex stack ( mPersonMtx ) ; /**** LOCK MUTEX ****/
setRateCap_locked ( val_in , val_out ) ;
}
2013-10-01 23:21:04 -04:00
}
void pqiperson : : setRateCap_locked ( float val_in , float val_out )
2012-01-08 13:40:09 -05:00
{
// set to all of them. (and us)
PQInterface : : setRateCap ( val_in , val_out ) ;
// clean up the children.
std : : map < uint32_t , pqiconnect * > : : iterator it ;
2014-10-24 18:07:26 -04:00
for ( it = kids . begin ( ) ; it ! = kids . end ( ) ; + + it )
2012-01-08 13:40:09 -05:00
{
( it - > second ) - > setRateCap ( val_in , val_out ) ;
}
}