add option to only connect to certain routers

pull/690/head
Jeff Becker 8 years ago
parent 5c64c2ff42
commit 5f396d6311
No known key found for this signature in database
GPG Key ID: AB950234D6EA286B

@ -184,6 +184,7 @@ namespace config {
trust.add_options() trust.add_options()
("trust.enabled", value<bool>()->default_value(false), "enable explicit trust options") ("trust.enabled", value<bool>()->default_value(false), "enable explicit trust options")
("trust.family", value<std::string>()->default_value(""), "Router Familiy to trust for first hops") ("trust.family", value<std::string>()->default_value(""), "Router Familiy to trust for first hops")
("trust.routers", value<std::string>()->default_value(""), "Only Connect to these routers")
("trust.hidden", value<bool>()->default_value(false), "should we hide our router from other routers?"); ("trust.hidden", value<bool>()->default_value(false), "should we hide our router from other routers?");
m_OptionsDesc m_OptionsDesc

@ -194,12 +194,40 @@ namespace i2p
{ {
LogPrint(eLogInfo, "Daemon: explicit trust enabled"); LogPrint(eLogInfo, "Daemon: explicit trust enabled");
std::string fam; i2p::config::GetOption("trust.family", fam); std::string fam; i2p::config::GetOption("trust.family", fam);
std::string routers; i2p::config::GetOption("trust.routers", routers);
bool restricted = false;
if (fam.length() > 0) if (fam.length() > 0)
{ {
LogPrint(eLogInfo, "Daemon: setting restricted routes to use family ", fam); std::set<std::string> fams;
i2p::transport::transports.RestrictRoutes({fam}); size_t pos = 0, comma;
} else do
LogPrint(eLogError, "Daemon: no family specified for restricted routes"); {
comma = fam.find (',', pos);
fams.insert (fam.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos));
pos = comma + 1;
}
while (comma != std::string::npos);
i2p::transport::transports.RestrictRoutesToFamilies(fams);
restricted = fams.size() > 0;
}
if (routers.length() > 0) {
std::set<i2p::data::IdentHash> idents;
size_t pos = 0, comma;
do
{
comma = routers.find (',', pos);
i2p::data::IdentHash ident;
ident.FromBase64 (routers.substr (pos, comma != std::string::npos ? comma - pos : std::string::npos));
idents.insert (ident);
pos = comma + 1;
}
while (comma != std::string::npos);
LogPrint(eLogInfo, "Daemon: setting restricted routes to use ", idents.size(), " trusted routesrs");
i2p::transport::transports.RestrictRoutesToRouters(idents);
restricted = idents.size() > 0;
}
if(!restricted)
LogPrint(eLogError, "Daemon: no trusted routers of families specififed");
} }
bool hidden; i2p::config::GetOption("trust.hidden", hidden); bool hidden; i2p::config::GetOption("trust.hidden", hidden);
if (hidden) if (hidden)

@ -126,10 +126,8 @@ namespace data
i2p::context.CleanupDestination (); i2p::context.CleanupDestination ();
lastDestinationCleanup = ts; lastDestinationCleanup = ts;
} }
// if we're in hidden mode don't publish or explore
// if (m_HiddenMode) continue; if (ts - lastPublish >= NETDB_PUBLISH_INTERVAL && !m_HiddenMode) // publish
if (ts - lastPublish >= NETDB_PUBLISH_INTERVAL) // publish
{ {
Publish (); Publish ();
lastPublish = ts; lastPublish = ts;
@ -147,8 +145,9 @@ namespace data
numRouters = 800/numRouters; numRouters = 800/numRouters;
if (numRouters < 1) numRouters = 1; if (numRouters < 1) numRouters = 1;
if (numRouters > 9) numRouters = 9; if (numRouters > 9) numRouters = 9;
m_Requests.ManageRequests (); m_Requests.ManageRequests ();
Explore (numRouters); if(!m_HiddenMode)
Explore (numRouters);
lastExploratory = ts; lastExploratory = ts;
} }
} }

