mirror of
				https://github.com/PurpleI2P/i2pd.git
				synced 2025-11-04 08:30:46 +00:00 
			
		
		
		
	reindent Datagram, Daemon, update default subscription in config example
Signed-off-by: R4SAS <r4sas@i2pmail.org>
This commit is contained in:
		
							parent
							
								
									0e5dc15005
								
							
						
					
					
						commit
						6966539b86
					
				
					 3 changed files with 383 additions and 380 deletions
				
			
		| 
						 | 
				
			
			@ -192,8 +192,8 @@ verify = true
 | 
			
		|||
 | 
			
		||||
[addressbook]
 | 
			
		||||
## AddressBook subscription URL for initial setup
 | 
			
		||||
## Default: inr.i2p at "mainline" I2P Network
 | 
			
		||||
# defaulturl = http://joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq.b32.i2p/export/alive-hosts.txt
 | 
			
		||||
## Default: reg.i2p at "mainline" I2P Network
 | 
			
		||||
# defaulturl = http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt
 | 
			
		||||
## Optional subscriptions URLs, separated by comma
 | 
			
		||||
# subscriptions = http://inr.i2p/export/alive-hosts.txt,http://stats.i2p/cgi-bin/newhosts.txt,http://rus.i2p/hosts.txt
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,403 +35,406 @@
 | 
			
		|||
 | 
			
		||||
namespace i2p
 | 
			
		||||
{
 | 
			
		||||
	namespace util
 | 
			
		||||
namespace util
 | 
			
		||||
{
 | 
			
		||||
	class Daemon_Singleton::Daemon_Singleton_Private
 | 
			
		||||
	{
 | 
			
		||||
		class Daemon_Singleton::Daemon_Singleton_Private
 | 
			
		||||
		{
 | 
			
		||||
		public:
 | 
			
		||||
			Daemon_Singleton_Private() {};
 | 
			
		||||
			~Daemon_Singleton_Private() {};
 | 
			
		||||
	public:
 | 
			
		||||
		Daemon_Singleton_Private() {};
 | 
			
		||||
		~Daemon_Singleton_Private() {};
 | 
			
		||||
 | 
			
		||||
			std::unique_ptr<i2p::http::HTTPServer> httpServer;
 | 
			
		||||
			std::unique_ptr<i2p::client::I2PControlService> m_I2PControlService;
 | 
			
		||||
			std::unique_ptr<i2p::transport::UPnP> UPnP;
 | 
			
		||||
			std::unique_ptr<i2p::util::NTPTimeSync> m_NTPSync;
 | 
			
		||||
		};
 | 
			
		||||
		std::unique_ptr<i2p::http::HTTPServer> httpServer;
 | 
			
		||||
		std::unique_ptr<i2p::client::I2PControlService> m_I2PControlService;
 | 
			
		||||
		std::unique_ptr<i2p::transport::UPnP> UPnP;
 | 
			
		||||
		std::unique_ptr<i2p::util::NTPTimeSync> m_NTPSync;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
		Daemon_Singleton::Daemon_Singleton() : isDaemon(false), running(true), d(*new Daemon_Singleton_Private()) {}
 | 
			
		||||
		Daemon_Singleton::~Daemon_Singleton() {
 | 
			
		||||
			delete &d;
 | 
			
		||||
		}
 | 
			
		||||
	Daemon_Singleton::Daemon_Singleton() : isDaemon(false), running(true), d(*new Daemon_Singleton_Private()) {}
 | 
			
		||||
	Daemon_Singleton::~Daemon_Singleton() {
 | 
			
		||||
		delete &d;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		bool Daemon_Singleton::IsService () const
 | 
			
		||||
		{
 | 
			
		||||
			bool service = false;
 | 
			
		||||
	bool Daemon_Singleton::IsService () const
 | 
			
		||||
	{
 | 
			
		||||
		bool service = false;
 | 
			
		||||
#ifndef _WIN32
 | 
			
		||||
			i2p::config::GetOption("service", service);
 | 
			
		||||
		i2p::config::GetOption("service", service);
 | 
			
		||||
#endif
 | 
			
		||||
			return service;
 | 
			
		||||
		}
 | 
			
		||||
		return service;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		bool Daemon_Singleton::init(int argc, char* argv[]) {
 | 
			
		||||
			return init(argc, argv, nullptr);
 | 
			
		||||
		}
 | 
			
		||||
	bool Daemon_Singleton::init(int argc, char* argv[]) {
 | 
			
		||||
		return init(argc, argv, nullptr);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		bool Daemon_Singleton::init(int argc, char* argv[], std::shared_ptr<std::ostream> logstream)
 | 
			
		||||
	bool Daemon_Singleton::init(int argc, char* argv[], std::shared_ptr<std::ostream> logstream)
 | 
			
		||||
	{
 | 
			
		||||
		i2p::config::Init();
 | 
			
		||||
		i2p::config::ParseCmdline(argc, argv);
 | 
			
		||||
 | 
			
		||||
		std::string config;  i2p::config::GetOption("conf",    config);
 | 
			
		||||
		std::string datadir; i2p::config::GetOption("datadir", datadir);
 | 
			
		||||
		i2p::fs::DetectDataDir(datadir, IsService());
 | 
			
		||||
		i2p::fs::Init();
 | 
			
		||||
 | 
			
		||||
		datadir = i2p::fs::GetDataDir();
 | 
			
		||||
 | 
			
		||||
		if (config == "")
 | 
			
		||||
		{
 | 
			
		||||
			i2p::config::Init();
 | 
			
		||||
			i2p::config::ParseCmdline(argc, argv);
 | 
			
		||||
 | 
			
		||||
			std::string config;  i2p::config::GetOption("conf",    config);
 | 
			
		||||
			std::string datadir; i2p::config::GetOption("datadir", datadir);
 | 
			
		||||
			i2p::fs::DetectDataDir(datadir, IsService());
 | 
			
		||||
			i2p::fs::Init();
 | 
			
		||||
 | 
			
		||||
			datadir = i2p::fs::GetDataDir();
 | 
			
		||||
 | 
			
		||||
			if (config == "")
 | 
			
		||||
			{
 | 
			
		||||
				config = i2p::fs::DataDirPath("i2pd.conf");
 | 
			
		||||
				if (!i2p::fs::Exists (config)) {
 | 
			
		||||
					// use i2pd.conf only if exists
 | 
			
		||||
					config = ""; /* reset */
 | 
			
		||||
				}
 | 
			
		||||
			config = i2p::fs::DataDirPath("i2pd.conf");
 | 
			
		||||
			if (!i2p::fs::Exists (config)) {
 | 
			
		||||
				// use i2pd.conf only if exists
 | 
			
		||||
				config = ""; /* reset */
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
			i2p::config::ParseConfig(config);
 | 
			
		||||
			i2p::config::Finalize();
 | 
			
		||||
		i2p::config::ParseConfig(config);
 | 
			
		||||
		i2p::config::Finalize();
 | 
			
		||||
 | 
			
		||||
			i2p::config::GetOption("daemon", isDaemon);
 | 
			
		||||
		i2p::config::GetOption("daemon", isDaemon);
 | 
			
		||||
 | 
			
		||||
			std::string logs     = ""; i2p::config::GetOption("log",      logs);
 | 
			
		||||
			std::string logfile  = ""; i2p::config::GetOption("logfile",  logfile);
 | 
			
		||||
			std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel);
 | 
			
		||||
			bool logclftime;           i2p::config::GetOption("logclftime", logclftime);
 | 
			
		||||
		std::string logs     = ""; i2p::config::GetOption("log",      logs);
 | 
			
		||||
		std::string logfile  = ""; i2p::config::GetOption("logfile",  logfile);
 | 
			
		||||
		std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel);
 | 
			
		||||
		bool logclftime;           i2p::config::GetOption("logclftime", logclftime);
 | 
			
		||||
 | 
			
		||||
			/* setup logging */
 | 
			
		||||
			if (logclftime)
 | 
			
		||||
				i2p::log::Logger().SetTimeFormat ("[%d/%b/%Y:%H:%M:%S %z]");
 | 
			
		||||
		/* setup logging */
 | 
			
		||||
		if (logclftime)
 | 
			
		||||
			i2p::log::Logger().SetTimeFormat ("[%d/%b/%Y:%H:%M:%S %z]");
 | 
			
		||||
 | 
			
		||||
			if (isDaemon && (logs == "" || logs == "stdout"))
 | 
			
		||||
				logs = "file";
 | 
			
		||||
		if (isDaemon && (logs == "" || logs == "stdout"))
 | 
			
		||||
			logs = "file";
 | 
			
		||||
 | 
			
		||||
			i2p::log::Logger().SetLogLevel(loglevel);
 | 
			
		||||
			if (logstream) {
 | 
			
		||||
				LogPrint(eLogInfo, "Log: will send messages to std::ostream");
 | 
			
		||||
				i2p::log::Logger().SendTo (logstream);
 | 
			
		||||
			} else if (logs == "file") {
 | 
			
		||||
				if (logfile == "")
 | 
			
		||||
					logfile = i2p::fs::DataDirPath("i2pd.log");
 | 
			
		||||
				LogPrint(eLogInfo, "Log: will send messages to ", logfile);
 | 
			
		||||
				i2p::log::Logger().SendTo (logfile);
 | 
			
		||||
		i2p::log::Logger().SetLogLevel(loglevel);
 | 
			
		||||
		if (logstream) {
 | 
			
		||||
			LogPrint(eLogInfo, "Log: will send messages to std::ostream");
 | 
			
		||||
			i2p::log::Logger().SendTo (logstream);
 | 
			
		||||
		} else if (logs == "file") {
 | 
			
		||||
			if (logfile == "")
 | 
			
		||||
				logfile = i2p::fs::DataDirPath("i2pd.log");
 | 
			
		||||
			LogPrint(eLogInfo, "Log: will send messages to ", logfile);
 | 
			
		||||
			i2p::log::Logger().SendTo (logfile);
 | 
			
		||||
#ifndef _WIN32
 | 
			
		||||
			} else if (logs == "syslog") {
 | 
			
		||||
				LogPrint(eLogInfo, "Log: will send messages to syslog");
 | 
			
		||||
				i2p::log::Logger().SendTo("i2pd", LOG_DAEMON);
 | 
			
		||||
		} else if (logs == "syslog") {
 | 
			
		||||
			LogPrint(eLogInfo, "Log: will send messages to syslog");
 | 
			
		||||
			i2p::log::Logger().SendTo("i2pd", LOG_DAEMON);
 | 
			
		||||
#endif
 | 
			
		||||
			} else {
 | 
			
		||||
				// use stdout -- default
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			// use stdout -- default
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
			LogPrint(eLogInfo,  "i2pd v", VERSION, " starting");
 | 
			
		||||
			LogPrint(eLogDebug, "FS: main config file: ", config);
 | 
			
		||||
			LogPrint(eLogDebug, "FS: data directory: ", datadir);
 | 
			
		||||
		LogPrint(eLogInfo,  "i2pd v", VERSION, " starting");
 | 
			
		||||
		LogPrint(eLogDebug, "FS: main config file: ", config);
 | 
			
		||||
		LogPrint(eLogDebug, "FS: data directory: ", datadir);
 | 
			
		||||
 | 
			
		||||
			bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation);
 | 
			
		||||
			bool aesni; i2p::config::GetOption("cpuext.aesni", aesni);
 | 
			
		||||
			bool avx; i2p::config::GetOption("cpuext.avx", avx);
 | 
			
		||||
			bool forceCpuExt; i2p::config::GetOption("cpuext.force", forceCpuExt);
 | 
			
		||||
			i2p::crypto::InitCrypto (precomputation, aesni, avx, forceCpuExt);
 | 
			
		||||
		bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation);
 | 
			
		||||
		bool aesni; i2p::config::GetOption("cpuext.aesni", aesni);
 | 
			
		||||
		bool avx; i2p::config::GetOption("cpuext.avx", avx);
 | 
			
		||||
		bool forceCpuExt; i2p::config::GetOption("cpuext.force", forceCpuExt);
 | 
			
		||||
		i2p::crypto::InitCrypto (precomputation, aesni, avx, forceCpuExt);
 | 
			
		||||
 | 
			
		||||
			int netID; i2p::config::GetOption("netid", netID);
 | 
			
		||||
			i2p::context.SetNetID (netID);
 | 
			
		||||
			i2p::context.Init ();
 | 
			
		||||
		int netID; i2p::config::GetOption("netid", netID);
 | 
			
		||||
		i2p::context.SetNetID (netID);
 | 
			
		||||
		i2p::context.Init ();
 | 
			
		||||
 | 
			
		||||
			bool ipv6;		i2p::config::GetOption("ipv6", ipv6);
 | 
			
		||||
			bool ipv4;		i2p::config::GetOption("ipv4", ipv4);
 | 
			
		||||
		bool ipv6;		i2p::config::GetOption("ipv6", ipv6);
 | 
			
		||||
		bool ipv4;		i2p::config::GetOption("ipv4", ipv4);
 | 
			
		||||
#ifdef MESHNET
 | 
			
		||||
			// manual override for meshnet
 | 
			
		||||
			ipv4 = false;
 | 
			
		||||
			ipv6 = true;
 | 
			
		||||
		// manual override for meshnet
 | 
			
		||||
		ipv4 = false;
 | 
			
		||||
		ipv6 = true;
 | 
			
		||||
#endif
 | 
			
		||||
			bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg);
 | 
			
		||||
			boost::asio::ip::address_v6 yggaddr;
 | 
			
		||||
			if (ygg)
 | 
			
		||||
		bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg);
 | 
			
		||||
		boost::asio::ip::address_v6 yggaddr;
 | 
			
		||||
		if (ygg)
 | 
			
		||||
		{
 | 
			
		||||
			std::string yggaddress; i2p::config::GetOption ("meshnets.yggaddress", yggaddress);
 | 
			
		||||
			if (!yggaddress.empty ())
 | 
			
		||||
			{
 | 
			
		||||
				std::string yggaddress; i2p::config::GetOption ("meshnets.yggaddress", yggaddress);
 | 
			
		||||
				if (!yggaddress.empty ())
 | 
			
		||||
				yggaddr = boost::asio::ip::address_v6::from_string (yggaddress);
 | 
			
		||||
				if (yggaddr.is_unspecified () || !i2p::util::net::IsYggdrasilAddress (yggaddr) ||
 | 
			
		||||
					!i2p::util::net::IsLocalAddress (yggaddr))
 | 
			
		||||
				{
 | 
			
		||||
					yggaddr = boost::asio::ip::address_v6::from_string (yggaddress);
 | 
			
		||||
					if (yggaddr.is_unspecified () || !i2p::util::net::IsYggdrasilAddress (yggaddr) || 
 | 
			
		||||
					    !i2p::util::net::IsLocalAddress (yggaddr)) 
 | 
			
		||||
					{
 | 
			
		||||
						LogPrint(eLogWarning, "Daemon: Can't find Yggdrasil address ", yggaddress);
 | 
			
		||||
						ygg = false;
 | 
			
		||||
					}	
 | 
			
		||||
					LogPrint(eLogWarning, "Daemon: Can't find Yggdrasil address ", yggaddress);
 | 
			
		||||
					ygg = false;
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{	
 | 
			
		||||
					yggaddr = i2p::util::net::GetYggdrasilAddress ();
 | 
			
		||||
					if (yggaddr.is_unspecified ())
 | 
			
		||||
					{
 | 
			
		||||
						LogPrint(eLogWarning, "Daemon: Yggdrasil is not running. Disabled");
 | 
			
		||||
						ygg = false;
 | 
			
		||||
					}	
 | 
			
		||||
				}	
 | 
			
		||||
			}	
 | 
			
		||||
			
 | 
			
		||||
			uint16_t port; i2p::config::GetOption("port", port);
 | 
			
		||||
			if (!i2p::config::IsDefault("port"))
 | 
			
		||||
			{
 | 
			
		||||
				LogPrint(eLogInfo, "Daemon: accepting incoming connections at port ", port);
 | 
			
		||||
				i2p::context.UpdatePort (port);
 | 
			
		||||
			}
 | 
			
		||||
			i2p::context.SetSupportsV6 (ipv6);
 | 
			
		||||
			i2p::context.SetSupportsV4 (ipv4);
 | 
			
		||||
			i2p::context.SetSupportsMesh (ygg, yggaddr);
 | 
			
		||||
			
 | 
			
		||||
			i2p::context.RemoveNTCPAddress (!ipv6); // TODO: remove later 
 | 
			
		||||
			bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
 | 
			
		||||
			if (ntcp2)
 | 
			
		||||
			{
 | 
			
		||||
				bool published; i2p::config::GetOption("ntcp2.published", published);
 | 
			
		||||
				if (published)
 | 
			
		||||
				{
 | 
			
		||||
					uint16_t ntcp2port; i2p::config::GetOption("ntcp2.port", ntcp2port);
 | 
			
		||||
					if (!ntcp2port) ntcp2port = port; // use standard port
 | 
			
		||||
					i2p::context.PublishNTCP2Address (ntcp2port, true); // publish
 | 
			
		||||
					if (ipv6)
 | 
			
		||||
					{
 | 
			
		||||
						std::string ipv6Addr; i2p::config::GetOption("ntcp2.addressv6", ipv6Addr);
 | 
			
		||||
						auto addr = boost::asio::ip::address_v6::from_string (ipv6Addr);
 | 
			
		||||
						if (!addr.is_unspecified () && addr != boost::asio::ip::address_v6::any ())
 | 
			
		||||
							i2p::context.UpdateNTCP2V6Address (addr); // set ipv6 address if configured
 | 
			
		||||
					}
 | 
			
		||||
					if (ygg)
 | 
			
		||||
						i2p::context.UpdateNTCP2V6Address (yggaddr); 
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
					i2p::context.PublishNTCP2Address (port, false); // unpublish
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			bool transit; i2p::config::GetOption("notransit", transit);
 | 
			
		||||
			i2p::context.SetAcceptsTunnels (!transit);
 | 
			
		||||
			uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);
 | 
			
		||||
			SetMaxNumTransitTunnels (transitTunnels);
 | 
			
		||||
 | 
			
		||||
			bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill);
 | 
			
		||||
			if (isFloodfill) {
 | 
			
		||||
				LogPrint(eLogInfo, "Daemon: router will be floodfill");
 | 
			
		||||
				i2p::context.SetFloodfill (true);
 | 
			
		||||
			}	else {
 | 
			
		||||
				i2p::context.SetFloodfill (false);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			/* this section also honors 'floodfill' flag, if set above */
 | 
			
		||||
			std::string bandwidth; i2p::config::GetOption("bandwidth", bandwidth);
 | 
			
		||||
			if (bandwidth.length () > 0)
 | 
			
		||||
			{
 | 
			
		||||
				if (bandwidth[0] >= 'K' && bandwidth[0] <= 'X')
 | 
			
		||||
				{
 | 
			
		||||
					i2p::context.SetBandwidth (bandwidth[0]);
 | 
			
		||||
					LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), "KBps");
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					auto value = std::atoi(bandwidth.c_str());
 | 
			
		||||
					if (value > 0)
 | 
			
		||||
					{
 | 
			
		||||
						i2p::context.SetBandwidth (value);
 | 
			
		||||
						LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), " KBps");
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						LogPrint(eLogInfo, "Daemon: unexpected bandwidth ", bandwidth, ". Set to 'low'");
 | 
			
		||||
						i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else if (isFloodfill)
 | 
			
		||||
			{
 | 
			
		||||
				LogPrint(eLogInfo, "Daemon: floodfill bandwidth set to 'extra'");
 | 
			
		||||
				i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				LogPrint(eLogInfo, "Daemon: bandwidth set to 'low'");
 | 
			
		||||
				i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			int shareRatio; i2p::config::GetOption("share", shareRatio);
 | 
			
		||||
			i2p::context.SetShareRatio (shareRatio);
 | 
			
		||||
 | 
			
		||||
			std::string family; i2p::config::GetOption("family", family);
 | 
			
		||||
			i2p::context.SetFamily (family);
 | 
			
		||||
			if (family.length () > 0)
 | 
			
		||||
				LogPrint(eLogInfo, "Daemon: family set to ", family);
 | 
			
		||||
 | 
			
		||||
			bool trust; i2p::config::GetOption("trust.enabled", trust);
 | 
			
		||||
			if (trust)
 | 
			
		||||
			{
 | 
			
		||||
				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)
 | 
			
		||||
				yggaddr = i2p::util::net::GetYggdrasilAddress ();
 | 
			
		||||
				if (yggaddr.is_unspecified ())
 | 
			
		||||
				{
 | 
			
		||||
					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;
 | 
			
		||||
					LogPrint(eLogWarning, "Daemon: Yggdrasil is not running. Disabled");
 | 
			
		||||
					ygg = false;
 | 
			
		||||
				}
 | 
			
		||||
				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 routers");
 | 
			
		||||
					i2p::transport::transports.RestrictRoutesToRouters(idents);
 | 
			
		||||
					restricted = idents.size() > 0;
 | 
			
		||||
				}
 | 
			
		||||
				if(!restricted)
 | 
			
		||||
					LogPrint(eLogError, "Daemon: no trusted routers of families specified");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			bool hidden; i2p::config::GetOption("trust.hidden", hidden);
 | 
			
		||||
			if (hidden)
 | 
			
		||||
			{
 | 
			
		||||
				LogPrint(eLogInfo, "Daemon: using hidden mode");
 | 
			
		||||
				i2p::data::netdb.SetHidden(true);
 | 
			
		||||
			}
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool Daemon_Singleton::start()
 | 
			
		||||
		uint16_t port; i2p::config::GetOption("port", port);
 | 
			
		||||
		if (!i2p::config::IsDefault("port"))
 | 
			
		||||
		{
 | 
			
		||||
			i2p::log::Logger().Start();
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: starting NetDB");
 | 
			
		||||
			i2p::data::netdb.Start();
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: accepting incoming connections at port ", port);
 | 
			
		||||
			i2p::context.UpdatePort (port);
 | 
			
		||||
		}
 | 
			
		||||
		i2p::context.SetSupportsV6 (ipv6);
 | 
			
		||||
		i2p::context.SetSupportsV4 (ipv4);
 | 
			
		||||
		i2p::context.SetSupportsMesh (ygg, yggaddr);
 | 
			
		||||
 | 
			
		||||
			bool upnp; i2p::config::GetOption("upnp.enabled", upnp);
 | 
			
		||||
			if (upnp) {
 | 
			
		||||
				d.UPnP = std::unique_ptr<i2p::transport::UPnP>(new i2p::transport::UPnP);
 | 
			
		||||
				d.UPnP->Start ();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			bool nettime; i2p::config::GetOption("nettime.enabled", nettime);
 | 
			
		||||
			if (nettime)
 | 
			
		||||
		i2p::context.RemoveNTCPAddress (!ipv6); // TODO: remove later
 | 
			
		||||
		bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
 | 
			
		||||
		if (ntcp2)
 | 
			
		||||
		{
 | 
			
		||||
			bool published; i2p::config::GetOption("ntcp2.published", published);
 | 
			
		||||
			if (published)
 | 
			
		||||
			{
 | 
			
		||||
				d.m_NTPSync = std::unique_ptr<i2p::util::NTPTimeSync>(new i2p::util::NTPTimeSync);
 | 
			
		||||
				d.m_NTPSync->Start ();
 | 
			
		||||
				uint16_t ntcp2port; i2p::config::GetOption("ntcp2.port", ntcp2port);
 | 
			
		||||
				if (!ntcp2port) ntcp2port = port; // use standard port
 | 
			
		||||
				i2p::context.PublishNTCP2Address (ntcp2port, true); // publish
 | 
			
		||||
				if (ipv6)
 | 
			
		||||
				{
 | 
			
		||||
					std::string ipv6Addr; i2p::config::GetOption("ntcp2.addressv6", ipv6Addr);
 | 
			
		||||
					auto addr = boost::asio::ip::address_v6::from_string (ipv6Addr);
 | 
			
		||||
					if (!addr.is_unspecified () && addr != boost::asio::ip::address_v6::any ())
 | 
			
		||||
						i2p::context.UpdateNTCP2V6Address (addr); // set ipv6 address if configured
 | 
			
		||||
				}
 | 
			
		||||
				if (ygg)
 | 
			
		||||
					i2p::context.UpdateNTCP2V6Address (yggaddr);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
				i2p::context.PublishNTCP2Address (port, false); // unpublish
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
			bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
 | 
			
		||||
			bool ssu; i2p::config::GetOption("ssu", ssu);
 | 
			
		||||
			bool checkInReserved; i2p::config::GetOption("reservedrange", checkInReserved);
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: starting Transports");
 | 
			
		||||
			if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled");
 | 
			
		||||
			if(!ntcp2) LogPrint(eLogInfo, "Daemon: ntcp2 disabled");
 | 
			
		||||
		bool transit; i2p::config::GetOption("notransit", transit);
 | 
			
		||||
		i2p::context.SetAcceptsTunnels (!transit);
 | 
			
		||||
		uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);
 | 
			
		||||
		SetMaxNumTransitTunnels (transitTunnels);
 | 
			
		||||
 | 
			
		||||
			i2p::transport::transports.SetCheckReserved(checkInReserved);
 | 
			
		||||
			i2p::transport::transports.Start(ntcp2, ssu);
 | 
			
		||||
			if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2())
 | 
			
		||||
				LogPrint(eLogInfo, "Daemon: Transports started");
 | 
			
		||||
		bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill);
 | 
			
		||||
		if (isFloodfill) {
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: router will be floodfill");
 | 
			
		||||
			i2p::context.SetFloodfill (true);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			i2p::context.SetFloodfill (false);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* this section also honors 'floodfill' flag, if set above */
 | 
			
		||||
		std::string bandwidth; i2p::config::GetOption("bandwidth", bandwidth);
 | 
			
		||||
		if (bandwidth.length () > 0)
 | 
			
		||||
		{
 | 
			
		||||
			if (bandwidth[0] >= 'K' && bandwidth[0] <= 'X')
 | 
			
		||||
			{
 | 
			
		||||
				i2p::context.SetBandwidth (bandwidth[0]);
 | 
			
		||||
				LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), "KBps");
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				LogPrint(eLogError, "Daemon: failed to start Transports");
 | 
			
		||||
				/** shut down netdb right away */
 | 
			
		||||
				i2p::transport::transports.Stop();
 | 
			
		||||
				i2p::data::netdb.Stop();
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			bool http; i2p::config::GetOption("http.enabled", http);
 | 
			
		||||
			if (http) {
 | 
			
		||||
				std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
 | 
			
		||||
				uint16_t    httpPort; i2p::config::GetOption("http.port", httpPort);
 | 
			
		||||
				LogPrint(eLogInfo, "Daemon: starting webconsole at ", httpAddr, ":", httpPort);
 | 
			
		||||
				try 
 | 
			
		||||
				auto value = std::atoi(bandwidth.c_str());
 | 
			
		||||
				if (value > 0)
 | 
			
		||||
				{
 | 
			
		||||
					d.httpServer = std::unique_ptr<i2p::http::HTTPServer>(new i2p::http::HTTPServer(httpAddr, httpPort));
 | 
			
		||||
					d.httpServer->Start();
 | 
			
		||||
				} 
 | 
			
		||||
				catch (std::exception& ex) 
 | 
			
		||||
					i2p::context.SetBandwidth (value);
 | 
			
		||||
					LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), " KBps");
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					LogPrint (eLogError, "Daemon: failed to start webconsole: ", ex.what ());
 | 
			
		||||
					ThrowFatal ("Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ());
 | 
			
		||||
					LogPrint(eLogInfo, "Daemon: unexpected bandwidth ", bandwidth, ". Set to 'low'");
 | 
			
		||||
					i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: starting Tunnels");
 | 
			
		||||
			i2p::tunnel::tunnels.Start();
 | 
			
		||||
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: starting Client");
 | 
			
		||||
			i2p::client::context.Start ();
 | 
			
		||||
 | 
			
		||||
			// I2P Control Protocol
 | 
			
		||||
			bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol);
 | 
			
		||||
			if (i2pcontrol) {
 | 
			
		||||
				std::string i2pcpAddr; i2p::config::GetOption("i2pcontrol.address", i2pcpAddr);
 | 
			
		||||
				uint16_t    i2pcpPort; i2p::config::GetOption("i2pcontrol.port",    i2pcpPort);
 | 
			
		||||
				LogPrint(eLogInfo, "Daemon: starting I2PControl at ", i2pcpAddr, ":", i2pcpPort);
 | 
			
		||||
				try 
 | 
			
		||||
				{
 | 
			
		||||
					d.m_I2PControlService = std::unique_ptr<i2p::client::I2PControlService>(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort));
 | 
			
		||||
					d.m_I2PControlService->Start ();
 | 
			
		||||
				} 
 | 
			
		||||
				catch (std::exception& ex) 
 | 
			
		||||
				{
 | 
			
		||||
					LogPrint (eLogError, "Daemon: failed to start I2PControl: ", ex.what ());
 | 
			
		||||
					ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ());
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
		else if (isFloodfill)
 | 
			
		||||
		{
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: floodfill bandwidth set to 'extra'");
 | 
			
		||||
			i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: bandwidth set to 'low'");
 | 
			
		||||
			i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool Daemon_Singleton::stop()
 | 
			
		||||
		int shareRatio; i2p::config::GetOption("share", shareRatio);
 | 
			
		||||
		i2p::context.SetShareRatio (shareRatio);
 | 
			
		||||
 | 
			
		||||
		std::string family; i2p::config::GetOption("family", family);
 | 
			
		||||
		i2p::context.SetFamily (family);
 | 
			
		||||
		if (family.length () > 0)
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: family set to ", family);
 | 
			
		||||
 | 
			
		||||
		bool trust; i2p::config::GetOption("trust.enabled", trust);
 | 
			
		||||
		if (trust)
 | 
			
		||||
		{
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: shutting down");
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: stopping Client");
 | 
			
		||||
			i2p::client::context.Stop();
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: stopping Tunnels");
 | 
			
		||||
			i2p::tunnel::tunnels.Stop();
 | 
			
		||||
 | 
			
		||||
			if (d.UPnP) 
 | 
			
		||||
			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)
 | 
			
		||||
			{
 | 
			
		||||
				d.UPnP->Stop ();
 | 
			
		||||
				d.UPnP = nullptr;
 | 
			
		||||
				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 (d.m_NTPSync)
 | 
			
		||||
			{
 | 
			
		||||
				d.m_NTPSync->Stop ();
 | 
			
		||||
				d.m_NTPSync = nullptr;
 | 
			
		||||
			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 routers");
 | 
			
		||||
				i2p::transport::transports.RestrictRoutesToRouters(idents);
 | 
			
		||||
				restricted = idents.size() > 0;
 | 
			
		||||
			}
 | 
			
		||||
			if(!restricted)
 | 
			
		||||
				LogPrint(eLogError, "Daemon: no trusted routers of families specified");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: stopping Transports");
 | 
			
		||||
		bool hidden; i2p::config::GetOption("trust.hidden", hidden);
 | 
			
		||||
		if (hidden)
 | 
			
		||||
		{
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: using hidden mode");
 | 
			
		||||
			i2p::data::netdb.SetHidden(true);
 | 
			
		||||
		}
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool Daemon_Singleton::start()
 | 
			
		||||
	{
 | 
			
		||||
		i2p::log::Logger().Start();
 | 
			
		||||
		LogPrint(eLogInfo, "Daemon: starting NetDB");
 | 
			
		||||
		i2p::data::netdb.Start();
 | 
			
		||||
 | 
			
		||||
		bool upnp; i2p::config::GetOption("upnp.enabled", upnp);
 | 
			
		||||
		if (upnp) {
 | 
			
		||||
			d.UPnP = std::unique_ptr<i2p::transport::UPnP>(new i2p::transport::UPnP);
 | 
			
		||||
			d.UPnP->Start ();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool nettime; i2p::config::GetOption("nettime.enabled", nettime);
 | 
			
		||||
		if (nettime)
 | 
			
		||||
		{
 | 
			
		||||
			d.m_NTPSync = std::unique_ptr<i2p::util::NTPTimeSync>(new i2p::util::NTPTimeSync);
 | 
			
		||||
			d.m_NTPSync->Start ();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
 | 
			
		||||
		bool ssu; i2p::config::GetOption("ssu", ssu);
 | 
			
		||||
		bool checkInReserved; i2p::config::GetOption("reservedrange", checkInReserved);
 | 
			
		||||
		LogPrint(eLogInfo, "Daemon: starting Transports");
 | 
			
		||||
		if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled");
 | 
			
		||||
		if(!ntcp2) LogPrint(eLogInfo, "Daemon: ntcp2 disabled");
 | 
			
		||||
 | 
			
		||||
		i2p::transport::transports.SetCheckReserved(checkInReserved);
 | 
			
		||||
		i2p::transport::transports.Start(ntcp2, ssu);
 | 
			
		||||
		if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2())
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: Transports started");
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			LogPrint(eLogError, "Daemon: failed to start Transports");
 | 
			
		||||
			/** shut down netdb right away */
 | 
			
		||||
			i2p::transport::transports.Stop();
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: stopping NetDB");
 | 
			
		||||
			i2p::data::netdb.Stop();
 | 
			
		||||
			if (d.httpServer) {
 | 
			
		||||
				LogPrint(eLogInfo, "Daemon: stopping HTTP Server");
 | 
			
		||||
				d.httpServer->Stop();
 | 
			
		||||
				d.httpServer = nullptr;
 | 
			
		||||
			}
 | 
			
		||||
			if (d.m_I2PControlService)
 | 
			
		||||
			{
 | 
			
		||||
				LogPrint(eLogInfo, "Daemon: stopping I2PControl");
 | 
			
		||||
				d.m_I2PControlService->Stop ();
 | 
			
		||||
				d.m_I2PControlService = nullptr;
 | 
			
		||||
			}
 | 
			
		||||
			i2p::crypto::TerminateCrypto ();
 | 
			
		||||
			i2p::log::Logger().Stop();
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool http; i2p::config::GetOption("http.enabled", http);
 | 
			
		||||
		if (http) {
 | 
			
		||||
			std::string httpAddr; i2p::config::GetOption("http.address", httpAddr);
 | 
			
		||||
			uint16_t    httpPort; i2p::config::GetOption("http.port", httpPort);
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: starting webconsole at ", httpAddr, ":", httpPort);
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				d.httpServer = std::unique_ptr<i2p::http::HTTPServer>(new i2p::http::HTTPServer(httpAddr, httpPort));
 | 
			
		||||
				d.httpServer->Start();
 | 
			
		||||
			}
 | 
			
		||||
			catch (std::exception& ex)
 | 
			
		||||
			{
 | 
			
		||||
				LogPrint (eLogError, "Daemon: failed to start webconsole: ", ex.what ());
 | 
			
		||||
				ThrowFatal ("Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		LogPrint(eLogInfo, "Daemon: starting Tunnels");
 | 
			
		||||
		i2p::tunnel::tunnels.Start();
 | 
			
		||||
 | 
			
		||||
		LogPrint(eLogInfo, "Daemon: starting Client");
 | 
			
		||||
		i2p::client::context.Start ();
 | 
			
		||||
 | 
			
		||||
		// I2P Control Protocol
 | 
			
		||||
		bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol);
 | 
			
		||||
		if (i2pcontrol) {
 | 
			
		||||
			std::string i2pcpAddr; i2p::config::GetOption("i2pcontrol.address", i2pcpAddr);
 | 
			
		||||
			uint16_t    i2pcpPort; i2p::config::GetOption("i2pcontrol.port",    i2pcpPort);
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: starting I2PControl at ", i2pcpAddr, ":", i2pcpPort);
 | 
			
		||||
			try
 | 
			
		||||
			{
 | 
			
		||||
				d.m_I2PControlService = std::unique_ptr<i2p::client::I2PControlService>(new i2p::client::I2PControlService (i2pcpAddr, i2pcpPort));
 | 
			
		||||
				d.m_I2PControlService->Start ();
 | 
			
		||||
			}
 | 
			
		||||
			catch (std::exception& ex)
 | 
			
		||||
			{
 | 
			
		||||
				LogPrint (eLogError, "Daemon: failed to start I2PControl: ", ex.what ());
 | 
			
		||||
				ThrowFatal ("Unable to start I2PControl service at ", i2pcpAddr, ":", i2pcpPort, ": ", ex.what ());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool Daemon_Singleton::stop()
 | 
			
		||||
	{
 | 
			
		||||
		LogPrint(eLogInfo, "Daemon: shutting down");
 | 
			
		||||
		LogPrint(eLogInfo, "Daemon: stopping Client");
 | 
			
		||||
		i2p::client::context.Stop();
 | 
			
		||||
		LogPrint(eLogInfo, "Daemon: stopping Tunnels");
 | 
			
		||||
		i2p::tunnel::tunnels.Stop();
 | 
			
		||||
 | 
			
		||||
		if (d.UPnP)
 | 
			
		||||
		{
 | 
			
		||||
			d.UPnP->Stop ();
 | 
			
		||||
			d.UPnP = nullptr;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (d.m_NTPSync)
 | 
			
		||||
		{
 | 
			
		||||
			d.m_NTPSync->Stop ();
 | 
			
		||||
			d.m_NTPSync = nullptr;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		LogPrint(eLogInfo, "Daemon: stopping Transports");
 | 
			
		||||
		i2p::transport::transports.Stop();
 | 
			
		||||
		LogPrint(eLogInfo, "Daemon: stopping NetDB");
 | 
			
		||||
		i2p::data::netdb.Stop();
 | 
			
		||||
		if (d.httpServer) {
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: stopping HTTP Server");
 | 
			
		||||
			d.httpServer->Stop();
 | 
			
		||||
			d.httpServer = nullptr;
 | 
			
		||||
		}
 | 
			
		||||
		if (d.m_I2PControlService)
 | 
			
		||||
		{
 | 
			
		||||
			LogPrint(eLogInfo, "Daemon: stopping I2PControl");
 | 
			
		||||
			d.m_I2PControlService->Stop ();
 | 
			
		||||
			d.m_I2PControlService = nullptr;
 | 
			
		||||
		}
 | 
			
		||||
		i2p::crypto::TerminateCrypto ();
 | 
			
		||||
		i2p::log::Logger().Stop();
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,8 +49,8 @@ namespace datagram
 | 
			
		|||
	std::shared_ptr<DatagramSession> DatagramDestination::GetSession(const i2p::data::IdentHash & ident)
 | 
			
		||||
	{
 | 
			
		||||
		return ObtainSession(ident);
 | 
			
		||||
	}	
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void DatagramDestination::SendDatagram (std::shared_ptr<DatagramSession> session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort)
 | 
			
		||||
	{
 | 
			
		||||
		if (session)
 | 
			
		||||
| 
						 | 
				
			
			@ -67,21 +67,21 @@ namespace datagram
 | 
			
		|||
			auto msg = CreateDataMessage ({{m_From.data (), m_From.size ()}, {m_Signature.data (), m_Signature.size ()}, {payload, len}},
 | 
			
		||||
				fromPort, toPort, false, !session->IsRatchets ()); // datagram
 | 
			
		||||
			session->SendMsg(msg);
 | 
			
		||||
		}	
 | 
			
		||||
	}	
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void DatagramDestination::SendRawDatagram (std::shared_ptr<DatagramSession> session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort)
 | 
			
		||||
	{
 | 
			
		||||
		if (session)
 | 
			
		||||
			session->SendMsg(CreateDataMessage ({{payload, len}}, fromPort, toPort, true, !session->IsRatchets ())); // raw
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
	void DatagramDestination::FlushSendQueue (std::shared_ptr<DatagramSession> session)
 | 
			
		||||
	{
 | 
			
		||||
		if (session)
 | 
			
		||||
			session->FlushSendQueue ();
 | 
			
		||||
	}	
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort,uint8_t * const &buf, size_t len)
 | 
			
		||||
	{
 | 
			
		||||
		i2p::data::IdentityEx identity;
 | 
			
		||||
| 
						 | 
				
			
			@ -242,7 +242,7 @@ namespace datagram
 | 
			
		|||
		if (msg || m_SendQueue.empty ())
 | 
			
		||||
			m_SendQueue.push_back(msg);
 | 
			
		||||
		// flush queue right away if full
 | 
			
		||||
		if (!msg || m_SendQueue.size() >= DATAGRAM_SEND_QUEUE_MAX_SIZE) 
 | 
			
		||||
		if (!msg || m_SendQueue.size() >= DATAGRAM_SEND_QUEUE_MAX_SIZE)
 | 
			
		||||
			FlushSendQueue();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -286,14 +286,14 @@ namespace datagram
 | 
			
		|||
			m_RemoteLeaseSet = m_LocalDestination->FindLeaseSet(m_RemoteIdent);
 | 
			
		||||
			if (!m_RemoteLeaseSet)
 | 
			
		||||
			{
 | 
			
		||||
				if(!m_RequestingLS) 
 | 
			
		||||
				if(!m_RequestingLS)
 | 
			
		||||
				{
 | 
			
		||||
					m_RequestingLS = true;
 | 
			
		||||
					m_LocalDestination->RequestDestination(m_RemoteIdent, std::bind(&DatagramSession::HandleLeaseSetUpdated, this, std::placeholders::_1));
 | 
			
		||||
				}
 | 
			
		||||
				return nullptr;
 | 
			
		||||
			}	
 | 
			
		||||
		}	
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (!m_RoutingSession || m_RoutingSession->IsTerminated () || !m_RoutingSession->IsReadyToSend ()) 
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -305,81 +305,81 @@ namespace datagram
 | 
			
		|||
					m_PendingRoutingSessions.clear ();
 | 
			
		||||
					found = true;
 | 
			
		||||
					break;
 | 
			
		||||
				}		
 | 
			
		||||
				}
 | 
			
		||||
			if (!found)
 | 
			
		||||
			{	
 | 
			
		||||
			{
 | 
			
		||||
				m_RoutingSession = m_LocalDestination->GetRoutingSession(m_RemoteLeaseSet, true);
 | 
			
		||||
				if (!m_RoutingSession->GetOwner () || !m_RoutingSession->IsReadyToSend ())
 | 
			
		||||
					m_PendingRoutingSessions.push_back (m_RoutingSession);
 | 
			
		||||
			}	
 | 
			
		||||
		}	
 | 
			
		||||
		
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		auto path = m_RoutingSession->GetSharedRoutingPath();
 | 
			
		||||
		if (path && m_RoutingSession->IsRatchets () &&
 | 
			
		||||
		    m_LastUse > m_RoutingSession->GetLastActivityTimestamp ()*1000 + DATAGRAM_SESSION_PATH_TIMEOUT)
 | 
			
		||||
		{	
 | 
			
		||||
		{
 | 
			
		||||
			m_RoutingSession->SetSharedRoutingPath (nullptr);
 | 
			
		||||
			path = nullptr;
 | 
			
		||||
		}
 | 
			
		||||
				
 | 
			
		||||
		if (path) 
 | 
			
		||||
 | 
			
		||||
		if (path)
 | 
			
		||||
		{
 | 
			
		||||
			if (path->outboundTunnel && !path->outboundTunnel->IsEstablished ())
 | 
			
		||||
			{	
 | 
			
		||||
			{
 | 
			
		||||
				// bad outbound tunnel, switch outbound tunnel
 | 
			
		||||
				path->outboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel(path->outboundTunnel);
 | 
			
		||||
				if (!path->outboundTunnel)
 | 
			
		||||
					m_RoutingSession->SetSharedRoutingPath (nullptr);
 | 
			
		||||
			}	
 | 
			
		||||
			
 | 
			
		||||
			if (path->remoteLease && path->remoteLease->ExpiresWithin(DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW)) 
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (path->remoteLease && path->remoteLease->ExpiresWithin(DATAGRAM_SESSION_LEASE_HANDOVER_WINDOW))
 | 
			
		||||
			{
 | 
			
		||||
				// bad lease, switch to next one
 | 
			
		||||
				if (m_RemoteLeaseSet) 
 | 
			
		||||
				if (m_RemoteLeaseSet)
 | 
			
		||||
				{
 | 
			
		||||
					auto ls = m_RemoteLeaseSet->GetNonExpiredLeasesExcluding(
 | 
			
		||||
						[&](const i2p::data::Lease& l) -> bool 
 | 
			
		||||
						[&](const i2p::data::Lease& l) -> bool
 | 
			
		||||
						{
 | 
			
		||||
							return l.tunnelID == path->remoteLease->tunnelID;
 | 
			
		||||
						});
 | 
			
		||||
					auto sz = ls.size();
 | 
			
		||||
					if (sz) 
 | 
			
		||||
					if (sz)
 | 
			
		||||
					{
 | 
			
		||||
						auto idx = rand() % sz;
 | 
			
		||||
						path->remoteLease = ls[idx];
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
						m_RoutingSession->SetSharedRoutingPath (nullptr);
 | 
			
		||||
				} 
 | 
			
		||||
				else 
 | 
			
		||||
				{	
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					// no remote lease set?
 | 
			
		||||
					LogPrint(eLogWarning, "DatagramSession: no cached remote lease set for ", m_RemoteIdent.ToBase32());
 | 
			
		||||
					m_RoutingSession->SetSharedRoutingPath (nullptr);
 | 
			
		||||
				}	
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} 
 | 
			
		||||
		else 
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			// no current path, make one
 | 
			
		||||
			path = std::make_shared<i2p::garlic::GarlicRoutingPath>();
 | 
			
		||||
			path->outboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel();
 | 
			
		||||
			if (!path->outboundTunnel) return nullptr;
 | 
			
		||||
				
 | 
			
		||||
			if (m_RemoteLeaseSet) 
 | 
			
		||||
 | 
			
		||||
			if (m_RemoteLeaseSet)
 | 
			
		||||
			{
 | 
			
		||||
				// pick random next good lease
 | 
			
		||||
				auto ls = m_RemoteLeaseSet->GetNonExpiredLeases();
 | 
			
		||||
				auto sz = ls.size();
 | 
			
		||||
				if (sz) 
 | 
			
		||||
				if (sz)
 | 
			
		||||
				{
 | 
			
		||||
					auto idx = rand() % sz;
 | 
			
		||||
					path->remoteLease = ls[idx];
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
					return nullptr;
 | 
			
		||||
			} 
 | 
			
		||||
			else 
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				// no remote lease set currently, bail
 | 
			
		||||
				LogPrint(eLogWarning, "DatagramSession: no remote lease set found for ", m_RemoteIdent.ToBase32());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue