2007-11-14 22:18:48 -05:00
/*
* " $Id: pqissl.cc,v 1.28 2007-03-17 19:32:59 rmf24 Exp $ "
*
* 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/pqissl.h"
# include "pqi/pqinetwork.h"
2010-06-26 08:31:24 -04:00
# include "pqi/sslfns.h"
2007-11-14 22:18:48 -05:00
2008-03-03 09:41:15 -05:00
# include "util/rsnet.h"
2008-07-10 12:29:18 -04:00
# include "util/rsdebug.h"
2012-04-13 20:30:23 -04:00
# include "util/rsstring.h"
2008-03-03 09:41:15 -05:00
2009-02-26 09:04:48 -05:00
# include <unistd.h>
2007-11-14 22:18:48 -05:00
# include <errno.h>
# include <openssl/err.h>
# include "pqi/pqissllistener.h"
2011-07-09 14:39:34 -04:00
# include "pqi/p3linkmgr.h"
2013-06-28 17:47:25 -04:00
# include <retroshare/rspeers.h>
2015-05-25 12:51:15 -04:00
# include <retroshare/rsdht.h>
2015-05-28 17:44:43 -04:00
# include <retroshare/rsbanlist.h>
2011-07-09 14:39:34 -04:00
2015-06-02 17:36:26 -04:00
# include "rsserver/p3face.h"
2007-11-14 22:18:48 -05:00
const int pqisslzone = 37714 ;
/*********
# define WAITING_NOT 0
# define WAITING_LOCAL_ADDR 1
# define WAITING_REMOTE_ADDR 2
# define WAITING_SOCK_CONNECT 3
# define WAITING_SSL_CONNECTION 4
# define WAITING_SSL_AUTHORISE 5
# define WAITING_FAIL_INTERFACE 6
# define PQISSL_PASSIVE 0x00
# define PQISSL_ACTIVE 0x01
2012-01-18 17:51:38 -05:00
# define PQISSL_DEBUG 1
# define PQISSL_LOG_DEBUG 1
2011-06-27 18:28:33 -04:00
2007-11-14 22:18:48 -05:00
const int PQISSL_LOCAL_FLAG = 0x01 ;
const int PQISSL_REMOTE_FLAG = 0x02 ;
const int PQISSL_UDP_FLAG = 0x02 ;
* * * * * * * * * * */
2010-06-25 17:44:24 -04:00
static const int PQISSL_MAX_READ_ZERO_COUNT = 20 ;
2010-07-13 08:13:56 -04:00
static const time_t PQISSL_MAX_READ_ZERO_TIME = 15 ; // 15 seconds of no data => reset. (atm HeartBeat pkt sent 5 secs)
2010-06-25 17:44:24 -04:00
static const int PQISSL_SSL_CONNECT_TIMEOUT = 30 ;
2007-11-14 22:18:48 -05:00
/********** PQI SSL STUFF ******************************************
*
* A little note on the notifyEvent ( FAILED ) . . . .
*
* this is called from
* ( 1 ) reset if needed !
* ( 2 ) Determine_Remote_Address ( when all options have failed ) .
*
* reset ( ) is only called when a TCP / SSL connection has been
* established , and there is an error . If there is a failed TCP
* connection , then an alternative address can be attempted .
*
* reset ( ) is called from
* ( 1 ) destruction .
* ( 2 ) disconnect ( )
* ( 3 ) bad waiting state .
*
* // TCP/or SSL connection already established....
* ( 5 ) pqissl : : SSL_Connection_Complete ( ) < - okay - > cos we made a TCP connection already .
* ( 6 ) pqissl : : accept ( ) < - okay cos something went wrong .
* ( 7 ) moretoread ( ) / cansend ( ) < - okay cos
*
*/
2011-07-09 14:39:34 -04:00
pqissl : : pqissl ( pqissllistener * l , PQInterface * parent , p3LinkMgr * lm )
2007-12-11 20:29:14 -05:00
: NetBinInterface ( parent , parent - > PeerId ( ) ) ,
2014-01-20 06:42:27 -05:00
mLinkMgr ( lm ) , pqil ( l ) ,
2013-10-01 06:11:34 -04:00
mSslMtx ( " pqissl " ) ,
2014-01-20 06:42:27 -05:00
active ( false ) , certvalid ( false ) , waiting ( WAITING_NOT ) ,
2007-11-14 22:18:48 -05:00
sslmode ( PQISSL_ACTIVE ) , ssl_connection ( NULL ) , sockfd ( - 1 ) ,
2014-01-20 06:42:27 -05:00
readpkt ( NULL ) , pktlen ( 0 ) , total_len ( 0 ) ,
2010-06-25 17:44:24 -04:00
attempt_ts ( 0 ) ,
2010-07-13 08:13:56 -04:00
sameLAN ( false ) , n_read_zero ( 0 ) , mReadZeroTS ( 0 ) ,
2008-02-26 21:32:20 -05:00
mConnectDelay ( 0 ) , mConnectTS ( 0 ) ,
2014-01-20 06:42:27 -05:00
mConnectTimeout ( 0 ) , mTimeoutTS ( 0 )
2007-11-14 22:18:48 -05:00
{
2013-10-01 06:11:34 -04:00
RsStackMutex stack ( mSslMtx ) ; /**** LOCKED MUTEX ****/
2008-01-25 01:36:40 -05:00
/* set address to zero */
2013-09-13 10:35:19 -04:00
sockaddr_storage_clear ( remote_addr ) ;
2008-01-25 01:36:40 -05:00
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2012-04-13 20:30:23 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone , " pqissl for PeerId: " + PeerId ( ) ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
2010-06-25 17:44:24 -04:00
#if 0
if ( ! ( AuthSSL : : getAuthSSL ( ) - > isAuthenticated ( PeerId ( ) ) ) )
{
rslog ( RSL_ALERT , pqisslzone ,
" pqissl::Warning Certificate Not Approved! " ) ;
rslog ( RSL_ALERT , pqisslzone ,
" \t pqissl will not initialise.... " ) ;
}
# else
2012-01-18 17:51:38 -05:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2010-06-25 17:44:24 -04:00
" pqissl::Warning SSL Certificate Approval Not CHECKED?? " ) ;
# endif
2007-11-14 22:18:48 -05:00
return ;
}
pqissl : : ~ pqissl ( )
{
2008-07-10 12:29:18 -04:00
rslog ( RSL_ALERT , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::~pqissl -> destroying pqissl " ) ;
stoplistening ( ) ; /* remove from pqissllistener only */
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::~pqissl() -> calling reset() " ) ;
2007-11-14 22:18:48 -05:00
reset ( ) ;
return ;
}
/********** Implementation of NetInterface *************************/
2013-09-13 10:35:19 -04:00
int pqissl : : connect ( const struct sockaddr_storage & raddr )
2007-11-14 22:18:48 -05:00
{
2013-10-01 06:11:34 -04:00
RsStackMutex stack ( mSslMtx ) ; /**** LOCKED MUTEX ****/
2007-11-14 22:18:48 -05:00
// reset failures
2008-01-25 01:36:40 -05:00
remote_addr = raddr ;
2007-11-14 22:18:48 -05:00
return ConnectAttempt ( ) ;
}
// tells pqilistener to listen for us.
int pqissl : : listen ( )
{
if ( pqil )
{
2008-01-25 01:36:40 -05:00
return pqil - > addlistenaddr ( PeerId ( ) , this ) ;
2007-11-14 22:18:48 -05:00
}
return 0 ;
}
int pqissl : : stoplistening ( )
{
if ( pqil )
{
2008-01-25 01:36:40 -05:00
pqil - > removeListenPort ( PeerId ( ) ) ;
2007-11-14 22:18:48 -05:00
}
return 1 ;
}
int pqissl : : disconnect ( )
{
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::disconnect() -> calling reset() " ) ;
2007-11-14 22:18:48 -05:00
return reset ( ) ;
}
2013-10-01 06:11:34 -04:00
int pqissl : : getConnectAddress ( struct sockaddr_storage & raddr )
{
RsStackMutex stack ( mSslMtx ) ; /**** LOCKED MUTEX ****/
raddr = remote_addr ;
// TODO.
return ( ! sockaddr_storage_isnull ( remote_addr ) ) ;
2009-12-14 13:11:19 -05:00
}
2008-03-31 10:06:59 -04:00
/* BinInterface version of reset() for pqistreamer */
int pqissl : : close ( )
{
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::close() -> calling reset() " ) ;
2008-03-31 10:06:59 -04:00
return reset ( ) ;
}
2007-11-14 22:18:48 -05:00
// put back on the listening queue.
int pqissl : : reset ( )
2013-10-01 06:11:34 -04:00
{
RsStackMutex stack ( mSslMtx ) ; /**** LOCKED MUTEX ****/
return reset_locked ( ) ;
}
int pqissl : : reset_locked ( )
2007-11-14 22:18:48 -05:00
{
2012-04-13 20:30:23 -04:00
std : : string outLog ;
2013-10-01 06:11:34 -04:00
bool neededReset = false ;
2007-11-14 22:18:48 -05:00
2013-10-01 06:11:34 -04:00
2007-11-14 22:18:48 -05:00
/* a reset shouldn't cause us to stop listening
* only reasons for stoplistening ( ) are ;
*
* ( 1 ) destruction .
* ( 2 ) connection .
* ( 3 ) WillListen state change
*
*/
2014-03-17 16:56:06 -04:00
outLog + = " pqissl::reset(): " + PeerId ( ) . toStdString ( ) ;
2012-04-13 20:30:23 -04:00
rs_sprintf_append ( outLog , " (A: %d " , ( int ) active ) ;
rs_sprintf_append ( outLog , " FD: %d " , sockfd ) ;
rs_sprintf_append ( outLog , " W: %d " , waiting ) ;
rs_sprintf_append ( outLog , " SSL: %p) " , ssl_connection ) ;
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2012-04-13 20:30:23 -04:00
outLog + = " \n " ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
2010-06-25 17:44:24 -04:00
if ( ssl_connection ! = NULL )
2007-11-14 22:18:48 -05:00
{
2012-01-18 17:51:38 -05:00
//outLog << "pqissl::reset() Shutting down SSL Connection";
//outLog << std::endl;
2010-06-25 17:44:24 -04:00
SSL_shutdown ( ssl_connection ) ;
SSL_free ( ssl_connection ) ;
2007-11-14 22:18:48 -05:00
neededReset = true ;
}
if ( sockfd > 0 )
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2012-04-13 20:30:23 -04:00
outLog + = " pqissl::reset() Shutting down (active) socket \n " ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
net_internal_close ( sockfd ) ;
sockfd = - 1 ;
neededReset = true ;
}
active = false ;
sockfd = - 1 ;
waiting = WAITING_NOT ;
ssl_connection = NULL ;
sameLAN = false ;
n_read_zero = 0 ;
2010-07-13 08:13:56 -04:00
mReadZeroTS = 0 ;
2009-07-21 16:14:31 -04:00
total_len = 0 ;
2012-01-18 17:51:38 -05:00
mTimeoutTS = 0 ;
2007-11-14 22:18:48 -05:00
if ( neededReset )
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2012-04-13 20:30:23 -04:00
outLog + = " pqissl::reset() Reset Required! \n " ;
outLog + = " pqissl::reset() Will Attempt notifyEvent(FAILED) \n " ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
}
2012-04-13 20:30:23 -04:00
rslog ( RSL_ALERT , pqisslzone , outLog ) ;
2007-11-14 22:18:48 -05:00
// notify people of problem!
// but only if we really shut something down.
if ( neededReset )
{
// clean up the streamer
if ( parent ( ) )
{
2013-10-01 06:11:34 -04:00
struct sockaddr_storage addr ;
sockaddr_storage_clear ( addr ) ;
parent ( ) - > notifyEvent ( this , NET_CONNECT_FAILED , addr ) ;
2007-11-14 22:18:48 -05:00
}
}
return 1 ;
}
2013-09-03 09:35:39 -04:00
bool pqissl : : connect_parameter ( uint32_t type , const std : : string & value )
{
2013-10-01 06:11:34 -04:00
RsStackMutex stack ( mSslMtx ) ; /**** LOCKED MUTEX ****/
2015-06-15 18:41:18 -04:00
/* remove unused parameter warnings */
( void ) type ;
2013-09-13 10:35:19 -04:00
( void ) value ;
2013-09-03 09:35:39 -04:00
return false ;
}
2008-02-26 21:32:20 -05:00
bool pqissl : : connect_parameter ( uint32_t type , uint32_t value )
{
2013-10-01 06:11:34 -04:00
RsStackMutex stack ( mSslMtx ) ; /**** LOCKED MUTEX ****/
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
{
2012-04-13 20:30:23 -04:00
std : : string out = " pqissl::connect_parameter() Peer: " + PeerId ( ) ;
rs_sprintf_append ( out , " type: %u value: %u " , type , value ) ;
rslog ( RSL_DEBUG_ALL , pqisslzone , out ) ;
2008-07-10 12:29:18 -04:00
}
2012-01-18 17:51:38 -05:00
# endif
2008-07-10 12:29:18 -04:00
2008-02-26 21:32:20 -05:00
if ( type = = NET_PARAM_CONNECT_DELAY )
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2012-04-13 20:30:23 -04:00
std : : string out = " pqissl::connect_parameter() Peer: " + PeerId ( ) ;
rs_sprintf_append ( out , " DELAY: %u " , value ) ;
rslog ( RSL_DEBUG_BASIC , pqisslzone , out ) ;
2012-01-18 17:51:38 -05:00
# endif
2008-07-10 12:29:18 -04:00
2008-02-26 21:32:20 -05:00
mConnectDelay = value ;
return true ;
}
2008-03-26 11:35:09 -04:00
else if ( type = = NET_PARAM_CONNECT_TIMEOUT )
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2012-04-13 20:30:23 -04:00
std : : string out = " pqissl::connect_parameter() Peer: " + PeerId ( ) ;
rs_sprintf_append ( out , " TIMEOUT: %u " , value ) ;
rslog ( RSL_DEBUG_BASIC , pqisslzone , out ) ;
2012-01-18 17:51:38 -05:00
# endif
2008-07-10 12:29:18 -04:00
2008-03-26 11:35:09 -04:00
mConnectTimeout = value ;
return true ;
}
return false ;
//return NetInterface::connect_parameter(type, value);
2008-02-26 21:32:20 -05:00
}
2007-11-14 22:18:48 -05:00
/********** End of Implementation of NetInterface ******************/
/********** Implementation of BinInterface **************************
* Only status ( ) + tick ( ) are here . . . as they are really related
* to the NetInterface , and not the BinInterface ,
*
*/
2013-06-28 17:47:25 -04:00
void pqissl : : getCryptoParams ( RsPeerCryptoParams & params )
{
2013-10-01 06:11:34 -04:00
RsStackMutex stack ( mSslMtx ) ; /**** LOCKED MUTEX ****/
2013-06-28 17:47:25 -04:00
if ( active )
{
params . connexion_state = 1 ;
params . cipher_name = std : : string ( SSL_get_cipher ( ssl_connection ) ) ;
int alg ;
int al2 = SSL_get_cipher_bits ( ssl_connection , & alg ) ;
params . cipher_bits_1 = alg ;
params . cipher_bits_2 = al2 ;
2015-04-01 14:29:59 -04:00
char * desc = SSL_CIPHER_description ( SSL_get_current_cipher ( ssl_connection ) , NULL , 0 ) ;
params . cipher_version = std : : string ( desc ) . find ( " TLSv1.2 " ) ! = std : : string : : npos ? std : : string ( " TLSv1.2 " ) : std : : string ( " TLSv1 " ) ;
OPENSSL_free ( desc ) ;
2013-06-28 17:47:25 -04:00
}
else
{
params . connexion_state = 0 ;
params . cipher_name . clear ( ) ;
params . cipher_bits_1 = 0 ;
params . cipher_bits_2 = 0 ;
params . cipher_version . clear ( ) ;
}
}
2015-05-16 07:19:53 -04:00
bool pqissl : : actAsServer ( )
{
return ( bool ) ssl_connection - > server ;
}
2007-11-14 22:18:48 -05:00
/* returns ...
* - 1 if inactive .
* 0 if connecting .
* 1 if connected .
*/
int pqissl : : status ( )
{
2013-10-01 06:11:34 -04:00
RsStackMutex stack ( mSslMtx ) ; /**** LOCKED MUTEX ****/
2007-11-14 22:18:48 -05:00
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2012-04-13 20:30:23 -04:00
std : : string out = " pqissl::status() " ;
2008-01-25 01:36:40 -05:00
2007-11-14 22:18:48 -05:00
if ( active )
{
2012-01-18 17:51:38 -05:00
int alg ;
2012-04-13 20:30:23 -04:00
out + = " active: \n " ;
2007-11-14 22:18:48 -05:00
// print out connection.
2012-04-13 20:30:23 -04:00
out + = " Connected TO : " + PeerId ( ) + " \n " ;
2007-11-14 22:18:48 -05:00
// print out cipher.
2012-04-13 20:30:23 -04:00
rs_sprintf_append ( out , " \t \t SSL Cipher:%s " , SSL_get_cipher ( ssl_connection ) ) ;
rs_sprintf_append ( out , " (%d:%d) " , SSL_get_cipher_bits ( ssl_connection , & alg ) , alg ) ;
rs_sprintf_append ( out , " Vers:%s \n \n " , SSL_get_cipher_version ( ssl_connection ) ) ;
2007-11-14 22:18:48 -05:00
}
else
{
2012-04-13 20:30:23 -04:00
out + = " Waiting for connection! \n " ;
2007-11-14 22:18:48 -05:00
}
2012-04-13 20:30:23 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone , out ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
if ( active )
{
return 1 ;
}
else if ( waiting > 0 )
{
return 0 ;
}
return - 1 ;
}
// tick......
int pqissl : : tick ( )
{
2013-10-01 06:11:34 -04:00
RsStackMutex stack ( mSslMtx ) ; /**** LOCKED MUTEX ****/
2007-11-14 22:18:48 -05:00
//pqistreamer::tick();
// continue existing connection attempt.
if ( ! active )
{
// if we are waiting.. continue the connection (only)
if ( waiting > 0 )
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2012-04-13 20:30:23 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone , " pqissl::tick() Continuing Connection Attempt! " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
2012-04-13 20:30:23 -04:00
ConnectAttempt ( ) ;
2007-11-14 22:18:48 -05:00
return 1 ;
}
}
return 1 ;
}
/********** End of Implementation of BinInterface ******************/
/********** Internals of SSL Connection ****************************/
int pqissl : : ConnectAttempt ( )
{
switch ( waiting )
{
case WAITING_NOT :
2008-02-26 21:32:20 -05:00
sslmode = PQISSL_ACTIVE ; /* we're starting this one */
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::ConnectAttempt() STATE = Not Waiting, starting connection " ) ;
2012-01-18 17:51:38 -05:00
# endif
2008-02-26 21:32:20 -05:00
case WAITING_DELAY :
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2008-02-26 21:32:20 -05:00
" pqissl::ConnectAttempt() STATE = Waiting Delay, starting connection " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
2008-02-26 21:32:20 -05:00
return Delay_Connection ( ) ;
//return Initiate_Connection(); /* now called by Delay_Connection() */
2007-11-14 22:18:48 -05:00
break ;
case WAITING_SOCK_CONNECT :
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::ConnectAttempt() STATE = Waiting Sock Connect " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
return Initiate_SSL_Connection ( ) ;
break ;
case WAITING_SSL_CONNECTION :
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::ConnectAttempt() STATE = Waiting SSL Connection " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
return Authorise_SSL_Connection ( ) ;
break ;
case WAITING_SSL_AUTHORISE :
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::ConnectAttempt() STATE = Waiting SSL Authorise " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
return Authorise_SSL_Connection ( ) ;
break ;
case WAITING_FAIL_INTERFACE :
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::ConnectAttempt() Failed - Retrying " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
2008-01-25 01:36:40 -05:00
return Failed_Connection ( ) ;
2007-11-14 22:18:48 -05:00
break ;
default :
2008-07-10 12:29:18 -04:00
rslog ( RSL_ALERT , pqisslzone ,
2011-08-06 08:27:23 -04:00
" pqissl::ConnectAttempt() STATE = Unknown - calling reset() " ) ;
2007-11-14 22:18:48 -05:00
2013-10-01 06:11:34 -04:00
reset_locked ( ) ;
2007-11-14 22:18:48 -05:00
break ;
}
2008-07-10 12:29:18 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::ConnectAttempt() Unknown " ) ;
2007-11-14 22:18:48 -05:00
return - 1 ;
}
2008-01-25 01:36:40 -05:00
/****************************** FAILED ATTEMPT ******************************
2007-11-14 22:18:48 -05:00
* Determine the Remote Address .
*
* Specifics :
* TCP / UDP
* TCP - check for which interface to use .
2008-01-25 01:36:40 -05:00
* UDP - check for request proxies . . . .
2007-11-14 22:18:48 -05:00
*
* X509 / XPGP - Same .
*
*/
2008-01-25 01:36:40 -05:00
int pqissl : : Failed_Connection ( )
2007-11-14 22:18:48 -05:00
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2008-01-25 01:36:40 -05:00
" pqissl::ConnectAttempt() Failed - Notifying " ) ;
2012-01-18 17:51:38 -05:00
# endif
2008-01-25 01:36:40 -05:00
2007-11-14 22:18:48 -05:00
if ( parent ( ) )
{
2013-10-01 06:11:34 -04:00
struct sockaddr_storage addr ;
sockaddr_storage_clear ( addr ) ;
parent ( ) - > notifyEvent ( this , NET_CONNECT_UNREACHABLE , addr ) ;
2007-11-14 22:18:48 -05:00
}
2013-10-01 06:11:34 -04:00
2007-11-14 22:18:48 -05:00
waiting = WAITING_NOT ;
2008-01-25 01:36:40 -05:00
return 1 ;
2007-11-14 22:18:48 -05:00
}
/****************************** MAKE CONNECTION *****************************
* Open Socket and Initiate Connection .
*
* Specifics :
* TCP / UDP
* TCP - socket ( ) / connect ( )
* UDP - tou_socket ( ) / tou_connect ( )
*
* X509 / XPGP - Same .
*
*/
2008-02-26 21:32:20 -05:00
int pqissl : : Delay_Connection ( )
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2008-02-26 21:32:20 -05:00
" pqissl::Delay_Connection() Attempting Outgoing Connection.... " ) ;
2012-01-18 17:51:38 -05:00
# endif
2008-02-26 21:32:20 -05:00
if ( waiting = = WAITING_NOT )
{
waiting = WAITING_DELAY ;
2014-05-31 21:16:34 -04:00
/* we cannot just jump to Initiate_Connection,
* but must switch to WAITING_DELAY for at least one cycle .
* to avoid deadlock between threads . . . .
* ie . so the connection stuff is called from tick ( ) , rather than connect ( )
*/
2008-02-26 21:32:20 -05:00
/* set Connection TS.
*/
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-02-26 21:32:20 -05:00
{
2012-04-13 20:30:23 -04:00
std : : string out ;
rs_sprintf ( out , " pqissl::Delay_Connection() Delaying Connection to %s for %lu seconds " , PeerId ( ) . c_str ( ) , mConnectDelay ) ;
rslog ( RSL_DEBUG_BASIC , pqisslzone , out ) ;
2008-02-26 21:32:20 -05:00
}
2012-01-18 17:51:38 -05:00
# endif
2008-02-26 21:32:20 -05:00
mConnectTS = time ( NULL ) + mConnectDelay ;
return 0 ;
}
else if ( waiting = = WAITING_DELAY )
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-02-26 21:32:20 -05:00
{
2012-04-13 20:30:23 -04:00
std : : string out ;
rs_sprintf ( out , " pqissl::Delay_Connection() Connection to %s starting in %ld seconds " , PeerId ( ) . c_str ( ) , mConnectTS - time ( NULL ) ) ;
rslog ( RSL_DEBUG_BASIC , pqisslzone , out ) ;
2008-02-26 21:32:20 -05:00
}
2012-01-18 17:51:38 -05:00
# endif
2014-05-31 21:16:34 -04:00
if ( time ( NULL ) > = mConnectTS )
2008-02-26 21:32:20 -05:00
{
return Initiate_Connection ( ) ;
}
return 0 ;
}
2008-07-10 12:29:18 -04:00
rslog ( RSL_WARNING , pqisslzone ,
2008-02-26 21:32:20 -05:00
" pqissl::Initiate_Connection() Already Attempt in Progress! " ) ;
return - 1 ;
}
2007-11-14 22:18:48 -05:00
int pqissl : : Initiate_Connection ( )
{
int err ;
2013-09-13 10:35:19 -04:00
struct sockaddr_storage addr = remote_addr ;
2007-11-14 22:18:48 -05:00
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Initiate_Connection() Attempting Outgoing Connection.... " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
2008-02-26 21:32:20 -05:00
if ( waiting ! = WAITING_DELAY )
2007-11-14 22:18:48 -05:00
{
2008-07-10 12:29:18 -04:00
rslog ( RSL_WARNING , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Initiate_Connection() Already Attempt in Progress! " ) ;
return - 1 ;
}
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Initiate_Connection() Opening Socket " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
// open socket connection to addr.
int osock = unix_socket ( PF_INET , SOCK_STREAM , 0 ) ;
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2007-11-14 22:18:48 -05:00
{
2012-04-13 20:30:23 -04:00
std : : string out ;
rs_sprintf ( out , " pqissl::Initiate_Connection() osock = %d " , osock ) ;
rslog ( RSL_DEBUG_BASIC , pqisslzone , out ) ;
2007-11-14 22:18:48 -05:00
}
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
if ( osock < 0 )
{
2012-04-13 20:30:23 -04:00
std : : string out = " pqissl::Initiate_Connection() Failed to open socket! \n " ;
out + = " Socket Error: " + socket_errorType ( errno ) ;
rslog ( RSL_WARNING , pqisslzone , out ) ;
2007-11-14 22:18:48 -05:00
net_internal_close ( osock ) ;
waiting = WAITING_FAIL_INTERFACE ;
return - 1 ;
}
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Initiate_Connection() Making Non-Blocking " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
err = unix_fcntl_nonblock ( osock ) ;
if ( err < 0 )
{
2012-04-13 20:30:23 -04:00
std : : string out ;
rs_sprintf ( out , " pqissl::Initiate_Connection() Error: Cannot make socket NON-Blocking: %d " , err ) ;
rslog ( RSL_WARNING , pqisslzone , out ) ;
2007-11-14 22:18:48 -05:00
waiting = WAITING_FAIL_INTERFACE ;
net_internal_close ( osock ) ;
return - 1 ;
}
2008-07-10 12:29:18 -04:00
{
2012-04-13 20:30:23 -04:00
std : : string out ;
2014-03-17 16:56:06 -04:00
rs_sprintf ( out , " pqissl::Initiate_Connection() Connecting To: %s via: " , PeerId ( ) . toStdString ( ) . c_str ( ) ) ;
2013-09-13 10:35:19 -04:00
out + = sockaddr_storage_tostring ( addr ) ;
2012-04-13 20:30:23 -04:00
rslog ( RSL_WARNING , pqisslzone , out ) ;
2007-11-14 22:18:48 -05:00
}
2013-09-13 10:35:19 -04:00
if ( sockaddr_storage_isnull ( addr ) )
2007-11-14 22:18:48 -05:00
{
2012-04-13 20:30:23 -04:00
rslog ( RSL_WARNING , pqisslzone , " pqissl::Initiate_Connection() Invalid (0.0.0.0) Remote Address, Aborting Connect. " ) ;
2007-11-14 22:18:48 -05:00
waiting = WAITING_FAIL_INTERFACE ;
net_internal_close ( osock ) ;
return - 1 ;
}
2010-11-12 16:05:59 -05:00
# ifdef WINDOWS_SYS
/* Set TCP buffer size for Windows systems */
int sockbufsize = 0 ;
int size = sizeof ( int ) ;
err = getsockopt ( osock , SOL_SOCKET , SO_RCVBUF , ( char * ) & sockbufsize , & size ) ;
2011-06-27 18:28:33 -04:00
# ifdef PQISSL_DEBUG
2010-11-12 16:05:59 -05:00
if ( err = = 0 ) {
std : : cerr < < " pqissl::Initiate_Connection: Current TCP receive buffer size " < < sockbufsize < < std : : endl ;
} else {
std : : cerr < < " pqissl::Initiate_Connection: Error getting TCP receive buffer size. Error " < < err < < std : : endl ;
}
2011-06-27 18:28:33 -04:00
# endif
2010-11-12 16:05:59 -05:00
sockbufsize = 0 ;
err = getsockopt ( osock , SOL_SOCKET , SO_SNDBUF , ( char * ) & sockbufsize , & size ) ;
2011-06-27 18:28:33 -04:00
# ifdef PQISSL_DEBUG
2010-11-12 16:05:59 -05:00
if ( err = = 0 ) {
std : : cerr < < " pqissl::Initiate_Connection: Current TCP send buffer size " < < sockbufsize < < std : : endl ;
} else {
std : : cerr < < " pqissl::Initiate_Connection: Error getting TCP send buffer size. Error " < < err < < std : : endl ;
}
2011-06-27 18:28:33 -04:00
# endif
2010-11-12 16:05:59 -05:00
sockbufsize = WINDOWS_TCP_BUFFER_SIZE ;
err = setsockopt ( osock , SOL_SOCKET , SO_RCVBUF , ( char * ) & sockbufsize , sizeof ( sockbufsize ) ) ;
2011-06-27 18:28:33 -04:00
# ifdef PQISSL_DEBUG
2010-11-12 16:05:59 -05:00
if ( err = = 0 ) {
std : : cerr < < " pqissl::Initiate_Connection: TCP receive buffer size set to " < < sockbufsize < < std : : endl ;
} else {
std : : cerr < < " pqissl::Initiate_Connection: Error setting TCP receive buffer size. Error " < < err < < std : : endl ;
}
2011-06-27 18:28:33 -04:00
# endif
2010-11-12 16:05:59 -05:00
err = setsockopt ( osock , SOL_SOCKET , SO_SNDBUF , ( char * ) & sockbufsize , sizeof ( sockbufsize ) ) ;
2011-06-27 18:28:33 -04:00
# ifdef PQISSL_DEBUG
2010-11-12 16:05:59 -05:00
if ( err = = 0 ) {
std : : cerr < < " pqissl::Initiate_Connection: TCP send buffer size set to " < < sockbufsize < < std : : endl ;
} else {
std : : cerr < < " pqissl::Initiate_Connection: Error setting TCP send buffer size. Error " < < err < < std : : endl ;
}
# endif
2011-06-27 18:28:33 -04:00
# endif // WINDOWS_SYS
2007-11-14 22:18:48 -05:00
2008-03-26 11:35:09 -04:00
mTimeoutTS = time ( NULL ) + mConnectTimeout ;
2008-07-09 05:55:09 -04:00
//std::cerr << "Setting Connect Timeout " << mConnectTimeout << " Seconds into Future " << std::endl;
2008-03-26 11:35:09 -04:00
2007-11-14 22:18:48 -05:00
if ( 0 ! = ( err = unix_connect ( osock , ( struct sockaddr * ) & addr , sizeof ( addr ) ) ) )
{
2012-04-13 20:30:23 -04:00
std : : string out ;
rs_sprintf ( out , " pqissl::Initiate_Connection() connect returns:%d -> errno: %d error: %s \n " , err , errno , socket_errorType ( errno ) . c_str ( ) ) ;
2007-11-14 22:18:48 -05:00
if ( errno = = EINPROGRESS )
{
// set state to waiting.....
waiting = WAITING_SOCK_CONNECT ;
sockfd = osock ;
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2012-04-13 20:30:23 -04:00
out + = " EINPROGRESS Waiting for Socket Connection " ;
rslog ( RSL_DEBUG_BASIC , pqisslzone , out ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
return 0 ;
}
else if ( ( errno = = ENETUNREACH ) | | ( errno = = ETIMEDOUT ) )
{
2014-03-17 16:56:06 -04:00
out + = " ENETUNREACHABLE: cert: " + PeerId ( ) . toStdString ( ) ;
2012-04-13 20:30:23 -04:00
rslog ( RSL_WARNING , pqisslzone , out ) ;
2007-11-14 22:18:48 -05:00
// Then send unreachable message.
net_internal_close ( osock ) ;
osock = - 1 ;
//reset();
waiting = WAITING_FAIL_INTERFACE ;
return - 1 ;
}
/* IF we get here ---- we Failed for some other reason.
* Should abandon this interface
* Known reasons to get here : EINVAL ( bad address )
*/
2012-04-13 20:30:23 -04:00
rs_sprintf_append ( out , " Error: Connection Failed: %d - %s " , errno , socket_errorType ( errno ) . c_str ( ) ) ;
2007-11-14 22:18:48 -05:00
net_internal_close ( osock ) ;
osock = - 1 ;
waiting = WAITING_FAIL_INTERFACE ;
2012-04-13 20:30:23 -04:00
rslog ( RSL_WARNING , pqisslzone , out ) ;
2013-09-24 01:30:01 -04:00
2007-11-14 22:18:48 -05:00
// extra output for the moment.
2013-09-24 01:30:01 -04:00
std : : cerr < < out ;
2007-11-14 22:18:48 -05:00
return - 1 ;
}
else
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Init_Connection() connect returned 0 " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
}
waiting = WAITING_SOCK_CONNECT ;
sockfd = osock ;
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Initiate_Connection() Waiting for Socket Connect " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
return 1 ;
}
/****************************** CHECK SOCKET *****************************
* Check the Socket .
*
* select ( ) and getsockopt ( ) .
*
* Specifics :
* TCP / UDP
* TCP - select ( ) / getsockopt ( )
* UDP - tou_error ( )
*
* X509 / XPGP - Same .
*
*/
2014-01-19 06:35:31 -05:00
bool pqissl : : CheckConnectionTimeout ( )
2007-11-14 22:18:48 -05:00
{
2008-03-26 11:35:09 -04:00
/* new TimeOut code. */
if ( time ( NULL ) > mTimeoutTS )
{
2012-04-13 20:30:23 -04:00
std : : string out ;
2014-03-17 16:56:06 -04:00
rs_sprintf ( out , " pqissl::Basic_Connection_Complete() Connection Timed Out. Peer: %s Period: %lu " , PeerId ( ) . toStdString ( ) . c_str ( ) , mConnectTimeout ) ;
2008-07-10 12:29:18 -04:00
2012-04-13 20:30:23 -04:00
rslog ( RSL_WARNING , pqisslzone , out ) ;
2008-03-26 11:35:09 -04:00
/* as sockfd is valid, this should close it all up */
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::Basic_Connection_Complete() -> calling reset() " ) ;
2013-10-01 06:11:34 -04:00
reset_locked ( ) ;
2014-01-19 06:35:31 -05:00
return true ;
2008-03-26 11:35:09 -04:00
}
2014-01-19 06:35:31 -05:00
return false ;
}
2008-03-26 11:35:09 -04:00
2014-01-19 06:35:31 -05:00
int pqissl : : Basic_Connection_Complete ( )
{
# ifdef PQISSL_LOG_DEBUG
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
" pqissl::Basic_Connection_Complete()... " ) ;
# endif
if ( CheckConnectionTimeout ( ) )
{
// calls reset.
return - 1 ;
}
2007-11-14 22:18:48 -05:00
if ( waiting ! = WAITING_SOCK_CONNECT )
{
2010-06-25 17:44:24 -04:00
rslog ( RSL_ALERT , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Basic_Connection_Complete() Wrong Mode " ) ;
return - 1 ;
}
2010-02-15 10:31:37 -05:00
if ( sockfd = = - 1 )
{
2010-06-25 17:44:24 -04:00
rslog ( RSL_ALERT , pqisslzone ,
2010-02-15 10:31:37 -05:00
" pqissl::Basic_Connection_Complete() problem with the socket descriptor. Aborting " ) ;
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::Basic_Connection_Complete() -> calling reset() " ) ;
2013-10-01 06:11:34 -04:00
reset_locked ( ) ;
2010-02-15 10:31:37 -05:00
return - 1 ;
}
// use select on the opened socket.
2007-11-14 22:18:48 -05:00
// Interestingly - This code might be portable....
fd_set ReadFDs , WriteFDs , ExceptFDs ;
FD_ZERO ( & ReadFDs ) ;
FD_ZERO ( & WriteFDs ) ;
FD_ZERO ( & ExceptFDs ) ;
FD_SET ( sockfd , & ReadFDs ) ;
FD_SET ( sockfd , & WriteFDs ) ;
FD_SET ( sockfd , & ExceptFDs ) ;
struct timeval timeout ;
timeout . tv_sec = 0 ;
timeout . tv_usec = 0 ;
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Basic_Connection_Complete() Selecting .... " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
int sr = 0 ;
if ( 0 > ( sr = select ( sockfd + 1 ,
& ReadFDs , & WriteFDs , & ExceptFDs , & timeout ) ) )
{
// select error.
2008-07-10 12:29:18 -04:00
rslog ( RSL_WARNING , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Basic_Connection_Complete() Select ERROR(1) " ) ;
net_internal_close ( sockfd ) ;
sockfd = - 1 ;
//reset();
waiting = WAITING_FAIL_INTERFACE ;
return - 1 ;
}
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2007-11-14 22:18:48 -05:00
{
2012-04-13 20:30:23 -04:00
std : : string out ;
rs_sprintf ( out , " pqissl::Basic_Connection_Complete() Select returned %d " , sr ) ;
rslog ( RSL_DEBUG_BASIC , pqisslzone , out ) ;
2007-11-14 22:18:48 -05:00
}
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
if ( FD_ISSET ( sockfd , & ExceptFDs ) )
{
// error - reset socket.
// this is a definite bad socket!.
2008-07-10 12:29:18 -04:00
rslog ( RSL_WARNING , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Basic_Connection_Complete() Select ERROR(2) " ) ;
net_internal_close ( sockfd ) ;
sockfd = - 1 ;
//reset();
waiting = WAITING_FAIL_INTERFACE ;
return - 1 ;
}
if ( FD_ISSET ( sockfd , & WriteFDs ) )
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Basic_Connection_Complete() Can Write! " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
}
else
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
// happens frequently so switched to debug msg.
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Basic_Connection_Complete() Not Yet Ready! " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
return 0 ;
}
if ( FD_ISSET ( sockfd , & ReadFDs ) )
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Basic_Connection_Complete() Can Read! " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
}
else
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2007-11-14 22:18:48 -05:00
// not ready return -1;
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Basic_Connection_Complete() Cannot Read! " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
}
int err = 1 ;
if ( 0 = = unix_getsockopt_error ( sockfd , & err ) )
{
if ( err = = 0 )
{
{
2012-04-13 20:30:23 -04:00
std : : string out ;
2014-03-17 16:56:06 -04:00
rs_sprintf ( out , " pqissl::Basic_Connection_Complete() TCP Connection Complete: cert: %s on osock: " , PeerId ( ) . toStdString ( ) . c_str ( ) , sockfd ) ;
2012-04-13 20:30:23 -04:00
rslog ( RSL_WARNING , pqisslzone , out ) ;
2007-11-14 22:18:48 -05:00
}
return 1 ;
}
else if ( err = = EINPROGRESS )
{
2014-03-17 16:56:06 -04:00
rslog ( RSL_WARNING , pqisslzone , " pqissl::Basic_Connection_Complete() EINPROGRESS: cert: " + PeerId ( ) . toStdString ( ) ) ;
2007-11-14 22:18:48 -05:00
return 0 ;
}
else if ( ( err = = ENETUNREACH ) | | ( err = = ETIMEDOUT ) )
{
2014-03-17 16:56:06 -04:00
rslog ( RSL_WARNING , pqisslzone , " pqissl::Basic_Connection_Complete() ENETUNREACH/ETIMEDOUT: cert: " + PeerId ( ) . toStdString ( ) ) ;
2007-11-14 22:18:48 -05:00
// Then send unreachable message.
net_internal_close ( sockfd ) ;
sockfd = - 1 ;
//reset();
waiting = WAITING_FAIL_INTERFACE ;
return - 1 ;
}
else if ( ( err = = EHOSTUNREACH ) | | ( err = = EHOSTDOWN ) )
{
2014-03-17 16:56:06 -04:00
rslog ( RSL_WARNING , pqisslzone , " pqissl::Basic_Connection_Complete() EHOSTUNREACH/EHOSTDOWN: cert: " + PeerId ( ) . toStdString ( ) ) ;
2007-11-14 22:18:48 -05:00
// Then send unreachable message.
net_internal_close ( sockfd ) ;
sockfd = - 1 ;
//reset();
waiting = WAITING_FAIL_INTERFACE ;
return - 1 ;
}
else if ( ( err = = ECONNREFUSED ) )
{
2014-03-17 16:56:06 -04:00
rslog ( RSL_WARNING , pqisslzone , " pqissl::Basic_Connection_Complete() ECONNREFUSED: cert: " + PeerId ( ) . toStdString ( ) ) ;
2007-11-14 22:18:48 -05:00
// Then send unreachable message.
net_internal_close ( sockfd ) ;
sockfd = - 1 ;
//reset();
waiting = WAITING_FAIL_INTERFACE ;
return - 1 ;
}
2012-04-13 20:30:23 -04:00
std : : string out ;
rs_sprintf ( out , " Error: Connection Failed UNKNOWN ERROR: %d - %s " , err , socket_errorType ( err ) . c_str ( ) ) ;
rslog ( RSL_WARNING , pqisslzone , out ) ;
2007-11-14 22:18:48 -05:00
net_internal_close ( sockfd ) ;
sockfd = - 1 ;
//reset(); // which will send Connect Failed,
return - 1 ;
}
2012-01-18 17:51:38 -05:00
rslog ( RSL_ALERT , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Basic_Connection_Complete() BAD GETSOCKOPT! " ) ;
waiting = WAITING_FAIL_INTERFACE ;
return - 1 ;
}
int pqissl : : Initiate_SSL_Connection ( )
{
int err ;
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Initiate_SSL_Connection() Checking Basic Connection " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
if ( 0 > = ( err = Basic_Connection_Complete ( ) ) )
{
return err ;
}
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Initiate_SSL_Connection() Basic Connection Okay " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
2010-06-25 17:44:24 -04:00
// setup timeout value.
ssl_connect_timeout = time ( NULL ) + PQISSL_SSL_CONNECT_TIMEOUT ;
2007-11-14 22:18:48 -05:00
// Perform SSL magic.
// library already inited by sslroot().
2010-06-25 17:44:24 -04:00
SSL * ssl = SSL_new ( AuthSSL : : getAuthSSL ( ) - > getCTX ( ) ) ;
2007-11-14 22:18:48 -05:00
if ( ssl = = NULL )
{
2008-07-10 12:29:18 -04:00
rslog ( RSL_ALERT , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Initiate_SSL_Connection() SSL_new failed! " ) ;
2010-06-25 17:44:24 -04:00
exit ( 1 ) ;
2007-11-14 22:18:48 -05:00
return - 1 ;
}
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Initiate_SSL_Connection() SSL Connection Okay " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
ssl_connection = ssl ;
2010-06-25 17:44:24 -04:00
net_internal_SSL_set_fd ( ssl , sockfd ) ;
2007-11-14 22:18:48 -05:00
if ( err < 1 )
{
2012-04-13 20:30:23 -04:00
std : : string out = " pqissl::Initiate_SSL_Connection() SSL_set_fd failed! \n " ;
printSSLError ( ssl , err , SSL_get_error ( ssl , err ) , ERR_get_error ( ) , out ) ;
2007-11-14 22:18:48 -05:00
2012-04-13 20:30:23 -04:00
rslog ( RSL_ALERT , pqisslzone , out ) ;
2007-11-14 22:18:48 -05:00
}
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Initiate_SSL_Connection() Waiting for SSL Connection " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
waiting = WAITING_SSL_CONNECTION ;
return 1 ;
}
int pqissl : : SSL_Connection_Complete ( )
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::SSL_Connection_Complete()??? ... Checking " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
if ( waiting = = WAITING_SSL_AUTHORISE )
{
2008-07-10 12:29:18 -04:00
rslog ( RSL_ALERT , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::SSL_Connection_Complete() Waiting = W_SSL_AUTH " ) ;
return 1 ;
}
if ( waiting ! = WAITING_SSL_CONNECTION )
{
2008-07-10 12:29:18 -04:00
rslog ( RSL_ALERT , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::SSL_Connection_Complete() Still Waiting.. " ) ;
return - 1 ;
}
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::SSL_Connection_Complete() Attempting SSL_connect " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
/* if we are passive - then accept! */
int err ;
if ( sslmode )
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2015-05-28 17:44:43 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone , " --------> Active Connect! Client side. " ) ;
2012-01-18 17:51:38 -05:00
# endif
2015-05-28 17:44:43 -04:00
err = SSL_connect ( ssl_connection ) ;
2007-11-14 22:18:48 -05:00
}
else
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2015-05-28 17:44:43 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone , " --------> Passive Accept! Server side. " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
err = SSL_accept ( ssl_connection ) ;
}
if ( err ! = 1 )
{
int serr = SSL_get_error ( ssl_connection , err ) ;
if ( ( serr = = SSL_ERROR_WANT_READ )
| | ( serr = = SSL_ERROR_WANT_WRITE ) )
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" Waiting for SSL handshake! " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
waiting = WAITING_SSL_CONNECTION ;
return 0 ;
}
2012-04-13 20:30:23 -04:00
std : : string out ;
rs_sprintf ( out , " pqissl::SSL_Connection_Complete() \n Issues with SSL Connect(%d)! \n " , err ) ;
printSSLError ( ssl_connection , err , serr , ERR_get_error ( ) , out ) ;
2007-11-14 22:18:48 -05:00
2012-04-13 20:30:23 -04:00
rslog ( RSL_WARNING , pqisslzone , out ) ;
2007-11-14 22:18:48 -05:00
// attempt real error.
2010-06-25 17:44:24 -04:00
Extract_Failed_SSL_Certificate ( ) ;
2007-11-14 22:18:48 -05:00
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::SSL_Connection_Complete() -> calling reset() " ) ;
2013-10-01 06:11:34 -04:00
reset_locked ( ) ;
2007-11-14 22:18:48 -05:00
waiting = WAITING_FAIL_INTERFACE ;
return - 1 ;
}
// if we get here... success v quickly.
2008-07-10 12:29:18 -04:00
2014-03-17 16:56:06 -04:00
rslog ( RSL_WARNING , pqisslzone , " pqissl::SSL_Connection_Complete() Success!: Peer: " + PeerId ( ) . toStdString ( ) ) ;
2007-11-14 22:18:48 -05:00
waiting = WAITING_SSL_AUTHORISE ;
return 1 ;
}
int pqissl : : Extract_Failed_SSL_Certificate ( )
{
2011-07-10 20:55:06 -04:00
std : : cerr < < " pqissl::Extract_Failed_SSL_Certificate() FAILED Connection due to Security Issues " ;
std : : cerr < < std : : endl ;
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Extract_Failed_SSL_Certificate() " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
// Get the Peer Certificate....
X509 * peercert = SSL_get_peer_certificate ( ssl_connection ) ;
2010-06-25 17:44:24 -04:00
if ( peercert = = NULL )
2007-11-14 22:18:48 -05:00
{
2008-07-10 12:29:18 -04:00
rslog ( RSL_WARNING , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Extract_Failed_SSL_Certificate() Peer Didnt Give Cert " ) ;
2011-07-10 20:55:06 -04:00
std : : cerr < < " pqissl::Extract_Failed_SSL_Certificate() ERROR Peer Didn't Give Us Certificate " ;
std : : cerr < < std : : endl ;
2007-11-14 22:18:48 -05:00
return - 1 ;
}
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2010-06-25 17:44:24 -04:00
" pqissl::Extract_Failed_SSL_Certificate() Have Peer Cert - Registering " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
2011-07-10 20:55:06 -04:00
std : : cerr < < " pqissl::Extract_Failed_SSL_Certificate() Passing FAILED Cert to AuthSSL for analysis " ;
std : : cerr < < std : : endl ;
2007-11-14 22:18:48 -05:00
// save certificate... (and ip locations)
// false for outgoing....
// we actually connected to remote_addr,
// which could be
// (pqissl's case) sslcert->serveraddr or sslcert->localaddr.
2012-09-14 17:04:16 -04:00
2014-03-17 16:56:06 -04:00
RsPeerId sslid ;
2012-09-14 17:04:16 -04:00
getX509id ( peercert , sslid ) ;
2014-03-17 16:56:06 -04:00
RsPgpId gpgid ( getX509CNString ( peercert - > cert_info - > issuer ) ) ;
2012-09-14 17:04:16 -04:00
std : : string sslcn = getX509CNString ( peercert - > cert_info - > subject ) ;
AuthSSL : : getAuthSSL ( ) - > FailedCertificate ( peercert , gpgid , sslid , sslcn , remote_addr , false ) ;
2013-08-22 03:26:13 -04:00
mLinkMgr - > notifyDeniedConnection ( gpgid , sslid , sslcn , remote_addr , false ) ;
2007-11-14 22:18:48 -05:00
return 1 ;
}
int pqissl : : Authorise_SSL_Connection ( )
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2010-06-25 17:44:24 -04:00
" pqissl::Authorise_SSL_Connection() " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
2010-06-25 17:44:24 -04:00
if ( time ( NULL ) > ssl_connect_timeout )
2007-11-14 22:18:48 -05:00
{
2011-08-06 08:27:23 -04:00
rslog ( RSL_WARNING , pqisslzone ,
2008-07-10 12:29:18 -04:00
" pqissl::Authorise_SSL_Connection() Connection Timed Out! " ) ;
2007-11-14 22:18:48 -05:00
/* as sockfd is valid, this should close it all up */
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::Authorise_Connection_Complete() -> calling reset() " ) ;
2013-10-01 06:11:34 -04:00
reset_locked ( ) ;
2007-11-14 22:18:48 -05:00
}
int err ;
if ( 0 > = ( err = SSL_Connection_Complete ( ) ) )
{
return err ;
}
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Authorise_SSL_Connection() SSL_Connection_Complete " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
// reset switch.
waiting = WAITING_NOT ;
X509 * peercert = SSL_get_peer_certificate ( ssl_connection ) ;
if ( peercert = = NULL )
{
2008-07-10 12:29:18 -04:00
rslog ( RSL_WARNING , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Authorise_SSL_Connection() Peer Didnt Give Cert " ) ;
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::Authorise_Connection_Complete() -> calling reset() " ) ;
2007-11-14 22:18:48 -05:00
// Failed completely
2013-10-01 06:11:34 -04:00
reset_locked ( ) ;
2007-11-14 22:18:48 -05:00
return - 1 ;
}
2010-03-05 16:27:42 -05:00
2014-03-17 16:56:06 -04:00
RsPeerId certPeerId ;
2010-02-05 15:39:01 -05:00
getX509id ( peercert , certPeerId ) ;
2014-03-17 16:56:06 -04:00
if ( RsPeerId ( certPeerId ) ! = PeerId ( ) ) {
2010-02-05 15:39:01 -05:00
rslog ( RSL_WARNING , pqisslzone ,
" pqissl::Authorise_SSL_Connection() the cert Id doesn't match the Peer id we're trying to connect to. " ) ;
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::Authorise_Connection_Complete() -> calling reset() " ) ;
2010-02-05 15:39:01 -05:00
// Failed completely
2013-10-01 06:11:34 -04:00
reset_locked ( ) ;
2010-02-05 15:39:01 -05:00
return - 1 ;
}
2007-11-14 22:18:48 -05:00
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::Authorise_SSL_Connection() Have Peer Cert " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
2010-06-25 17:44:24 -04:00
// save certificate... (and ip locations)
// false for outgoing....
// we actually connected to remote_addr,
// which could be
// (pqissl's case) sslcert->serveraddr or sslcert->localaddr.
2015-05-25 10:02:45 -04:00
bool res = AuthSSL : : getAuthSSL ( ) - > CheckCertificate ( PeerId ( ) , peercert ) ;
2010-06-25 17:44:24 -04:00
bool certCorrect = true ; /* WE know it okay already! */
2015-05-30 05:29:43 -04:00
uint32_t check_result ;
2015-06-03 10:01:46 -04:00
uint32_t checking_flags = RSBANLIST_CHECKING_FLAGS_BLACKLIST ;
if ( rsPeers - > servicePermissionFlags ( PeerId ( ) ) & RS_NODE_PERM_REQUIRE_WL )
checking_flags | = RSBANLIST_CHECKING_FLAGS_WHITELIST ;
2015-05-30 05:29:43 -04:00
2015-06-03 10:01:46 -04:00
if ( ! rsBanList - > isAddressAccepted ( remote_addr , checking_flags , & check_result ) )
2015-05-28 17:44:43 -04:00
{
2015-06-16 14:52:44 -04:00
std : : cerr < < " (SS) connection attempt from banned IP address " < < sockaddr_storage_iptostring ( remote_addr ) < < " . Refusing it. Reason: " < < check_result < < " . Attack?? " < < std : : endl ;
2015-06-02 17:36:26 -04:00
RsServer : : notify ( ) - > AddFeedItem ( RS_FEED_ITEM_SEC_IP_BLACKLISTED , PeerId ( ) . toStdString ( ) , sockaddr_storage_iptostring ( remote_addr ) , " " , " " , check_result ) ;
2015-05-28 17:44:43 -04:00
reset_locked ( ) ;
return 0 ;
2015-05-25 12:51:15 -04:00
}
2010-06-25 17:44:24 -04:00
// check it's the right one.
if ( certCorrect )
{
// then okay...
2014-03-17 16:56:06 -04:00
rslog ( RSL_WARNING , pqisslzone , " pqissl::Authorise_SSL_Connection() Accepting Conn. Peer: " + PeerId ( ) . toStdString ( ) ) ;
2010-06-25 17:44:24 -04:00
2015-05-25 10:02:45 -04:00
//std::cerr << "pqissl::Authorise_SSL_Connection(): accepting connection from " << sockaddr_storage_iptostring(remote_addr) << std::endl;
2013-10-01 06:11:34 -04:00
accept_locked ( ssl_connection , sockfd , remote_addr ) ;
2010-06-25 17:44:24 -04:00
return 1 ;
}
2014-03-17 16:56:06 -04:00
rslog ( RSL_WARNING , pqisslzone , " pqissl::Authorise_SSL_Connection() Something Wrong ... Shutdown. Peer: " + PeerId ( ) . toStdString ( ) ) ;
2010-06-25 17:44:24 -04:00
// else shutdown ssl connection.
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::Authorise_Connection_Complete() -> calling reset() " ) ;
2010-06-25 17:44:24 -04:00
2013-10-01 06:11:34 -04:00
reset_locked ( ) ;
2010-06-25 17:44:24 -04:00
return 0 ;
2007-11-14 22:18:48 -05:00
}
2013-10-01 06:11:34 -04:00
/* This function is public, and callable from pqilistener - so must be mutex protected */
2013-09-13 10:35:19 -04:00
int pqissl : : accept ( SSL * ssl , int fd , const struct sockaddr_storage & foreign_addr ) // initiate incoming connection.
2013-10-01 06:11:34 -04:00
{
2015-06-23 15:36:47 -04:00
# ifdef PQISSL_DEBUG
2013-10-01 23:21:04 -04:00
std : : cerr < < " pqissl::accept() " ;
2015-06-23 15:36:47 -04:00
std : : cerr < < std : : endl ;
# endif
2013-10-01 23:21:04 -04:00
2013-10-01 06:11:34 -04:00
RsStackMutex stack ( mSslMtx ) ; /**** LOCKED MUTEX ****/
return accept_locked ( ssl , fd , foreign_addr ) ;
}
int pqissl : : accept_locked ( SSL * ssl , int fd , const struct sockaddr_storage & foreign_addr ) // initiate incoming connection.
2007-11-14 22:18:48 -05:00
{
2015-05-30 05:29:43 -04:00
uint32_t check_result ;
2015-06-03 10:01:46 -04:00
uint32_t checking_flags = RSBANLIST_CHECKING_FLAGS_BLACKLIST ;
if ( rsPeers - > servicePermissionFlags ( PeerId ( ) ) & RS_NODE_PERM_REQUIRE_WL )
checking_flags | = RSBANLIST_CHECKING_FLAGS_WHITELIST ;
2015-05-30 05:29:43 -04:00
2015-06-03 10:01:46 -04:00
if ( ! rsBanList - > isAddressAccepted ( foreign_addr , checking_flags , & check_result ) )
2015-05-28 17:44:43 -04:00
{
2015-05-30 05:29:43 -04:00
std : : cerr < < " (SS) refusing incoming SSL connection from blacklisted foreign address " < < sockaddr_storage_iptostring ( foreign_addr )
< < " . Reason: " < < check_result < < " . " < < std : : endl ;
2015-06-02 17:36:26 -04:00
RsServer : : notify ( ) - > AddFeedItem ( RS_FEED_ITEM_SEC_IP_BLACKLISTED , PeerId ( ) . toStdString ( ) , sockaddr_storage_iptostring ( foreign_addr ) , " " , " " , check_result ) ;
2015-05-28 17:44:43 -04:00
reset_locked ( ) ;
return - 1 ;
}
2007-11-14 22:18:48 -05:00
if ( waiting ! = WAITING_NOT )
{
2014-03-17 16:56:06 -04:00
rslog ( RSL_WARNING , pqisslzone , " pqissl::accept() Peer: " + PeerId ( ) . toStdString ( ) + " - Two connections in progress - Shut 1 down! " ) ;
2007-11-14 22:18:48 -05:00
// outgoing connection in progress.
// shut this baby down.
//
// Thought I should shut down one in progress, and continue existing one!
// But the existing one might be broke.... take second.
// all we need is to never stop listening.
switch ( waiting )
{
case WAITING_SOCK_CONNECT :
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::accept() STATE = Waiting Sock Connect - close the socket " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
break ;
case WAITING_SSL_CONNECTION :
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::accept() STATE = Waiting SSL Connection - close sockfd + ssl_conn " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
break ;
case WAITING_SSL_AUTHORISE :
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::accept() STATE = Waiting SSL Authorise - close sockfd + ssl_conn " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
break ;
case WAITING_FAIL_INTERFACE :
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::accept() STATE = Failed, ignore? " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
break ;
default :
2008-07-10 12:29:18 -04:00
rslog ( RSL_ALERT , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::accept() STATE = Unknown - ignore? " ) ;
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::accept() -> calling reset() " ) ;
2013-10-01 06:11:34 -04:00
reset_locked ( ) ;
2007-11-14 22:18:48 -05:00
break ;
}
//waiting = WAITING_FAIL_INTERFACE;
//return -1;
}
/* shutdown existing - in all cases use the new one */
if ( ( ssl_connection ) & & ( ssl_connection ! = ssl ) )
{
2011-08-04 18:57:12 -04:00
rslog ( RSL_ALERT , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::accept() closing Previous/Existing ssl_connection " ) ;
SSL_shutdown ( ssl_connection ) ;
}
if ( ( sockfd > - 1 ) & & ( sockfd ! = fd ) )
{
2011-08-04 18:57:12 -04:00
rslog ( RSL_ALERT , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::accept() closing Previous/Existing sockfd " ) ;
net_internal_close ( sockfd ) ;
}
// save ssl + sock.
ssl_connection = ssl ;
sockfd = fd ;
/* if we connected - then just writing the same over,
* but if from ssllistener then we need to save the address .
*/
remote_addr = foreign_addr ;
/* check whether it is on the same LAN */
2013-09-13 10:35:19 -04:00
struct sockaddr_storage localaddr ;
mLinkMgr - > getLocalAddress ( localaddr ) ;
sameLAN = sockaddr_storage_samesubnet ( remote_addr , localaddr ) ;
2007-11-14 22:18:48 -05:00
{
2014-03-17 16:56:06 -04:00
std : : string out = " pqissl::accept() SUCCESSFUL connection to: " + PeerId ( ) . toStdString ( ) ;
2013-09-13 10:35:19 -04:00
out + = " localaddr: " + sockaddr_storage_iptostring ( localaddr ) ;
out + = " remoteaddr: " + sockaddr_storage_iptostring ( remote_addr ) ;
2012-01-18 17:51:38 -05:00
2012-04-13 20:30:23 -04:00
if ( sameLAN )
{
out + = " SAME LAN " ;
}
else
{
out + = " DIFF LANs " ;
}
2007-11-14 22:18:48 -05:00
2012-04-13 20:30:23 -04:00
rslog ( RSL_WARNING , pqisslzone , out ) ;
2007-11-14 22:18:48 -05:00
}
// establish the ssl details.
// cipher name.
int err ;
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2007-11-14 22:18:48 -05:00
{
2012-01-18 17:51:38 -05:00
int alg ;
2012-04-13 20:30:23 -04:00
std : : string out ;
rs_sprintf ( out , " SSL Cipher:%s \n " , SSL_get_cipher ( ssl ) ) ;
rs_sprintf_append ( out , " SSL Cipher Bits:%d - %d \n " , SSL_get_cipher_bits ( ssl , & alg ) , alg ) ;
rs_sprintf_append ( out , " SSL Cipher Version:%s \n " , SSL_get_cipher_version ( ssl ) ) ;
rslog ( RSL_DEBUG_BASIC , pqisslzone , out ) ;
2007-11-14 22:18:48 -05:00
}
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
// make non-blocking / or check.....
if ( ( err = net_internal_fcntl_nonblock ( sockfd ) ) < 0 )
{
2008-07-10 12:29:18 -04:00
rslog ( RSL_ALERT , pqisslzone , " Error: Cannot make socket NON-Blocking: " ) ;
2007-11-14 22:18:48 -05:00
active = false ;
waiting = WAITING_FAIL_INTERFACE ;
// failed completely.
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::accept() -> calling reset() " ) ;
2013-10-01 06:11:34 -04:00
reset_locked ( ) ;
2007-11-14 22:18:48 -05:00
return - 1 ;
}
else
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone , " pqissl::accept() Socket Made Non-Blocking! " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
}
2008-07-10 12:29:18 -04:00
// we want to continue listening - incase this socket is crap, and they try again.
2007-11-14 22:18:48 -05:00
//stoplistening();
active = true ;
waiting = WAITING_NOT ;
2015-04-23 14:49:13 -04:00
# ifdef PQISSL_DEBUG
2013-10-01 23:21:04 -04:00
std : : cerr < < " pqissl::accept_locked() connection complete - notifying parent " ;
2015-04-23 14:49:13 -04:00
std : : cerr < < std : : endl ;
# endif
2013-10-01 23:21:04 -04:00
2007-11-14 22:18:48 -05:00
// Notify the pqiperson.... (Both Connect/Receive)
if ( parent ( ) )
{
2013-10-01 06:11:34 -04:00
struct sockaddr_storage addr = remote_addr ;
parent ( ) - > notifyEvent ( this , NET_CONNECT_SUCCESS , addr ) ;
2007-11-14 22:18:48 -05:00
}
return 1 ;
}
/********** Implementation of BinInterface **************************
* All the rest of the BinInterface .
2013-10-01 06:11:34 -04:00
* This functions much be Mutex protected .
2007-11-14 22:18:48 -05:00
*
*/
int pqissl : : senddata ( void * data , int len )
{
2013-10-01 06:11:34 -04:00
RsStackMutex stack ( mSslMtx ) ; /**** LOCKED MUTEX ****/
2009-02-26 09:04:48 -05:00
int tmppktlen ;
2009-03-03 14:40:42 -05:00
2014-10-30 15:55:10 -04:00
// safety check. Apparently this avoids some SIGSEGV.
//
if ( ssl_connection = = NULL )
return - 1 ;
2011-06-27 18:28:33 -04:00
# ifdef PQISSL_DEBUG
2009-07-21 16:14:31 -04:00
std : : cout < < " Sending data thread= " < < pthread_self ( ) < < " , ssl= " < < ( void * ) this < < " , size= " < < len < < std : : endl ;
# endif
2009-03-03 14:40:42 -05:00
tmppktlen = SSL_write ( ssl_connection , data , len ) ;
2009-02-26 09:04:48 -05:00
2007-11-14 22:18:48 -05:00
if ( len ! = tmppktlen )
{
2014-03-17 16:56:06 -04:00
std : : string out = " pqissl::senddata() " + PeerId ( ) . toStdString ( ) ;
2012-04-13 20:30:23 -04:00
rs_sprintf_append ( out , " Partial Send: len: %d sent: %d " , len , tmppktlen ) ;
2007-11-14 22:18:48 -05:00
int err = SSL_get_error ( ssl_connection , tmppktlen ) ;
// incomplete operations - to repeat....
// handled by the pqistreamer...
if ( err = = SSL_ERROR_SYSCALL )
{
2012-04-13 20:30:23 -04:00
rs_sprintf_append ( out , " SSL_write() SSL_ERROR_SYSCALL SOCKET_DEAD -> calling reset() errno: %d " , errno ) ;
out + = socket_errorType ( errno ) ;
std : : cerr < < out < < std : : endl ;
rslog ( RSL_ALERT , pqisslzone , out ) ;
2010-08-02 19:21:59 -04:00
/* extra debugging - based on SSL_get_error() man page */
{
int errsys = errno ;
int sslerr = 0 ;
2012-04-13 20:30:23 -04:00
std : : string out2 ;
rs_sprintf ( out2 , " SSL_ERROR_SYSCALL, ret == %d errno: %d %s \n " , tmppktlen , errsys , socket_errorType ( errsys ) . c_str ( ) ) ;
2010-08-02 19:21:59 -04:00
while ( 0 ! = ( sslerr = ERR_get_error ( ) ) )
{
2012-04-13 20:30:23 -04:00
rs_sprintf_append ( out2 , " SSLERR:%d: " , sslerr ) ;
2010-08-02 19:21:59 -04:00
char sslbuf [ 256 ] = { 0 } ;
2012-04-13 20:30:23 -04:00
out2 + = ERR_error_string ( sslerr , sslbuf ) ;
out2 + = " \n " ;
2010-08-02 19:21:59 -04:00
}
2012-04-13 20:30:23 -04:00
rslog ( RSL_ALERT , pqisslzone , out2 ) ;
2010-08-02 19:21:59 -04:00
}
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::senddata() -> calling reset() " ) ;
2013-10-01 06:11:34 -04:00
reset_locked ( ) ;
2007-11-14 22:18:48 -05:00
return - 1 ;
}
else if ( err = = SSL_ERROR_WANT_WRITE )
{
2012-04-13 20:30:23 -04:00
out + = " SSL_write() SSL_ERROR_WANT_WRITE " ;
rslog ( RSL_WARNING , pqisslzone , out ) ;
2007-11-14 22:18:48 -05:00
return - 1 ;
}
else if ( err = = SSL_ERROR_WANT_READ )
{
2012-04-13 20:30:23 -04:00
out + = " SSL_write() SSL_ERROR_WANT_READ " ;
rslog ( RSL_WARNING , pqisslzone , out ) ;
//std::cerr << out << std::endl;
2007-11-14 22:18:48 -05:00
return - 1 ;
}
else
{
2012-04-13 20:30:23 -04:00
rs_sprintf_append ( out , " SSL_write() UNKNOWN ERROR: %d \n " , err ) ;
2007-11-14 22:18:48 -05:00
printSSLError ( ssl_connection , tmppktlen , err , ERR_get_error ( ) , out ) ;
2012-04-13 20:30:23 -04:00
out + = " \n \t Resetting! " ;
std : : cerr < < out < < std : : endl ;
rslog ( RSL_ALERT , pqisslzone , out ) ;
2007-11-14 22:18:48 -05:00
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::senddata() -> calling reset() " ) ;
2013-10-01 06:11:34 -04:00
reset_locked ( ) ;
2007-11-14 22:18:48 -05:00
return - 1 ;
}
}
return tmppktlen ;
}
int pqissl : : readdata ( void * data , int len )
{
2013-10-01 06:11:34 -04:00
RsStackMutex stack ( mSslMtx ) ; /**** LOCKED MUTEX ****/
2011-06-27 18:28:33 -04:00
# ifdef PQISSL_DEBUG
2009-07-21 16:14:31 -04:00
std : : cout < < " Reading data thread= " < < pthread_self ( ) < < " , ssl= " < < ( void * ) this < < std : : endl ;
# endif
2009-03-01 10:12:22 -05:00
// There is a do, because packets can be splitted into multiple ssl buffers
// when they are larger than 16384 bytes. Such packets have to be read in
// multiple slices.
2009-02-15 15:13:35 -05:00
do
2007-11-14 22:18:48 -05:00
{
2009-03-01 10:12:22 -05:00
int tmppktlen ;
2011-06-27 18:28:33 -04:00
# ifdef PQISSL_DEBUG
2009-07-21 16:14:31 -04:00
std : : cerr < < " calling SSL_read. len= " < < len < < " , total_len= " < < total_len < < std : : endl ;
# endif
2011-06-24 17:44:29 -04:00
tmppktlen = SSL_read ( ssl_connection , ( void * ) ( & ( ( ( uint8_t * ) data ) [ total_len ] ) ) , len - total_len ) ;
2011-06-27 18:28:33 -04:00
# ifdef PQISSL_DEBUG
2009-07-21 16:14:31 -04:00
std : : cerr < < " have read " < < tmppktlen < < " bytes " < < std : : endl ;
std : : cerr < < " data[0] = "
2011-06-24 17:44:29 -04:00
< < ( int ) ( ( uint8_t * ) data ) [ total_len + 0 ] < < " "
< < ( int ) ( ( uint8_t * ) data ) [ total_len + 1 ] < < " "
< < ( int ) ( ( uint8_t * ) data ) [ total_len + 2 ] < < " "
< < ( int ) ( ( uint8_t * ) data ) [ total_len + 3 ] < < " "
< < ( int ) ( ( uint8_t * ) data ) [ total_len + 4 ] < < " "
< < ( int ) ( ( uint8_t * ) data ) [ total_len + 5 ] < < " "
< < ( int ) ( ( uint8_t * ) data ) [ total_len + 6 ] < < " "
< < ( int ) ( ( uint8_t * ) data ) [ total_len + 7 ] < < std : : endl ;
2009-07-21 16:14:31 -04:00
# endif
2007-11-14 22:18:48 -05:00
2009-03-01 10:12:22 -05:00
// Need to catch errors.....
//
2009-02-15 15:13:35 -05:00
if ( tmppktlen < = 0 ) // probably needs a reset.
2007-11-14 22:18:48 -05:00
{
2012-04-13 20:30:23 -04:00
std : : string out ;
2009-03-20 19:43:24 -04:00
2009-02-15 15:13:35 -05:00
int error = SSL_get_error ( ssl_connection , tmppktlen ) ;
unsigned long err2 = ERR_get_error ( ) ;
2007-11-14 22:18:48 -05:00
2009-03-20 19:43:24 -04:00
//printSSLError(ssl_connection, tmppktlen, error, err2, out);
2009-02-15 15:13:35 -05:00
if ( ( error = = SSL_ERROR_ZERO_RETURN ) & & ( err2 = = 0 ) )
{
/* this code will be called when
* ( 1 ) moretoread - > returns true . +
* ( 2 ) SSL_read fails .
*
* There are two ways this can happen :
* ( 1 ) there is a little data on the socket , but not enough
* for a full SSL record , so there legimitately is no error , and the moretoread ( )
* was correct , but the read fails .
*
* ( 2 ) the socket has been closed correctly . this leads to moretoread ( ) - > true ,
* and ZERO error . . . . we catch this case by counting how many times
* it occurs in a row ( cos the other one will not ) .
*/
2010-07-13 08:13:56 -04:00
if ( n_read_zero = = 0 )
{
/* first read_zero */
mReadZeroTS = time ( NULL ) ;
}
2009-02-15 15:13:35 -05:00
+ + n_read_zero ;
2014-03-17 16:56:06 -04:00
out + = " pqissl::readdata() " + PeerId ( ) . toStdString ( ) ;
2012-04-13 20:30:23 -04:00
rs_sprintf_append ( out , " SSL_read() SSL_ERROR_ZERO_RETURN : nReadZero: %d " , n_read_zero ) ;
2009-02-15 15:13:35 -05:00
2010-07-13 08:13:56 -04:00
if ( ( PQISSL_MAX_READ_ZERO_COUNT < n_read_zero )
& & ( time ( NULL ) - mReadZeroTS > PQISSL_MAX_READ_ZERO_TIME ) )
2009-02-15 15:13:35 -05:00
{
2012-04-13 20:30:23 -04:00
out + = " Count passed Limit, shutting down! " ;
rs_sprintf_append ( out , " ReadZero Age: %ld " , time ( NULL ) - mReadZeroTS ) ;
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::readdata() -> calling reset() " ) ;
2013-10-01 06:11:34 -04:00
reset_locked ( ) ;
2009-02-15 15:13:35 -05:00
}
2012-04-13 20:30:23 -04:00
rslog ( RSL_ALERT , pqisslzone , out ) ;
2013-04-04 09:12:00 -04:00
//std::cerr << out << std::endl ;
2009-03-03 14:40:42 -05:00
return - 1 ;
2009-02-15 15:13:35 -05:00
}
/* the only real error we expect */
if ( error = = SSL_ERROR_SYSCALL )
2007-11-14 22:18:48 -05:00
{
2014-03-17 16:56:06 -04:00
out + = " pqissl::readdata() " + PeerId ( ) . toStdString ( ) ;
2012-04-13 20:30:23 -04:00
out + = " SSL_read() SSL_ERROR_SYSCALL " ;
out + = " SOCKET_DEAD -> calling reset() " ;
rs_sprintf_append ( out , " errno: %d " , errno ) ;
out + = " " + socket_errorType ( errno ) ;
rslog ( RSL_ALERT , pqisslzone , out ) ;
2010-08-02 19:21:59 -04:00
/* extra debugging - based on SSL_get_error() man page */
{
int syserr = errno ;
int sslerr = 0 ;
2012-04-13 20:30:23 -04:00
std : : string out2 ;
rs_sprintf ( out2 , " SSL_ERROR_SYSCALL, ret == %d errno: %d %s \n " , tmppktlen , syserr , socket_errorType ( syserr ) . c_str ( ) ) ;
2010-08-02 19:21:59 -04:00
while ( 0 ! = ( sslerr = ERR_get_error ( ) ) )
{
2012-04-13 20:30:23 -04:00
rs_sprintf_append ( out2 , " SSLERR:%d : " , sslerr ) ;
2010-08-02 19:21:59 -04:00
char sslbuf [ 256 ] = { 0 } ;
2012-04-13 20:30:23 -04:00
out2 + = ERR_error_string ( sslerr , sslbuf ) ;
out2 + = " \n " ;
2010-08-02 19:21:59 -04:00
}
2012-04-13 20:30:23 -04:00
rslog ( RSL_ALERT , pqisslzone , out2 ) ;
2010-08-02 19:21:59 -04:00
}
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::readdata() -> calling reset() " ) ;
2013-10-01 06:11:34 -04:00
reset_locked ( ) ;
2012-04-13 20:30:23 -04:00
std : : cerr < < out < < std : : endl ;
2009-02-15 15:13:35 -05:00
return - 1 ;
}
else if ( error = = SSL_ERROR_WANT_WRITE )
{
2012-04-13 20:30:23 -04:00
out + = " SSL_read() SSL_ERROR_WANT_WRITE " ;
rslog ( RSL_WARNING , pqisslzone , out ) ;
std : : cerr < < out < < std : : endl ;
2009-02-15 15:13:35 -05:00
return - 1 ;
}
2012-01-18 17:51:38 -05:00
else if ( error = = SSL_ERROR_WANT_READ )
{
// SSL_WANT_READ is not a crittical error. It's just a sign that
// the internal SSL buffer is not ready to accept more data. So -1
2013-06-24 17:23:50 -04:00
// is returned, and the connection will be retried as is on next
2012-01-18 17:51:38 -05:00
// call of readdata().
# ifdef PQISSL_DEBUG
2012-04-13 20:30:23 -04:00
out + = " SSL_read() SSL_ERROR_WANT_READ " ;
rslog ( RSL_DEBUG_BASIC , pqisslzone , out ) ;
2012-01-18 17:51:38 -05:00
# endif
2009-02-15 15:13:35 -05:00
return - 1 ;
}
else
{
2012-04-13 20:30:23 -04:00
rs_sprintf_append ( out , " SSL_read() UNKNOWN ERROR: %d Resetting! " , error ) ;
rslog ( RSL_ALERT , pqisslzone , out ) ;
std : : cerr < < out < < std : : endl ;
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::readdata() -> calling reset() " ) ;
2013-10-01 06:11:34 -04:00
reset_locked ( ) ;
2009-02-15 15:13:35 -05:00
return - 1 ;
2007-11-14 22:18:48 -05:00
}
2012-04-13 20:30:23 -04:00
rslog ( RSL_ALERT , pqisslzone , out ) ;
2009-02-15 15:13:35 -05:00
//exit(1);
2007-11-14 22:18:48 -05:00
}
else
2009-02-15 15:13:35 -05:00
total_len + = tmppktlen ;
} while ( total_len < len ) ;
2007-11-14 22:18:48 -05:00
2011-06-27 18:28:33 -04:00
# ifdef PQISSL_DEBUG
2009-07-21 16:14:31 -04:00
std : : cerr < < " pqissl: have read data of length " < < total_len < < " , expected is " < < len < < std : : endl ;
# endif
2009-02-15 15:13:35 -05:00
if ( len ! = total_len )
{
2012-04-13 20:30:23 -04:00
std : : string out ;
rs_sprintf ( out , " pqissl::readdata() Full Packet Not read! \n -> Expected len(%d) actually read(%d) " , len , total_len ) ;
std : : cerr < < out < < std : : endl ;
rslog ( RSL_WARNING , pqisslzone , out ) ;
2007-11-14 22:18:48 -05:00
}
2009-07-21 16:14:31 -04:00
total_len = 0 ; // reset the packet pointer as we have finished a packet.
2007-11-14 22:18:48 -05:00
n_read_zero = 0 ;
2009-02-15 15:13:35 -05:00
return len ; //tmppktlen;
2007-11-14 22:18:48 -05:00
}
// dummy function currently.
int pqissl : : netstatus ( )
{
return 1 ;
}
int pqissl : : isactive ( )
{
2014-12-16 16:46:07 -05:00
return active ; // no need to mutex this. It's atomic.
2007-11-14 22:18:48 -05:00
}
2013-10-01 06:11:34 -04:00
bool pqissl : : moretoread ( uint32_t usec )
2007-11-14 22:18:48 -05:00
{
2013-10-01 06:11:34 -04:00
RsStackMutex stack ( mSslMtx ) ; /**** LOCKED MUTEX ****/
2011-09-06 14:54:55 -04:00
# ifdef PQISSL_DEBUG
2007-11-14 22:18:48 -05:00
{
2012-04-13 20:30:23 -04:00
std : : string out ;
rs_sprintf ( out , " pqissl::moretoread() polling socket (%d) " , sockfd ) ;
rslog ( RSL_DEBUG_ALL , pqisslzone , out ) ;
2007-11-14 22:18:48 -05:00
}
2011-09-06 14:54:55 -04:00
# endif
2007-11-14 22:18:48 -05:00
fd_set ReadFDs , WriteFDs , ExceptFDs ;
FD_ZERO ( & ReadFDs ) ;
FD_ZERO ( & WriteFDs ) ;
FD_ZERO ( & ExceptFDs ) ;
FD_SET ( sockfd , & ReadFDs ) ;
2013-10-01 23:21:04 -04:00
// Dont set WriteFDs.
2007-11-14 22:18:48 -05:00
FD_SET ( sockfd , & ExceptFDs ) ;
struct timeval timeout ;
timeout . tv_sec = 0 ;
2013-10-01 06:11:34 -04:00
timeout . tv_usec = usec ;
2007-11-14 22:18:48 -05:00
if ( select ( sockfd + 1 , & ReadFDs , & WriteFDs , & ExceptFDs , & timeout ) < 0 )
{
2008-07-10 12:29:18 -04:00
rslog ( RSL_ALERT , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::moretoread() Select ERROR! " ) ;
return 0 ;
}
if ( FD_ISSET ( sockfd , & ExceptFDs ) )
{
// error - reset socket.
2008-07-10 12:29:18 -04:00
rslog ( RSL_ALERT , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::moretoread() Select Exception ERROR! " ) ;
// this is a definite bad socket!.
// reset.
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::moretoread() -> calling reset() " ) ;
2013-10-01 06:11:34 -04:00
reset_locked ( ) ;
2007-11-14 22:18:48 -05:00
return 0 ;
}
if ( FD_ISSET ( sockfd , & ReadFDs ) )
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_LOG_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::moretoread() Data to Read! " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
return 1 ;
}
else
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_ALL , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::moretoread() No Data to Read! " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
return 0 ;
}
}
2013-10-01 06:11:34 -04:00
bool pqissl : : cansend ( uint32_t usec )
2007-11-14 22:18:48 -05:00
{
2013-10-01 06:11:34 -04:00
RsStackMutex stack ( mSslMtx ) ; /**** LOCKED MUTEX ****/
2011-09-06 14:54:55 -04:00
# ifdef PQISSL_DEBUG
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_ALL , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::cansend() polling socket! " ) ;
2011-09-06 14:54:55 -04:00
# endif
2007-11-14 22:18:48 -05:00
// Interestingly - This code might be portable....
fd_set ReadFDs , WriteFDs , ExceptFDs ;
FD_ZERO ( & ReadFDs ) ;
FD_ZERO ( & WriteFDs ) ;
FD_ZERO ( & ExceptFDs ) ;
2013-10-01 23:21:04 -04:00
// Dont Set ReadFDs.
2007-11-14 22:18:48 -05:00
FD_SET ( sockfd , & WriteFDs ) ;
FD_SET ( sockfd , & ExceptFDs ) ;
struct timeval timeout ;
timeout . tv_sec = 0 ;
2013-10-01 06:11:34 -04:00
timeout . tv_usec = usec ;
2007-11-14 22:18:48 -05:00
if ( select ( sockfd + 1 , & ReadFDs , & WriteFDs , & ExceptFDs , & timeout ) < 0 )
{
// select error.
2008-07-10 12:29:18 -04:00
rslog ( RSL_ALERT , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::cansend() Select Error! " ) ;
return 0 ;
}
if ( FD_ISSET ( sockfd , & ExceptFDs ) )
{
// error - reset socket.
2008-07-10 12:29:18 -04:00
rslog ( RSL_ALERT , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::cansend() Select Exception! " ) ;
// this is a definite bad socket!.
// reset.
2011-08-06 08:27:23 -04:00
rslog ( RSL_ALERT , pqisslzone , " pqissl::cansend() -> calling reset() " ) ;
2013-10-01 06:11:34 -04:00
reset_locked ( ) ;
2007-11-14 22:18:48 -05:00
return 0 ;
}
if ( FD_ISSET ( sockfd , & WriteFDs ) )
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_DEBUG
2007-11-14 22:18:48 -05:00
// write can work.
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_ALL , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::cansend() Can Write! " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
return 1 ;
}
else
{
2012-01-18 17:51:38 -05:00
# ifdef PQISSL_DEBUG
2007-11-14 22:18:48 -05:00
// write can work.
2008-07-10 12:29:18 -04:00
rslog ( RSL_DEBUG_BASIC , pqisslzone ,
2007-11-14 22:18:48 -05:00
" pqissl::cansend() Can *NOT* Write! " ) ;
2012-01-18 17:51:38 -05:00
# endif
2007-11-14 22:18:48 -05:00
return 0 ;
}
}
2014-03-17 16:56:06 -04:00
RsFileHash pqissl : : gethash ( )
2007-11-14 22:18:48 -05:00
{
2014-03-17 16:56:06 -04:00
return RsFileHash ( ) ;
2007-11-14 22:18:48 -05:00
}
2008-01-25 01:36:40 -05:00
/********** End of Implementation of BinInterface ******************/
2007-11-14 22:18:48 -05:00
2013-09-26 19:53:06 -04:00
int pqissl : : net_internal_close ( int fd )
{
return unix_close ( fd ) ;
}
int pqissl : : net_internal_SSL_set_fd ( SSL * ssl , int fd )
{
return SSL_set_fd ( ssl , fd ) ;
}
int pqissl : : net_internal_fcntl_nonblock ( int fd )
{
return unix_fcntl_nonblock ( fd ) ;
}