2020-05-22 13:18:41 +00:00
/*
2023-06-12 02:10:32 +00:00
* Copyright ( c ) 2013 - 2023 , The PurpleI2P Project
2020-05-22 13:18:41 +00:00
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
2014-12-02 20:47:44 +00:00
# include <string.h>
2014-12-02 16:42:35 +00:00
# include "Log.h"
2014-12-03 02:45:01 +00:00
# include "ClientContext.h"
2016-11-04 01:31:21 +00:00
# include "util.h"
2014-12-02 15:34:02 +00:00
# include "BOB.h"
namespace i2p
{
namespace client
{
2018-01-06 03:48:51 +00:00
BOBI2PInboundTunnel : : BOBI2PInboundTunnel ( const boost : : asio : : ip : : tcp : : endpoint & ep , std : : shared_ptr < ClientDestination > localDestination ) :
2017-11-10 16:27:20 +00:00
BOBI2PTunnel ( localDestination ) , m_Acceptor ( localDestination - > GetService ( ) , ep )
2014-12-03 19:48:41 +00:00
{
}
BOBI2PInboundTunnel : : ~ BOBI2PInboundTunnel ( )
{
2014-12-05 00:29:20 +00:00
Stop ( ) ;
2014-12-03 19:48:41 +00:00
}
void BOBI2PInboundTunnel : : Start ( )
{
m_Acceptor . listen ( ) ;
Accept ( ) ;
}
void BOBI2PInboundTunnel : : Stop ( )
{
m_Acceptor . close ( ) ;
2015-01-07 18:09:59 +00:00
ClearHandlers ( ) ;
2014-12-03 19:48:41 +00:00
}
void BOBI2PInboundTunnel : : Accept ( )
{
2015-04-06 19:02:37 +00:00
auto receiver = std : : make_shared < AddressReceiver > ( ) ;
2015-04-06 18:41:07 +00:00
receiver - > socket = std : : make_shared < boost : : asio : : ip : : tcp : : socket > ( GetService ( ) ) ;
2014-12-07 14:48:03 +00:00
m_Acceptor . async_accept ( * receiver - > socket , std : : bind ( & BOBI2PInboundTunnel : : HandleAccept , this ,
std : : placeholders : : _1 , receiver ) ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-03 19:48:41 +00:00
2015-04-06 19:02:37 +00:00
void BOBI2PInboundTunnel : : HandleAccept ( const boost : : system : : error_code & ecode , std : : shared_ptr < AddressReceiver > receiver )
2014-12-03 19:48:41 +00:00
{
if ( ! ecode )
{
2018-01-06 03:48:51 +00:00
Accept ( ) ;
2014-12-07 14:48:03 +00:00
ReceiveAddress ( receiver ) ;
2014-12-03 19:48:41 +00:00
}
}
2015-04-06 19:02:37 +00:00
void BOBI2PInboundTunnel : : ReceiveAddress ( std : : shared_ptr < AddressReceiver > receiver )
2014-12-03 19:48:41 +00:00
{
2014-12-07 14:48:03 +00:00
receiver - > socket - > async_read_some ( boost : : asio : : buffer (
2020-03-01 10:25:50 +00:00
receiver - > buffer + receiver - > bufferOffset ,
BOB_COMMAND_BUFFER_SIZE - receiver - > bufferOffset ) ,
2018-01-06 03:48:51 +00:00
std : : bind ( & BOBI2PInboundTunnel : : HandleReceivedAddress , this ,
2020-03-01 10:25:50 +00:00
std : : placeholders : : _1 , std : : placeholders : : _2 , receiver ) ) ;
2014-12-03 19:48:41 +00:00
}
2018-01-06 03:48:51 +00:00
2014-12-03 19:48:41 +00:00
void BOBI2PInboundTunnel : : HandleReceivedAddress ( const boost : : system : : error_code & ecode , std : : size_t bytes_transferred ,
2015-04-06 19:02:37 +00:00
std : : shared_ptr < AddressReceiver > receiver )
2014-12-03 19:48:41 +00:00
{
if ( ecode )
2021-11-27 19:53:53 +00:00
LogPrint ( eLogError , " BOB: Inbound tunnel read error: " , ecode . message ( ) ) ;
2014-12-03 19:48:41 +00:00
else
{
2014-12-07 14:48:03 +00:00
receiver - > bufferOffset + = bytes_transferred ;
receiver - > buffer [ receiver - > bufferOffset ] = 0 ;
char * eol = strchr ( receiver - > buffer , ' \n ' ) ;
2014-12-03 19:48:41 +00:00
if ( eol )
{
* eol = 0 ;
2018-01-06 03:48:51 +00:00
if ( eol ! = receiver - > buffer & & eol [ - 1 ] = = ' \r ' ) eol [ - 1 ] = 0 ; // workaround for Transmission, it sends '\r\n' terminated address
2014-12-07 14:48:03 +00:00
receiver - > data = ( uint8_t * ) eol + 1 ;
receiver - > dataLen = receiver - > bufferOffset - ( eol - receiver - > buffer + 1 ) ;
2019-03-28 16:19:19 +00:00
auto addr = context . GetAddressBook ( ) . GetAddress ( receiver - > buffer ) ;
if ( ! addr )
2014-12-04 19:16:33 +00:00
{
2021-11-27 19:53:53 +00:00
LogPrint ( eLogError , " BOB: Address " , receiver - > buffer , " not found " ) ;
2014-12-04 19:16:33 +00:00
return ;
}
2019-03-28 16:19:19 +00:00
if ( addr - > IsIdentHash ( ) )
{
auto leaseSet = GetLocalDestination ( ) - > FindLeaseSet ( addr - > identHash ) ;
if ( leaseSet )
CreateConnection ( receiver , leaseSet ) ;
else
GetLocalDestination ( ) - > RequestDestination ( addr - > identHash ,
std : : bind ( & BOBI2PInboundTunnel : : HandleDestinationRequestComplete ,
this , std : : placeholders : : _1 , receiver ) ) ;
}
2014-12-03 19:48:41 +00:00
else
2019-03-28 16:19:19 +00:00
GetLocalDestination ( ) - > RequestDestinationWithEncryptedLeaseSet ( addr - > blindedPublicKey ,
std : : bind ( & BOBI2PInboundTunnel : : HandleDestinationRequestComplete ,
this , std : : placeholders : : _1 , receiver ) ) ;
2014-12-03 19:48:41 +00:00
}
else
{
2014-12-07 14:48:03 +00:00
if ( receiver - > bufferOffset < BOB_COMMAND_BUFFER_SIZE )
ReceiveAddress ( receiver ) ;
2014-12-06 20:31:39 +00:00
else
2021-11-27 19:53:53 +00:00
LogPrint ( eLogError , " BOB: Missing inbound address " ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-03 19:48:41 +00:00
}
}
2015-04-07 16:02:25 +00:00
void BOBI2PInboundTunnel : : HandleDestinationRequestComplete ( std : : shared_ptr < i2p : : data : : LeaseSet > leaseSet , std : : shared_ptr < AddressReceiver > receiver )
2014-12-03 19:48:41 +00:00
{
2015-04-07 16:02:25 +00:00
if ( leaseSet )
CreateConnection ( receiver , leaseSet ) ;
else
2015-12-18 06:27:35 +00:00
LogPrint ( eLogError , " BOB: LeaseSet for inbound destination not found " ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-03 19:48:41 +00:00
2015-04-06 19:02:37 +00:00
void BOBI2PInboundTunnel : : CreateConnection ( std : : shared_ptr < AddressReceiver > receiver , std : : shared_ptr < const i2p : : data : : LeaseSet > leaseSet )
2014-12-03 19:48:41 +00:00
{
2015-12-18 06:27:35 +00:00
LogPrint ( eLogDebug , " BOB: New inbound connection " ) ;
2014-12-07 14:48:03 +00:00
auto connection = std : : make_shared < I2PTunnelConnection > ( this , receiver - > socket , leaseSet ) ;
2015-01-07 18:09:59 +00:00
AddHandler ( connection ) ;
2014-12-07 14:48:03 +00:00
connection - > I2PConnect ( receiver - > data , receiver - > dataLen ) ;
2014-12-03 19:48:41 +00:00
}
2023-06-12 02:10:32 +00:00
BOBI2POutboundTunnel : : BOBI2POutboundTunnel ( const std : : string & outhost , uint16_t port ,
2015-02-24 20:40:50 +00:00
std : : shared_ptr < ClientDestination > localDestination , bool quiet ) : BOBI2PTunnel ( localDestination ) ,
2019-05-29 16:05:03 +00:00
m_Endpoint ( boost : : asio : : ip : : address : : from_string ( outhost ) , port ) , m_IsQuiet ( quiet )
2014-12-05 19:13:16 +00:00
{
}
2018-01-06 03:48:51 +00:00
2014-12-05 19:13:16 +00:00
void BOBI2POutboundTunnel : : Start ( )
{
Accept ( ) ;
}
void BOBI2POutboundTunnel : : Stop ( )
{
2015-01-07 18:09:59 +00:00
ClearHandlers ( ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-05 19:13:16 +00:00
void BOBI2POutboundTunnel : : Accept ( )
{
2018-01-06 03:48:51 +00:00
auto localDestination = GetLocalDestination ( ) ;
2014-12-05 19:13:16 +00:00
if ( localDestination )
localDestination - > AcceptStreams ( std : : bind ( & BOBI2POutboundTunnel : : HandleAccept , this , std : : placeholders : : _1 ) ) ;
else
2015-12-18 06:27:35 +00:00
LogPrint ( eLogError , " BOB: Local destination not set for server tunnel " ) ;
2014-12-05 19:13:16 +00:00
}
void BOBI2POutboundTunnel : : HandleAccept ( std : : shared_ptr < i2p : : stream : : Stream > stream )
{
if ( stream )
2018-01-06 03:48:51 +00:00
{
2022-10-09 01:41:28 +00:00
auto conn = std : : make_shared < I2PTunnelConnection > ( this , stream , m_Endpoint , m_IsQuiet ) ;
2015-01-07 18:09:59 +00:00
AddHandler ( conn ) ;
2014-12-05 19:13:16 +00:00
conn - > Connect ( ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-05 19:13:16 +00:00
}
2019-05-29 16:05:03 +00:00
BOBDestination : : BOBDestination ( std : : shared_ptr < ClientDestination > localDestination ,
const std : : string & nickname , const std : : string & inhost , const std : : string & outhost ,
2023-06-12 02:10:32 +00:00
const uint16_t inport , const uint16_t outport , const bool quiet ) :
2018-01-06 03:48:51 +00:00
m_LocalDestination ( localDestination ) ,
2019-05-29 16:05:03 +00:00
m_OutboundTunnel ( nullptr ) , m_InboundTunnel ( nullptr ) ,
m_Nickname ( nickname ) , m_InHost ( inhost ) , m_OutHost ( outhost ) ,
2022-06-13 13:53:16 +00:00
m_InPort ( inport ) , m_OutPort ( outport ) , m_Quiet ( quiet ) , m_IsRunning ( false )
2014-12-07 02:23:43 +00:00
{
}
2018-01-06 03:48:51 +00:00
2014-12-07 02:23:43 +00:00
BOBDestination : : ~ BOBDestination ( )
{
delete m_OutboundTunnel ;
delete m_InboundTunnel ;
2015-02-24 20:40:50 +00:00
i2p : : client : : context . DeleteLocalDestination ( m_LocalDestination ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-07 02:23:43 +00:00
void BOBDestination : : Start ( )
{
if ( m_OutboundTunnel ) m_OutboundTunnel - > Start ( ) ;
if ( m_InboundTunnel ) m_InboundTunnel - > Start ( ) ;
2022-06-13 13:53:16 +00:00
m_IsRunning = true ;
2014-12-07 02:23:43 +00:00
}
2018-01-06 03:48:51 +00:00
2014-12-07 02:23:43 +00:00
void BOBDestination : : Stop ( )
2018-01-06 03:48:51 +00:00
{
2014-12-08 02:04:02 +00:00
StopTunnels ( ) ;
2015-02-24 20:40:50 +00:00
m_LocalDestination - > Stop ( ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-05 19:13:16 +00:00
2014-12-08 02:04:02 +00:00
void BOBDestination : : StopTunnels ( )
{
2022-06-13 13:53:16 +00:00
m_IsRunning = false ;
2014-12-08 02:04:02 +00:00
if ( m_OutboundTunnel )
2018-01-06 03:48:51 +00:00
{
2014-12-08 02:04:02 +00:00
m_OutboundTunnel - > Stop ( ) ;
delete m_OutboundTunnel ;
m_OutboundTunnel = nullptr ;
2018-01-06 03:48:51 +00:00
}
2014-12-08 02:04:02 +00:00
if ( m_InboundTunnel )
2018-01-06 03:48:51 +00:00
{
2014-12-08 02:04:02 +00:00
m_InboundTunnel - > Stop ( ) ;
delete m_InboundTunnel ;
m_InboundTunnel = nullptr ;
2018-01-06 03:48:51 +00:00
}
}
2023-06-12 02:10:32 +00:00
void BOBDestination : : CreateInboundTunnel ( uint16_t port , const std : : string & inhost )
2014-12-07 02:23:43 +00:00
{
2014-12-08 02:04:02 +00:00
if ( ! m_InboundTunnel )
2017-11-10 16:27:20 +00:00
{
2019-05-29 16:05:03 +00:00
// update inport and inhost (user can stop tunnel and change)
m_InPort = port ;
m_InHost = inhost ;
2017-11-10 16:27:20 +00:00
boost : : asio : : ip : : tcp : : endpoint ep ( boost : : asio : : ip : : tcp : : v4 ( ) , port ) ;
2019-05-29 16:05:03 +00:00
if ( ! inhost . empty ( ) )
2017-11-10 16:27:20 +00:00
{
boost : : system : : error_code ec ;
2019-05-29 16:05:03 +00:00
auto addr = boost : : asio : : ip : : address : : from_string ( inhost , ec ) ;
2017-11-10 16:27:20 +00:00
if ( ! ec )
ep . address ( addr ) ;
else
2018-01-06 03:48:51 +00:00
LogPrint ( eLogError , " BOB: " , ec . message ( ) ) ;
}
2017-11-10 16:27:20 +00:00
m_InboundTunnel = new BOBI2PInboundTunnel ( ep , m_LocalDestination ) ;
}
2014-12-07 02:23:43 +00:00
}
2018-01-06 03:48:51 +00:00
2023-06-12 02:10:32 +00:00
void BOBDestination : : CreateOutboundTunnel ( const std : : string & outhost , uint16_t port , bool quiet )
2014-12-07 02:23:43 +00:00
{
2014-12-08 02:04:02 +00:00
if ( ! m_OutboundTunnel )
2019-05-29 16:05:03 +00:00
{
// update outport and outhost (user can stop tunnel and change)
m_OutPort = port ;
m_OutHost = outhost ;
m_OutboundTunnel = new BOBI2POutboundTunnel ( outhost , port , m_LocalDestination , quiet ) ;
}
2018-01-06 03:48:51 +00:00
}
BOBCommandSession : : BOBCommandSession ( BOBCommandChannel & owner ) :
2016-07-19 15:08:28 +00:00
m_Owner ( owner ) , m_Socket ( m_Owner . GetService ( ) ) ,
2019-05-29 16:05:03 +00:00
m_ReceiveBuffer ( BOB_COMMAND_BUFFER_SIZE + 1 ) , m_SendBuffer ( BOB_COMMAND_BUFFER_SIZE + 1 ) ,
m_IsOpen ( true ) , m_IsQuiet ( false ) , m_IsActive ( false ) ,
2016-07-11 18:35:59 +00:00
m_InPort ( 0 ) , m_OutPort ( 0 ) , m_CurrentDestination ( nullptr )
2014-12-02 16:42:35 +00:00
{
}
2014-12-02 20:47:44 +00:00
BOBCommandSession : : ~ BOBCommandSession ( )
{
}
2014-12-02 21:45:51 +00:00
void BOBCommandSession : : Terminate ( )
{
m_Socket . close ( ) ;
2018-01-06 03:48:51 +00:00
m_IsOpen = false ;
2014-12-02 21:45:51 +00:00
}
2014-12-02 20:47:44 +00:00
void BOBCommandSession : : Receive ( )
{
2019-05-29 16:05:03 +00:00
boost : : asio : : async_read_until ( m_Socket , m_ReceiveBuffer , ' \n ' ,
std : : bind ( & BOBCommandSession : : HandleReceivedLine , shared_from_this ( ) ,
std : : placeholders : : _1 , std : : placeholders : : _2 ) ) ;
2014-12-02 20:47:44 +00:00
}
2020-03-01 10:25:50 +00:00
2019-05-29 16:05:03 +00:00
void BOBCommandSession : : HandleReceivedLine ( const boost : : system : : error_code & ecode , std : : size_t bytes_transferred )
2014-12-02 20:47:44 +00:00
{
2019-05-29 16:05:03 +00:00
if ( ecode )
2014-12-02 21:45:51 +00:00
{
2021-11-27 19:53:53 +00:00
LogPrint ( eLogError , " BOB: Command channel read error: " , ecode . message ( ) ) ;
2014-12-05 00:29:20 +00:00
if ( ecode ! = boost : : asio : : error : : operation_aborted )
Terminate ( ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-02 20:47:44 +00:00
else
2018-01-06 03:48:51 +00:00
{
2019-05-29 16:05:03 +00:00
std : : string line ;
2020-03-01 10:25:50 +00:00
2019-05-29 16:05:03 +00:00
std : : istream is ( & m_ReceiveBuffer ) ;
std : : getline ( is , line ) ;
2020-03-01 10:25:50 +00:00
2019-05-29 16:05:03 +00:00
std : : string command , operand ;
std : : istringstream iss ( line ) ;
iss > > command > > operand ;
2020-03-01 10:25:50 +00:00
2019-05-29 16:05:03 +00:00
// process command
auto & handlers = m_Owner . GetCommandHandlers ( ) ;
auto it = handlers . find ( command ) ;
if ( it ! = handlers . end ( ) )
2014-12-02 20:47:44 +00:00
{
2019-05-29 16:05:03 +00:00
( this - > * ( it - > second ) ) ( operand . c_str ( ) , operand . length ( ) ) ;
2014-12-02 20:47:44 +00:00
}
else
{
2021-11-27 19:53:53 +00:00
LogPrint ( eLogError , " BOB: Unknown command " , command . c_str ( ) ) ;
2019-05-29 16:05:03 +00:00
SendReplyError ( " unknown command " ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-02 21:45:51 +00:00
}
}
2019-05-29 16:05:03 +00:00
void BOBCommandSession : : Send ( )
2014-12-02 21:45:51 +00:00
{
2019-05-29 16:05:03 +00:00
boost : : asio : : async_write ( m_Socket , m_SendBuffer ,
2014-12-02 21:45:51 +00:00
boost : : asio : : transfer_all ( ) ,
2018-01-06 03:48:51 +00:00
std : : bind ( & BOBCommandSession : : HandleSent , shared_from_this ( ) ,
2014-12-02 21:45:51 +00:00
std : : placeholders : : _1 , std : : placeholders : : _2 ) ) ;
}
void BOBCommandSession : : HandleSent ( const boost : : system : : error_code & ecode , std : : size_t bytes_transferred )
{
if ( ecode )
2019-05-29 16:05:03 +00:00
{
2021-11-27 19:53:53 +00:00
LogPrint ( eLogError , " BOB: Command channel send error: " , ecode . message ( ) ) ;
2014-12-05 00:29:20 +00:00
if ( ecode ! = boost : : asio : : error : : operation_aborted )
Terminate ( ) ;
2014-12-02 21:45:51 +00:00
}
else
{
2014-12-02 20:47:44 +00:00
if ( m_IsOpen )
Receive ( ) ;
2014-12-02 21:45:51 +00:00
else
2018-01-06 03:48:51 +00:00
Terminate ( ) ;
2014-12-02 20:47:44 +00:00
}
}
2014-12-02 21:45:51 +00:00
void BOBCommandSession : : SendReplyOK ( const char * msg )
{
2019-05-29 16:05:03 +00:00
std : : ostream os ( & m_SendBuffer ) ;
os < < " OK " ;
if ( msg )
{
os < < " " < < msg ;
}
os < < std : : endl ;
Send ( ) ;
2014-12-02 21:45:51 +00:00
}
void BOBCommandSession : : SendReplyError ( const char * msg )
{
2019-05-29 16:05:03 +00:00
std : : ostream os ( & m_SendBuffer ) ;
os < < " ERROR " < < msg < < std : : endl ;
Send ( ) ;
2014-12-02 21:45:51 +00:00
}
2018-01-06 03:48:51 +00:00
2014-12-05 21:03:43 +00:00
void BOBCommandSession : : SendVersion ( )
{
2019-05-29 16:05:03 +00:00
std : : ostream os ( & m_SendBuffer ) ;
os < < " BOB 00.00.10 " < < std : : endl ;
SendReplyOK ( ) ;
}
2019-06-25 15:59:44 +00:00
void BOBCommandSession : : SendRaw ( const char * data )
2019-05-29 16:05:03 +00:00
{
std : : ostream os ( & m_SendBuffer ) ;
2019-06-25 15:59:44 +00:00
os < < data < < std : : endl ;
2019-05-29 16:05:03 +00:00
}
2020-03-01 10:25:50 +00:00
2023-07-06 17:08:39 +00:00
void BOBCommandSession : : BuildStatusLine ( bool currentTunnel , std : : shared_ptr < BOBDestination > dest , std : : string & out )
2019-05-29 16:05:03 +00:00
{
// helper lambdas
2019-06-10 21:04:59 +00:00
const auto issetStr = [ ] ( const std : : string & str ) { return str . empty ( ) ? " not_set " : str ; } ; // for inhost, outhost
const auto issetNum = [ & issetStr ] ( const int p ) { return issetStr ( p = = 0 ? " " : std : : to_string ( p ) ) ; } ; // for inport, outport
2019-05-29 16:05:03 +00:00
const auto destExists = [ ] ( const BOBDestination * const dest ) { return dest ! = nullptr ; } ;
2023-07-06 17:08:39 +00:00
const auto destReady = [ ] ( const BOBDestination * const dest ) { return dest & & dest - > IsRunning ( ) ; } ;
2019-05-29 16:05:03 +00:00
const auto bool_str = [ ] ( const bool v ) { return v ? " true " : " false " ; } ; // bool -> str
2020-03-01 10:25:50 +00:00
2019-05-29 16:05:03 +00:00
// tunnel info
const std : : string nickname = currentTunnel ? m_Nickname : dest - > GetNickname ( ) ;
const bool quiet = currentTunnel ? m_IsQuiet : dest - > GetQuiet ( ) ;
2019-06-10 21:04:59 +00:00
const std : : string inhost = issetStr ( currentTunnel ? m_InHost : dest - > GetInHost ( ) ) ;
const std : : string outhost = issetStr ( currentTunnel ? m_OutHost : dest - > GetOutHost ( ) ) ;
2019-05-29 16:05:03 +00:00
const std : : string inport = issetNum ( currentTunnel ? m_InPort : dest - > GetInPort ( ) ) ;
const std : : string outport = issetNum ( currentTunnel ? m_OutPort : dest - > GetOutPort ( ) ) ;
2023-07-06 17:08:39 +00:00
const bool keys = destExists ( dest . get ( ) ) ; // key must exist when destination is created
const bool starting = destExists ( dest . get ( ) ) & & ! destReady ( dest . get ( ) ) ;
const bool running = destExists ( dest . get ( ) ) & & destReady ( dest . get ( ) ) ;
2019-05-29 16:05:03 +00:00
const bool stopping = false ;
2020-03-01 10:25:50 +00:00
2019-05-29 16:05:03 +00:00
// build line
std : : stringstream ss ;
2019-06-25 15:59:44 +00:00
ss < < " DATA "
< < " NICKNAME: " < < nickname < < " " < < " STARTING: " < < bool_str ( starting ) < < " "
2019-05-29 16:05:03 +00:00
< < " RUNNING: " < < bool_str ( running ) < < " " < < " STOPPING: " < < bool_str ( stopping ) < < " "
< < " KEYS: " < < bool_str ( keys ) < < " " < < " QUIET: " < < bool_str ( quiet ) < < " "
< < " INPORT: " < < inport < < " " < < " INHOST: " < < inhost < < " "
< < " OUTPORT: " < < outport < < " " < < " OUTHOST: " < < outhost ;
out = ss . str ( ) ;
2014-12-06 03:25:31 +00:00
}
2018-01-06 03:48:51 +00:00
2014-12-02 20:47:44 +00:00
void BOBCommandSession : : ZapCommandHandler ( const char * operand , size_t len )
{
LogPrint ( eLogDebug , " BOB: zap " ) ;
2014-12-02 21:45:51 +00:00
Terminate ( ) ;
}
void BOBCommandSession : : QuitCommandHandler ( const char * operand , size_t len )
{
LogPrint ( eLogDebug , " BOB: quit " ) ;
2014-12-02 20:47:44 +00:00
m_IsOpen = false ;
2014-12-02 21:45:51 +00:00
SendReplyOK ( " Bye! " ) ;
2014-12-02 20:47:44 +00:00
}
2014-12-03 02:45:01 +00:00
void BOBCommandSession : : StartCommandHandler ( const char * operand , size_t len )
{
LogPrint ( eLogDebug , " BOB: start " , m_Nickname ) ;
2016-07-21 18:02:13 +00:00
if ( m_IsActive )
{
SendReplyError ( " tunnel is active " ) ;
2018-01-06 03:48:51 +00:00
return ;
2016-07-21 18:02:13 +00:00
}
2019-05-29 16:05:03 +00:00
if ( ! m_Keys . GetPublic ( ) ) // keys are set ?
{
SendReplyError ( " Keys must be set. " ) ;
return ;
}
if ( m_InPort = = 0
& & m_OutHost . empty ( ) & & m_OutPort = = 0 )
{
SendReplyError ( " (inhost):inport or outhost:outport must be set. " ) ;
return ;
}
if ( ! m_InHost . empty ( ) )
{
// TODO: FIXME: temporary validation, until hostname support is added
boost : : system : : error_code ec ;
boost : : asio : : ip : : address : : from_string ( m_InHost , ec ) ;
if ( ec )
{
SendReplyError ( " inhost must be a valid IPv4 address. " ) ;
return ;
}
}
if ( ! m_OutHost . empty ( ) )
{
// TODO: FIXME: temporary validation, until hostname support is added
boost : : system : : error_code ec ;
boost : : asio : : ip : : address : : from_string ( m_OutHost , ec ) ;
if ( ec )
{
SendReplyError ( " outhost must be a IPv4 address. " ) ;
return ;
}
}
2020-03-01 10:25:50 +00:00
2014-12-08 02:04:02 +00:00
if ( ! m_CurrentDestination )
2018-01-06 03:48:51 +00:00
{
2023-07-06 17:08:39 +00:00
m_CurrentDestination = std : : make_shared < BOBDestination > ( i2p : : client : : context . CreateNewLocalDestination ( m_Keys , true , & m_Options ) , // deleted in clear command
2020-03-01 10:25:50 +00:00
m_Nickname , m_InHost , m_OutHost , m_InPort , m_OutPort , m_IsQuiet ) ;
2014-12-08 02:04:02 +00:00
m_Owner . AddDestination ( m_Nickname , m_CurrentDestination ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-07 02:23:43 +00:00
if ( m_InPort )
2019-05-29 16:05:03 +00:00
m_CurrentDestination - > CreateInboundTunnel ( m_InPort , m_InHost ) ;
if ( m_OutPort & & ! m_OutHost . empty ( ) )
m_CurrentDestination - > CreateOutboundTunnel ( m_OutHost , m_OutPort , m_IsQuiet ) ;
2018-01-06 03:48:51 +00:00
m_CurrentDestination - > Start ( ) ;
2016-07-21 18:02:13 +00:00
SendReplyOK ( " Tunnel starting " ) ;
m_IsActive = true ;
2018-01-06 03:48:51 +00:00
}
2016-07-11 18:35:59 +00:00
2014-12-03 20:24:30 +00:00
void BOBCommandSession : : StopCommandHandler ( const char * operand , size_t len )
{
2016-07-21 18:02:13 +00:00
LogPrint ( eLogDebug , " BOB: stop " , m_Nickname ) ;
if ( ! m_IsActive )
{
SendReplyError ( " tunnel is inactive " ) ;
return ;
}
2014-12-07 02:23:43 +00:00
auto dest = m_Owner . FindDestination ( m_Nickname ) ;
if ( dest )
2014-12-03 20:24:30 +00:00
{
2014-12-08 02:04:02 +00:00
dest - > StopTunnels ( ) ;
2016-07-21 18:02:13 +00:00
SendReplyOK ( " Tunnel stopping " ) ;
2014-12-03 20:24:30 +00:00
}
else
SendReplyError ( " tunnel not found " ) ;
2016-07-21 18:02:13 +00:00
m_IsActive = false ;
2018-01-06 03:48:51 +00:00
}
2014-12-03 02:45:01 +00:00
void BOBCommandSession : : SetNickCommandHandler ( const char * operand , size_t len )
{
2014-12-07 02:23:43 +00:00
LogPrint ( eLogDebug , " BOB: setnick " , operand ) ;
2022-06-13 13:53:16 +00:00
if ( * operand )
{
auto dest = m_Owner . FindDestination ( operand ) ;
if ( ! dest )
{
m_Nickname = operand ;
std : : string msg ( " Nickname set to " ) ;
msg + = m_Nickname ;
SendReplyOK ( msg . c_str ( ) ) ;
}
else
SendReplyError ( " tunnel is active " ) ;
}
else
SendReplyError ( " no nickname has been set " ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-03 02:45:01 +00:00
2014-12-03 20:24:30 +00:00
void BOBCommandSession : : GetNickCommandHandler ( const char * operand , size_t len )
{
2014-12-07 02:23:43 +00:00
LogPrint ( eLogDebug , " BOB: getnick " , operand ) ;
2022-06-13 13:53:16 +00:00
if ( * operand )
2018-01-06 03:48:51 +00:00
{
2022-06-13 13:53:16 +00:00
m_CurrentDestination = m_Owner . FindDestination ( operand ) ;
if ( m_CurrentDestination )
{
m_Keys = m_CurrentDestination - > GetKeys ( ) ;
m_IsActive = m_CurrentDestination - > IsRunning ( ) ;
m_Nickname = operand ;
}
if ( m_Nickname = = operand )
{
std : : string msg ( " Nickname set to " ) ;
msg + = m_Nickname ;
SendReplyOK ( msg . c_str ( ) ) ;
}
else
SendReplyError ( " no nickname has been set " ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-03 20:24:30 +00:00
else
2018-01-06 03:48:51 +00:00
SendReplyError ( " no nickname has been set " ) ;
}
2014-12-03 20:24:30 +00:00
2014-12-03 02:45:01 +00:00
void BOBCommandSession : : NewkeysCommandHandler ( const char * operand , size_t len )
{
2018-01-06 03:48:51 +00:00
LogPrint ( eLogDebug , " BOB: newkeys " ) ;
2017-12-01 18:43:00 +00:00
i2p : : data : : SigningKeyType signatureType = i2p : : data : : SIGNING_KEY_TYPE_DSA_SHA1 ;
i2p : : data : : CryptoKeyType cryptoType = i2p : : data : : CRYPTO_KEY_TYPE_ELGAMAL ;
2017-12-01 21:25:32 +00:00
if ( * operand )
{
try
{
char * operand1 = ( char * ) strchr ( operand , ' ' ) ;
2018-01-06 03:48:51 +00:00
if ( operand1 )
2017-12-01 21:25:32 +00:00
{
* operand1 = 0 ; operand1 + + ;
cryptoType = std : : stoi ( operand1 ) ;
}
2018-01-06 03:48:51 +00:00
signatureType = std : : stoi ( operand ) ;
2017-12-01 21:25:32 +00:00
}
catch ( std : : invalid_argument & ex )
{
2021-11-27 19:53:53 +00:00
LogPrint ( eLogWarning , " BOB: Error on newkeys: " , ex . what ( ) ) ;
2017-12-01 21:25:32 +00:00
}
2018-01-06 03:48:51 +00:00
}
2022-10-24 19:12:07 +00:00
m_Keys = i2p : : data : : PrivateKeys : : CreateRandomKeys ( signatureType , cryptoType , true ) ;
2015-11-03 14:15:49 +00:00
SendReplyOK ( m_Keys . GetPublic ( ) - > ToBase64 ( ) . c_str ( ) ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-03 02:45:01 +00:00
2014-12-04 02:01:40 +00:00
void BOBCommandSession : : SetkeysCommandHandler ( const char * operand , size_t len )
{
2014-12-07 02:23:43 +00:00
LogPrint ( eLogDebug , " BOB: setkeys " , operand ) ;
2022-06-13 13:53:16 +00:00
if ( * operand & & m_Keys . FromBase64 ( operand ) )
2017-03-25 20:53:20 +00:00
SendReplyOK ( m_Keys . GetPublic ( ) - > ToBase64 ( ) . c_str ( ) ) ;
else
SendReplyError ( " invalid keys " ) ;
2014-12-04 02:01:40 +00:00
}
2018-01-06 03:48:51 +00:00
2014-12-04 02:01:40 +00:00
void BOBCommandSession : : GetkeysCommandHandler ( const char * operand , size_t len )
2018-01-06 03:48:51 +00:00
{
2014-12-04 02:01:40 +00:00
LogPrint ( eLogDebug , " BOB: getkeys " ) ;
2016-10-11 14:18:42 +00:00
if ( m_Keys . GetPublic ( ) ) // keys are set ?
SendReplyOK ( m_Keys . ToBase64 ( ) . c_str ( ) ) ;
else
SendReplyError ( " keys are not set " ) ;
}
2014-12-04 02:01:40 +00:00
void BOBCommandSession : : GetdestCommandHandler ( const char * operand , size_t len )
{
LogPrint ( eLogDebug , " BOB: getdest " ) ;
2017-11-10 14:49:50 +00:00
if ( m_Keys . GetPublic ( ) ) // keys are set ?
SendReplyOK ( m_Keys . GetPublic ( ) - > ToBase64 ( ) . c_str ( ) ) ;
else
SendReplyError ( " keys are not set " ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-03 02:45:01 +00:00
void BOBCommandSession : : OuthostCommandHandler ( const char * operand , size_t len )
{
2014-12-07 02:23:43 +00:00
LogPrint ( eLogDebug , " BOB: outhost " , operand ) ;
2022-06-13 13:53:16 +00:00
if ( * operand )
{
m_OutHost = operand ;
SendReplyOK ( " outhost set " ) ;
}
else
SendReplyError ( " empty outhost " ) ;
2014-12-03 02:45:01 +00:00
}
2018-01-06 03:48:51 +00:00
2014-12-03 02:45:01 +00:00
void BOBCommandSession : : OutportCommandHandler ( const char * operand , size_t len )
{
2014-12-07 02:23:43 +00:00
LogPrint ( eLogDebug , " BOB: outport " , operand ) ;
2022-06-13 13:53:16 +00:00
if ( * operand )
{
2023-06-12 02:10:32 +00:00
int port = std : : stoi ( operand ) ;
if ( port > = 0 & & port < 65536 )
{
m_OutPort = port ;
2022-06-13 13:53:16 +00:00
SendReplyOK ( " outbound port set " ) ;
2023-06-12 02:10:32 +00:00
}
2022-06-13 13:53:16 +00:00
else
SendReplyError ( " port out of range " ) ;
}
2016-07-21 18:02:13 +00:00
else
2022-06-13 13:53:16 +00:00
SendReplyError ( " empty outport " ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-03 20:02:19 +00:00
void BOBCommandSession : : InhostCommandHandler ( const char * operand , size_t len )
{
2014-12-07 02:23:43 +00:00
LogPrint ( eLogDebug , " BOB: inhost " , operand ) ;
2022-06-13 13:53:16 +00:00
if ( * operand )
{
m_InHost = operand ;
SendReplyOK ( " inhost set " ) ;
}
else
SendReplyError ( " empty inhost " ) ;
2014-12-03 20:02:19 +00:00
}
2018-01-06 03:48:51 +00:00
2014-12-03 20:02:19 +00:00
void BOBCommandSession : : InportCommandHandler ( const char * operand , size_t len )
{
2014-12-07 02:23:43 +00:00
LogPrint ( eLogDebug , " BOB: inport " , operand ) ;
2022-06-13 13:53:16 +00:00
if ( * operand )
{
2023-06-12 02:10:32 +00:00
int port = std : : stoi ( operand ) ;
if ( port > = 0 & & port < 65536 )
{
m_InPort = port ;
2022-06-13 13:53:16 +00:00
SendReplyOK ( " inbound port set " ) ;
2023-06-12 02:10:32 +00:00
}
2022-06-13 13:53:16 +00:00
else
SendReplyError ( " port out of range " ) ;
}
2016-07-21 18:02:13 +00:00
else
2022-06-13 13:53:16 +00:00
SendReplyError ( " empty inport " ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-05 19:13:16 +00:00
void BOBCommandSession : : QuietCommandHandler ( const char * operand , size_t len )
{
LogPrint ( eLogDebug , " BOB: quiet " ) ;
2016-07-21 18:02:13 +00:00
if ( m_Nickname . length ( ) > 0 )
{
if ( ! m_IsActive )
{
m_IsQuiet = true ;
SendReplyOK ( " Quiet set " ) ;
}
else
SendReplyError ( " tunnel is active " ) ;
}
else
SendReplyError ( " no nickname has been set " ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-05 21:03:43 +00:00
void BOBCommandSession : : LookupCommandHandler ( const char * operand , size_t len )
{
2014-12-07 02:23:43 +00:00
LogPrint ( eLogDebug , " BOB: lookup " , operand ) ;
2022-06-13 13:53:16 +00:00
if ( * operand )
2020-03-01 10:25:50 +00:00
{
2022-06-13 13:53:16 +00:00
auto addr = context . GetAddressBook ( ) . GetAddress ( operand ) ;
if ( ! addr )
2020-03-01 10:25:50 +00:00
{
2022-06-13 13:53:16 +00:00
SendReplyError ( " Address Not found " ) ;
2019-03-28 16:19:19 +00:00
return ;
}
2023-07-06 17:08:39 +00:00
auto localDestination = ( m_CurrentDestination & & m_CurrentDestination - > IsRunning ( ) ) ?
m_CurrentDestination - > GetLocalDestination ( ) : i2p : : client : : context . GetSharedLocalDestination ( ) ;
2023-07-06 16:30:33 +00:00
if ( ! localDestination )
{
SendReplyError ( " No local destination " ) ;
return ;
}
2022-06-13 13:53:16 +00:00
if ( addr - > IsIdentHash ( ) )
2020-03-01 10:25:50 +00:00
{
2022-06-13 13:53:16 +00:00
// we might have leaseset already
auto leaseSet = localDestination - > FindLeaseSet ( addr - > identHash ) ;
if ( leaseSet )
{
SendReplyOK ( leaseSet - > GetIdentity ( ) - > ToBase64 ( ) . c_str ( ) ) ;
return ;
}
}
// trying to request
auto s = shared_from_this ( ) ;
auto requstCallback = [ s ] ( std : : shared_ptr < i2p : : data : : LeaseSet > ls )
{
if ( ls )
s - > SendReplyOK ( ls - > GetIdentity ( ) - > ToBase64 ( ) . c_str ( ) ) ;
else
s - > SendReplyError ( " LeaseSet Not found " ) ;
} ;
if ( addr - > IsIdentHash ( ) )
localDestination - > RequestDestination ( addr - > identHash , requstCallback ) ;
else
localDestination - > RequestDestinationWithEncryptedLeaseSet ( addr - > blindedPublicKey , requstCallback ) ;
}
2019-03-28 16:19:19 +00:00
else
2022-06-13 13:53:16 +00:00
SendReplyError ( " empty lookup address " ) ;
2014-12-05 21:03:43 +00:00
}
2021-02-21 21:20:57 +00:00
void BOBCommandSession : : LookupLocalCommandHandler ( const char * operand , size_t len )
{
LogPrint ( eLogDebug , " BOB: lookup local " , operand ) ;
2022-06-13 13:53:16 +00:00
if ( * operand )
2021-02-21 21:20:57 +00:00
{
2022-06-13 13:53:16 +00:00
auto addr = context . GetAddressBook ( ) . GetAddress ( operand ) ;
if ( ! addr )
{
SendReplyError ( " Address Not found " ) ;
return ;
}
auto ls = i2p : : data : : netdb . FindLeaseSet ( addr - > identHash ) ;
if ( ls )
SendReplyOK ( ls - > GetIdentity ( ) - > ToBase64 ( ) . c_str ( ) ) ;
else
SendReplyError ( " Local LeaseSet Not found " ) ;
2021-02-21 21:20:57 +00:00
}
else
2022-06-13 13:53:16 +00:00
SendReplyError ( " empty lookup address " ) ;
2021-02-21 21:20:57 +00:00
}
2021-11-27 20:30:35 +00:00
2014-12-06 00:16:54 +00:00
void BOBCommandSession : : ClearCommandHandler ( const char * operand , size_t len )
{
LogPrint ( eLogDebug , " BOB: clear " ) ;
2014-12-08 02:04:02 +00:00
m_Owner . DeleteDestination ( m_Nickname ) ;
2016-07-21 18:02:13 +00:00
m_Nickname = " " ;
2014-12-06 00:16:54 +00:00
SendReplyOK ( " cleared " ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-05 21:03:43 +00:00
2014-12-06 03:25:31 +00:00
void BOBCommandSession : : ListCommandHandler ( const char * operand , size_t len )
{
LogPrint ( eLogDebug , " BOB: list " ) ;
2019-05-29 16:05:03 +00:00
std : : string statusLine ;
bool sentCurrent = false ;
2016-08-05 18:23:54 +00:00
const auto & destinations = m_Owner . GetDestinations ( ) ;
for ( const auto & it : destinations )
2019-05-29 16:05:03 +00:00
{
BuildStatusLine ( false , it . second , statusLine ) ;
2019-06-25 15:59:44 +00:00
SendRaw ( statusLine . c_str ( ) ) ;
2019-05-29 16:05:03 +00:00
if ( m_Nickname . compare ( it . second - > GetNickname ( ) ) = = 0 )
sentCurrent = true ;
}
if ( ! sentCurrent & & ! m_Nickname . empty ( ) )
{
2019-06-25 17:04:27 +00:00
// add the current tunnel to the list.
// this is for the incomplete tunnel which has not been started yet.
2019-05-29 16:47:35 +00:00
BuildStatusLine ( true , m_CurrentDestination , statusLine ) ;
2019-06-25 15:59:44 +00:00
SendRaw ( statusLine . c_str ( ) ) ;
2019-05-29 16:05:03 +00:00
}
2014-12-06 03:25:31 +00:00
SendReplyOK ( " Listing done " ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-06 03:25:31 +00:00
void BOBCommandSession : : OptionCommandHandler ( const char * operand , size_t len )
{
LogPrint ( eLogDebug , " BOB: option " , operand ) ;
2014-12-06 20:31:39 +00:00
const char * value = strchr ( operand , ' = ' ) ;
if ( value )
2018-01-06 03:48:51 +00:00
{
2016-07-21 18:02:13 +00:00
std : : string msg ( " option " ) ;
2014-12-06 20:31:39 +00:00
* ( const_cast < char * > ( value ) ) = 0 ;
2018-01-06 03:48:51 +00:00
m_Options [ operand ] = value + 1 ;
2016-07-21 18:02:13 +00:00
msg + = operand ;
2014-12-06 20:31:39 +00:00
* ( const_cast < char * > ( value ) ) = ' = ' ;
2016-07-21 18:02:13 +00:00
msg + = " set to " ;
2022-05-17 16:02:12 +00:00
msg + = value + 1 ;
2016-07-21 18:02:13 +00:00
SendReplyOK ( msg . c_str ( ) ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-06 20:31:39 +00:00
else
SendReplyError ( " malformed " ) ;
2018-01-06 03:48:51 +00:00
}
2016-07-16 13:31:33 +00:00
void BOBCommandSession : : StatusCommandHandler ( const char * operand , size_t len )
{
LogPrint ( eLogDebug , " BOB: status " , operand ) ;
2019-06-25 17:18:40 +00:00
const std : : string name = operand ;
2019-05-29 16:05:03 +00:00
std : : string statusLine ;
2019-06-25 17:18:40 +00:00
// always prefer destination
2022-06-13 13:53:16 +00:00
auto dest = m_Owner . FindDestination ( name ) ;
if ( dest )
2016-07-19 15:08:28 +00:00
{
2019-06-25 17:18:40 +00:00
// tunnel destination exists
2022-06-13 13:53:16 +00:00
BuildStatusLine ( false , dest , statusLine ) ;
2019-05-29 16:05:03 +00:00
SendReplyOK ( statusLine . c_str ( ) ) ;
}
else
{
2019-06-25 17:18:40 +00:00
if ( m_Nickname = = name & & ! name . empty ( ) )
2018-01-06 03:48:51 +00:00
{
2019-06-25 17:18:40 +00:00
// tunnel is incomplete / has not been started yet
BuildStatusLine ( true , nullptr , statusLine ) ;
2019-05-29 16:05:03 +00:00
SendReplyOK ( statusLine . c_str ( ) ) ;
2018-01-06 03:48:51 +00:00
}
2016-07-19 15:08:28 +00:00
else
2018-01-06 03:48:51 +00:00
{
2019-05-29 16:05:03 +00:00
SendReplyError ( " no nickname has been set " ) ;
2018-01-06 03:48:51 +00:00
}
2019-05-29 16:05:03 +00:00
}
}
void BOBCommandSession : : HelpCommandHandler ( const char * operand , size_t len )
{
auto helpStrings = m_Owner . GetHelpStrings ( ) ;
2022-06-13 13:53:16 +00:00
if ( ! * operand )
2019-05-29 16:05:03 +00:00
{
std : : stringstream ss ;
ss < < " COMMANDS: " ;
for ( auto const & x : helpStrings )
2018-01-06 03:48:51 +00:00
{
2019-05-29 16:05:03 +00:00
ss < < " " < < x . first ;
2018-01-06 03:48:51 +00:00
}
2019-05-29 16:05:03 +00:00
const std : : string & str = ss . str ( ) ;
SendReplyOK ( str . c_str ( ) ) ;
2016-07-19 15:08:28 +00:00
}
2016-07-16 13:31:33 +00:00
else
2019-05-29 16:05:03 +00:00
{
auto it = helpStrings . find ( operand ) ;
if ( it ! = helpStrings . end ( ) )
{
SendReplyOK ( it - > second . c_str ( ) ) ;
return ;
}
SendReplyError ( " No such command " ) ;
}
2018-01-06 03:48:51 +00:00
}
2023-06-12 02:10:32 +00:00
BOBCommandChannel : : BOBCommandChannel ( const std : : string & address , uint16_t port ) :
2020-02-04 16:48:56 +00:00
RunnableService ( " BOB " ) ,
m_Acceptor ( GetIOService ( ) , boost : : asio : : ip : : tcp : : endpoint ( boost : : asio : : ip : : address : : from_string ( address ) , port ) )
2014-12-02 15:34:02 +00:00
{
2014-12-03 02:45:01 +00:00
// command -> handler
2018-01-06 03:48:51 +00:00
m_CommandHandlers [ BOB_COMMAND_ZAP ] = & BOBCommandSession : : ZapCommandHandler ;
2014-12-02 21:45:51 +00:00
m_CommandHandlers [ BOB_COMMAND_QUIT ] = & BOBCommandSession : : QuitCommandHandler ;
2014-12-03 02:45:01 +00:00
m_CommandHandlers [ BOB_COMMAND_START ] = & BOBCommandSession : : StartCommandHandler ;
2014-12-03 20:24:30 +00:00
m_CommandHandlers [ BOB_COMMAND_STOP ] = & BOBCommandSession : : StopCommandHandler ;
2014-12-03 02:45:01 +00:00
m_CommandHandlers [ BOB_COMMAND_SETNICK ] = & BOBCommandSession : : SetNickCommandHandler ;
2014-12-03 20:24:30 +00:00
m_CommandHandlers [ BOB_COMMAND_GETNICK ] = & BOBCommandSession : : GetNickCommandHandler ;
2014-12-03 02:45:01 +00:00
m_CommandHandlers [ BOB_COMMAND_NEWKEYS ] = & BOBCommandSession : : NewkeysCommandHandler ;
2014-12-04 02:01:40 +00:00
m_CommandHandlers [ BOB_COMMAND_GETKEYS ] = & BOBCommandSession : : GetkeysCommandHandler ;
m_CommandHandlers [ BOB_COMMAND_SETKEYS ] = & BOBCommandSession : : SetkeysCommandHandler ;
m_CommandHandlers [ BOB_COMMAND_GETDEST ] = & BOBCommandSession : : GetdestCommandHandler ;
2014-12-03 02:45:01 +00:00
m_CommandHandlers [ BOB_COMMAND_OUTHOST ] = & BOBCommandSession : : OuthostCommandHandler ;
m_CommandHandlers [ BOB_COMMAND_OUTPORT ] = & BOBCommandSession : : OutportCommandHandler ;
2014-12-03 20:02:19 +00:00
m_CommandHandlers [ BOB_COMMAND_INHOST ] = & BOBCommandSession : : InhostCommandHandler ;
m_CommandHandlers [ BOB_COMMAND_INPORT ] = & BOBCommandSession : : InportCommandHandler ;
2014-12-05 19:13:16 +00:00
m_CommandHandlers [ BOB_COMMAND_QUIET ] = & BOBCommandSession : : QuietCommandHandler ;
2014-12-05 21:03:43 +00:00
m_CommandHandlers [ BOB_COMMAND_LOOKUP ] = & BOBCommandSession : : LookupCommandHandler ;
2021-11-27 20:30:35 +00:00
m_CommandHandlers [ BOB_COMMAND_LOOKUP_LOCAL ] = & BOBCommandSession : : LookupLocalCommandHandler ;
2014-12-06 00:16:54 +00:00
m_CommandHandlers [ BOB_COMMAND_CLEAR ] = & BOBCommandSession : : ClearCommandHandler ;
2014-12-06 03:25:31 +00:00
m_CommandHandlers [ BOB_COMMAND_LIST ] = & BOBCommandSession : : ListCommandHandler ;
m_CommandHandlers [ BOB_COMMAND_OPTION ] = & BOBCommandSession : : OptionCommandHandler ;
2016-07-16 13:31:33 +00:00
m_CommandHandlers [ BOB_COMMAND_STATUS ] = & BOBCommandSession : : StatusCommandHandler ;
2019-05-29 16:05:03 +00:00
m_CommandHandlers [ BOB_COMMAND_HELP ] = & BOBCommandSession : : HelpCommandHandler ;
// command -> help string
m_HelpStrings [ BOB_COMMAND_ZAP ] = BOB_HELP_ZAP ;
m_HelpStrings [ BOB_COMMAND_QUIT ] = BOB_HELP_QUIT ;
m_HelpStrings [ BOB_COMMAND_START ] = BOB_HELP_START ;
m_HelpStrings [ BOB_COMMAND_STOP ] = BOB_HELP_STOP ;
m_HelpStrings [ BOB_COMMAND_SETNICK ] = BOB_HELP_SETNICK ;
m_HelpStrings [ BOB_COMMAND_GETNICK ] = BOB_HELP_GETNICK ;
m_HelpStrings [ BOB_COMMAND_NEWKEYS ] = BOB_HELP_NEWKEYS ;
m_HelpStrings [ BOB_COMMAND_GETKEYS ] = BOB_HELP_GETKEYS ;
m_HelpStrings [ BOB_COMMAND_SETKEYS ] = BOB_HELP_SETKEYS ;
m_HelpStrings [ BOB_COMMAND_GETDEST ] = BOB_HELP_GETDEST ;
m_HelpStrings [ BOB_COMMAND_OUTHOST ] = BOB_HELP_OUTHOST ;
m_HelpStrings [ BOB_COMMAND_OUTPORT ] = BOB_HELP_OUTPORT ;
m_HelpStrings [ BOB_COMMAND_INHOST ] = BOB_HELP_INHOST ;
m_HelpStrings [ BOB_COMMAND_INPORT ] = BOB_HELP_INPORT ;
m_HelpStrings [ BOB_COMMAND_QUIET ] = BOB_HELP_QUIET ;
m_HelpStrings [ BOB_COMMAND_LOOKUP ] = BOB_HELP_LOOKUP ;
m_HelpStrings [ BOB_COMMAND_CLEAR ] = BOB_HELP_CLEAR ;
m_HelpStrings [ BOB_COMMAND_LIST ] = BOB_HELP_LIST ;
m_HelpStrings [ BOB_COMMAND_OPTION ] = BOB_HELP_OPTION ;
m_HelpStrings [ BOB_COMMAND_STATUS ] = BOB_HELP_STATUS ;
m_HelpStrings [ BOB_COMMAND_HELP ] = BOB_HELP_HELP ;
2014-12-02 15:34:02 +00:00
}
BOBCommandChannel : : ~ BOBCommandChannel ( )
{
2020-03-01 10:25:50 +00:00
if ( IsRunning ( ) )
2020-02-04 16:48:56 +00:00
Stop ( ) ;
2014-12-02 16:42:35 +00:00
}
void BOBCommandChannel : : Start ( )
{
Accept ( ) ;
2020-02-04 16:48:56 +00:00
StartIOService ( ) ;
2014-12-02 16:42:35 +00:00
}
void BOBCommandChannel : : Stop ( )
{
2016-08-05 18:23:54 +00:00
for ( auto & it : m_Destinations )
2014-12-03 20:24:30 +00:00
it . second - > Stop ( ) ;
2018-01-06 03:48:51 +00:00
m_Acceptor . cancel ( ) ;
2020-02-04 16:48:56 +00:00
StopIOService ( ) ;
2014-12-02 16:42:35 +00:00
}
2023-07-06 17:08:39 +00:00
void BOBCommandChannel : : AddDestination ( const std : : string & name , std : : shared_ptr < BOBDestination > dest )
2014-12-03 02:45:01 +00:00
{
2023-07-06 17:08:39 +00:00
m_Destinations . emplace ( name , dest ) ;
2018-01-06 03:48:51 +00:00
}
2014-12-03 20:24:30 +00:00
2014-12-08 02:04:02 +00:00
void BOBCommandChannel : : DeleteDestination ( const std : : string & name )
{
auto it = m_Destinations . find ( name ) ;
if ( it ! = m_Destinations . end ( ) )
{
it - > second - > Stop ( ) ;
m_Destinations . erase ( it ) ;
2018-01-06 03:48:51 +00:00
}
}
2023-07-06 17:08:39 +00:00
std : : shared_ptr < BOBDestination > BOBCommandChannel : : FindDestination ( const std : : string & name )
2014-12-03 20:24:30 +00:00
{
2014-12-07 02:23:43 +00:00
auto it = m_Destinations . find ( name ) ;
if ( it ! = m_Destinations . end ( ) )
2014-12-03 20:24:30 +00:00
return it - > second ;
2018-01-06 03:48:51 +00:00
return nullptr ;
2014-12-03 20:24:30 +00:00
}
2018-01-06 03:48:51 +00:00
2014-12-02 16:42:35 +00:00
void BOBCommandChannel : : Accept ( )
{
2014-12-02 20:47:44 +00:00
auto newSession = std : : make_shared < BOBCommandSession > ( * this ) ;
m_Acceptor . async_accept ( newSession - > GetSocket ( ) , std : : bind ( & BOBCommandChannel : : HandleAccept , this ,
std : : placeholders : : _1 , newSession ) ) ;
2014-12-02 16:42:35 +00:00
}
2014-12-02 20:47:44 +00:00
void BOBCommandChannel : : HandleAccept ( const boost : : system : : error_code & ecode , std : : shared_ptr < BOBCommandSession > session )
2014-12-02 16:42:35 +00:00
{
if ( ecode ! = boost : : asio : : error : : operation_aborted )
Accept ( ) ;
if ( ! ecode )
{
2015-12-18 06:27:35 +00:00
LogPrint ( eLogInfo , " BOB: New command connection from " , session - > GetSocket ( ) . remote_endpoint ( ) ) ;
2018-01-06 03:48:51 +00:00
session - > SendVersion ( ) ;
2014-12-02 16:42:35 +00:00
}
else
2021-11-27 19:53:53 +00:00
LogPrint ( eLogError , " BOB: Accept error: " , ecode . message ( ) ) ;
2014-12-02 15:34:02 +00:00
}
}
}