29 if( location.
socks() )
33 throw SocksError(
"invalid port" ) ;
41 g_port_t far_port_n = htons(
static_cast<g_port_t
>(far_port) ) ;
42 g_port_t far_port_lo = far_port_n & 0xffU ;
43 g_port_t far_port_hi = (far_port_n>>8U) & g_port_t(0xffU) ;
47 data.reserve( far_host.size() + 10U ) ;
48 data.append( 1U , 4 ) ;
49 data.append( 1U , 1 ) ;
50 data.append( 1U ,
static_cast<char>(far_port_lo) ) ;
51 data.append( 1U ,
static_cast<char>(far_port_hi) ) ;
52 data.append( 1U , 0 ) ;
53 data.append( 1U , 0 ) ;
54 data.append( 1U , 0 ) ;
55 data.append( 1U , 1 ) ;
56 data.append( userid ) ;
57 data.append( 1U , 0 ) ;
58 data.append( far_host ) ;
59 data.append( 1U , 0 ) ;
66 if( m_request_offset >= m_request.size() )
69 const char * p = m_request.data() + m_request_offset ;
70 std::size_t n = m_request.size() - m_request_offset ;
72 ssize_t rc = io.
write( p , n ) ;
75 throw SocksError(
"socket write error" ) ;
77 else if( rc < 0 ||
static_cast<std::size_t
>(rc) < n )
79 std::size_t nsent = rc < 0 ? std::size_t(0U) : static_cast<std::size_t>(rc) ;
80 m_request_offset += nsent ;
85 m_request_offset = m_request.size() ;
92 std::array<char,8U> buffer {} ;
93 ssize_t rc = io.
read( buffer.data() , buffer.size() ) ;
96 throw SocksError(
"disconnected" ) ;
100 throw SocksError(
"socket read error" ) ;
108 G_ASSERT( rc >= 1 && rc <= 8 ) ;
109 std::size_t n = std::min( buffer.size() ,
static_cast<std::size_t
>(rc) ) ;
110 m_response.append( buffer.data() , n ) ;
113 if( m_response.size() >= 8U )
115 G_ASSERT( m_response.size() == 8U ) ;
116 if( m_response[0] != 0 )
118 throw SocksError(
"invalid response" ) ;
120 else if( m_response[1] !=
'Z' )
122 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.