|
|
@ -16,6 +16,13 @@ namespace client |
|
|
|
m_Stream = m_Owner->GetLocalDestination ()->CreateStream (*leaseSet); |
|
|
|
m_Stream = m_Owner->GetLocalDestination ()->CreateStream (*leaseSet); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
I2PTunnelConnection::I2PTunnelConnection (I2PTunnel * owner, |
|
|
|
|
|
|
|
boost::asio::ip::tcp::socket * socket, std::shared_ptr<i2p::stream::Stream> stream): |
|
|
|
|
|
|
|
m_Socket (socket), m_Stream (stream), m_Owner (owner), |
|
|
|
|
|
|
|
m_RemoteEndpoint (socket->remote_endpoint ()), m_IsQuiet (true) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
I2PTunnelConnection::I2PTunnelConnection (I2PTunnel * owner, std::shared_ptr<i2p::stream::Stream> stream, |
|
|
|
I2PTunnelConnection::I2PTunnelConnection (I2PTunnel * owner, std::shared_ptr<i2p::stream::Stream> stream, |
|
|
|
boost::asio::ip::tcp::socket * socket, const boost::asio::ip::tcp::endpoint& target, bool quiet): |
|
|
|
boost::asio::ip::tcp::socket * socket, const boost::asio::ip::tcp::endpoint& target, bool quiet): |
|
|
|
m_Socket (socket), m_Stream (stream), m_Owner (owner), m_RemoteEndpoint (target), m_IsQuiet (quiet) |
|
|
|
m_Socket (socket), m_Stream (stream), m_Owner (owner), m_RemoteEndpoint (target), m_IsQuiet (quiet) |
|
|
@ -174,11 +181,7 @@ namespace client |
|
|
|
|
|
|
|
|
|
|
|
void I2PClientTunnel::Start () |
|
|
|
void I2PClientTunnel::Start () |
|
|
|
{ |
|
|
|
{ |
|
|
|
i2p::data::IdentHash identHash; |
|
|
|
GetIdentHash(); |
|
|
|
if (i2p::client::context.GetAddressBook ().GetIdentHash (m_Destination, identHash)) |
|
|
|
|
|
|
|
m_DestinationIdentHash = new i2p::data::IdentHash (identHash); |
|
|
|
|
|
|
|
if (!m_DestinationIdentHash) |
|
|
|
|
|
|
|
LogPrint ("I2PTunnel unknown destination ", m_Destination); |
|
|
|
|
|
|
|
m_Acceptor.listen (); |
|
|
|
m_Acceptor.listen (); |
|
|
|
Accept (); |
|
|
|
Accept (); |
|
|
|
} |
|
|
|
} |
|
|
@ -188,9 +191,26 @@ namespace client |
|
|
|
m_Acceptor.close(); |
|
|
|
m_Acceptor.close(); |
|
|
|
m_Timer.cancel (); |
|
|
|
m_Timer.cancel (); |
|
|
|
ClearConnections (); |
|
|
|
ClearConnections (); |
|
|
|
|
|
|
|
auto *originalIdentHash = m_DestinationIdentHash; |
|
|
|
m_DestinationIdentHash = nullptr; |
|
|
|
m_DestinationIdentHash = nullptr; |
|
|
|
|
|
|
|
delete originalIdentHash; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* HACK: maybe we should create a caching IdentHash provider in AddressBook */ |
|
|
|
|
|
|
|
const i2p::data::IdentHash * I2PClientTunnel::GetIdentHash () |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (!m_DestinationIdentHash) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
i2p::data::IdentHash identHash; |
|
|
|
|
|
|
|
if (i2p::client::context.GetAddressBook ().GetIdentHash (m_Destination, identHash)) |
|
|
|
|
|
|
|
m_DestinationIdentHash = new i2p::data::IdentHash (identHash); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
LogPrint (eLogWarning,"Remote destination ", m_Destination, " not found"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return m_DestinationIdentHash; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void I2PClientTunnel::Accept () |
|
|
|
void I2PClientTunnel::Accept () |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto newSocket = new boost::asio::ip::tcp::socket (GetService ()); |
|
|
|
auto newSocket = new boost::asio::ip::tcp::socket (GetService ()); |
|
|
@ -202,63 +222,37 @@ namespace client |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!ecode) |
|
|
|
if (!ecode) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (!m_DestinationIdentHash) |
|
|
|
const i2p::data::IdentHash *identHash = GetIdentHash(); |
|
|
|
{ |
|
|
|
if (identHash) |
|
|
|
i2p::data::IdentHash identHash; |
|
|
|
GetLocalDestination ()->CreateStream ( |
|
|
|
if (i2p::client::context.GetAddressBook ().GetIdentHash (m_Destination, identHash)) |
|
|
|
std::bind (&I2PClientTunnel::HandleStreamRequestComplete, |
|
|
|
m_DestinationIdentHash = new i2p::data::IdentHash (identHash); |
|
|
|
this, std::placeholders::_1, socket), *identHash); |
|
|
|
} |
|
|
|
|
|
|
|
if (m_DestinationIdentHash) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// try to get a LeaseSet
|
|
|
|
|
|
|
|
m_RemoteLeaseSet = GetLocalDestination ()->FindLeaseSet (*m_DestinationIdentHash); |
|
|
|
|
|
|
|
if (m_RemoteLeaseSet && m_RemoteLeaseSet->HasNonExpiredLeases ()) |
|
|
|
|
|
|
|
CreateConnection (socket); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
GetLocalDestination ()->RequestDestination (*m_DestinationIdentHash, |
|
|
|
|
|
|
|
std::bind (&I2PClientTunnel::HandleLeaseSetRequestComplete, |
|
|
|
|
|
|
|
this, std::placeholders::_1, socket)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint ("Remote destination ", m_Destination, " not found"); |
|
|
|
LogPrint (eLogError,"Closing socket"); |
|
|
|
delete socket; |
|
|
|
delete socket; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Accept (); |
|
|
|
Accept (); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
delete socket; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void I2PClientTunnel::HandleLeaseSetRequestComplete (bool success, boost::asio::ip::tcp::socket * socket) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
if (success) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
if (m_DestinationIdentHash) |
|
|
|
LogPrint (eLogError,"Closing socket on accept because: ", ecode.message ()); |
|
|
|
{ |
|
|
|
|
|
|
|
m_RemoteLeaseSet = GetLocalDestination ()->FindLeaseSet (*m_DestinationIdentHash); |
|
|
|
|
|
|
|
CreateConnection (socket); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
delete socket; |
|
|
|
delete socket; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void I2PClientTunnel::CreateConnection (boost::asio::ip::tcp::socket * socket) |
|
|
|
void I2PClientTunnel::HandleStreamRequestComplete (std::shared_ptr<i2p::stream::Stream> stream, boost::asio::ip::tcp::socket * socket) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (m_RemoteLeaseSet) // leaseSet found
|
|
|
|
if (stream) |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint ("New I2PTunnel connection"); |
|
|
|
LogPrint (eLogInfo,"New I2PTunnel connection"); |
|
|
|
auto connection = std::make_shared<I2PTunnelConnection>(this, socket, m_RemoteLeaseSet); |
|
|
|
auto connection = std::make_shared<I2PTunnelConnection>(this, socket, stream); |
|
|
|
AddConnection (connection); |
|
|
|
AddConnection (connection); |
|
|
|
connection->I2PConnect (); |
|
|
|
connection->I2PConnect (); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
LogPrint ("LeaseSet for I2PTunnel destination not found"); |
|
|
|
LogPrint (eLogError,"Issue when creating the stream, check the previous warnings for more info."); |
|
|
|
delete socket; |
|
|
|
delete socket; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|