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]
 | 
				
			||||||
## AddressBook subscription URL for initial setup
 | 
					## AddressBook subscription URL for initial setup
 | 
				
			||||||
## Default: inr.i2p at "mainline" I2P Network
 | 
					## Default: reg.i2p at "mainline" I2P Network
 | 
				
			||||||
# defaulturl = http://joajgazyztfssty4w2on5oaqksz6tqoxbduy553y34mf4byv6gpq.b32.i2p/export/alive-hosts.txt
 | 
					# defaulturl = http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt
 | 
				
			||||||
## Optional subscriptions URLs, separated by comma
 | 
					## 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
 | 
					# 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 i2p
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	namespace util
 | 
					namespace util
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						class Daemon_Singleton::Daemon_Singleton_Private
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		class Daemon_Singleton::Daemon_Singleton_Private
 | 
						public:
 | 
				
			||||||
		{
 | 
							Daemon_Singleton_Private() {};
 | 
				
			||||||
		public:
 | 
							~Daemon_Singleton_Private() {};
 | 
				
			||||||
			Daemon_Singleton_Private() {};
 | 
					 | 
				
			||||||
			~Daemon_Singleton_Private() {};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			std::unique_ptr<i2p::http::HTTPServer> httpServer;
 | 
							std::unique_ptr<i2p::http::HTTPServer> httpServer;
 | 
				
			||||||
			std::unique_ptr<i2p::client::I2PControlService> m_I2PControlService;
 | 
							std::unique_ptr<i2p::client::I2PControlService> m_I2PControlService;
 | 
				
			||||||
			std::unique_ptr<i2p::transport::UPnP> UPnP;
 | 
							std::unique_ptr<i2p::transport::UPnP> UPnP;
 | 
				
			||||||
			std::unique_ptr<i2p::util::NTPTimeSync> m_NTPSync;
 | 
							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() : isDaemon(false), running(true), d(*new Daemon_Singleton_Private()) {}
 | 
				
			||||||
		Daemon_Singleton::~Daemon_Singleton() {
 | 
						Daemon_Singleton::~Daemon_Singleton() {
 | 
				
			||||||
			delete &d;
 | 
							delete &d;
 | 
				
			||||||
		}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool Daemon_Singleton::IsService () const
 | 
						bool Daemon_Singleton::IsService () const
 | 
				
			||||||
		{
 | 
						{
 | 
				
			||||||
			bool service = false;
 | 
							bool service = false;
 | 
				
			||||||
#ifndef _WIN32
 | 
					#ifndef _WIN32
 | 
				
			||||||
			i2p::config::GetOption("service", service);
 | 
							i2p::config::GetOption("service", service);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
			return service;
 | 
							return service;
 | 
				
			||||||
		}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool Daemon_Singleton::init(int argc, char* argv[]) {
 | 
						bool Daemon_Singleton::init(int argc, char* argv[]) {
 | 
				
			||||||
			return init(argc, argv, nullptr);
 | 
							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();
 | 
								config = i2p::fs::DataDirPath("i2pd.conf");
 | 
				
			||||||
			i2p::config::ParseCmdline(argc, argv);
 | 
								if (!i2p::fs::Exists (config)) {
 | 
				
			||||||
 | 
									// use i2pd.conf only if exists
 | 
				
			||||||
			std::string config;  i2p::config::GetOption("conf",    config);
 | 
									config = ""; /* reset */
 | 
				
			||||||
			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 */
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			i2p::config::ParseConfig(config);
 | 
							i2p::config::ParseConfig(config);
 | 
				
			||||||
			i2p::config::Finalize();
 | 
							i2p::config::Finalize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			i2p::config::GetOption("daemon", isDaemon);
 | 
							i2p::config::GetOption("daemon", isDaemon);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			std::string logs     = ""; i2p::config::GetOption("log",      logs);
 | 
							std::string logs     = ""; i2p::config::GetOption("log",      logs);
 | 
				
			||||||
			std::string logfile  = ""; i2p::config::GetOption("logfile",  logfile);
 | 
							std::string logfile  = ""; i2p::config::GetOption("logfile",  logfile);
 | 
				
			||||||
			std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel);
 | 
							std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel);
 | 
				
			||||||
			bool logclftime;           i2p::config::GetOption("logclftime", logclftime);
 | 
							bool logclftime;           i2p::config::GetOption("logclftime", logclftime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* setup logging */
 | 
							/* setup logging */
 | 
				
			||||||
			if (logclftime)
 | 
							if (logclftime)
 | 
				
			||||||
				i2p::log::Logger().SetTimeFormat ("[%d/%b/%Y:%H:%M:%S %z]");
 | 
								i2p::log::Logger().SetTimeFormat ("[%d/%b/%Y:%H:%M:%S %z]");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (isDaemon && (logs == "" || logs == "stdout"))
 | 
							if (isDaemon && (logs == "" || logs == "stdout"))
 | 
				
			||||||
				logs = "file";
 | 
								logs = "file";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			i2p::log::Logger().SetLogLevel(loglevel);
 | 
							i2p::log::Logger().SetLogLevel(loglevel);
 | 
				
			||||||
			if (logstream) {
 | 
							if (logstream) {
 | 
				
			||||||
				LogPrint(eLogInfo, "Log: will send messages to std::ostream");
 | 
								LogPrint(eLogInfo, "Log: will send messages to std::ostream");
 | 
				
			||||||
				i2p::log::Logger().SendTo (logstream);
 | 
								i2p::log::Logger().SendTo (logstream);
 | 
				
			||||||
			} else if (logs == "file") {
 | 
							} else if (logs == "file") {
 | 
				
			||||||
				if (logfile == "")
 | 
								if (logfile == "")
 | 
				
			||||||
					logfile = i2p::fs::DataDirPath("i2pd.log");
 | 
									logfile = i2p::fs::DataDirPath("i2pd.log");
 | 
				
			||||||
				LogPrint(eLogInfo, "Log: will send messages to ", logfile);
 | 
								LogPrint(eLogInfo, "Log: will send messages to ", logfile);
 | 
				
			||||||
				i2p::log::Logger().SendTo (logfile);
 | 
								i2p::log::Logger().SendTo (logfile);
 | 
				
			||||||
#ifndef _WIN32
 | 
					#ifndef _WIN32
 | 
				
			||||||
			} else if (logs == "syslog") {
 | 
							} else if (logs == "syslog") {
 | 
				
			||||||
				LogPrint(eLogInfo, "Log: will send messages to syslog");
 | 
								LogPrint(eLogInfo, "Log: will send messages to syslog");
 | 
				
			||||||
				i2p::log::Logger().SendTo("i2pd", LOG_DAEMON);
 | 
								i2p::log::Logger().SendTo("i2pd", LOG_DAEMON);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
			} else {
 | 
							} else {
 | 
				
			||||||
				// use stdout -- default
 | 
								// use stdout -- default
 | 
				
			||||||
			}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			LogPrint(eLogInfo,  "i2pd v", VERSION, " starting");
 | 
							LogPrint(eLogInfo,  "i2pd v", VERSION, " starting");
 | 
				
			||||||
			LogPrint(eLogDebug, "FS: main config file: ", config);
 | 
							LogPrint(eLogDebug, "FS: main config file: ", config);
 | 
				
			||||||
			LogPrint(eLogDebug, "FS: data directory: ", datadir);
 | 
							LogPrint(eLogDebug, "FS: data directory: ", datadir);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation);
 | 
							bool precomputation; i2p::config::GetOption("precomputation.elgamal", precomputation);
 | 
				
			||||||
			bool aesni; i2p::config::GetOption("cpuext.aesni", aesni);
 | 
							bool aesni; i2p::config::GetOption("cpuext.aesni", aesni);
 | 
				
			||||||
			bool avx; i2p::config::GetOption("cpuext.avx", avx);
 | 
							bool avx; i2p::config::GetOption("cpuext.avx", avx);
 | 
				
			||||||
			bool forceCpuExt; i2p::config::GetOption("cpuext.force", forceCpuExt);
 | 
							bool forceCpuExt; i2p::config::GetOption("cpuext.force", forceCpuExt);
 | 
				
			||||||
			i2p::crypto::InitCrypto (precomputation, aesni, avx, forceCpuExt);
 | 
							i2p::crypto::InitCrypto (precomputation, aesni, avx, forceCpuExt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			int netID; i2p::config::GetOption("netid", netID);
 | 
							int netID; i2p::config::GetOption("netid", netID);
 | 
				
			||||||
			i2p::context.SetNetID (netID);
 | 
							i2p::context.SetNetID (netID);
 | 
				
			||||||
			i2p::context.Init ();
 | 
							i2p::context.Init ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			bool ipv6;		i2p::config::GetOption("ipv6", ipv6);
 | 
							bool ipv6;		i2p::config::GetOption("ipv6", ipv6);
 | 
				
			||||||
			bool ipv4;		i2p::config::GetOption("ipv4", ipv4);
 | 
							bool ipv4;		i2p::config::GetOption("ipv4", ipv4);
 | 
				
			||||||
#ifdef MESHNET
 | 
					#ifdef MESHNET
 | 
				
			||||||
			// manual override for meshnet
 | 
							// manual override for meshnet
 | 
				
			||||||
			ipv4 = false;
 | 
							ipv4 = false;
 | 
				
			||||||
			ipv6 = true;
 | 
							ipv6 = true;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
			bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg);
 | 
							bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg);
 | 
				
			||||||
			boost::asio::ip::address_v6 yggaddr;
 | 
							boost::asio::ip::address_v6 yggaddr;
 | 
				
			||||||
			if (ygg)
 | 
							if (ygg)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								std::string yggaddress; i2p::config::GetOption ("meshnets.yggaddress", yggaddress);
 | 
				
			||||||
 | 
								if (!yggaddress.empty ())
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				std::string yggaddress; i2p::config::GetOption ("meshnets.yggaddress", yggaddress);
 | 
									yggaddr = boost::asio::ip::address_v6::from_string (yggaddress);
 | 
				
			||||||
				if (!yggaddress.empty ())
 | 
									if (yggaddr.is_unspecified () || !i2p::util::net::IsYggdrasilAddress (yggaddr) ||
 | 
				
			||||||
 | 
										!i2p::util::net::IsLocalAddress (yggaddr))
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					yggaddr = boost::asio::ip::address_v6::from_string (yggaddress);
 | 
										LogPrint(eLogWarning, "Daemon: Can't find Yggdrasil address ", yggaddress);
 | 
				
			||||||
					if (yggaddr.is_unspecified () || !i2p::util::net::IsYggdrasilAddress (yggaddr) || 
 | 
										ygg = false;
 | 
				
			||||||
					    !i2p::util::net::IsLocalAddress (yggaddr)) 
 | 
					 | 
				
			||||||
					{
 | 
					 | 
				
			||||||
						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
 | 
								else
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				LogPrint(eLogInfo, "Daemon: bandwidth set to 'low'");
 | 
									yggaddr = i2p::util::net::GetYggdrasilAddress ();
 | 
				
			||||||
				i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2);
 | 
									if (yggaddr.is_unspecified ())
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			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)
 | 
					 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					std::set<std::string> fams;
 | 
										LogPrint(eLogWarning, "Daemon: Yggdrasil is not running. Disabled");
 | 
				
			||||||
					size_t pos = 0, comma;
 | 
										ygg = false;
 | 
				
			||||||
					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 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: accepting incoming connections at port ", port);
 | 
				
			||||||
			LogPrint(eLogInfo, "Daemon: starting NetDB");
 | 
								i2p::context.UpdatePort (port);
 | 
				
			||||||
			i2p::data::netdb.Start();
 | 
							}
 | 
				
			||||||
 | 
							i2p::context.SetSupportsV6 (ipv6);
 | 
				
			||||||
 | 
							i2p::context.SetSupportsV4 (ipv4);
 | 
				
			||||||
 | 
							i2p::context.SetSupportsMesh (ygg, yggaddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			bool upnp; i2p::config::GetOption("upnp.enabled", upnp);
 | 
							i2p::context.RemoveNTCPAddress (!ipv6); // TODO: remove later
 | 
				
			||||||
			if (upnp) {
 | 
							bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
 | 
				
			||||||
				d.UPnP = std::unique_ptr<i2p::transport::UPnP>(new i2p::transport::UPnP);
 | 
							if (ntcp2)
 | 
				
			||||||
				d.UPnP->Start ();
 | 
							{
 | 
				
			||||||
			}
 | 
								bool published; i2p::config::GetOption("ntcp2.published", published);
 | 
				
			||||||
 | 
								if (published)
 | 
				
			||||||
			bool nettime; i2p::config::GetOption("nettime.enabled", nettime);
 | 
					 | 
				
			||||||
			if (nettime)
 | 
					 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				d.m_NTPSync = std::unique_ptr<i2p::util::NTPTimeSync>(new i2p::util::NTPTimeSync);
 | 
									uint16_t ntcp2port; i2p::config::GetOption("ntcp2.port", ntcp2port);
 | 
				
			||||||
				d.m_NTPSync->Start ();
 | 
									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 transit; i2p::config::GetOption("notransit", transit);
 | 
				
			||||||
			bool ssu; i2p::config::GetOption("ssu", ssu);
 | 
							i2p::context.SetAcceptsTunnels (!transit);
 | 
				
			||||||
			bool checkInReserved; i2p::config::GetOption("reservedrange", checkInReserved);
 | 
							uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);
 | 
				
			||||||
			LogPrint(eLogInfo, "Daemon: starting Transports");
 | 
							SetMaxNumTransitTunnels (transitTunnels);
 | 
				
			||||||
			if(!ssu) LogPrint(eLogInfo, "Daemon: ssu disabled");
 | 
					 | 
				
			||||||
			if(!ntcp2) LogPrint(eLogInfo, "Daemon: ntcp2 disabled");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			i2p::transport::transports.SetCheckReserved(checkInReserved);
 | 
							bool isFloodfill; i2p::config::GetOption("floodfill", isFloodfill);
 | 
				
			||||||
			i2p::transport::transports.Start(ntcp2, ssu);
 | 
							if (isFloodfill) {
 | 
				
			||||||
			if (i2p::transport::transports.IsBoundSSU() || i2p::transport::transports.IsBoundNTCP2())
 | 
								LogPrint(eLogInfo, "Daemon: router will be floodfill");
 | 
				
			||||||
				LogPrint(eLogInfo, "Daemon: Transports started");
 | 
								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
 | 
								else
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				LogPrint(eLogError, "Daemon: failed to start Transports");
 | 
									auto value = std::atoi(bandwidth.c_str());
 | 
				
			||||||
				/** shut down netdb right away */
 | 
									if (value > 0)
 | 
				
			||||||
				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 
 | 
					 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					d.httpServer = std::unique_ptr<i2p::http::HTTPServer>(new i2p::http::HTTPServer(httpAddr, httpPort));
 | 
										i2p::context.SetBandwidth (value);
 | 
				
			||||||
					d.httpServer->Start();
 | 
										LogPrint(eLogInfo, "Daemon: bandwidth set to ", i2p::context.GetBandwidthLimit (), " KBps");
 | 
				
			||||||
				} 
 | 
									}
 | 
				
			||||||
				catch (std::exception& ex) 
 | 
									else
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					LogPrint (eLogError, "Daemon: failed to start webconsole: ", ex.what ());
 | 
										LogPrint(eLogInfo, "Daemon: unexpected bandwidth ", bandwidth, ". Set to 'low'");
 | 
				
			||||||
					ThrowFatal ("Unable to start webconsole at ", httpAddr, ":", httpPort, ": ", ex.what ());
 | 
										i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if (isFloodfill)
 | 
				
			||||||
			LogPrint(eLogInfo, "Daemon: starting Tunnels");
 | 
							{
 | 
				
			||||||
			i2p::tunnel::tunnels.Start();
 | 
								LogPrint(eLogInfo, "Daemon: floodfill bandwidth set to 'extra'");
 | 
				
			||||||
 | 
								i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_EXTRA_BANDWIDTH1);
 | 
				
			||||||
			LogPrint(eLogInfo, "Daemon: starting Client");
 | 
							}
 | 
				
			||||||
			i2p::client::context.Start ();
 | 
							else
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
			// I2P Control Protocol
 | 
								LogPrint(eLogInfo, "Daemon: bandwidth set to 'low'");
 | 
				
			||||||
			bool i2pcontrol; i2p::config::GetOption("i2pcontrol.enabled", i2pcontrol);
 | 
								i2p::context.SetBandwidth (i2p::data::CAPS_FLAG_LOW_BANDWIDTH2);
 | 
				
			||||||
			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()
 | 
							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: explicit trust enabled");
 | 
				
			||||||
			LogPrint(eLogInfo, "Daemon: stopping Client");
 | 
								std::string fam; i2p::config::GetOption("trust.family", fam);
 | 
				
			||||||
			i2p::client::context.Stop();
 | 
								std::string routers; i2p::config::GetOption("trust.routers", routers);
 | 
				
			||||||
			LogPrint(eLogInfo, "Daemon: stopping Tunnels");
 | 
								bool restricted = false;
 | 
				
			||||||
			i2p::tunnel::tunnels.Stop();
 | 
								if (fam.length() > 0)
 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (d.UPnP) 
 | 
					 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				d.UPnP->Stop ();
 | 
									std::set<std::string> fams;
 | 
				
			||||||
				d.UPnP = nullptr;
 | 
									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) {
 | 
				
			||||||
			if (d.m_NTPSync)
 | 
									std::set<i2p::data::IdentHash> idents;
 | 
				
			||||||
			{
 | 
									size_t pos = 0, comma;
 | 
				
			||||||
				d.m_NTPSync->Stop ();
 | 
									do
 | 
				
			||||||
				d.m_NTPSync = nullptr;
 | 
									{
 | 
				
			||||||
 | 
										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();
 | 
								i2p::transport::transports.Stop();
 | 
				
			||||||
			LogPrint(eLogInfo, "Daemon: stopping NetDB");
 | 
					 | 
				
			||||||
			i2p::data::netdb.Stop();
 | 
								i2p::data::netdb.Stop();
 | 
				
			||||||
			if (d.httpServer) {
 | 
								return false;
 | 
				
			||||||
				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;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							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)
 | 
						std::shared_ptr<DatagramSession> DatagramDestination::GetSession(const i2p::data::IdentHash & ident)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return ObtainSession(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)
 | 
						void DatagramDestination::SendDatagram (std::shared_ptr<DatagramSession> session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (session)
 | 
							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}},
 | 
								auto msg = CreateDataMessage ({{m_From.data (), m_From.size ()}, {m_Signature.data (), m_Signature.size ()}, {payload, len}},
 | 
				
			||||||
				fromPort, toPort, false, !session->IsRatchets ()); // datagram
 | 
									fromPort, toPort, false, !session->IsRatchets ()); // datagram
 | 
				
			||||||
			session->SendMsg(msg);
 | 
								session->SendMsg(msg);
 | 
				
			||||||
		}	
 | 
							}
 | 
				
			||||||
	}	
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void DatagramDestination::SendRawDatagram (std::shared_ptr<DatagramSession> session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort)
 | 
						void DatagramDestination::SendRawDatagram (std::shared_ptr<DatagramSession> session, const uint8_t * payload, size_t len, uint16_t fromPort, uint16_t toPort)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (session)
 | 
							if (session)
 | 
				
			||||||
			session->SendMsg(CreateDataMessage ({{payload, len}}, fromPort, toPort, true, !session->IsRatchets ())); // raw
 | 
								session->SendMsg(CreateDataMessage ({{payload, len}}, fromPort, toPort, true, !session->IsRatchets ())); // raw
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
	void DatagramDestination::FlushSendQueue (std::shared_ptr<DatagramSession> session)
 | 
						void DatagramDestination::FlushSendQueue (std::shared_ptr<DatagramSession> session)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (session)
 | 
							if (session)
 | 
				
			||||||
			session->FlushSendQueue ();
 | 
								session->FlushSendQueue ();
 | 
				
			||||||
	}	
 | 
						}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
	void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort,uint8_t * const &buf, size_t len)
 | 
						void DatagramDestination::HandleDatagram (uint16_t fromPort, uint16_t toPort,uint8_t * const &buf, size_t len)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		i2p::data::IdentityEx identity;
 | 
							i2p::data::IdentityEx identity;
 | 
				
			||||||
