@ -30,7 +30,7 @@ bool fNameLookup = DEFAULT_NAME_LOOKUP;
// Need ample time for negotiation for very slow proxies such as Tor
std : : chrono : : milliseconds g_socks5_recv_timeout = 20 s ;
static std : : atomic < bool > interruptSocks5Recv ( false ) ;
CThreadInterrupt g_socks5_interrupt ;
std : : vector < CNetAddr > WrappedGetAddrInfo ( const std : : string & name , bool allow_lookup )
{
@ -269,7 +269,7 @@ enum class IntrRecvError {
* IntrRecvError : : OK only if all of the specified number of bytes were
* read .
*
* @ see This function can be interrupted by calling InterruptSocks5( bool ) .
* @ see This function can be interrupted by calling g_socks5_interrupt( ) .
* Sockets can be made non - blocking with Sock : : SetNonBlocking ( ) .
*/
static IntrRecvError InterruptibleRecv ( uint8_t * data , size_t len , std : : chrono : : milliseconds timeout , const Sock & sock )
@ -297,8 +297,9 @@ static IntrRecvError InterruptibleRecv(uint8_t* data, size_t len, std::chrono::m
return IntrRecvError : : NetworkError ;
}
}
if ( interruptSocks5Recv )
if ( g_socks5_ interrupt) {
return IntrRecvError : : Interrupted ;
}
curTime = Now < SteadyMilliseconds > ( ) ;
}
return len = = 0 ? IntrRecvError : : OK : IntrRecvError : : Timeout ;
@ -331,6 +332,7 @@ static std::string Socks5ErrorString(uint8_t err)
bool Socks5 ( const std : : string & strDest , uint16_t port , const ProxyCredentials * auth , const Sock & sock )
{
try {
IntrRecvError recvr ;
LogPrint ( BCLog : : NET , " SOCKS5 connecting %s \n " , strDest ) ;
if ( strDest . size ( ) > 255 ) {
@ -347,10 +349,7 @@ bool Socks5(const std::string& strDest, uint16_t port, const ProxyCredentials* a
vSocks5Init . push_back ( 0x01 ) ; // 1 method identifier follows...
vSocks5Init . push_back ( SOCKS5Method : : NOAUTH ) ;
}
ssize_t ret = sock . Send ( vSocks5Init . data ( ) , vSocks5Init . size ( ) , MSG_NOSIGNAL ) ;
if ( ret ! = ( ssize_t ) vSocks5Init . size ( ) ) {
return error ( " Error sending to proxy " ) ;
}
sock . SendComplete ( vSocks5Init , g_socks5_recv_timeout , g_socks5_interrupt ) ;
uint8_t pchRet1 [ 2 ] ;
if ( InterruptibleRecv ( pchRet1 , 2 , g_socks5_recv_timeout , sock ) ! = IntrRecvError : : OK ) {
LogPrintf ( " Socks5() connect to %s:%d failed: InterruptibleRecv() timeout or other failure \n " , strDest , port ) ;
@ -369,10 +368,7 @@ bool Socks5(const std::string& strDest, uint16_t port, const ProxyCredentials* a
vAuth . insert ( vAuth . end ( ) , auth - > username . begin ( ) , auth - > username . end ( ) ) ;
vAuth . push_back ( auth - > password . size ( ) ) ;
vAuth . insert ( vAuth . end ( ) , auth - > password . begin ( ) , auth - > password . end ( ) ) ;
ret = sock . Send ( vAuth . data ( ) , vAuth . size ( ) , MSG_NOSIGNAL ) ;
if ( ret ! = ( ssize_t ) vAuth . size ( ) ) {
return error ( " Error sending authentication to proxy " ) ;
}
sock . SendComplete ( vAuth , g_socks5_recv_timeout , g_socks5_interrupt ) ;
LogPrint ( BCLog : : PROXY , " SOCKS5 sending proxy authentication %s:%s \n " , auth - > username , auth - > password ) ;
uint8_t pchRetA [ 2 ] ;
if ( InterruptibleRecv ( pchRetA , 2 , g_socks5_recv_timeout , sock ) ! = IntrRecvError : : OK ) {
@ -395,10 +391,7 @@ bool Socks5(const std::string& strDest, uint16_t port, const ProxyCredentials* a
vSocks5 . insert ( vSocks5 . end ( ) , strDest . begin ( ) , strDest . end ( ) ) ;
vSocks5 . push_back ( ( port > > 8 ) & 0xFF ) ;
vSocks5 . push_back ( ( port > > 0 ) & 0xFF ) ;
ret = sock . Send ( vSocks5 . data ( ) , vSocks5 . size ( ) , MSG_NOSIGNAL ) ;
if ( ret ! = ( ssize_t ) vSocks5 . size ( ) ) {
return error ( " Error sending to proxy " ) ;
}
sock . SendComplete ( vSocks5 , g_socks5_recv_timeout , g_socks5_interrupt ) ;
uint8_t pchRet2 [ 4 ] ;
if ( ( recvr = InterruptibleRecv ( pchRet2 , 4 , g_socks5_recv_timeout , sock ) ) ! = IntrRecvError : : OK ) {
if ( recvr = = IntrRecvError : : Timeout ) {
@ -422,12 +415,10 @@ bool Socks5(const std::string& strDest, uint16_t port, const ProxyCredentials* a
return error ( " Error: malformed proxy response " ) ;
}
uint8_t pchRet3 [ 256 ] ;
switch ( pchRet2 [ 3 ] )
{
switch ( pchRet2 [ 3 ] ) {
case SOCKS5Atyp : : IPV4 : recvr = InterruptibleRecv ( pchRet3 , 4 , g_socks5_recv_timeout , sock ) ; break ;
case SOCKS5Atyp : : IPV6 : recvr = InterruptibleRecv ( pchRet3 , 16 , g_socks5_recv_timeout , sock ) ; break ;
case SOCKS5Atyp : : DOMAINNAME :
{
case SOCKS5Atyp : : DOMAINNAME : {
recvr = InterruptibleRecv ( pchRet3 , 1 , g_socks5_recv_timeout , sock ) ;
if ( recvr ! = IntrRecvError : : OK ) {
return error ( " Error reading from proxy " ) ;
@ -446,6 +437,9 @@ bool Socks5(const std::string& strDest, uint16_t port, const ProxyCredentials* a
}
LogPrint ( BCLog : : NET , " SOCKS5 connected %s \n " , strDest ) ;
return true ;
} catch ( const std : : runtime_error & e ) {
return error ( " Error during SOCKS5 proxy handshake: %s " , e . what ( ) ) ;
}
}
std : : unique_ptr < Sock > CreateSockTCP ( const CService & address_family )
@ -678,11 +672,6 @@ bool LookupSubNet(const std::string& subnet_str, CSubNet& subnet_out)
return false ;
}
void InterruptSocks5 ( bool interrupt )
{
interruptSocks5Recv = interrupt ;
}
bool IsBadPort ( uint16_t port )
{
/* Don't forget to update doc/p2p-bad-ports.md if you change this list. */