Browse Source

[NTCP2] fix socks proxy support

Signed-off-by: R4SAS <r4sas@i2pmail.org>
pull/1515/head
R4SAS 4 years ago
parent
commit
1aa0da3382
  1. 10
      libi2pd/Config.cpp
  2. 119
      libi2pd/NTCP2.cpp
  3. 2
      libi2pd/NTCP2.h
  4. 1
      libi2pd/NTCPSession.cpp
  5. 62
      libi2pd/Transports.cpp
  6. 42
      libi2pd_client/SOCKS.cpp

10
libi2pd/Config.cpp

@ -58,9 +58,9 @@ namespace config {
("floodfill", bool_switch()->default_value(false), "Router will be floodfill (default: disabled)") ("floodfill", bool_switch()->default_value(false), "Router will be floodfill (default: disabled)")
("bandwidth", value<std::string>()->default_value(""), "Bandwidth limit: integer in KBps or letters: L (32), O (256), P (2048), X (>9000)") ("bandwidth", value<std::string>()->default_value(""), "Bandwidth limit: integer in KBps or letters: L (32), O (256), P (2048), X (>9000)")
("share", value<int>()->default_value(100), "Limit of transit traffic from max bandwidth in percents. (default: 100)") ("share", value<int>()->default_value(100), "Limit of transit traffic from max bandwidth in percents. (default: 100)")
("ntcp", value<bool>()->default_value(false), "Enable NTCP transport (default: disabled)") ("ntcp", value<bool>()->default_value(false), "Enable NTCP transport (default: disabled)")
("ssu", value<bool>()->default_value(true), "Enable SSU transport (default: enabled)") ("ssu", value<bool>()->default_value(true), "Enable SSU transport (default: enabled)")
("ntcpproxy", value<std::string>()->default_value(""), "Proxy URL for NTCP transport") ("ntcpproxy", value<std::string>()->default_value(""), "Proxy URL for NTCP transport")
#ifdef _WIN32 #ifdef _WIN32
("svcctl", value<std::string>()->default_value(""), "Windows service management ('install' or 'remove')") ("svcctl", value<std::string>()->default_value(""), "Windows service management ('install' or 'remove')")
("insomnia", bool_switch()->default_value(false), "Prevent system from sleeping (default: disabled)") ("insomnia", bool_switch()->default_value(false), "Prevent system from sleeping (default: disabled)")
@ -97,7 +97,8 @@ namespace config {
("httpproxy.address", value<std::string>()->default_value("127.0.0.1"), "HTTP Proxy listen address") ("httpproxy.address", value<std::string>()->default_value("127.0.0.1"), "HTTP Proxy listen address")
("httpproxy.port", value<uint16_t>()->default_value(4444), "HTTP Proxy listen port") ("httpproxy.port", value<uint16_t>()->default_value(4444), "HTTP Proxy listen port")
("httpproxy.keys", value<std::string>()->default_value(""), "File to persist HTTP Proxy keys") ("httpproxy.keys", value<std::string>()->default_value(""), "File to persist HTTP Proxy keys")
("httpproxy.signaturetype", value<i2p::data::SigningKeyType>()->default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default") ("httpproxy.signaturetype", value<i2p::data::SigningKeyType>()->
default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default")
("httpproxy.inbound.length", value<std::string>()->default_value("3"), "HTTP proxy inbound tunnel length") ("httpproxy.inbound.length", value<std::string>()->default_value("3"), "HTTP proxy inbound tunnel length")
("httpproxy.outbound.length", value<std::string>()->default_value("3"), "HTTP proxy outbound tunnel length") ("httpproxy.outbound.length", value<std::string>()->default_value("3"), "HTTP proxy outbound tunnel length")
("httpproxy.inbound.quantity", value<std::string>()->default_value("5"), "HTTP proxy inbound tunnels quantity") ("httpproxy.inbound.quantity", value<std::string>()->default_value("5"), "HTTP proxy inbound tunnels quantity")
@ -114,7 +115,8 @@ namespace config {
("socksproxy.address", value<std::string>()->default_value("127.0.0.1"), "SOCKS Proxy listen address") ("socksproxy.address", value<std::string>()->default_value("127.0.0.1"), "SOCKS Proxy listen address")
("socksproxy.port", value<uint16_t>()->default_value(4447), "SOCKS Proxy listen port") ("socksproxy.port", value<uint16_t>()->default_value(4447), "SOCKS Proxy listen port")
("socksproxy.keys", value<std::string>()->default_value(""), "File to persist SOCKS Proxy keys") ("socksproxy.keys", value<std::string>()->default_value(""), "File to persist SOCKS Proxy keys")
("socksproxy.signaturetype", value<i2p::data::SigningKeyType>()->default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default") ("socksproxy.signaturetype", value<i2p::data::SigningKeyType>()->
default_value(i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519), "Signature type for new keys. 7 (EdDSA) by default")
("socksproxy.inbound.length", value<std::string>()->default_value("3"), "SOCKS proxy inbound tunnel length") ("socksproxy.inbound.length", value<std::string>()->default_value("3"), "SOCKS proxy inbound tunnel length")
("socksproxy.outbound.length", value<std::string>()->default_value("3"), "SOCKS proxy outbound tunnel length") ("socksproxy.outbound.length", value<std::string>()->default_value("3"), "SOCKS proxy outbound tunnel length")
("socksproxy.inbound.quantity", value<std::string>()->default_value("5"), "SOCKS proxy inbound tunnels quantity") ("socksproxy.inbound.quantity", value<std::string>()->default_value("5"), "SOCKS proxy inbound tunnels quantity")

119
libi2pd/NTCP2.cpp

@ -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;
@ -1443,14 +1466,14 @@ namespace transport
return; return;
} }
switch (m_ProxyType) switch (m_ProxyType)
{ {
case eSocksProxy: case eSocksProxy:
{ {
// 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());
@ -1549,38 +1572,13 @@ namespace transport
} }
default: default:
LogPrint(eLogError, "NTCP2: unknown proxy type, invalid state"); LogPrint(eLogError, "NTCP2: unknown proxy type, invalid state");
} }
} }
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(), [buff](const boost::system::error_code & ec, std::size_t written)
[](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());
@ -1628,9 +1616,9 @@ 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();
}); });
} }
} }
} }