| 
						 | 
					@ -242,7 +242,7 @@ namespace datagram
 | 
				
			||||||
		if (msg || m_SendQueue.empty ())
 | 
							if (msg || m_SendQueue.empty ())
 | 
				
			||||||
			m_SendQueue.push_back(msg);
 | 
								m_SendQueue.push_back(msg);
 | 
				
			||||||
		// flush queue right away if full
 | 
							// 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();
 | 
								FlushSendQueue();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -286,14 +286,14 @@ namespace datagram
 | 
				
			||||||
			m_RemoteLeaseSet = m_LocalDestination->FindLeaseSet(m_RemoteIdent);
 | 
								m_RemoteLeaseSet = m_LocalDestination->FindLeaseSet(m_RemoteIdent);
 | 
				
			||||||
			if (!m_RemoteLeaseSet)
 | 
								if (!m_RemoteLeaseSet)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				if(!m_RequestingLS) 
 | 
									if(!m_RequestingLS)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					m_RequestingLS = true;
 | 
										m_RequestingLS = true;
 | 
				
			||||||
					m_LocalDestination->RequestDestination(m_RemoteIdent, std::bind(&DatagramSession::HandleLeaseSetUpdated, this, std::placeholders::_1));
 | 
										m_LocalDestination->RequestDestination(m_RemoteIdent, std::bind(&DatagramSession::HandleLeaseSetUpdated, this, std::placeholders::_1));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				return nullptr;
 | 
									return nullptr;
 | 
				
			||||||
			}	
 | 
								}
 | 
				
			||||||
		}	
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!m_RoutingSession || m_RoutingSession->IsTerminated () || !m_RoutingSession->IsReadyToSend ()) 
 | 
							if (!m_RoutingSession || m_RoutingSession->IsTerminated () || !m_RoutingSession->IsReadyToSend ()) 
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
| 
						 | 
					@ -305,81 +305,81 @@ namespace datagram
 | 
				
			||||||
					m_PendingRoutingSessions.clear ();
 | 
										m_PendingRoutingSessions.clear ();
 | 
				
			||||||
					found = true;
 | 
										found = true;
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				}		
 | 
									}
 | 
				
			||||||
			if (!found)
 | 
								if (!found)
 | 
				
			||||||
			{	
 | 
								{
 | 
				
			||||||
				m_RoutingSession = m_LocalDestination->GetRoutingSession(m_RemoteLeaseSet, true);
 | 
									m_RoutingSession = m_LocalDestination->GetRoutingSession(m_RemoteLeaseSet, true);
 | 
				
			||||||
				if (!m_RoutingSession->GetOwner () || !m_RoutingSession->IsReadyToSend ())
 | 
									if (!m_RoutingSession->GetOwner () || !m_RoutingSession->IsReadyToSend ())
 | 
				
			||||||
					m_PendingRoutingSessions.push_back (m_RoutingSession);
 | 
										m_PendingRoutingSessions.push_back (m_RoutingSession);
 | 
				
			||||||
			}	
 | 
								}
 | 
				
			||||||
		}	
 | 
							}
 | 
				
			||||||
		
 | 
					
 | 
				
			||||||
		auto path = m_RoutingSession->GetSharedRoutingPath();
 | 
							auto path = m_RoutingSession->GetSharedRoutingPath();
 | 
				
			||||||
		if (path && m_RoutingSession->IsRatchets () &&
 | 
							if (path && m_RoutingSession->IsRatchets () &&
 | 
				
			||||||
		    m_LastUse > m_RoutingSession->GetLastActivityTimestamp ()*1000 + DATAGRAM_SESSION_PATH_TIMEOUT)
 | 
							    m_LastUse > m_RoutingSession->GetLastActivityTimestamp ()*1000 + DATAGRAM_SESSION_PATH_TIMEOUT)
 | 
				
			||||||
		{	
 | 
							{
 | 
				
			||||||
			m_RoutingSession->SetSharedRoutingPath (nullptr);
 | 
								m_RoutingSession->SetSharedRoutingPath (nullptr);
 | 
				
			||||||
			path = nullptr;
 | 
								path = nullptr;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
				
 | 
					
 | 
				
			||||||
		if (path) 
 | 
							if (path)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (path->outboundTunnel && !path->outboundTunnel->IsEstablished ())
 | 
								if (path->outboundTunnel && !path->outboundTunnel->IsEstablished ())
 | 
				
			||||||
			{	
 | 
								{
 | 
				
			||||||
				// bad outbound tunnel, switch outbound tunnel
 | 
									// bad outbound tunnel, switch outbound tunnel
 | 
				
			||||||
				path->outboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel(path->outboundTunnel);
 | 
									path->outboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel(path->outboundTunnel);
 | 
				
			||||||
				if (!path->outboundTunnel)
 | 
									if (!path->outboundTunnel)
 | 
				
			||||||
					m_RoutingSession->SetSharedRoutingPath (nullptr);
 | 
										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
 | 
									// bad lease, switch to next one
 | 
				
			||||||
				if (m_RemoteLeaseSet) 
 | 
									if (m_RemoteLeaseSet)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					auto ls = m_RemoteLeaseSet->GetNonExpiredLeasesExcluding(
 | 
										auto ls = m_RemoteLeaseSet->GetNonExpiredLeasesExcluding(
 | 
				
			||||||
						[&](const i2p::data::Lease& l) -> bool 
 | 
											[&](const i2p::data::Lease& l) -> bool
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
							return l.tunnelID == path->remoteLease->tunnelID;
 | 
												return l.tunnelID == path->remoteLease->tunnelID;
 | 
				
			||||||
						});
 | 
											});
 | 
				
			||||||
					auto sz = ls.size();
 | 
										auto sz = ls.size();
 | 
				
			||||||
					if (sz) 
 | 
										if (sz)
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						auto idx = rand() % sz;
 | 
											auto idx = rand() % sz;
 | 
				
			||||||
						path->remoteLease = ls[idx];
 | 
											path->remoteLease = ls[idx];
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					else
 | 
										else
 | 
				
			||||||
						m_RoutingSession->SetSharedRoutingPath (nullptr);
 | 
											m_RoutingSession->SetSharedRoutingPath (nullptr);
 | 
				
			||||||
				} 
 | 
									}
 | 
				
			||||||
				else 
 | 
									else
 | 
				
			||||||
				{	
 | 
									{
 | 
				
			||||||
					// no remote lease set?
 | 
										// no remote lease set?
 | 
				
			||||||
					LogPrint(eLogWarning, "DatagramSession: no cached remote lease set for ", m_RemoteIdent.ToBase32());
 | 
										LogPrint(eLogWarning, "DatagramSession: no cached remote lease set for ", m_RemoteIdent.ToBase32());
 | 
				
			||||||
					m_RoutingSession->SetSharedRoutingPath (nullptr);
 | 
										m_RoutingSession->SetSharedRoutingPath (nullptr);
 | 
				
			||||||
				}	
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} 
 | 
							}
 | 
				
			||||||
		else 
 | 
							else
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			// no current path, make one
 | 
								// no current path, make one
 | 
				
			||||||
			path = std::make_shared<i2p::garlic::GarlicRoutingPath>();
 | 
								path = std::make_shared<i2p::garlic::GarlicRoutingPath>();
 | 
				
			||||||
			path->outboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel();
 | 
								path->outboundTunnel = m_LocalDestination->GetTunnelPool()->GetNextOutboundTunnel();
 | 
				
			||||||
			if (!path->outboundTunnel) return nullptr;
 | 
								if (!path->outboundTunnel) return nullptr;
 | 
				
			||||||
				
 | 
					
 | 
				
			||||||
			if (m_RemoteLeaseSet) 
 | 
								if (m_RemoteLeaseSet)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				// pick random next good lease
 | 
									// pick random next good lease
 | 
				
			||||||
				auto ls = m_RemoteLeaseSet->GetNonExpiredLeases();
 | 
									auto ls = m_RemoteLeaseSet->GetNonExpiredLeases();
 | 
				
			||||||
				auto sz = ls.size();
 | 
									auto sz = ls.size();
 | 
				
			||||||
				if (sz) 
 | 
									if (sz)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					auto idx = rand() % sz;
 | 
										auto idx = rand() % sz;
 | 
				
			||||||
					path->remoteLease = ls[idx];
 | 
										path->remoteLease = ls[idx];
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				else
 | 
									else
 | 
				
			||||||
					return nullptr;
 | 
										return nullptr;
 | 
				
			||||||
			} 
 | 
								}
 | 
				
			||||||
			else 
 | 
								else
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				// no remote lease set currently, bail
 | 
									// no remote lease set currently, bail
 | 
				
			||||||
				LogPrint(eLogWarning, "DatagramSession: no remote lease set found for ", m_RemoteIdent.ToBase32());
 | 
									LogPrint(eLogWarning, "DatagramSession: no remote lease set found for ", m_RemoteIdent.ToBase32());
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue