30 if( location.
socks() )
34 throw SocksError(
"invalid port" ) ;
37 m_request_offset = 0U ;
43 g_port_t far_port_n = htons(
static_cast<g_port_t
>(far_port) ) ;
44 g_port_t far_port_lo = far_port_n & 0xffU ;
45 g_port_t far_port_hi = (far_port_n>>8U) & g_port_t(0xffU) ;
49 data.reserve( far_host.size() + 10U ) ;
50 data.append( 1U , 4 ) ;
51 data.append( 1U , 1 ) ;
52 data.append( 1U ,
static_cast<char>(far_port_lo) ) ;
53 data.append( 1U ,
static_cast<char>(far_port_hi) ) ;
54 data.append( 1U , 0 ) ;
55 data.append( 1U , 0 ) ;
56 data.append( 1U , 0 ) ;
57 data.append( 1U , 1 ) ;
58 data.append( userid ) ;
59 data.append( 1U , 0 ) ;
60 data.append( far_host ) ;
61 data.append( 1U , 0 ) ;
68 if( m_request_offset >= m_request.size() )
71 const char * p = m_request.data() + m_request_offset ;
72 std::size_t n = m_request.size() - m_request_offset ;
74 ssize_t rc = io.
write( p , n ) ;
77 throw SocksError(
"socket write error" ) ;
79 else if( rc < 0 ||
static_cast<std::size_t
>(rc) < n )
81 std::size_t nsent = rc < 0 ? std::size_t(0U) : static_cast<std::size_t>(rc) ;
82 m_request_offset += nsent ;
87 m_request_offset = m_request.size() ;
94 std::array<char,8U> buffer {} ;
95 ssize_t rc = io.
read( &buffer[0] , buffer.size() ) ;
98 throw SocksError(
"disconnected" ) ;
102 throw SocksError(
"socket read error" ) ;
110 G_ASSERT( rc >= 1 && rc <= 8 ) ;
111 std::size_t n = std::min( buffer.size() ,
static_cast<std::size_t
>(rc) ) ;
112 m_response.append( &buffer[0] , n ) ;
115 if( m_response.size() >= 8U )
117 G_ASSERT( m_response.size() == 8U ) ;
118 if( m_response[0] != 0 )
120 throw SocksError(
"invalid response" ) ;
122 else if( m_response[1] !=
'Z' )
124 throw SocksError(
"request rejected" ) ;
static bool validPort(unsigned int n)
Returns true if the port number is within the valid range.
A class that represents the remote target for out-going client connections.
std::string socksFarHost() const
Returns the port for the socks far server.
unsigned int socksFarPort() const
Returns the port number for the socks far server.
static Location socks(const std::string &socks_server, const std::string &far_server)
Factory function for a remote location explicitly accessed via socks.
bool send(G::ReadWrite &)
Sends the connect-request pdu using the given file descriptor.
bool read(G::ReadWrite &)
Reads the response using the given file descriptor.
Socks(const Location &)
Constructor.
static std::string buildPdu(const std::string &far_host, unsigned int far_port)
Builds a SOCKS4a connect request pdu.
An abstract interface for reading and writing from a non-blocking i/o channel.
virtual ssize_type write(const char *buf, size_type len)=0
Sends data.
virtual bool eWouldBlock() const =0
See read() and write().
virtual ssize_type read(char *buffer, size_type buffer_length)=0
Reads data.