Browse Source

[socks] changes

Signed-off-by: R4SAS <r4sas@i2pmail.org>
socks5
R4SAS 3 years ago
parent
commit
ab5c966fdf
  1. 3
      libi2pd_client/ClientContext.cpp
  2. 56
      libi2pd_client/SOCKS.cpp

3
libi2pd_client/ClientContext.cpp

@ -634,7 +634,8 @@ namespace client
{ {
// socks proxy // socks proxy
std::string outproxy = section.second.get("outproxy", ""); std::string outproxy = section.second.get("outproxy", "");
auto tun = std::make_shared<i2p::proxy::SOCKSProxy>(name, address, port, !outproxy.empty(), outproxy, destinationPort, localDestination); uint32_t outproxyport = section.second.get("outproxyport", 0);
auto tun = std::make_shared<i2p::proxy::SOCKSProxy>(name, address, port, !outproxy.empty(), outproxy, outproxyport, localDestination);
clientTunnel = tun; clientTunnel = tun;
clientEndpoint = tun->GetLocalEndpoint (); clientEndpoint = tun->GetLocalEndpoint ();
} }

56
libi2pd_client/SOCKS.cpp

@ -31,7 +31,6 @@ namespace proxy
static const size_t SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE = 8; static const size_t SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE = 8;
static const size_t SOCKS_UPSTREAM_SOCKS5_INIT_REPLY_SIZE = 2; static const size_t SOCKS_UPSTREAM_SOCKS5_INIT_REPLY_SIZE = 2;
static const size_t SOCKS_UPSTREAM_SOCKS5_CONNECT_REPLY_MIN_SIZE = 10;
struct SOCKSDnsAddress struct SOCKSDnsAddress
{ {
@ -258,19 +257,19 @@ namespace proxy
break; break;
case ADDR_DNS: case ADDR_DNS:
std::string address(addr.dns.value, addr.dns.size); std::string address(addr.dns.value, addr.dns.size);
if(address.substr(addr.dns.size - 4, 4) == ".i2p") // overwrite if requested address inside I2P //if(address.substr(addr.dns.size - 4, 4) == ".i2p") // overwrite if requested address inside I2P
{ {
m_response[3] = ADDR_IPV4; m_response[3] = ADDR_IPV4;
size += 4; size += 4;
memset(m_response + 4, 0, 6); // six HEX zeros memset(m_response + 4, 0, 6); // six HEX zeros
} }
else /*else
{ {
size += (1 + addr.dns.size); /* name length + resolved address */ size += (1 + addr.dns.size); // name length + resolved address
m_response[4] = addr.dns.size; m_response[4] = addr.dns.size;
memcpy(m_response + 5, addr.dns.value, addr.dns.size); memcpy(m_response + 5, addr.dns.value, addr.dns.size); // 4 - header + 1 - record size
htobe16buf(m_response + size - 2, port); htobe16buf(m_response + size - 2, port);
} }*/
break; break;
} }
return boost::asio::const_buffers_1(m_response, size); return boost::asio::const_buffers_1(m_response, size);
@ -738,32 +737,43 @@ namespace proxy
void SOCKSHandler::HandleUpstreamData(uint8_t * dataptr, std::size_t len) void SOCKSHandler::HandleUpstreamData(uint8_t * dataptr, std::size_t len)
{ {
if (m_state == UPSTREAM_HANDSHAKE) { if (m_state == UPSTREAM_HANDSHAKE)
{
m_upstream_response_len += len; m_upstream_response_len += len;
// handle handshake data // handle handshake data
if (m_upstream_response_len == SOCKS_UPSTREAM_SOCKS5_INIT_REPLY_SIZE) { if (m_upstream_response_len == SOCKS_UPSTREAM_SOCKS5_INIT_REPLY_SIZE)
if (m_upstream_response[0] == '\x05' && m_upstream_response[1] != AUTH_UNACCEPTABLE) { {
LogPrint(eLogInfo, "SOCKS: upstream proxy: success greeting"); if (m_upstream_response[0] == '\x05' && m_upstream_response[1] != AUTH_UNACCEPTABLE)
{
LogPrint(eLogInfo, "SOCKS: upstream SOCKS5 proxy: success greeting");
SendUpstreamRequest(m_socksv, false); SendUpstreamRequest(m_socksv, false);
} else { }
LogPrint(eLogError, "SOCKS: upstream proxy failure: no acceptable methods were offered"); else
{
LogPrint(eLogError, "SOCKS: upstream SOCKS5 proxy failure: no acceptable methods were offered");
SocksRequestFailed(SOCKS5_GEN_FAIL); SocksRequestFailed(SOCKS5_GEN_FAIL);
} }
} }
else if (m_upstream_response[0] == '\x05' && m_upstream_response_len >= SOCKS_UPSTREAM_SOCKS5_CONNECT_REPLY_MIN_SIZE) else if (m_upstream_response[0] == '\x05')
{ {
uint8_t resp = m_upstream_response[1]; if (m_upstream_response[1] == SOCKS5_OK)
if (resp == SOCKS5_OK) { {
LogPrint(eLogInfo, "SOCKS: upstream SOCKS5 proxy: successully established");
SocksUpstreamSuccess(); SocksUpstreamSuccess();
} else { }
LogPrint(eLogError, "SOCKS: upstream proxy failure: ", (int) resp); else
{
LogPrint(eLogError, "SOCKS: upstream proxy failure: ", (int) m_upstream_response[1]);
SocksRequestFailed(SOCKS5_GEN_FAIL); SocksRequestFailed(SOCKS5_GEN_FAIL);
} }
} }
else if (m_upstream_response_len < SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE) { else if (m_upstream_response_len < SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE)
{
// too small, continue reading // too small, continue reading
AsyncUpstreamSockRead(); AsyncUpstreamSockRead();
} else if (len == SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE) { }
else if (len == SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE)
{
// just right // just right
uint8_t resp = m_upstream_response[1]; uint8_t resp = m_upstream_response[1];
if (resp == SOCKS4_OK) { if (resp == SOCKS4_OK) {
@ -775,11 +785,15 @@ namespace proxy
// TODO: runtime error? // TODO: runtime error?
SocksRequestFailed(SOCKS5_GEN_FAIL); SocksRequestFailed(SOCKS5_GEN_FAIL);
} }
} else { }
else
{
// too big // too big
SocksRequestFailed(SOCKS5_GEN_FAIL); SocksRequestFailed(SOCKS5_GEN_FAIL);
} }
} else { }
else
{
// invalid state // invalid state
LogPrint(eLogError, "SOCKS: Invalid state reading from upstream: ", (int) m_state); LogPrint(eLogError, "SOCKS: Invalid state reading from upstream: ", (int) m_state);
} }

Loading…
Cancel
Save