mirror of
				https://github.com/PurpleI2P/i2pd.git
				synced 2025-11-04 00:20:46 +00:00 
			
		
		
		
	add option to only connect to certain routers
This commit is contained in:
		
							parent
							
								
									5c64c2ff42
								
							
						
					
					
						commit
						5f396d6311
					
				
					 6 changed files with 130 additions and 26 deletions
				
			
		| 
						 | 
				
			
			@ -184,6 +184,7 @@ namespace config {
 | 
			
		|||
  	trust.add_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.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?");
 | 
			
		||||
 | 
			
		||||
    m_OptionsDesc
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										36
									
								
								Daemon.cpp
									
										
									
									
									
								
							
							
						
						
									
										36
									
								
								Daemon.cpp
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -194,12 +194,40 @@ namespace i2p
 | 
			
		|||
      {
 | 
			
		||||
        LogPrint(eLogInfo, "Daemon: explicit trust enabled");
 | 
			
		||||
        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)
 | 
			
		||||
        {
 | 
			
		||||
          LogPrint(eLogInfo, "Daemon: setting restricted routes to use family ", fam);
 | 
			
		||||
          i2p::transport::transports.RestrictRoutes({fam});
 | 
			
		||||
        } else
 | 
			
		||||
          LogPrint(eLogError, "Daemon: no family specified for restricted routes");
 | 
			
		||||
					std::set<std::string> fams;
 | 
			
		||||
					size_t pos = 0, comma;
 | 
			
		||||
					do
 | 
			
		||||
					{
 | 
			
		||||
						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);
 | 
			
		||||
      if (hidden)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -126,10 +126,8 @@ namespace data
 | 
			
		|||
					i2p::context.CleanupDestination ();
 | 
			
		||||
					lastDestinationCleanup = ts;
 | 
			
		||||
				}
 | 
			
		||||
        // if we're in hidden mode don't publish or explore
 | 
			
		||||
				// if (m_HiddenMode) continue;
 | 
			
		||||
        
 | 
			
		||||
				if (ts - lastPublish >= NETDB_PUBLISH_INTERVAL) // publish 
 | 
			
		||||
				if (ts - lastPublish >= NETDB_PUBLISH_INTERVAL && !m_HiddenMode) // publish 
 | 
			
		||||
				{
 | 
			
		||||
					Publish ();
 | 
			
		||||
					lastPublish = ts;
 | 
			
		||||
| 
						 | 
				
			
			@ -148,7 +146,8 @@ namespace data
 | 
			
		|||
						if (numRouters < 1) numRouters = 1;
 | 
			
		||||
						if (numRouters > 9) numRouters = 9;	
 | 
			
		||||
						m_Requests.ManageRequests ();
 | 
			
		||||
						Explore (numRouters);
 | 
			
		||||
						if(!m_HiddenMode)
 | 
			
		||||
							Explore (numRouters);
 | 
			
		||||
						lastExploratory = ts;
 | 
			
		||||
					}	
 | 
			
		||||
				}	
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -241,6 +241,7 @@ namespace transport
 | 
			
		|||
				i2p::HandleI2NPMessage (it);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		if(RoutesRestricted() && ! IsRestrictedPeer(ident)) return;
 | 
			
		||||
		auto it = m_Peers.find (ident);
 | 
			
		||||
		if (it == m_Peers.end ())
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -494,6 +495,12 @@ namespace transport
 | 
			
		|||
		
 | 
			
		||||
	void Transports::DetectExternalIP ()
 | 
			
		||||
	{
 | 
			
		||||
		if (RoutesRestricted())
 | 
			
		||||
  	{
 | 
			
		||||
			LogPrint(eLogInfo, "Transports: restricted routes enabled, not detecting ip");
 | 
			
		||||
			i2p::context.SetStatus (eRouterStatusFirewalled);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		if (m_SSUServer)
 | 
			
		||||
		{
 | 
			
		||||
#ifndef MESHNET
 | 
			
		||||
| 
						 | 
				
			
			@ -520,8 +527,10 @@ namespace transport
 | 
			
		|||
 | 
			
		||||
	void Transports::PeerTest ()
 | 
			
		||||
	{
 | 
			
		||||
		if (RoutesRestricted()) return;
 | 
			
		||||
		if (m_SSUServer)
 | 
			
		||||
		{
 | 
			
		||||
			
 | 
			
		||||
			bool statusChanged = false;
 | 
			
		||||
			for (int i = 0; i < 5; i++)
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -578,6 +587,12 @@ namespace transport
 | 
			
		|||
			}
 | 
			
		||||
			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
 | 
			
		||||
				std::unique_lock<std::mutex>	l(m_PeersMutex);	
 | 
			
		||||
				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 ());	
 | 
			
		||||
		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);
 | 
			
		||||
    m_TrustedFamilies.clear();
 | 
			
		||||
| 
						 | 
				
			
			@ -663,22 +678,71 @@ namespace transport
 | 
			
		|||
      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 {
 | 
			
		||||
    std::lock_guard<std::mutex> lock(m_FamilyMutex);
 | 
			
		||||
    return m_TrustedFamilies.size() > 0;
 | 
			
		||||
    std::unique_lock<std::mutex> famlock(m_FamilyMutex);
 | 
			
		||||
		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 */
 | 
			
		||||
  std::shared_ptr<const i2p::data::RouterInfo> Transports::GetRestrictedPeer() const {
 | 
			
		||||
    std::string fam;
 | 
			
		||||
    {
 | 
			
		||||
      std::lock_guard<std::mutex> lock(m_FamilyMutex);
 | 
			
		||||
      // TODO: random family (?)
 | 
			
		||||
      fam = m_TrustedFamilies[0];
 | 
			
		||||
    }
 | 
			
		||||
    boost::to_lower(fam);
 | 
			
		||||
    return i2p::data::netdb.GetRandomRouterInFamily(fam);
 | 
			
		||||
  std::shared_ptr<const i2p::data::RouterInfo> Transports::GetRestrictedPeer() const
 | 
			
		||||
	{
 | 
			
		||||
		{
 | 
			
		||||
			std::lock_guard<std::mutex> l(m_FamilyMutex);
 | 
			
		||||
			std::string fam;
 | 
			
		||||
			auto sz = m_TrustedFamilies.size();
 | 
			
		||||
			if(sz > 1)
 | 
			
		||||
			{
 | 
			
		||||
				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;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								Transports.h
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								Transports.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -110,7 +110,11 @@ namespace transport
 | 
			
		|||
    /** do we want to use restricted routes? */
 | 
			
		||||
    bool RoutesRestricted() const;  
 | 
			
		||||
    /** 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 ();
 | 
			
		||||
			
 | 
			
		||||
| 
						 | 
				
			
			@ -158,6 +162,10 @@ namespace transport
 | 
			
		|||
    std::vector<std::string> m_TrustedFamilies;
 | 
			
		||||
    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:
 | 
			
		||||
 | 
			
		||||
			// for HTTP only
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -644,7 +644,9 @@ namespace tunnel
 | 
			
		|||
		{
 | 
			
		||||
			// trying to create one more oubound tunnel
 | 
			
		||||
			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;
 | 
			
		||||
			LogPrint (eLogDebug, "Tunnel: creating one hop outbound tunnel");
 | 
			
		||||
			CreateTunnel<OutboundTunnel> (
 | 
			
		||||
| 
						 | 
				
			
			@ -706,7 +708,9 @@ namespace tunnel
 | 
			
		|||
		if (m_OutboundTunnels.empty () || m_InboundTunnels.size () < 5) 
 | 
			
		||||
		{
 | 
			
		||||
			// 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) {
 | 
			
		||||
				LogPrint (eLogWarning, "Tunnel: can't find any router, skip creating tunnel");
 | 
			
		||||
				return;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue