@ -1148,7 +1148,7 @@ namespace transport
NTCP2Server : : NTCP2Server ( ) :
NTCP2Server : : NTCP2Server ( ) :
RunnableServiceWithWork ( " NTCP2 " ) , m_TerminationTimer ( GetService ( ) ) ,
RunnableServiceWithWork ( " NTCP2 " ) , m_TerminationTimer ( GetService ( ) ) ,
m_Resolver ( GetService ( ) )
m_Resolver ( GetService ( ) ) , m_ProxyType ( eNoProxy ) , m_ProxyEndpoint ( nullptr )
{
{
}
}
@ -1164,25 +1164,23 @@ namespace transport
StartIOService ( ) ;
StartIOService ( ) ;
if ( UsingProxy ( ) )
if ( UsingProxy ( ) )
{
{
LogPrint ( eLogError , " NTCP2: USING PROXY " ) ;
LogPrint ( eLogInfo , " NTCP2: Using proxy to connect to peers " ) ;
// TODO: resolve proxy until it is resolved
// TODO: resolve proxy until it is resolved
boost : : asio : : ip : : tcp : : resolver : : query q ( m_ProxyAddress , std : : to_string ( m_ProxyPort ) ) ;
boost : : asio : : ip : : tcp : : resolver : : query q ( m_ProxyAddress , std : : to_string ( m_ProxyPort ) ) ;
boost : : system : : error_code e ;
boost : : system : : error_code e ;
auto itr = m_Resolver . resolve ( q , e ) ;
auto itr = m_Resolver . resolve ( q , e ) ;
if ( e )
if ( e )
{
LogPrint ( eLogError , " NTCP2: Failed to resolve proxy " , e . message ( ) ) ;
LogPrint ( eLogError , " NTCP2: Failed to resolve proxy " , e . message ( ) ) ;
}
else
else
{
{
m_ProxyEndpoint . reset ( new boost : : asio : : ip : : tcp : : endpoint ( * itr ) ) ;
m_ProxyEndpoint . reset ( new boost : : asio : : ip : : tcp : : endpoint ( * itr ) ) ;
if ( m_ProxyEndpoint )
if ( m_ProxyEndpoint )
LogPrint ( eLogError , " NTCP2: m_ProxyEndpoint " , * m_ProxyEndpoint ) ;
LogPrint ( eLogDebug , " NTCP2: m_ProxyEndpoint " , * m_ProxyEndpoint ) ;
}
}
}
}
else
else
{
{
LogPrint ( eLogError , " NTCP2: NOTUSING PROXY " ) ;
LogPrint ( eLogInfo , " NTCP2: Proxy is not used " ) ;
auto & addresses = context . GetRouterInfo ( ) . GetAddresses ( ) ;
auto & addresses = context . GetRouterInfo ( ) . GetAddresses ( ) ;
for ( const auto & address : addresses )
for ( const auto & address : addresses )
{
{
@ -1426,6 +1424,31 @@ namespace transport
}
}
}
}
void NTCP2Server : : ConnectWithProxy ( const std : : string & host , uint16_t port , RemoteAddressType addrtype , std : : shared_ptr < NTCP2Session > conn )
{
if ( ! m_ProxyEndpoint ) return ;
GetService ( ) . post ( [ this , host , port , addrtype , conn ] ( ) {
if ( this - > AddNTCP2Session ( conn ) )
{
auto timer = std : : make_shared < boost : : asio : : deadline_timer > ( GetService ( ) ) ;
auto timeout = NTCP_CONNECT_TIMEOUT * 5 ;
conn - > SetTerminationTimeout ( timeout * 2 ) ;
timer - > expires_from_now ( boost : : posix_time : : seconds ( timeout ) ) ;
timer - > async_wait ( [ conn , timeout ] ( const boost : : system : : error_code & ecode )
{
if ( ecode ! = boost : : asio : : error : : operation_aborted )
{
LogPrint ( eLogInfo , " NTCP2: Not connected in " , timeout , " seconds " ) ;
i2p : : data : : netdb . SetUnreachable ( conn - > GetRemoteIdentity ( ) - > GetIdentHash ( ) , true ) ;
conn - > Terminate ( ) ;
}
} ) ;
conn - > GetSocket ( ) . async_connect ( * m_ProxyEndpoint , std : : bind ( & NTCP2Server : : HandleProxyConnect , this , std : : placeholders : : _1 , conn , timer , host , port , addrtype ) ) ;
}
} ) ;
}
void NTCP2Server : : UseProxy ( ProxyType proxytype , const std : : string & addr , uint16_t port )
void NTCP2Server : : UseProxy ( ProxyType proxytype , const std : : string & addr , uint16_t port )
{
{
m_ProxyType = proxytype ;
m_ProxyType = proxytype ;
@ -1449,8 +1472,8 @@ namespace transport
// TODO: support username/password auth etc
// TODO: support username/password auth etc
static const uint8_t buff [ 3 ] = { 0x05 , 0x01 , 0x00 } ;
static const uint8_t buff [ 3 ] = { 0x05 , 0x01 , 0x00 } ;
boost : : asio : : async_write ( conn - > GetSocket ( ) , boost : : asio : : buffer ( buff , 3 ) , boost : : asio : : transfer_all ( ) ,
boost : : asio : : async_write ( conn - > GetSocket ( ) , boost : : asio : : buffer ( buff , 3 ) , boost : : asio : : transfer_all ( ) ,
[ ] ( const boost : : system : : error_code & ec , std : : size_t transferred )
[ ] ( const boost : : system : : error_code & ec , std : : size_t transferred )
{
{
( void ) transferred ;
( void ) transferred ;
if ( ec )
if ( ec )
{
{
@ -1505,8 +1528,8 @@ namespace transport
out < < req . to_string ( ) ;
out < < req . to_string ( ) ;
boost : : asio : : async_write ( conn - > GetSocket ( ) , writebuff . data ( ) , boost : : asio : : transfer_all ( ) ,
boost : : asio : : async_write ( conn - > GetSocket ( ) , writebuff . data ( ) , boost : : asio : : transfer_all ( ) ,
[ ] ( const boost : : system : : error_code & ec , std : : size_t transferred )
[ ] ( const boost : : system : : error_code & ec , std : : size_t transferred )
{
{
( void ) transferred ;
( void ) transferred ;
if ( ec )
if ( ec )
LogPrint ( eLogError , " NTCP2: http proxy write error " , ec . message ( ) ) ;
LogPrint ( eLogError , " NTCP2: http proxy write error " , ec . message ( ) ) ;
@ -1552,35 +1575,10 @@ namespace transport
}
}
}
}
void NTCP2Server : : ConnectWithProxy ( const std : : string & host , uint16_t port , RemoteAddressType addrtype , std : : shared_ptr < NTCP2Session > conn )
{
if ( ! m_ProxyEndpoint ) return ;
GetService ( ) . post ( [ this , host , port , addrtype , conn ] ( ) {
if ( this - > AddNTCP2Session ( conn ) )
{
auto timer = std : : make_shared < boost : : asio : : deadline_timer > ( GetService ( ) ) ;
auto timeout = NTCP_CONNECT_TIMEOUT * 5 ;
conn - > SetTerminationTimeout ( timeout * 2 ) ;
timer - > expires_from_now ( boost : : posix_time : : seconds ( timeout ) ) ;
timer - > async_wait ( [ conn , timeout ] ( const boost : : system : : error_code & ecode )
{
if ( ecode ! = boost : : asio : : error : : operation_aborted )
{
LogPrint ( eLogInfo , " NTCP2: Not connected in " , timeout , " seconds " ) ;
i2p : : data : : netdb . SetUnreachable ( conn - > GetRemoteIdentity ( ) - > GetIdentHash ( ) , true ) ;
conn - > Terminate ( ) ;
}
} ) ;
conn - > GetSocket ( ) . async_connect ( * m_ProxyEndpoint , std : : bind ( & NTCP2Server : : HandleProxyConnect , this , std : : placeholders : : _1 , conn , timer , host , port , addrtype ) ) ;
}
} ) ;
}
void NTCP2Server : : AfterSocksHandshake ( std : : shared_ptr < NTCP2Session > conn , std : : shared_ptr < boost : : asio : : deadline_timer > timer , const std : : string & host , uint16_t port , RemoteAddressType addrtype )
void NTCP2Server : : AfterSocksHandshake ( std : : shared_ptr < NTCP2Session > conn , std : : shared_ptr < boost : : asio : : deadline_timer > timer , const std : : string & host , uint16_t port , RemoteAddressType addrtype )
{
{
// build request
// build request
size_t sz = 0 ;
size_t sz = 6 ; // header + port
auto buff = std : : make_shared < std : : vector < int8_t > > ( 256 ) ;
auto buff = std : : make_shared < std : : vector < int8_t > > ( 256 ) ;
auto readbuff = std : : make_shared < std : : vector < int8_t > > ( 256 ) ;
auto readbuff = std : : make_shared < std : : vector < int8_t > > ( 256 ) ;
( * buff ) [ 0 ] = 0x05 ;
( * buff ) [ 0 ] = 0x05 ;
@ -1590,37 +1588,27 @@ namespace transport
if ( addrtype = = eIP4Address )
if ( addrtype = = eIP4Address )
{
{
( * buff ) [ 3 ] = 0x01 ;
( * buff ) [ 3 ] = 0x01 ;
auto addr = boost : : asio : : ip : : address : : from_string ( host ) . to_v4 ( ) ;
auto addrbytes = boost : : asio : : ip : : address : : from_string ( host ) . to_v4 ( ) . to_bytes ( ) ;
auto addrbytes = addr . to_bytes ( ) ;
sz + = 4 ;
auto addrsize = addrbytes . size ( ) ;
memcpy ( buff - > data ( ) + 4 , addrbytes . data ( ) , 4 ) ;
memcpy ( buff - > data ( ) + 4 , addrbytes . data ( ) , addrsize ) ;
}
}
else if ( addrtype = = eIP6Address )
else if ( addrtype = = eIP6Address )
{
{
( * buff ) [ 3 ] = 0x04 ;
( * buff ) [ 3 ] = 0x04 ;
auto addr = boost : : asio : : ip : : address : : from_string ( host ) . to_v6 ( ) ;
auto addrbytes = boost : : asio : : ip : : address : : from_string ( host ) . to_v6 ( ) . to_bytes ( ) ;
auto addrbytes = addr . to_bytes ( ) ;
sz + = 16 ;
auto addrsize = addrbytes . size ( ) ;
memcpy ( buff - > data ( ) + 4 , addrbytes . data ( ) , 16 ) ;
memcpy ( buff - > data ( ) + 4 , addrbytes . data ( ) , addrsize ) ;
}
}
else if ( addrtype = = eHostname )
else if ( addrtype = = eHostname )
{
{
( * buff ) [ 3 ] = 0x03 ;
// We mustn't really fall here because all connections are made to IP addresses
size_t addrsize = host . size ( ) ;
LogPrint ( eLogError , " NTCP2: Tried to connect to domain name via socks proxy " ) ;
sz = addrsize + 1 + 4 ;
return ;
if ( 2 + sz > buff - > size ( ) )
{
// too big
return ;
}
( * buff ) [ 4 ] = ( uint8_t ) addrsize ;
memcpy ( buff - > data ( ) + 5 , host . c_str ( ) , addrsize ) ;
}
}
htobe16buf ( buff - > data ( ) + sz , port ) ;
htobe16buf ( buff - > data ( ) + sz - 2 , port ) ;
sz + = 2 ;
boost : : asio : : async_write ( conn - > GetSocket ( ) , boost : : asio : : buffer ( buff - > data ( ) , sz ) , boost : : asio : : transfer_all ( ) ,
boost : : asio : : async_write ( conn - > GetSocket ( ) , boost : : asio : : buffer ( buff - > data ( ) , sz ) , boost : : asio : : transfer_all ( ) ,
[ ] ( const boost : : system : : error_code & ec , std : : size_t written )
[ buff ] ( const boost : : system : : error_code & ec , std : : size_t written )
{
{
if ( ec )
if ( ec )
{
{
LogPrint ( eLogError , " NTCP2: failed to write handshake to socks proxy " , ec . message ( ) ) ;
LogPrint ( eLogError , " NTCP2: failed to write handshake to socks proxy " , ec . message ( ) ) ;
@ -1630,7 +1618,7 @@ namespace transport
boost : : asio : : async_read ( conn - > GetSocket ( ) , boost : : asio : : buffer ( readbuff - > data ( ) , 10 ) ,
boost : : asio : : async_read ( conn - > GetSocket ( ) , boost : : asio : : buffer ( readbuff - > data ( ) , 10 ) ,
[ timer , conn , sz , readbuff ] ( const boost : : system : : error_code & e , std : : size_t transferred )
[ timer , conn , sz , readbuff ] ( const boost : : system : : error_code & e , std : : size_t transferred )
{
{
if ( e )
if ( e )
{
{
LogPrint ( eLogError , " NTCP2: socks proxy read error " , e . message ( ) ) ;
LogPrint ( eLogError , " NTCP2: socks proxy read error " , e . message ( ) ) ;
@ -1650,6 +1638,5 @@ namespace transport
conn - > Terminate ( ) ;
conn - > Terminate ( ) ;
} ) ;
} ) ;
}
}
}
}
}
}