2017-04-08 16:51:35 +00:00
|
|
|
#include "MatchedDestination.h"
|
|
|
|
#include "Log.h"
|
|
|
|
#include "ClientContext.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace i2p
|
|
|
|
{
|
|
|
|
namespace client
|
|
|
|
{
|
|
|
|
MatchedTunnelDestination::MatchedTunnelDestination(const i2p::data::PrivateKeys & keys, const std::string & remoteName, const std::map<std::string, std::string> * params)
|
2020-02-04 19:17:23 +00:00
|
|
|
: RunnableClientDestination(keys, false, params),
|
2017-04-08 16:51:35 +00:00
|
|
|
m_RemoteName(remoteName) {}
|
|
|
|
|
2017-04-08 18:15:08 +00:00
|
|
|
|
2017-04-08 16:51:35 +00:00
|
|
|
void MatchedTunnelDestination::ResolveCurrentLeaseSet()
|
|
|
|
{
|
2019-03-28 16:19:19 +00:00
|
|
|
auto addr = i2p::client::context.GetAddressBook().GetAddress (m_RemoteName);
|
|
|
|
if(addr && addr->IsIdentHash ())
|
2017-04-08 16:51:35 +00:00
|
|
|
{
|
2019-03-28 16:19:19 +00:00
|
|
|
m_RemoteIdent = addr->identHash;
|
2017-04-08 16:51:35 +00:00
|
|
|
auto ls = FindLeaseSet(m_RemoteIdent);
|
|
|
|
if(ls)
|
|
|
|
HandleFoundCurrentLeaseSet(ls);
|
|
|
|
else
|
|
|
|
RequestDestination(m_RemoteIdent, std::bind(&MatchedTunnelDestination::HandleFoundCurrentLeaseSet, this, std::placeholders::_1));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
LogPrint(eLogWarning, "Destination: failed to resolve ", m_RemoteName);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MatchedTunnelDestination::HandleFoundCurrentLeaseSet(std::shared_ptr<const i2p::data::LeaseSet> ls)
|
|
|
|
{
|
|
|
|
if(ls)
|
|
|
|
{
|
|
|
|
LogPrint(eLogDebug, "Destination: resolved remote lease set for ", m_RemoteName);
|
|
|
|
m_RemoteLeaseSet = ls;
|
|
|
|
}
|
|
|
|
else
|
2017-04-08 18:15:08 +00:00
|
|
|
{
|
|
|
|
m_ResolveTimer->expires_from_now(boost::posix_time::seconds(1));
|
|
|
|
m_ResolveTimer->async_wait([&](const boost::system::error_code & ec) {
|
|
|
|
if(!ec) ResolveCurrentLeaseSet();
|
|
|
|
});
|
|
|
|
}
|
2017-04-08 16:51:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-02-02 23:58:58 +00:00
|
|
|
void MatchedTunnelDestination::Start()
|
2017-04-08 16:51:35 +00:00
|
|
|
{
|
2020-02-02 23:58:58 +00:00
|
|
|
ClientDestination::Start();
|
|
|
|
m_ResolveTimer = std::make_shared<boost::asio::deadline_timer>(GetService());
|
|
|
|
GetTunnelPool()->SetCustomPeerSelector(this);
|
|
|
|
ResolveCurrentLeaseSet();
|
2017-04-08 16:51:35 +00:00
|
|
|
}
|
|
|
|
|
2020-02-02 23:58:58 +00:00
|
|
|
void MatchedTunnelDestination::Stop()
|
2017-04-08 16:51:35 +00:00
|
|
|
{
|
2020-02-02 23:58:58 +00:00
|
|
|
ClientDestination::Stop();
|
|
|
|
if(m_ResolveTimer)
|
|
|
|
m_ResolveTimer->cancel();
|
2017-04-08 16:51:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool MatchedTunnelDestination::SelectPeers(i2p::tunnel::Path & path, int hops, bool inbound)
|
|
|
|
{
|
|
|
|
auto pool = GetTunnelPool();
|
|
|
|
if(!i2p::tunnel::StandardSelectPeers(path, hops, inbound, std::bind(&i2p::tunnel::TunnelPool::SelectNextHop, pool, std::placeholders::_1)))
|
|
|
|
return false;
|
|
|
|
// more here for outbound tunnels
|
|
|
|
if(!inbound && m_RemoteLeaseSet)
|
|
|
|
{
|
|
|
|
if(m_RemoteLeaseSet->IsExpired())
|
|
|
|
{
|
|
|
|
ResolveCurrentLeaseSet();
|
|
|
|
}
|
|
|
|
if(m_RemoteLeaseSet && !m_RemoteLeaseSet->IsExpired())
|
|
|
|
{
|
|
|
|
// remote lease set is good
|
|
|
|
auto leases = m_RemoteLeaseSet->GetNonExpiredLeases();
|
|
|
|
// pick lease
|
|
|
|
std::shared_ptr<i2p::data::RouterInfo> obep;
|
|
|
|
while(!obep && leases.size() > 0) {
|
|
|
|
auto idx = rand() % leases.size();
|
|
|
|
auto lease = leases[idx];
|
|
|
|
obep = i2p::data::netdb.FindRouter(lease->tunnelGateway);
|
|
|
|
leases.erase(leases.begin()+idx);
|
|
|
|
}
|
|
|
|
if(obep) {
|
|
|
|
path.push_back(obep->GetRouterIdentity());
|
|
|
|
LogPrint(eLogDebug, "Destination: found OBEP matching IBGW");
|
|
|
|
} else
|
|
|
|
LogPrint(eLogWarning, "Destination: could not find proper IBGW for matched outbound tunnel");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|