@ -240,7 +240,8 @@ namespace transport
for (auto& it: msgs) for (auto& it: msgs)
i2p::HandleI2NPMessage (it); i2p::HandleI2NPMessage (it);
return; return;
} }
if(RoutesRestricted() && ! IsRestrictedPeer(ident)) return;
auto it = m_Peers.find (ident); auto it = m_Peers.find (ident);
if (it == m_Peers.end ()) if (it == m_Peers.end ())
{ {
@ -494,6 +495,12 @@ namespace transport
void Transports::DetectExternalIP () void Transports::DetectExternalIP ()
{ {
if (RoutesRestricted())
{
LogPrint(eLogInfo, "Transports: restricted routes enabled, not detecting ip");
i2p::context.SetStatus (eRouterStatusFirewalled);
return;
}
if (m_SSUServer) if (m_SSUServer)
{ {
#ifndef MESHNET #ifndef MESHNET
@ -520,8 +527,10 @@ namespace transport
void Transports::PeerTest () void Transports::PeerTest ()
{ {
if (RoutesRestricted()) return;
if (m_SSUServer) if (m_SSUServer)
{ {
bool statusChanged = false; bool statusChanged = false;
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
{ {
@ -578,6 +587,12 @@ namespace transport
} }
else // incoming connection else // incoming connection
{ {
if(RoutesRestricted() && ! IsRestrictedPeer(ident)) {
// not trusted
LogPrint(eLogWarning, "Transports: closing untrusted inbound connection from ", ident.ToBase64());
session->Done();
return;
}
session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); // send DatabaseStore session->SendI2NPMessages ({ CreateDatabaseStoreMsg () }); // send DatabaseStore
std::unique_lock<std::mutex> l(m_PeersMutex); std::unique_lock<std::mutex> l(m_PeersMutex);
m_Peers.insert (std::make_pair (ident, Peer{ 0, nullptr, { session }, i2p::util::GetSecondsSinceEpoch (), {} })); m_Peers.insert (std::make_pair (ident, Peer{ 0, nullptr, { session }, i2p::util::GetSecondsSinceEpoch (), {} }));
@ -655,7 +670,7 @@ namespace transport
std::advance (it, rand () % m_Peers.size ()); std::advance (it, rand () % m_Peers.size ());
return it != m_Peers.end () ? it->second.router : nullptr; return it != m_Peers.end () ? it->second.router : nullptr;
} }
void Transports::RestrictRoutes(std::vector<std::string> families) void Transports::RestrictRoutesToFamilies(std::set<std::string> families)
{ {
std::lock_guard<std::mutex> lock(m_FamilyMutex); std::lock_guard<std::mutex> lock(m_FamilyMutex);
m_TrustedFamilies.clear(); m_TrustedFamilies.clear();
@ -663,22 +678,71 @@ namespace transport
m_TrustedFamilies.push_back(fam); m_TrustedFamilies.push_back(fam);
} }
void Transports::RestrictRoutesToRouters(std::set<i2p::data::IdentHash> routers)
{
std::unique_lock<std::mutex> lock(m_TrustedRoutersMutex);
m_TrustedRouters.clear();
for (const auto & ri : routers )
m_TrustedRouters.push_back(ri);
}
bool Transports::RoutesRestricted() const { bool Transports::RoutesRestricted() const {
std::lock_guard<std::mutex> lock(m_FamilyMutex); std::unique_lock<std::mutex> famlock(m_FamilyMutex);
return m_TrustedFamilies.size() > 0; std::unique_lock<std::mutex> routerslock(m_TrustedRoutersMutex);
return m_TrustedFamilies.size() > 0 || m_TrustedRouters.size() > 0;
} }
/** XXX: if routes are not restricted this dies */ /** XXX: if routes are not restricted this dies */
std::shared_ptr<const i2p::data::RouterInfo> Transports::GetRestrictedPeer() const { std::shared_ptr<const i2p::data::RouterInfo> Transports::GetRestrictedPeer() const
std::string fam; {
{ {
std::lock_guard<std::mutex> lock(m_FamilyMutex); std::lock_guard<std::mutex> l(m_FamilyMutex);
// TODO: random family (?) std::string fam;
fam = m_TrustedFamilies[0]; auto sz = m_TrustedFamilies.size();
} if(sz > 1)
boost::to_lower(fam); {
return i2p::data::netdb.GetRandomRouterInFamily(fam); auto it = m_TrustedFamilies.begin ();
std::advance(it, rand() % sz);
fam = *it;
boost::to_lower(fam);
}
else if (sz == 1)
{
fam = m_TrustedFamilies[0];
}
if (fam.size())
return i2p::data::netdb.GetRandomRouterInFamily(fam);
}
{
std::unique_lock<std::mutex> l(m_TrustedRoutersMutex);
auto sz = m_TrustedRouters.size();
if (sz)
{
if(sz == 1)
return i2p::data::netdb.FindRouter(m_TrustedRouters[0]);
auto it = m_TrustedRouters.begin();
std::advance(it, rand() % sz);
return i2p::data::netdb.FindRouter(*it);
}
}
return nullptr;
} }
bool Transports::IsRestrictedPeer(const i2p::data::IdentHash & ih) const
{
{
std::unique_lock<std::mutex> l(m_TrustedRoutersMutex);
for (const auto & r : m_TrustedRouters )
if ( r == ih ) return true;
}
{
std::unique_lock<std::mutex> l(m_FamilyMutex);
auto ri = i2p::data::netdb.FindRouter(ih);
for (const auto & fam : m_TrustedFamilies)
if(ri->IsFamily(fam)) return true;
}
return false;
}
} }
} }

@ -110,7 +110,11 @@ namespace transport
/** do we want to use restricted routes? */ /** do we want to use restricted routes? */
bool RoutesRestricted() const; bool RoutesRestricted() const;
/** restrict routes to use only these router families for first hops */ /** restrict routes to use only these router families for first hops */
void RestrictRoutes(std::vector<std::string> families); void RestrictRoutesToFamilies(std::set<std::string> families);
/** restrict routes to use only these routers for first hops */
void RestrictRoutesToRouters(std::set<i2p::data::IdentHash> routers);
bool IsRestrictedPeer(const i2p::data::IdentHash & ident) const;
void PeerTest (); void PeerTest ();
@ -157,6 +161,10 @@ namespace transport
/** which router families to trust for first hops */ /** which router families to trust for first hops */
std::vector<std::string> m_TrustedFamilies; std::vector<std::string> m_TrustedFamilies;
mutable std::mutex m_FamilyMutex; mutable std::mutex m_FamilyMutex;
/** which routers for first hop to trust */
std::vector<i2p::data::IdentHash> m_TrustedRouters;
mutable std::mutex m_TrustedRoutersMutex;
public: public:

@ -644,7 +644,9 @@ namespace tunnel
{ {
// trying to create one more oubound tunnel // trying to create one more oubound tunnel
auto inboundTunnel = GetNextInboundTunnel (); auto inboundTunnel = GetNextInboundTunnel ();
auto router = i2p::data::netdb.GetRandomRouter (); auto router = i2p::transport::transports.RoutesRestricted() ?
i2p::transport::transports.GetRestrictedPeer() :
i2p::data::netdb.GetRandomRouter ();
if (!inboundTunnel || !router) return; if (!inboundTunnel || !router) return;
LogPrint (eLogDebug, "Tunnel: creating one hop outbound tunnel"); LogPrint (eLogDebug, "Tunnel: creating one hop outbound tunnel");
CreateTunnel<OutboundTunnel> ( CreateTunnel<OutboundTunnel> (
@ -706,7 +708,9 @@ namespace tunnel
if (m_OutboundTunnels.empty () || m_InboundTunnels.size () < 5) if (m_OutboundTunnels.empty () || m_InboundTunnels.size () < 5)
{ {
// trying to create one more inbound tunnel // trying to create one more inbound tunnel
auto router = i2p::data::netdb.GetRandomRouter (); auto router = i2p::transport::transports.RoutesRestricted() ?
i2p::transport::transports.GetRestrictedPeer() :
i2p::data::netdb.GetRandomRouter ();
if (!router) { if (!router) {
LogPrint (eLogWarning, "Tunnel: can't find any router, skip creating tunnel"); LogPrint (eLogWarning, "Tunnel: can't find any router, skip creating tunnel");
return; return;

Loading…
Cancel
Save