2
libi2pd/NTCP2.h

@ -274,7 +274,7 @@ namespace transport
std::map<i2p::data::IdentHash, std::shared_ptr<NTCP2Session> > m_NTCP2Sessions; std::map<i2p::data::IdentHash, std::shared_ptr<NTCP2Session> > m_NTCP2Sessions;
std::list<std::shared_ptr<NTCP2Session> > m_PendingIncomingSessions; std::list<std::shared_ptr<NTCP2Session> > m_PendingIncomingSessions;
ProxyType m_ProxyType =eNoProxy; ProxyType m_ProxyType;
std::string m_ProxyAddress; std::string m_ProxyAddress;
uint16_t m_ProxyPort; uint16_t m_ProxyPort;
boost::asio::ip::tcp::resolver m_Resolver; boost::asio::ip::tcp::resolver m_Resolver;

1
libi2pd/NTCPSession.cpp

@ -1193,7 +1193,6 @@ namespace transport
void NTCPServer::AfterSocksHandshake(std::shared_ptr<NTCPSession> conn, std::shared_ptr<boost::asio::deadline_timer> timer, const std::string & host, uint16_t port, RemoteAddressType addrtype) void NTCPServer::AfterSocksHandshake(std::shared_ptr<NTCPSession> 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 = 0;
uint8_t buff[256]; uint8_t buff[256];

62
libi2pd/Transports.cpp

@ -176,7 +176,7 @@ namespace transport
if (proxyurl.schema == "http") if (proxyurl.schema == "http")
proxytype = NTCPServer::eHTTPProxy; proxytype = NTCPServer::eHTTPProxy;
m_NTCPServer->UseProxy(proxytype, proxyurl.host, proxyurl.port) ; m_NTCPServer->UseProxy(proxytype, proxyurl.host, proxyurl.port);
m_NTCPServer->Start(); m_NTCPServer->Start();
if(!m_NTCPServer->NetworkIsReady()) if(!m_NTCPServer->NetworkIsReady())
{ {
@ -194,7 +194,7 @@ namespace transport
return; return;
} }
// create NTCP2. TODO: move to acceptor // create NTCP2. TODO: move to acceptor
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
if (ntcp2) if (ntcp2)
{ {
if(!ntcp2proxy.empty()) if(!ntcp2proxy.empty())
@ -209,7 +209,7 @@ namespace transport
if (proxyurl.schema == "http") if (proxyurl.schema == "http")
proxytype = NTCP2Server::eHTTPProxy; proxytype = NTCP2Server::eHTTPProxy;
m_NTCP2Server->UseProxy(proxytype, proxyurl.host, proxyurl.port) ; m_NTCP2Server->UseProxy(proxytype, proxyurl.host, proxyurl.port);
m_NTCP2Server->Start(); m_NTCP2Server->Start();
} }
else else
@ -424,36 +424,36 @@ namespace transport
{ {
if (peer.router) // we have RI already if (peer.router) // we have RI already
{ {
if (!peer.numAttempts) // NTCP2 if (!peer.numAttempts) // NTCP2
{ {
peer.numAttempts++; peer.numAttempts++;
if (m_NTCP2Server) // we support NTCP2 if (m_NTCP2Server) // we support NTCP2
{ {
// NTCP2 have priority over NTCP // NTCP2 have priority over NTCP
auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only auto address = peer.router->GetNTCP2Address (true, !context.SupportsV6 ()); // published only
if (address) if (address)
{ {
auto s = std::make_shared<NTCP2Session> (*m_NTCP2Server, peer.router); auto s = std::make_shared<NTCP2Session> (*m_NTCP2Server, peer.router);
if(m_NTCP2Server->UsingProxy()) if(m_NTCP2Server->UsingProxy())
{ {
NTCP2Server::RemoteAddressType remote = NTCP2Server::eIP4Address; NTCP2Server::RemoteAddressType remote = NTCP2Server::eIP4Address;
std::string addr = address->host.to_string(); std::string addr = address->host.to_string();
if(address->host.is_v6()) if(address->host.is_v6())
remote = NTCP2Server::eIP6Address; remote = NTCP2Server::eIP6Address;
m_NTCP2Server->ConnectWithProxy(addr, address->port, remote, s); m_NTCP2Server->ConnectWithProxy(addr, address->port, remote, s);
} }
else else
m_NTCP2Server->Connect (address->host, address->port, s); m_NTCP2Server->Connect (address->host, address->port, s);
return true; return true;
} }
} }
} }
if (peer.numAttempts == 1) // NTCP1 if (peer.numAttempts == 1) // NTCP1
{ {
peer.numAttempts++; peer.numAttempts++;
auto address = peer.router->GetNTCPAddress (!context.SupportsV6 ()); auto address = peer.router->GetNTCPAddress (!context.SupportsV6 ());
if (address && m_NTCPServer) if (address && m_NTCPServer)
{ {

42
libi2pd_client/SOCKS.cpp

@ -118,7 +118,7 @@ namespace proxy
boost::asio::const_buffers_1 GenerateSOCKS5SelectAuth(authMethods method); boost::asio::const_buffers_1 GenerateSOCKS5SelectAuth(authMethods method);
boost::asio::const_buffers_1 GenerateSOCKS4Response(errTypes error, uint32_t ip, uint16_t port); boost::asio::const_buffers_1 GenerateSOCKS4Response(errTypes error, uint32_t ip, uint16_t port);
boost::asio::const_buffers_1 GenerateSOCKS5Response(errTypes error, addrTypes type, const address &addr, uint16_t port); boost::asio::const_buffers_1 GenerateSOCKS5Response(errTypes error, addrTypes type, const address &addr, uint16_t port);
boost::asio::const_buffers_1 GenerateUpstreamRequest(); boost::asio::const_buffers_1 GenerateUpstreamRequest();
bool Socks5ChooseAuth(); bool Socks5ChooseAuth();
void SocksRequestFailed(errTypes error); void SocksRequestFailed(errTypes error);
void SocksRequestSuccess(); void SocksRequestSuccess();
@ -128,27 +128,27 @@ namespace proxy
void HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream); void HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream);
void ForwardSOCKS(); void ForwardSOCKS();
void SocksUpstreamSuccess(); void SocksUpstreamSuccess();
void AsyncUpstreamSockRead(); void AsyncUpstreamSockRead();
void SendUpstreamRequest(); void SendUpstreamRequest();
void HandleUpstreamData(uint8_t * buff, std::size_t len); void HandleUpstreamData(uint8_t * buff, std::size_t len);
void HandleUpstreamSockSend(const boost::system::error_code & ecode, std::size_t bytes_transfered); void HandleUpstreamSockSend(const boost::system::error_code & ecode, std::size_t bytes_transfered);
void HandleUpstreamSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered); void HandleUpstreamSockRecv(const boost::system::error_code & ecode, std::size_t bytes_transfered);
void HandleUpstreamConnected(const boost::system::error_code & ecode, void HandleUpstreamConnected(const boost::system::error_code & ecode,
boost::asio::ip::tcp::resolver::iterator itr); boost::asio::ip::tcp::resolver::iterator itr);
void HandleUpstreamResolved(const boost::system::error_code & ecode, void HandleUpstreamResolved(const boost::system::error_code & ecode,
boost::asio::ip::tcp::resolver::iterator itr); boost::asio::ip::tcp::resolver::iterator itr);
boost::asio::ip::tcp::resolver m_proxy_resolver; boost::asio::ip::tcp::resolver m_proxy_resolver;
uint8_t m_sock_buff[socks_buffer_size]; uint8_t m_sock_buff[socks_buffer_size];
std::shared_ptr<boost::asio::ip::tcp::socket> m_sock, m_upstreamSock; std::shared_ptr<boost::asio::ip::tcp::socket> m_sock, m_upstreamSock;
std::shared_ptr<i2p::stream::Stream> m_stream; std::shared_ptr<i2p::stream::Stream> m_stream;
uint8_t *m_remaining_data; //Data left to be sent uint8_t *m_remaining_data; //Data left to be sent
uint8_t *m_remaining_upstream_data; //upstream data left to be forwarded uint8_t *m_remaining_upstream_data; //upstream data left to be forwarded
uint8_t m_response[7+max_socks_hostname_size]; uint8_t m_response[7+max_socks_hostname_size];
uint8_t m_upstream_response[SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE]; uint8_t m_upstream_response[SOCKS_UPSTREAM_SOCKS4A_REPLY_SIZE];
uint8_t m_upstream_request[14+max_socks_hostname_size]; uint8_t m_upstream_request[14+max_socks_hostname_size];
std::size_t m_upstream_response_len; std::size_t m_upstream_response_len;
address m_address; //Address address m_address; //Address
std::size_t m_remaining_data_len; //Size of the data left to be sent std::size_t m_remaining_data_len; //Size of the data left to be sent
uint32_t m_4aip; //Used in 4a requests uint32_t m_4aip; //Used in 4a requests
@ -161,11 +161,11 @@ namespace proxy
cmdTypes m_cmd; // Command requested cmdTypes m_cmd; // Command requested
state m_state; state m_state;
const bool m_UseUpstreamProxy; // do we want to use the upstream proxy for non i2p addresses? const bool m_UseUpstreamProxy; // do we want to use the upstream proxy for non i2p addresses?
const std::string m_UpstreamProxyAddress; const std::string m_UpstreamProxyAddress;
const uint16_t m_UpstreamProxyPort; const uint16_t m_UpstreamProxyPort;
public: public:
SOCKSHandler(SOCKSServer * parent, std::shared_ptr<boost::asio::ip::tcp::socket> sock, const std::string & upstreamAddr, const uint16_t upstreamPort, const bool useUpstream) : SOCKSHandler(SOCKSServer * parent, std::shared_ptr<boost::asio::ip::tcp::socket> sock, const std::string & upstreamAddr, const uint16_t upstreamPort, const bool useUpstream) :
I2PServiceHandler(parent), I2PServiceHandler(parent),
m_proxy_resolver(parent->GetService()), m_proxy_resolver(parent->GetService()),
m_sock(sock), m_stream(nullptr), m_sock(sock), m_stream(nullptr),
@ -226,7 +226,7 @@ namespace proxy
boost::asio::const_buffers_1 SOCKSHandler::GenerateSOCKS5Response(SOCKSHandler::errTypes error, SOCKSHandler::addrTypes type, const SOCKSHandler::address &addr, uint16_t port) boost::asio::const_buffers_1 SOCKSHandler::GenerateSOCKS5Response(SOCKSHandler::errTypes error, SOCKSHandler::addrTypes type, const SOCKSHandler::address &addr, uint16_t port)
{ {
size_t size = 6; size_t size = 6; // header + port
assert(error <= SOCKS5_ADDR_UNSUP); assert(error <= SOCKS5_ADDR_UNSUP);
m_response[0] = '\x05'; //Version m_response[0] = '\x05'; //Version
m_response[1] = error; //Response code m_response[1] = error; //Response code
@ -235,15 +235,15 @@ namespace proxy
switch (type) switch (type)
{ {
case ADDR_IPV4: case ADDR_IPV4:
size = 10; size += 4;
htobe32buf(m_response + 4, addr.ip); htobe32buf(m_response + 4, addr.ip);
break; break;
case ADDR_IPV6: case ADDR_IPV6:
size = 22; size += 16;
memcpy(m_response + 4, addr.ipv6, 16); memcpy(m_response + 4, addr.ipv6, 16);
break; break;
case ADDR_DNS: case ADDR_DNS:
size = 7 + addr.dns.size; size += (1 + addr.dns.size); /* name length + domain name */
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);
// replace type to IPv4 for support socks5 clients // replace type to IPv4 for support socks5 clients

Loading…
Cancel
Save