mirror of
https://github.com/PurpleI2P/i2pd
synced 2024-11-10 00:00:29 +03:00
support upstream proxy through local sockets
This commit is contained in:
parent
f2b720617c
commit
a4a3f8e96b
@ -139,9 +139,11 @@ 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();
|
template<typename Socket>
|
||||||
|
void SocksUpstreamSuccess(std::shared_ptr<Socket>& upstreamSock);
|
||||||
void AsyncUpstreamSockRead();
|
void AsyncUpstreamSockRead();
|
||||||
void SendUpstreamRequest();
|
template<typename Socket>
|
||||||
|
void SendUpstreamRequest(std::shared_ptr<Socket>& upstreamSock);
|
||||||
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,
|
||||||
@ -150,6 +152,9 @@ namespace proxy
|
|||||||
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;
|
||||||
|
#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
|
||||||
|
std::shared_ptr<boost::asio::local::stream_protocol::socket> m_upstreamLocalSock;
|
||||||
|
#endif
|
||||||
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
|
||||||
@ -212,6 +217,14 @@ namespace proxy
|
|||||||
m_upstreamSock->close();
|
m_upstreamSock->close();
|
||||||
m_upstreamSock = nullptr;
|
m_upstreamSock = nullptr;
|
||||||
}
|
}
|
||||||
|
#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
|
||||||
|
if (m_upstreamLocalSock)
|
||||||
|
{
|
||||||
|
LogPrint(eLogDebug, "SOCKS: Closing upstream local socket");
|
||||||
|
m_upstreamLocalSock->close();
|
||||||
|
m_upstreamLocalSock = nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (m_stream)
|
if (m_stream)
|
||||||
{
|
{
|
||||||
LogPrint(eLogDebug, "SOCKS: Closing stream");
|
LogPrint(eLogDebug, "SOCKS: Closing stream");
|
||||||
@ -677,13 +690,45 @@ namespace proxy
|
|||||||
void SOCKSHandler::ForwardSOCKS()
|
void SOCKSHandler::ForwardSOCKS()
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "SOCKS: Forwarding to upstream");
|
LogPrint(eLogInfo, "SOCKS: Forwarding to upstream");
|
||||||
|
if (m_UpstreamProxyPort) // TCP
|
||||||
|
{
|
||||||
EnterState(UPSTREAM_RESOLVE);
|
EnterState(UPSTREAM_RESOLVE);
|
||||||
boost::asio::ip::tcp::resolver::query q(m_UpstreamProxyAddress, std::to_string(m_UpstreamProxyPort));
|
boost::asio::ip::tcp::resolver::query q(m_UpstreamProxyAddress, std::to_string(m_UpstreamProxyPort));
|
||||||
m_proxy_resolver.async_resolve(q, std::bind(&SOCKSHandler::HandleUpstreamResolved, shared_from_this(),
|
m_proxy_resolver.async_resolve(q, std::bind(&SOCKSHandler::HandleUpstreamResolved, shared_from_this(),
|
||||||
std::placeholders::_1, std::placeholders::_2));
|
std::placeholders::_1, std::placeholders::_2));
|
||||||
}
|
}
|
||||||
|
else if (!m_UpstreamProxyAddress.empty ())// local
|
||||||
|
{
|
||||||
|
#if defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
|
||||||
|
EnterState(UPSTREAM_CONNECT);
|
||||||
|
m_upstreamLocalSock = std::make_shared<boost::asio::local::stream_protocol::socket>(GetOwner()->GetService());
|
||||||
|
auto s = shared_from_this ();
|
||||||
|
m_upstreamLocalSock->async_connect(m_UpstreamProxyAddress,
|
||||||
|
[s](const boost::system::error_code& ecode)
|
||||||
|
{
|
||||||
|
if (ecode)
|
||||||
|
{
|
||||||
|
LogPrint(eLogWarning, "SOCKS: Could not connect to local upstream proxy: ", ecode.message());
|
||||||
|
s->SocksRequestFailed(SOCKS5_NET_UNREACH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LogPrint(eLogInfo, "SOCKS: Connected to local upstream proxy");
|
||||||
|
s->SendUpstreamRequest(s->m_upstreamLocalSock);
|
||||||
|
});
|
||||||
|
#else
|
||||||
|
LogPrint(eLogError, "SOCKS: Local sockets for upstream proxy not supported");
|
||||||
|
SocksRequestFailed(SOCKS5_ADDR_UNSUP);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogPrint(eLogError, "SOCKS: Incorrect upstream proxy address");
|
||||||
|
SocksRequestFailed(SOCKS5_ADDR_UNSUP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SOCKSHandler::SocksUpstreamSuccess()
|
template<typename Socket>
|
||||||
|
void SOCKSHandler::SocksUpstreamSuccess(std::shared_ptr<Socket>& upstreamSock)
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "SOCKS: Upstream success");
|
LogPrint(eLogInfo, "SOCKS: Upstream success");
|
||||||
boost::asio::const_buffers_1 response(nullptr, 0);
|
boost::asio::const_buffers_1 response(nullptr, 0);
|
||||||
@ -700,27 +745,27 @@ namespace proxy
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
m_sock->send(response);
|
m_sock->send(response);
|
||||||
auto forwarder = CreateSocketsPipe (GetOwner(), m_sock, m_upstreamSock);
|
auto forwarder = CreateSocketsPipe (GetOwner(), m_sock, upstreamSock);
|
||||||
m_upstreamSock = nullptr;
|
upstreamSock = nullptr;
|
||||||
m_sock = nullptr;
|
m_sock = nullptr;
|
||||||
GetOwner()->AddHandler(forwarder);
|
GetOwner()->AddHandler(forwarder);
|
||||||
forwarder->Start();
|
forwarder->Start();
|
||||||
Terminate();
|
Terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Socket>
|
||||||
void SOCKSHandler::SendUpstreamRequest()
|
void SOCKSHandler::SendUpstreamRequest(std::shared_ptr<Socket>& upstreamSock)
|
||||||
{
|
{
|
||||||
LogPrint(eLogInfo, "SOCKS: Negotiating with upstream proxy");
|
LogPrint(eLogInfo, "SOCKS: Negotiating with upstream proxy");
|
||||||
EnterState(UPSTREAM_HANDSHAKE);
|
EnterState(UPSTREAM_HANDSHAKE);
|
||||||
if (m_upstreamSock)
|
if (upstreamSock)
|
||||||
{
|
{
|
||||||
auto s = shared_from_this ();
|
auto s = shared_from_this ();
|
||||||
i2p::transport::Socks5Handshake (*m_upstreamSock, std::make_pair(m_address.dns.ToString (), m_port),
|
i2p::transport::Socks5Handshake (*upstreamSock, std::make_pair(m_address.dns.ToString (), m_port),
|
||||||
[s](const boost::system::error_code& ec)
|
[s, &upstreamSock](const boost::system::error_code& ec)
|
||||||
{
|
{
|
||||||
if (!ec)
|
if (!ec)
|
||||||
s->SocksUpstreamSuccess();
|
s->SocksUpstreamSuccess(upstreamSock);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
s->SocksRequestFailed(SOCKS5_NET_UNREACH);
|
s->SocksRequestFailed(SOCKS5_NET_UNREACH);
|
||||||
@ -740,7 +785,7 @@ namespace proxy
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LogPrint(eLogInfo, "SOCKS: Connected to upstream proxy");
|
LogPrint(eLogInfo, "SOCKS: Connected to upstream proxy");
|
||||||
SendUpstreamRequest();
|
SendUpstreamRequest(m_upstreamSock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SOCKSHandler::HandleUpstreamResolved(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr)
|
void SOCKSHandler::HandleUpstreamResolved(const boost::system::error_code & ecode, boost::asio::ip::tcp::resolver::iterator itr)
|
||||||
|
Loading…
Reference in New Issue
Block a user