mirror of
				https://github.com/PurpleI2P/i2pd.git
				synced 2025-11-04 00:20:46 +00:00 
			
		
		
		
	cleanup code (spaces, tabs)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
This commit is contained in:
		
							parent
							
								
									d31cd2e5d6
								
							
						
					
					
						commit
						6b4ffcff5a
					
				
					 70 changed files with 848 additions and 847 deletions
				
			
		| 
						 | 
				
			
			@ -79,7 +79,7 @@ namespace util
 | 
			
		|||
		i2p::config::Init();
 | 
			
		||||
		i2p::config::ParseCmdline(argc, argv);
 | 
			
		||||
 | 
			
		||||
		std::string config;  i2p::config::GetOption("conf", config);
 | 
			
		||||
		std::string config; i2p::config::GetOption("conf", config);
 | 
			
		||||
		std::string datadir;
 | 
			
		||||
		if(DaemonDataDir != "") {
 | 
			
		||||
			datadir = DaemonDataDir;
 | 
			
		||||
| 
						 | 
				
			
			@ -111,9 +111,9 @@ namespace util
 | 
			
		|||
 | 
			
		||||
		certsdir = i2p::fs::GetCertsDir();
 | 
			
		||||
 | 
			
		||||
		std::string logs     = ""; i2p::config::GetOption("log",      logs);
 | 
			
		||||
		std::string logfile  = ""; i2p::config::GetOption("logfile",  logfile);
 | 
			
		||||
		std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel);
 | 
			
		||||
		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 */
 | 
			
		||||
| 
						 | 
				
			
			@ -254,17 +254,17 @@ namespace util
 | 
			
		|||
		}
 | 
			
		||||
		bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
 | 
			
		||||
		if (ssu2)
 | 
			
		||||
		{	
 | 
			
		||||
		{
 | 
			
		||||
			bool published; i2p::config::GetOption("ssu2.published", published);
 | 
			
		||||
			if (published)
 | 
			
		||||
			{
 | 
			
		||||
				uint16_t ssu2port; i2p::config::GetOption("ssu2.port", ssu2port);
 | 
			
		||||
				i2p::context.PublishSSU2Address (ssu2port, true, ipv4, ipv6); // publish
 | 
			
		||||
			}	
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
				i2p::context.PublishSSU2Address (0, false, ipv4, ipv6); // unpublish
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		bool transit; i2p::config::GetOption("notransit", transit);
 | 
			
		||||
		i2p::context.SetAcceptsTunnels (!transit);
 | 
			
		||||
		uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -324,9 +324,9 @@ namespace http {
 | 
			
		|||
					default:
 | 
			
		||||
						s << tr("Unknown");
 | 
			
		||||
				}
 | 
			
		||||
				if (address->IsV6 ()) 
 | 
			
		||||
				if (address->IsV6 ())
 | 
			
		||||
				{
 | 
			
		||||
					if (address->IsV4 ()) s << "v4"; 
 | 
			
		||||
					if (address->IsV4 ()) s << "v4";
 | 
			
		||||
					s << "v6";
 | 
			
		||||
				}
 | 
			
		||||
				s << "</td>\r\n";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -98,8 +98,8 @@ namespace http
 | 
			
		|||
	void ShowSAMSessions (std::stringstream& s);
 | 
			
		||||
	void ShowI2PTunnels (std::stringstream& s);
 | 
			
		||||
	void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token);
 | 
			
		||||
    void ShowSAMSession (std::stringstream& s, const std::string& id);
 | 
			
		||||
    void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id);
 | 
			
		||||
	void ShowSAMSession (std::stringstream& s, const std::string& id);
 | 
			
		||||
	void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id);
 | 
			
		||||
} // http
 | 
			
		||||
} // i2p
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,29 +66,28 @@ namespace client
 | 
			
		|||
		m_SSLContext.use_private_key_file (i2pcp_key, boost::asio::ssl::context::pem);
 | 
			
		||||
 | 
			
		||||
		// handlers
 | 
			
		||||
		m_MethodHandlers["Authenticate"]   = &I2PControlService::AuthenticateHandler;
 | 
			
		||||
		m_MethodHandlers["Echo"]           = &I2PControlService::EchoHandler;
 | 
			
		||||
		m_MethodHandlers["I2PControl"]     = &I2PControlService::I2PControlHandler;
 | 
			
		||||
		m_MethodHandlers["RouterInfo"]     = &I2PControlService::RouterInfoHandler;
 | 
			
		||||
		m_MethodHandlers["RouterManager"]  = &I2PControlService::RouterManagerHandler;
 | 
			
		||||
		m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler;
 | 
			
		||||
		m_MethodHandlers["ClientServicesInfo"]     = &I2PControlService::ClientServicesInfoHandler;
 | 
			
		||||
		m_MethodHandlers["Authenticate"]       = &I2PControlService::AuthenticateHandler;
 | 
			
		||||
		m_MethodHandlers["Echo"]               = &I2PControlService::EchoHandler;
 | 
			
		||||
		m_MethodHandlers["I2PControl"]         = &I2PControlService::I2PControlHandler;
 | 
			
		||||
		m_MethodHandlers["RouterInfo"]         = &I2PControlService::RouterInfoHandler;
 | 
			
		||||
		m_MethodHandlers["RouterManager"]      = &I2PControlService::RouterManagerHandler;
 | 
			
		||||
		m_MethodHandlers["NetworkSetting"]     = &I2PControlService::NetworkSettingHandler;
 | 
			
		||||
		m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler;
 | 
			
		||||
 | 
			
		||||
		// I2PControl
 | 
			
		||||
		m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler;
 | 
			
		||||
 | 
			
		||||
		// RouterInfo
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.uptime"]  = &I2PControlService::UptimeHandler;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.status"]  = &I2PControlService::StatusHandler;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.netdb.knownpeers"]   = &I2PControlService::NetDbKnownPeersHandler;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.netdb.activepeers"]  = &I2PControlService::NetDbActivePeersHandler;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"]  = &I2PControlService::InboundBandwidth1S;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.net.status"]         = &I2PControlService::NetStatusHandler;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.uptime"]                    = &I2PControlService::UptimeHandler;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.version"]                   = &I2PControlService::VersionHandler;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.status"]                    = &I2PControlService::StatusHandler;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.netdb.knownpeers"]          = &I2PControlService::NetDbKnownPeersHandler;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.netdb.activepeers"]         = &I2PControlService::NetDbActivePeersHandler;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"]         = &I2PControlService::InboundBandwidth1S;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.net.bw.outbound.1s"]        = &I2PControlService::OutboundBandwidth1S;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.net.status"]                = &I2PControlService::NetStatusHandler;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] =
 | 
			
		||||
&I2PControlService::TunnelsSuccessRateHandler;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"]   = &I2PControlService::TunnelsSuccessRateHandler;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.net.total.received.bytes"]  = &I2PControlService::NetTotalReceivedBytes;
 | 
			
		||||
		m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"]      = &I2PControlService::NetTotalSentBytes;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -104,10 +103,10 @@ namespace client
 | 
			
		|||
		// ClientServicesInfo
 | 
			
		||||
		m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlService::I2PTunnelInfoHandler;
 | 
			
		||||
		m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlService::HTTPProxyInfoHandler;
 | 
			
		||||
		m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler;
 | 
			
		||||
		m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler;
 | 
			
		||||
		m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler;
 | 
			
		||||
		m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler;
 | 
			
		||||
		m_ClientServicesInfoHandlers["SOCKS"]     = &I2PControlService::SOCKSInfoHandler;
 | 
			
		||||
		m_ClientServicesInfoHandlers["SAM"]       = &I2PControlService::SAMInfoHandler;
 | 
			
		||||
		m_ClientServicesInfoHandlers["BOB"]       = &I2PControlService::BOBInfoHandler;
 | 
			
		||||
		m_ClientServicesInfoHandlers["I2CP"]      = &I2PControlService::I2CPInfoHandler;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	I2PControlService::~I2PControlService ()
 | 
			
		||||
| 
						 | 
				
			
			@ -168,7 +167,7 @@ namespace client
 | 
			
		|||
			Accept ();
 | 
			
		||||
 | 
			
		||||
		if (ecode) {
 | 
			
		||||
			LogPrint (eLogError, "I2PControl: Accept error: ",  ecode.message ());
 | 
			
		||||
			LogPrint (eLogError, "I2PControl: Accept error: ", ecode.message ());
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		LogPrint (eLogDebug, "I2PControl: New request from ", socket->lowest_layer ().remote_endpoint ());
 | 
			
		||||
| 
						 | 
				
			
			@ -290,12 +289,12 @@ namespace client
 | 
			
		|||
	{
 | 
			
		||||
		ss << "\"" << name << "\":";
 | 
			
		||||
		if (value.length () > 0)
 | 
			
		||||
		{	
 | 
			
		||||
		{
 | 
			
		||||
			if (quotes)
 | 
			
		||||
				ss << "\"" << value << "\"";
 | 
			
		||||
			else
 | 
			
		||||
				ss << value;
 | 
			
		||||
		}	
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			ss << "null";
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -479,7 +478,7 @@ namespace client
 | 
			
		|||
 | 
			
		||||
	void I2PControlService::NetTotalSentBytes (std::ostringstream& results)
 | 
			
		||||
	{
 | 
			
		||||
		InsertParam (results, "i2p.router.net.total.sent.bytes",     (double)i2p::transport::transports.GetTotalSentBytes ());
 | 
			
		||||
		InsertParam (results, "i2p.router.net.total.sent.bytes", (double)i2p::transport::transports.GetTotalSentBytes ());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -507,7 +506,7 @@ namespace client
 | 
			
		|||
		m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(1)); // 1 second to make sure response has been sent
 | 
			
		||||
		m_ShutdownTimer.async_wait (
 | 
			
		||||
			[](const boost::system::error_code& ecode)
 | 
			
		||||
		    {
 | 
			
		||||
			{
 | 
			
		||||
				Daemon.running = 0;
 | 
			
		||||
			});
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -521,7 +520,7 @@ namespace client
 | 
			
		|||
		m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(timeout + 1)); // + 1 second
 | 
			
		||||
		m_ShutdownTimer.async_wait (
 | 
			
		||||
			[](const boost::system::error_code& ecode)
 | 
			
		||||
		    {
 | 
			
		||||
			{
 | 
			
		||||
				Daemon.running = 0;
 | 
			
		||||
			});
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -93,7 +93,7 @@ namespace transport
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
		isError = err != UPNPDISCOVER_SUCCESS;
 | 
			
		||||
#else  // MINIUPNPC_API_VERSION >= 8
 | 
			
		||||
#else // MINIUPNPC_API_VERSION >= 8
 | 
			
		||||
		err = 0;
 | 
			
		||||
		m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0);
 | 
			
		||||
		isError = m_Devlist == NULL;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,7 +51,7 @@ namespace transport
 | 
			
		|||
		private:
 | 
			
		||||
 | 
			
		||||
			void Discover ();
 | 
			
		||||
			int  CheckMapping (const char* port, const char* type);
 | 
			
		||||
			int CheckMapping (const char* port, const char* type);
 | 
			
		||||
			void PortMapping ();
 | 
			
		||||
			void TryPortMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address);
 | 
			
		||||
			void CloseMapping ();
 | 
			
		||||
| 
						 | 
				
			
			@ -80,7 +80,7 @@ namespace transport
 | 
			
		|||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else  // USE_UPNP
 | 
			
		||||
#else // USE_UPNP
 | 
			
		||||
namespace i2p {
 | 
			
		||||
namespace transport {
 | 
			
		||||
	/* class stub */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,8 +24,8 @@ namespace data {
 | 
			
		|||
	size_t ByteStreamToBase32 (const uint8_t * InBuf, size_t len, char * outBuf, size_t outLen);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes
 | 
			
		||||
	*/
 | 
			
		||||
	 * Compute the size for a buffer to contain encoded base64 given that the size of the input is input_size bytes
 | 
			
		||||
	 */
 | 
			
		||||
	size_t Base64EncodingBufferSize(const size_t input_size);
 | 
			
		||||
 | 
			
		||||
	std::string ToBase64Standard (const std::string& in); // using standard table, for Proxy-Authorization
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -99,7 +99,7 @@ namespace data
 | 
			
		|||
	static size_t BlindECDSA (i2p::data::SigningKeyType sigType, const uint8_t * key, const uint8_t * seed, Fn blind, Args&&...args)
 | 
			
		||||
	// blind is BlindEncodedPublicKeyECDSA or BlindEncodedPrivateKeyECDSA
 | 
			
		||||
	{
 | 
			
		||||
		size_t publicKeyLength  = 0;
 | 
			
		||||
		size_t publicKeyLength = 0;
 | 
			
		||||
		EC_GROUP * group = nullptr;
 | 
			
		||||
		switch (sigType)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -147,8 +147,8 @@ namespace data
 | 
			
		|||
		memcpy (m_PublicKey.data (), identity->GetSigningPublicKeyBuffer (), len);
 | 
			
		||||
		m_SigType = identity->GetSigningKeyType ();
 | 
			
		||||
		if (m_SigType == i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519)
 | 
			
		||||
			m_BlindedSigType = i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519; // 7 -> 11	
 | 
			
		||||
		else		
 | 
			
		||||
			m_BlindedSigType = i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519; // 7 -> 11
 | 
			
		||||
		else
 | 
			
		||||
			m_BlindedSigType = m_SigType;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,8 +28,8 @@ namespace data
 | 
			
		|||
 | 
			
		||||
			const uint8_t * GetPublicKey () const { return m_PublicKey.data (); };
 | 
			
		||||
			size_t GetPublicKeyLen () const { return m_PublicKey.size (); };
 | 
			
		||||
			SigningKeyType GetSigType () const  { return m_SigType; };
 | 
			
		||||
			SigningKeyType GetBlindedSigType () const  { return m_BlindedSigType; };
 | 
			
		||||
			SigningKeyType GetSigType () const { return m_SigType; };
 | 
			
		||||
			SigningKeyType GetBlindedSigType () const { return m_BlindedSigType; };
 | 
			
		||||
			bool IsValid () const { return GetSigType (); }; // signature type 0 means invalid
 | 
			
		||||
 | 
			
		||||
			void GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const; // 32 bytes
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -277,7 +277,7 @@ namespace config {
 | 
			
		|||
			("ssu2.published", value<bool>()->default_value(false),        "Publish SSU2 (default: disabled)")
 | 
			
		||||
			("ssu2.port", value<uint16_t>()->default_value(0),            "Port to listen for incoming SSU2 packets (default: auto)")
 | 
			
		||||
		;
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		options_description nettime("Time sync options");
 | 
			
		||||
		nettime.add_options()
 | 
			
		||||
			("nettime.enabled", value<bool>()->default_value(false),       "Disable time sync (default: disabled)")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,16 +29,16 @@ namespace config {
 | 
			
		|||
	extern boost::program_options::variables_map m_Options;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief  Initialize list of acceptable parameters
 | 
			
		||||
	 * @brief Initialize list of acceptable parameters
 | 
			
		||||
	 *
 | 
			
		||||
	 * Should be called before any Parse* functions.
 | 
			
		||||
	 */
 | 
			
		||||
	void Init();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief  Parse cmdline parameters, and show help if requested
 | 
			
		||||
	 * @param  argc  Cmdline arguments count, should be passed from main().
 | 
			
		||||
	 * @param  argv  Cmdline parameters array, should be passed from main()
 | 
			
		||||
	 * @brief Parse cmdline parameters, and show help if requested
 | 
			
		||||
	 * @param argc Cmdline arguments count, should be passed from main().
 | 
			
		||||
	 * @param argv Cmdline parameters array, should be passed from main()
 | 
			
		||||
	 *
 | 
			
		||||
	 * If --help is given in parameters, shows its list with description
 | 
			
		||||
	 * and terminates the program with exitcode 0.
 | 
			
		||||
| 
						 | 
				
			
			@ -52,8 +52,8 @@ namespace config {
 | 
			
		|||
	void ParseCmdline(int argc, char* argv[], bool ignoreUnknown = false);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief  Load and parse given config file
 | 
			
		||||
	 * @param  path  Path to config file
 | 
			
		||||
	 * @brief Load and parse given config file
 | 
			
		||||
	 * @param path Path to config file
 | 
			
		||||
	 *
 | 
			
		||||
	 * If error occurred when opening file path is points to,
 | 
			
		||||
	 * we show the error message and terminate program.
 | 
			
		||||
| 
						 | 
				
			
			@ -67,14 +67,14 @@ namespace config {
 | 
			
		|||
	void ParseConfig(const std::string& path);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief  Used to combine options from cmdline, config and default values
 | 
			
		||||
	 * @brief Used to combine options from cmdline, config and default values
 | 
			
		||||
	 */
 | 
			
		||||
	void Finalize();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief  Accessor to parameters by name
 | 
			
		||||
	 * @param  name  Name of the requested parameter
 | 
			
		||||
	 * @param  value Variable where to store option
 | 
			
		||||
	 * @brief Accessor to parameters by name
 | 
			
		||||
	 * @param name Name of the requested parameter
 | 
			
		||||
	 * @param value Variable where to store option
 | 
			
		||||
	 * @return this function returns false if parameter not found
 | 
			
		||||
	 *
 | 
			
		||||
	 * Example: uint16_t port; GetOption("sam.port", port);
 | 
			
		||||
| 
						 | 
				
			
			@ -98,9 +98,9 @@ namespace config {
 | 
			
		|||
	bool GetOptionAsAny(const std::string& name, boost::any& value);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief  Set value of given parameter
 | 
			
		||||
	 * @param  name  Name of settable parameter
 | 
			
		||||
	 * @param  value New parameter value
 | 
			
		||||
	 * @brief Set value of given parameter
 | 
			
		||||
	 * @param name Name of settable parameter
 | 
			
		||||
	 * @param value New parameter value
 | 
			
		||||
	 * @return true if value set up successful, false otherwise
 | 
			
		||||
	 *
 | 
			
		||||
	 * Example: uint16_t port = 2827; SetOption("bob.port", port);
 | 
			
		||||
| 
						 | 
				
			
			@ -116,8 +116,8 @@ namespace config {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief  Check is value explicitly given or default
 | 
			
		||||
	 * @param  name  Name of checked parameter
 | 
			
		||||
	 * @brief Check is value explicitly given or default
 | 
			
		||||
	 * @param name Name of checked parameter
 | 
			
		||||
	 * @return true if value set to default, false otherwise
 | 
			
		||||
	 */
 | 
			
		||||
	bool IsDefault(const char *name);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1313,8 +1313,8 @@ namespace crypto
 | 
			
		|||
		for (const auto& it: bufs)
 | 
			
		||||
			SHA256_Update (&ctx, it.first, it.second);
 | 
			
		||||
		SHA256_Final (m_H, &ctx);
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void NoiseSymmetricState::MixKey (const uint8_t * sharedSecret)
 | 
			
		||||
	{
 | 
			
		||||
		HKDF (m_CK, sharedSecret, 32, "", m_CK);
 | 
			
		||||
| 
						 | 
				
			
			@ -1330,7 +1330,7 @@ namespace crypto
 | 
			
		|||
		SHA256_Init (&ctx);
 | 
			
		||||
		SHA256_Update (&ctx, hh, 32);
 | 
			
		||||
		SHA256_Update (&ctx, pub, 32);
 | 
			
		||||
		SHA256_Final (state.m_H, &ctx);  // h = MixHash(pub) = SHA256(hh || pub)
 | 
			
		||||
		SHA256_Final (state.m_H, &ctx); // h = MixHash(pub) = SHA256(hh || pub)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub)
 | 
			
		||||
| 
						 | 
				
			
			@ -1368,12 +1368,12 @@ namespace crypto
 | 
			
		|||
		}; // SHA256 ("Noise_XKchaobfse+hs1+hs2+hs3_25519_ChaChaPoly_SHA256")
 | 
			
		||||
		static const uint8_t hh[32] =
 | 
			
		||||
		{
 | 
			
		||||
			0xdc, 0x85, 0xe6, 0xaf, 0x7b, 0x02, 0x65, 0x0c, 0xf1, 0xf9, 0x0d, 0x71, 0xfb, 0xc6, 0xd4, 0x53, 
 | 
			
		||||
			0xdc, 0x85, 0xe6, 0xaf, 0x7b, 0x02, 0x65, 0x0c, 0xf1, 0xf9, 0x0d, 0x71, 0xfb, 0xc6, 0xd4, 0x53,
 | 
			
		||||
			0xa7, 0xcf, 0x6d, 0xbf, 0xbd, 0x52, 0x5e, 0xa5, 0xb5, 0x79, 0x1c, 0x47, 0xb3, 0x5e, 0xbc, 0x33
 | 
			
		||||
		}; // SHA256 (protocolNameHash)
 | 
			
		||||
		InitNoiseState (state, protocolNameHash, hh, pub);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub)
 | 
			
		||||
	{
 | 
			
		||||
		static const uint8_t protocolNameHash[32] =
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,24 +30,24 @@
 | 
			
		|||
 | 
			
		||||
// recognize openssl version and features
 | 
			
		||||
#if (defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER >= 0x3050200fL)) // LibreSSL 3.5.2 and above
 | 
			
		||||
#   define LEGACY_OPENSSL 0
 | 
			
		||||
#	define LEGACY_OPENSSL 0
 | 
			
		||||
#elif ((OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER)) // 1.0.2 and below or LibreSSL
 | 
			
		||||
#   define LEGACY_OPENSSL 1
 | 
			
		||||
#   define X509_getm_notBefore X509_get_notBefore
 | 
			
		||||
#   define X509_getm_notAfter X509_get_notAfter
 | 
			
		||||
#	define LEGACY_OPENSSL 1
 | 
			
		||||
#	define X509_getm_notBefore X509_get_notBefore
 | 
			
		||||
#	define X509_getm_notAfter X509_get_notAfter
 | 
			
		||||
#else
 | 
			
		||||
#   define LEGACY_OPENSSL 0
 | 
			
		||||
#   if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
 | 
			
		||||
#       define OPENSSL_HKDF 1
 | 
			
		||||
#       define OPENSSL_EDDSA 1
 | 
			
		||||
#       define OPENSSL_X25519 1
 | 
			
		||||
#	define LEGACY_OPENSSL 0
 | 
			
		||||
#	if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
 | 
			
		||||
#		define OPENSSL_HKDF 1
 | 
			
		||||
#		define OPENSSL_EDDSA 1
 | 
			
		||||
#		define OPENSSL_X25519 1
 | 
			
		||||
#		if (OPENSSL_VERSION_NUMBER != 0x030000000) // 3.0.0, regression in SipHash
 | 
			
		||||
#       	define OPENSSL_SIPHASH 1
 | 
			
		||||
#			define OPENSSL_SIPHASH 1
 | 
			
		||||
#		endif
 | 
			
		||||
#   endif
 | 
			
		||||
#   if !defined OPENSSL_NO_CHACHA && !defined OPENSSL_NO_POLY1305 // some builds might not include them
 | 
			
		||||
#       define OPENSSL_AEAD_CHACHA20_POLY1305 1
 | 
			
		||||
#   endif
 | 
			
		||||
#	endif
 | 
			
		||||
#	if !defined OPENSSL_NO_CHACHA && !defined OPENSSL_NO_POLY1305 // some builds might not include them
 | 
			
		||||
#		define OPENSSL_AEAD_CHACHA20_POLY1305 1
 | 
			
		||||
#	endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace i2p
 | 
			
		||||
| 
						 | 
				
			
			@ -385,7 +385,7 @@ inline int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
 | 
			
		|||
		if (dh->p) BN_free (dh->p);
 | 
			
		||||
		if (dh->q) BN_free (dh->q);
 | 
			
		||||
		if (dh->g) BN_free (dh->g);
 | 
			
		||||
		dh->p = p; dh->q = q; dh->g = g;  return 1;
 | 
			
		||||
		dh->p = p; dh->q = q; dh->g = g; return 1;
 | 
			
		||||
	}
 | 
			
		||||
inline int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -324,7 +324,7 @@ namespace datagram
 | 
			
		|||
 | 
			
		||||
		auto path = m_RoutingSession->GetSharedRoutingPath();
 | 
			
		||||
		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);
 | 
			
		||||
			path = nullptr;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -350,8 +350,8 @@ namespace client
 | 
			
		|||
			{
 | 
			
		||||
				s->AddECIESx25519Key (data.k, data.t);
 | 
			
		||||
			});
 | 
			
		||||
	}	
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void LeaseSetDestination::ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg)
 | 
			
		||||
	{
 | 
			
		||||
		m_Service.post (std::bind (&LeaseSetDestination::HandleGarlicMessage, shared_from_this (), msg));
 | 
			
		||||
| 
						 | 
				
			
			@ -417,7 +417,7 @@ namespace client
 | 
			
		|||
				std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
 | 
			
		||||
				auto it = m_RemoteLeaseSets.find (key);
 | 
			
		||||
				if (it != m_RemoteLeaseSets.end () &&
 | 
			
		||||
				    it->second->GetStoreType () == buf[DATABASE_STORE_TYPE_OFFSET]) // update only if same type
 | 
			
		||||
					it->second->GetStoreType () == buf[DATABASE_STORE_TYPE_OFFSET]) // update only if same type
 | 
			
		||||
				{
 | 
			
		||||
					leaseSet = it->second;
 | 
			
		||||
					if (leaseSet->IsNewer (buf + offset, len - offset))
 | 
			
		||||
| 
						 | 
				
			
			@ -587,7 +587,7 @@ namespace client
 | 
			
		|||
			LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found");
 | 
			
		||||
			m_ExcludedFloodfills.clear ();
 | 
			
		||||
			return;
 | 
			
		||||
		}	
 | 
			
		||||
		}
 | 
			
		||||
		auto outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false));
 | 
			
		||||
		auto inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true));
 | 
			
		||||
		if (!outbound || !inbound)
 | 
			
		||||
| 
						 | 
				
			
			@ -599,22 +599,22 @@ namespace client
 | 
			
		|||
			{
 | 
			
		||||
				outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false));
 | 
			
		||||
				if (outbound)
 | 
			
		||||
				{	
 | 
			
		||||
				{
 | 
			
		||||
					inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true));
 | 
			
		||||
					if (!inbound)
 | 
			
		||||
						LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels");
 | 
			
		||||
				}	
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
					LogPrint (eLogError, "Destination: Can't publish LeaseSet. No outbound tunnels");
 | 
			
		||||
			}	
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
				LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found");
 | 
			
		||||
			if (!floodfill || !outbound || !inbound)
 | 
			
		||||
			{
 | 
			
		||||
				m_ExcludedFloodfills.clear ();
 | 
			
		||||
				return;
 | 
			
		||||
			}	
 | 
			
		||||
		}	
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		m_ExcludedFloodfills.insert (floodfill->GetIdentHash ());
 | 
			
		||||
		LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ());
 | 
			
		||||
		RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -212,7 +212,7 @@ namespace garlic
 | 
			
		|||
			uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only
 | 
			
		||||
			std::shared_ptr<i2p::crypto::X25519Keys> m_EphemeralKeys;
 | 
			
		||||
			SessionState m_State = eSessionStateNew;
 | 
			
		||||
			uint64_t m_SessionCreatedTimestamp = 0,  m_LastActivityTimestamp = 0, // incoming (in seconds)
 | 
			
		||||
			uint64_t m_SessionCreatedTimestamp = 0, m_LastActivityTimestamp = 0, // incoming (in seconds)
 | 
			
		||||
				m_LastSentTimestamp = 0; // in milliseconds
 | 
			
		||||
			std::shared_ptr<RatchetTagSet> m_SendTagset, m_NSRSendTagset;
 | 
			
		||||
			std::unique_ptr<i2p::data::IdentHash> m_Destination;// TODO: might not need it
 | 
			
		||||
| 
						 | 
				
			
			@ -229,7 +229,7 @@ namespace garlic
 | 
			
		|||
			{
 | 
			
		||||
				return m_Destination ? *m_Destination : i2p::data::IdentHash ();
 | 
			
		||||
			}
 | 
			
		||||
	 };
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// single session for all incoming messages
 | 
			
		||||
	class RouterIncomingRatchetSession: public ECIESX25519AEADRatchetSession
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,7 +33,7 @@ namespace crypto
 | 
			
		|||
		BN_add (l, l, tmp);
 | 
			
		||||
		BN_sub_word (two_252_2, 2); // 2^252 - 2
 | 
			
		||||
 | 
			
		||||
		 // -121665*inv(121666)
 | 
			
		||||
		// -121665*inv(121666)
 | 
			
		||||
		d = BN_new ();
 | 
			
		||||
		BN_set_word (tmp, 121666);
 | 
			
		||||
		BN_mod_inverse (tmp, tmp, q, ctx);
 | 
			
		||||
| 
						 | 
				
			
			@ -61,7 +61,7 @@ namespace crypto
 | 
			
		|||
		BN_mod (By, By, q, ctx); // % q
 | 
			
		||||
 | 
			
		||||
		// precalculate Bi256 table
 | 
			
		||||
		Bi256Carry = { Bx, By };  // B
 | 
			
		||||
		Bi256Carry = { Bx, By }; // B
 | 
			
		||||
		for (int i = 0; i < 32; i++)
 | 
			
		||||
		{
 | 
			
		||||
			Bi256[i][0] = Bi256Carry; // first point
 | 
			
		||||
| 
						 | 
				
			
			@ -215,7 +215,7 @@ namespace crypto
 | 
			
		|||
		if (!t1) { t1 = BN_CTX_get (ctx); BN_mul (t1, p1.x, p1.y, ctx); }
 | 
			
		||||
		if (!t2) { t2 = BN_CTX_get (ctx); BN_mul (t2, p2.x, p2.y, ctx); }
 | 
			
		||||
		BN_mul (t3, t1, t2, ctx);
 | 
			
		||||
		BN_mul (t3, t3, d, ctx);  // C = d*t1*t2
 | 
			
		||||
		BN_mul (t3, t3, d, ctx); // C = d*t1*t2
 | 
			
		||||
 | 
			
		||||
		if (p1.z)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -264,9 +264,9 @@ namespace crypto
 | 
			
		|||
		else
 | 
			
		||||
		{
 | 
			
		||||
			BN_mul (t2, p.x, p.y, ctx); // t = x*y
 | 
			
		||||
			BN_sqr (t2, t2, ctx);  // t2 = t^2
 | 
			
		||||
			BN_sqr (t2, t2, ctx); // t2 = t^2
 | 
			
		||||
		}
 | 
			
		||||
		BN_mul (t2, t2, d, ctx);  // t2 = C = d*t^2
 | 
			
		||||
		BN_mul (t2, t2, d, ctx); // t2 = C = d*t^2
 | 
			
		||||
		if (p.z)
 | 
			
		||||
			BN_sqr (z2, p.z, ctx); // z2 = D = z^2
 | 
			
		||||
		else
 | 
			
		||||
| 
						 | 
				
			
			@ -349,7 +349,7 @@ namespace crypto
 | 
			
		|||
			BN_mod_inverse (y, p.z, q, ctx);
 | 
			
		||||
			BN_mod_mul (x, p.x, y, q, ctx); // x = x/z
 | 
			
		||||
			BN_mod_mul (y, p.y, y, q, ctx); // y = y/z
 | 
			
		||||
			return  EDDSAPoint{x, y};
 | 
			
		||||
			return EDDSAPoint{x, y};
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			return EDDSAPoint{BN_dup (p.x), BN_dup (p.y)};
 | 
			
		||||
| 
						 | 
				
			
			@ -506,13 +506,13 @@ namespace crypto
 | 
			
		|||
			std::swap (z2, z3);
 | 
			
		||||
		}
 | 
			
		||||
		BN_mod_inverse (z2, z2, q, ctx);
 | 
			
		||||
		BIGNUM * res =  BN_new (); // not from ctx
 | 
			
		||||
		BIGNUM * res = BN_new (); // not from ctx
 | 
			
		||||
		BN_mod_mul(res, x2, z2, q, ctx);
 | 
			
		||||
		BN_CTX_end (ctx);
 | 
			
		||||
		return res;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void Ed25519::ScalarMul (const uint8_t * p, const  uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
 | 
			
		||||
	void Ed25519::ScalarMul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
 | 
			
		||||
	{
 | 
			
		||||
		BIGNUM * p1 = DecodeBN<32> (p);
 | 
			
		||||
		uint8_t k[32];
 | 
			
		||||
| 
						 | 
				
			
			@ -524,7 +524,7 @@ namespace crypto
 | 
			
		|||
		BN_free (p1); BN_free (n); BN_free (q1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void Ed25519::ScalarMulB (const  uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
 | 
			
		||||
	void Ed25519::ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const
 | 
			
		||||
	{
 | 
			
		||||
		BIGNUM *p1 = BN_new (); BN_set_word (p1, 9);
 | 
			
		||||
		uint8_t k[32];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -85,8 +85,8 @@ namespace crypto
 | 
			
		|||
			EDDSAPoint DecodePublicKey (const uint8_t * buf, BN_CTX * ctx) const;
 | 
			
		||||
			void EncodePublicKey (const EDDSAPoint& publicKey, uint8_t * buf, BN_CTX * ctx) const;
 | 
			
		||||
#if !OPENSSL_X25519
 | 
			
		||||
			void ScalarMul (const uint8_t * p, const  uint8_t * e, uint8_t * buf, BN_CTX * ctx) const; // p is point, e is number for x25519
 | 
			
		||||
			void ScalarMulB (const  uint8_t * e, uint8_t * buf, BN_CTX * ctx) const;
 | 
			
		||||
			void ScalarMul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const; // p is point, e is number for x25519
 | 
			
		||||
			void ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const;
 | 
			
		||||
#endif
 | 
			
		||||
			void BlindPublicKey (const uint8_t * pub, const uint8_t * seed, uint8_t * blinded); // for encrypted LeaseSet2, pub - 32, seed - 64, blinded - 32
 | 
			
		||||
			void BlindPrivateKey (const uint8_t * priv, const uint8_t * seed, uint8_t * blindedPriv, uint8_t * blindedPub); // for encrypted LeaseSet2, pub - 32, seed - 64, blinded - 32
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -189,7 +189,7 @@ namespace crypto
 | 
			
		|||
		// assume a < p, so don't check for a % p = 0, but a = 0 only
 | 
			
		||||
		if (BN_is_zero(a)) return 0;
 | 
			
		||||
		BIGNUM * r = BN_CTX_get (ctx);
 | 
			
		||||
		BN_mod_exp (r, a, p12, p, ctx); // 	r = a^((p-1)/2) mod p
 | 
			
		||||
		BN_mod_exp (r, a, p12, p, ctx); // r = a^((p-1)/2) mod p
 | 
			
		||||
		if (BN_is_word(r, 1))
 | 
			
		||||
			return 1;
 | 
			
		||||
		else if (BN_is_zero(r))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										12
									
								
								libi2pd/FS.h
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								libi2pd/FS.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -83,8 +83,8 @@ namespace fs {
 | 
			
		|||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief Set datadir either from cmdline option or using autodetection
 | 
			
		||||
	 * @param cmdline_param  Value of cmdline parameter --datadir=<something>
 | 
			
		||||
	 * @param isService      Value of cmdline parameter --service
 | 
			
		||||
	 * @param cmdline_param Value of cmdline parameter --datadir=<something>
 | 
			
		||||
	 * @param isService Value of cmdline parameter --service
 | 
			
		||||
	 *
 | 
			
		||||
	 * Examples of autodetected paths:
 | 
			
		||||
	 *
 | 
			
		||||
| 
						 | 
				
			
			@ -93,11 +93,11 @@ namespace fs {
 | 
			
		|||
	 *   Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/
 | 
			
		||||
	 *   Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/i2pd/
 | 
			
		||||
	 */
 | 
			
		||||
	 void DetectDataDir(const std::string & cmdline_datadir, bool isService = false);
 | 
			
		||||
	void DetectDataDir(const std::string & cmdline_datadir, bool isService = false);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief Set certsdir either from cmdline option or using autodetection
 | 
			
		||||
	 * @param cmdline_param  Value of cmdline parameter --certsdir=<something>
 | 
			
		||||
	 * @param cmdline_param Value of cmdline parameter --certsdir=<something>
 | 
			
		||||
	 *
 | 
			
		||||
	 * Examples of autodetected paths:
 | 
			
		||||
	 *
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +106,7 @@ namespace fs {
 | 
			
		|||
	 *   Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/certificates
 | 
			
		||||
	 *   Unix: /var/lib/i2pd/certificates (system=1) >> ~/.i2pd/ or /tmp/i2pd/certificates
 | 
			
		||||
	 */
 | 
			
		||||
	 void SetCertsDir(const std::string & cmdline_certsdir);
 | 
			
		||||
	void SetCertsDir(const std::string & cmdline_certsdir);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief Create subdirectories inside datadir
 | 
			
		||||
| 
						 | 
				
			
			@ -115,7 +115,7 @@ namespace fs {
 | 
			
		|||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief Get list of files in directory
 | 
			
		||||
	 * @param path  Path to directory
 | 
			
		||||
	 * @param path Path to directory
 | 
			
		||||
	 * @param files Vector to store found files
 | 
			
		||||
	 * @return true on success and false if directory not exists
 | 
			
		||||
	 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -148,8 +148,8 @@ namespace data
 | 
			
		|||
		if (it != m_SigningKeys.end ())
 | 
			
		||||
			return it->second.second;
 | 
			
		||||
		return 0;
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	std::string CreateFamilySignature (const std::string& family, const IdentHash& ident)
 | 
			
		||||
	{
 | 
			
		||||
		auto filename = i2p::fs::DataDirPath("family", (family + ".key"));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -293,14 +293,14 @@ namespace garlic
 | 
			
		|||
		size_t size = 0;
 | 
			
		||||
		if (isDestination)
 | 
			
		||||
		{
 | 
			
		||||
			buf[size] = eGarlicDeliveryTypeDestination << 5;//  delivery instructions flag destination
 | 
			
		||||
			buf[size] = eGarlicDeliveryTypeDestination << 5;// delivery instructions flag destination
 | 
			
		||||
			size++;
 | 
			
		||||
			memcpy (buf + size, m_Destination->GetIdentHash (), 32);
 | 
			
		||||
			size += 32;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			buf[size] = 0;//  delivery instructions flag local
 | 
			
		||||
			buf[size] = 0;// delivery instructions flag local
 | 
			
		||||
			size++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -487,8 +487,8 @@ namespace garlic
 | 
			
		|||
	void GarlicDestination::SubmitECIESx25519Key (const uint8_t * key, uint64_t tag)
 | 
			
		||||
	{
 | 
			
		||||
		AddECIESx25519Key (key, tag);
 | 
			
		||||
	}	
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void GarlicDestination::HandleGarlicMessage (std::shared_ptr<I2NPMessage> msg)
 | 
			
		||||
	{
 | 
			
		||||
		uint8_t * buf = msg->GetPayload ();
 | 
			
		||||
| 
						 | 
				
			
			@ -744,7 +744,7 @@ namespace garlic
 | 
			
		|||
				LogPrint (eLogError, "Garlic: Message is too short");
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			buf += GetI2NPMessageLength (buf, len - offset); //  I2NP
 | 
			
		||||
			buf += GetI2NPMessageLength (buf, len - offset); // I2NP
 | 
			
		||||
			buf += 4; // CloveID
 | 
			
		||||
			buf += 8; // Date
 | 
			
		||||
			buf += 3; // Certificate
 | 
			
		||||
| 
						 | 
				
			
			@ -1024,7 +1024,7 @@ namespace garlic
 | 
			
		|||
		uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
 | 
			
		||||
		for (auto it: files)
 | 
			
		||||
			if (ts >= i2p::fs::GetLastUpdateTime (it) + INCOMING_TAGS_EXPIRATION_TIMEOUT)
 | 
			
		||||
				 i2p::fs::Remove (it);
 | 
			
		||||
				i2p::fs::Remove (it);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,7 +96,7 @@ namespace crypto
 | 
			
		|||
		EC_POINT * C = EC_POINT_new (m_Group);
 | 
			
		||||
		EC_POINT_mul (m_Group, C, z1, pub, z2, ctx); // z1*P + z2*pub
 | 
			
		||||
		BIGNUM * x = BN_CTX_get (ctx);
 | 
			
		||||
		GetXY  (C, x, nullptr); // Cx
 | 
			
		||||
		GetXY (C, x, nullptr); // Cx
 | 
			
		||||
		BN_mod (x, x, q, ctx); // Cx % q
 | 
			
		||||
		bool ret = !BN_cmp (x, r); // Cx = r ?
 | 
			
		||||
		EC_POINT_free (C);
 | 
			
		||||
| 
						 | 
				
			
			@ -111,8 +111,8 @@ namespace crypto
 | 
			
		|||
		BN_CTX * ctx = BN_CTX_new ();
 | 
			
		||||
		BN_CTX_start (ctx);
 | 
			
		||||
		EC_POINT * C = EC_POINT_new (m_Group); // C = k*P = (rx, ry)
 | 
			
		||||
		EC_POINT * Q  = nullptr;
 | 
			
		||||
		if (EC_POINT_set_compressed_coordinates_GFp (m_Group, C, r, isNegativeY ? 1 : 0,  ctx))
 | 
			
		||||
		EC_POINT * Q = nullptr;
 | 
			
		||||
		if (EC_POINT_set_compressed_coordinates_GFp (m_Group, C, r, isNegativeY ? 1 : 0, ctx))
 | 
			
		||||
		{
 | 
			
		||||
			EC_POINT * S = EC_POINT_new (m_Group); // S = s*P
 | 
			
		||||
			EC_POINT_mul (m_Group, S, s, nullptr, nullptr, ctx);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -279,7 +279,7 @@ namespace http
 | 
			
		|||
				method  = tokens[0];
 | 
			
		||||
				uri     = tokens[1];
 | 
			
		||||
				version = tokens[2];
 | 
			
		||||
				expect = HEADER_LINE;
 | 
			
		||||
				expect  = HEADER_LINE;
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -363,7 +363,7 @@ namespace http
 | 
			
		|||
			return false; /* no header */
 | 
			
		||||
		if (it->second.find("gzip") != std::string::npos)
 | 
			
		||||
			return true; /* gotcha! */
 | 
			
		||||
		if (includingI2PGzip &&  it->second.find("x-i2p-gzip") != std::string::npos)
 | 
			
		||||
		if (includingI2PGzip && it->second.find("x-i2p-gzip") != std::string::npos)
 | 
			
		||||
			return true;
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -409,7 +409,7 @@ namespace http
 | 
			
		|||
				/* all ok */
 | 
			
		||||
				version = tokens[0];
 | 
			
		||||
				status  = tokens[2];
 | 
			
		||||
				expect = HEADER_LINE;
 | 
			
		||||
				expect  = HEADER_LINE;
 | 
			
		||||
			} else {
 | 
			
		||||
				std::string line = str.substr(pos, eol - pos);
 | 
			
		||||
				auto p = parse_header_line(line);
 | 
			
		||||
| 
						 | 
				
			
			@ -460,7 +460,7 @@ namespace http
 | 
			
		|||
			case 304: ptr = "Not Modified"; break;
 | 
			
		||||
			case 307: ptr = "Temporary Redirect"; break;
 | 
			
		||||
			/* client error */
 | 
			
		||||
			case 400: ptr = "Bad Request";  break;
 | 
			
		||||
			case 400: ptr = "Bad Request"; break;
 | 
			
		||||
			case 401: ptr = "Unauthorized"; break;
 | 
			
		||||
			case 403: ptr = "Forbidden"; break;
 | 
			
		||||
			case 404: ptr = "Not Found"; break;
 | 
			
		||||
| 
						 | 
				
			
			@ -471,7 +471,7 @@ namespace http
 | 
			
		|||
			case 502: ptr = "Bad Gateway"; break;
 | 
			
		||||
			case 503: ptr = "Not Implemented"; break;
 | 
			
		||||
			case 504: ptr = "Gateway Timeout"; break;
 | 
			
		||||
			default:  ptr = "Unknown Status";  break;
 | 
			
		||||
			default:  ptr = "Unknown Status"; break;
 | 
			
		||||
		}
 | 
			
		||||
		return ptr;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -161,7 +161,7 @@ namespace http
 | 
			
		|||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief Merge HTTP response content with Transfer-Encoding: chunked
 | 
			
		||||
	 * @param in  Input stream
 | 
			
		||||
	 * @param in Input stream
 | 
			
		||||
	 * @param out Output stream
 | 
			
		||||
	 * @return true on success, false otherwise
 | 
			
		||||
	 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -171,7 +171,7 @@ namespace i2p
 | 
			
		|||
	std::shared_ptr<I2NPMessage> CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest,
 | 
			
		||||
		const std::set<i2p::data::IdentHash>& excludedFloodfills,
 | 
			
		||||
		std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel, const uint8_t * replyKey,
 | 
			
		||||
		    const uint8_t * replyTag, bool replyECIES)
 | 
			
		||||
			const uint8_t * replyTag, bool replyECIES)
 | 
			
		||||
	{
 | 
			
		||||
		int cnt = excludedFloodfills.size ();
 | 
			
		||||
		auto m = cnt > 7 ? NewI2NPMessage () : NewI2NPShortMessage ();
 | 
			
		||||
| 
						 | 
				
			
			@ -244,7 +244,7 @@ namespace i2p
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router,
 | 
			
		||||
	    uint32_t replyToken, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel)
 | 
			
		||||
		uint32_t replyToken, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel)
 | 
			
		||||
	{
 | 
			
		||||
		if (!router) // we send own RouterInfo
 | 
			
		||||
			router = context.GetSharedRouterInfo ();
 | 
			
		||||
| 
						 | 
				
			
			@ -629,7 +629,7 @@ namespace i2p
 | 
			
		|||
						// we send it to reply tunnel
 | 
			
		||||
						transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET,
 | 
			
		||||
						CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET),
 | 
			
		||||
							i2p::garlic::WrapECIESX25519Message (replyMsg,  noiseState.m_CK + 32, tag)));
 | 
			
		||||
							i2p::garlic::WrapECIESX25519Message (replyMsg, noiseState.m_CK + 32, tag)));
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -150,7 +150,7 @@ namespace tunnel
 | 
			
		|||
		std::shared_ptr<i2p::tunnel::InboundTunnel> from;
 | 
			
		||||
 | 
			
		||||
		I2NPMessage (): buf (nullptr),len (I2NP_HEADER_SIZE + 2),
 | 
			
		||||
			offset(2), maxLen (0), from (nullptr) {};  // reserve 2 bytes for NTCP header
 | 
			
		||||
			offset(2), maxLen (0), from (nullptr) {}; // reserve 2 bytes for NTCP header
 | 
			
		||||
 | 
			
		||||
		// header accessors
 | 
			
		||||
		uint8_t * GetHeader () { return GetBuffer (); };
 | 
			
		||||
| 
						 | 
				
			
			@ -274,8 +274,8 @@ namespace tunnel
 | 
			
		|||
		uint32_t replyTunnelID, bool exploratory = false, std::set<i2p::data::IdentHash> * excludedPeers = nullptr);
 | 
			
		||||
	std::shared_ptr<I2NPMessage> CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest,
 | 
			
		||||
		const std::set<i2p::data::IdentHash>& excludedFloodfills,
 | 
			
		||||
	    std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel,
 | 
			
		||||
	    const uint8_t * replyKey, const uint8_t * replyTag, bool replyECIES = false);
 | 
			
		||||
		std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel,
 | 
			
		||||
		const uint8_t * replyKey, const uint8_t * replyTag, bool replyECIES = false);
 | 
			
		||||
	std::shared_ptr<I2NPMessage> CreateDatabaseSearchReply (const i2p::data::IdentHash& ident, std::vector<i2p::data::IdentHash> routers);
 | 
			
		||||
 | 
			
		||||
	std::shared_ptr<I2NPMessage> CreateDatabaseStoreMsg (std::shared_ptr<const i2p::data::RouterInfo> router = nullptr, uint32_t replyToken = 0, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel = nullptr);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,7 +64,7 @@ namespace data
 | 
			
		|||
			{
 | 
			
		||||
				case SIGNING_KEY_TYPE_ECDSA_SHA256_P256:
 | 
			
		||||
				{
 | 
			
		||||
					size_t padding =  128 - i2p::crypto::ECDSAP256_KEY_LENGTH; // 64 = 128 - 64
 | 
			
		||||
					size_t padding = 128 - i2p::crypto::ECDSAP256_KEY_LENGTH; // 64 = 128 - 64
 | 
			
		||||
					RAND_bytes (m_StandardIdentity.signingKey, padding);
 | 
			
		||||
					memcpy (m_StandardIdentity.signingKey + padding, signingKey, i2p::crypto::ECDSAP256_KEY_LENGTH);
 | 
			
		||||
					break;
 | 
			
		||||
| 
						 | 
				
			
			@ -788,7 +788,7 @@ namespace data
 | 
			
		|||
			keys.m_OfflineSignature.resize (pubKeyLen + m_Public->GetSignatureLen () + 6);
 | 
			
		||||
			htobe32buf (keys.m_OfflineSignature.data (), expires); // expires
 | 
			
		||||
			htobe16buf (keys.m_OfflineSignature.data () + 4, type); // type
 | 
			
		||||
			GenerateSigningKeyPair (type, keys.m_SigningPrivateKey, keys.m_OfflineSignature.data () + 6); // public  key
 | 
			
		||||
			GenerateSigningKeyPair (type, keys.m_SigningPrivateKey, keys.m_OfflineSignature.data () + 6); // public key
 | 
			
		||||
			Sign (keys.m_OfflineSignature.data (), pubKeyLen + 6, keys.m_OfflineSignature.data () + 6 + pubKeyLen); // signature
 | 
			
		||||
			// recreate signer
 | 
			
		||||
			keys.m_Signer = nullptr;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -120,7 +120,7 @@ namespace data
 | 
			
		|||
			CryptoKeyType GetCryptoKeyType () const;
 | 
			
		||||
			void DropVerifier () const; // to save memory
 | 
			
		||||
 | 
			
		||||
  			bool operator == (const IdentityEx & other) const { return GetIdentHash() == other.GetIdentHash(); }
 | 
			
		||||
			bool operator == (const IdentityEx & other) const { return GetIdentHash() == other.GetIdentHash(); }
 | 
			
		||||
			void RecalculateIdentHash(uint8_t * buff=nullptr);
 | 
			
		||||
 | 
			
		||||
			static i2p::crypto::Verifier * CreateVerifier (SigningKeyType keyType);
 | 
			
		||||
| 
						 | 
				
			
			@ -222,7 +222,7 @@ namespace data
 | 
			
		|||
			RoutingDestination () {};
 | 
			
		||||
			virtual ~RoutingDestination () {};
 | 
			
		||||
 | 
			
		||||
			virtual std::shared_ptr<const IdentityEx> GetIdentity ()  const = 0;
 | 
			
		||||
			virtual std::shared_ptr<const IdentityEx> GetIdentity () const = 0;
 | 
			
		||||
			virtual void Encrypt (const uint8_t * data, uint8_t * encrypted) const = 0; // encrypt data for
 | 
			
		||||
			virtual bool IsDestination () const = 0; // for garlic
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -582,7 +582,7 @@ namespace data
 | 
			
		|||
	// helper for ExtractClientAuthData
 | 
			
		||||
	static inline bool GetAuthCookie (const uint8_t * authClients, int numClients, const uint8_t * okm, uint8_t * authCookie)
 | 
			
		||||
	{
 | 
			
		||||
		// try to find clientCookie_i  for clientID_i = okm[44:51]
 | 
			
		||||
		// try to find clientCookie_i for clientID_i = okm[44:51]
 | 
			
		||||
		for (int i = 0; i < numClients; i++)
 | 
			
		||||
		{
 | 
			
		||||
			if (!memcmp (okm + 44, authClients + i*40, 8)) // clientID_i
 | 
			
		||||
| 
						 | 
				
			
			@ -606,7 +606,7 @@ namespace data
 | 
			
		|||
			{
 | 
			
		||||
				const uint8_t * ephemeralPublicKey = buf + offset; offset += 32; // ephemeralPublicKey
 | 
			
		||||
				uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients
 | 
			
		||||
				const uint8_t * authClients = buf + offset; offset +=  numClients*40; // authClients
 | 
			
		||||
				const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients
 | 
			
		||||
				if (offset > len)
 | 
			
		||||
				{
 | 
			
		||||
					LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in DH auth data");
 | 
			
		||||
| 
						 | 
				
			
			@ -632,7 +632,7 @@ namespace data
 | 
			
		|||
			{
 | 
			
		||||
				const uint8_t * authSalt = buf + offset; offset += 32; // authSalt
 | 
			
		||||
				uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients
 | 
			
		||||
				const uint8_t * authClients = buf + offset; offset +=  numClients*40; // authClients
 | 
			
		||||
				const uint8_t * authClients = buf + offset; offset += numClients*40; // authClients
 | 
			
		||||
				if (offset > len)
 | 
			
		||||
				{
 | 
			
		||||
					LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in PSK auth data");
 | 
			
		||||
| 
						 | 
				
			
			@ -737,7 +737,7 @@ namespace data
 | 
			
		|||
			htobe64buf (m_Buffer + offset, ts);
 | 
			
		||||
			offset += 8; // end date
 | 
			
		||||
		}
 | 
			
		||||
		//  we don't sign it yet. must be signed later on
 | 
			
		||||
		// we don't sign it yet. must be signed later on
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	LocalLeaseSet::LocalLeaseSet (std::shared_ptr<const IdentityEx> identity, const uint8_t * buf, size_t len):
 | 
			
		||||
| 
						 | 
				
			
			@ -995,7 +995,7 @@ namespace data
 | 
			
		|||
			ek.GenerateKeys (); // esk and epk
 | 
			
		||||
			memcpy (authData, ek.GetPublicKey (), 32); authData += 32; // epk
 | 
			
		||||
			htobe16buf (authData, authKeys->size ()); authData += 2; // num clients
 | 
			
		||||
			uint8_t authInput[100]; //  sharedSecret || cpk_i || subcredential || publishedTimestamp
 | 
			
		||||
			uint8_t authInput[100]; // sharedSecret || cpk_i || subcredential || publishedTimestamp
 | 
			
		||||
			memcpy (authInput + 64, subcredential, 36);
 | 
			
		||||
			for (auto& it: *authKeys)
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -128,8 +128,8 @@ namespace data
 | 
			
		|||
	};
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
			validate lease set buffer signature and extract expiration timestamp
 | 
			
		||||
			@returns true if the leaseset is well formed and signature is valid
 | 
			
		||||
	 * validate lease set buffer signature and extract expiration timestamp
 | 
			
		||||
	 * @returns true if the leaseset is well formed and signature is valid
 | 
			
		||||
	 */
 | 
			
		||||
	bool LeaseSetBufferValidate(const uint8_t * ptr, size_t sz, uint64_t & expires);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ namespace log {
 | 
			
		|||
 | 
			
		||||
#ifndef _WIN32
 | 
			
		||||
	/**
 | 
			
		||||
	 * @brief  Maps our log levels to syslog one
 | 
			
		||||
	 * @brief Maps our log levels to syslog one
 | 
			
		||||
	 * @return syslog priority LOG_*, as defined in syslog.h
 | 
			
		||||
	 */
 | 
			
		||||
	static inline int GetSyslogPrio (enum LogLevel l) {
 | 
			
		||||
| 
						 | 
				
			
			@ -113,11 +113,11 @@ namespace log {
 | 
			
		|||
 | 
			
		||||
	std::string str_tolower(std::string s) {
 | 
			
		||||
		std::transform(s.begin(), s.end(), s.begin(),
 | 
			
		||||
					// static_cast<int(*)(int)>(std::tolower)         // wrong
 | 
			
		||||
					// [](int c){ return std::tolower(c); }           // wrong
 | 
			
		||||
					// [](char c){ return std::tolower(c); }          // wrong
 | 
			
		||||
					   [](unsigned char c){ return std::tolower(c); } // correct
 | 
			
		||||
					);
 | 
			
		||||
			// static_cast<int(*)(int)>(std::tolower)      // wrong
 | 
			
		||||
			// [](int c){ return std::tolower(c); }        // wrong
 | 
			
		||||
			// [](char c){ return std::tolower(c); }       // wrong
 | 
			
		||||
			[](unsigned char c){ return std::tolower(c); } // correct
 | 
			
		||||
		);
 | 
			
		||||
		return s;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -170,7 +170,7 @@ namespace log {
 | 
			
		|||
				break;
 | 
			
		||||
			case eLogStdout:
 | 
			
		||||
			default:
 | 
			
		||||
				std::cout    << TimeAsString(msg->timestamp)
 | 
			
		||||
				std::cout << TimeAsString(msg->timestamp)
 | 
			
		||||
					<< "@" << short_tid
 | 
			
		||||
					<< "/" << LogMsgColors[msg->level] << g_LogLevelStr[msg->level] << LogMsgColors[eNumLogLevels]
 | 
			
		||||
					<< " - " << msg->text << std::endl;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,7 +52,7 @@ namespace log {
 | 
			
		|||
	{
 | 
			
		||||
		private:
 | 
			
		||||
 | 
			
		||||
			enum LogType  m_Destination;
 | 
			
		||||
			enum LogType m_Destination;
 | 
			
		||||
			enum LogLevel m_MinLevel;
 | 
			
		||||
			std::shared_ptr<std::ostream> m_LogStream;
 | 
			
		||||
			std::string m_Logfile;
 | 
			
		||||
| 
						 | 
				
			
			@ -75,7 +75,7 @@ namespace log {
 | 
			
		|||
 | 
			
		||||
			/**
 | 
			
		||||
			 * @brief Makes formatted string from unix timestamp
 | 
			
		||||
			 * @param ts  Second since epoch
 | 
			
		||||
			 * @param ts Second since epoch
 | 
			
		||||
			 *
 | 
			
		||||
			 * This function internally caches the result for last provided value
 | 
			
		||||
			 */
 | 
			
		||||
| 
						 | 
				
			
			@ -86,52 +86,52 @@ namespace log {
 | 
			
		|||
			Log ();
 | 
			
		||||
			~Log ();
 | 
			
		||||
 | 
			
		||||
			LogType  GetLogType  () { return m_Destination; };
 | 
			
		||||
			LogType GetLogType () { return m_Destination; };
 | 
			
		||||
			LogLevel GetLogLevel () { return m_MinLevel; };
 | 
			
		||||
 | 
			
		||||
			void Start ();
 | 
			
		||||
			void Stop ();
 | 
			
		||||
 | 
			
		||||
			/**
 | 
			
		||||
			 * @brief  Sets minimal allowed level for log messages
 | 
			
		||||
			 * @param  level  String with wanted minimal msg level
 | 
			
		||||
			 * @brief Sets minimal allowed level for log messages
 | 
			
		||||
			 * @param level String with wanted minimal msg level
 | 
			
		||||
			 */
 | 
			
		||||
			void     SetLogLevel (const std::string& level);
 | 
			
		||||
			void SetLogLevel (const std::string& level);
 | 
			
		||||
 | 
			
		||||
			/**
 | 
			
		||||
			 * @brief Sets log destination to logfile
 | 
			
		||||
			 * @param path  Path to logfile
 | 
			
		||||
			 * @param path Path to logfile
 | 
			
		||||
			 */
 | 
			
		||||
			void SendTo (const std::string &path);
 | 
			
		||||
 | 
			
		||||
			/**
 | 
			
		||||
			 * @brief Sets log destination to given output stream
 | 
			
		||||
			 * @param os  Output stream
 | 
			
		||||
			 * @param os Output stream
 | 
			
		||||
			 */
 | 
			
		||||
			void SendTo (std::shared_ptr<std::ostream> os);
 | 
			
		||||
 | 
			
		||||
			/**
 | 
			
		||||
			 * @brief  Sets format for timestamps in log
 | 
			
		||||
			 * @param  format  String with timestamp format
 | 
			
		||||
			 * @brief Sets format for timestamps in log
 | 
			
		||||
			 * @param format String with timestamp format
 | 
			
		||||
			 */
 | 
			
		||||
			void SetTimeFormat (std::string format) { m_TimeFormat = format; };
 | 
			
		||||
 | 
			
		||||
	#ifndef _WIN32
 | 
			
		||||
			/**
 | 
			
		||||
			 * @brief Sets log destination to syslog
 | 
			
		||||
			 * @param name     Wanted program name
 | 
			
		||||
			 * @param name Wanted program name
 | 
			
		||||
			 * @param facility Wanted log category
 | 
			
		||||
			 */
 | 
			
		||||
			void SendTo (const char *name, int facility);
 | 
			
		||||
	#endif
 | 
			
		||||
 | 
			
		||||
			/**
 | 
			
		||||
			 * @brief  Format log message and write to output stream/syslog
 | 
			
		||||
			 * @param  msg  Pointer to processed message
 | 
			
		||||
			 * @brief Format log message and write to output stream/syslog
 | 
			
		||||
			 * @param msg Pointer to processed message
 | 
			
		||||
			 */
 | 
			
		||||
			void Append(std::shared_ptr<i2p::log::LogMsg> &);
 | 
			
		||||
 | 
			
		||||
			/** @brief  Reopen log file */
 | 
			
		||||
			/** @brief Reopen log file */
 | 
			
		||||
			void Reopen();
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -144,8 +144,8 @@ namespace log {
 | 
			
		|||
	 */
 | 
			
		||||
	struct LogMsg {
 | 
			
		||||
		std::time_t timestamp;
 | 
			
		||||
		std::string text; /**< message text as single string */
 | 
			
		||||
		LogLevel level;   /**< message level */
 | 
			
		||||
		std::string text;    /**< message text as single string */
 | 
			
		||||
		LogLevel level;      /**< message level */
 | 
			
		||||
		std::thread::id tid; /**< id of thread that generated message */
 | 
			
		||||
 | 
			
		||||
		LogMsg (LogLevel lvl, std::time_t ts, std::string&& txt): timestamp(ts), text(std::move(txt)), level(lvl) {}
 | 
			
		||||
| 
						 | 
				
			
			@ -153,7 +153,7 @@ namespace log {
 | 
			
		|||
 | 
			
		||||
	Log & Logger();
 | 
			
		||||
 | 
			
		||||
	typedef std::function<void (const std::string&)>  ThrowFunction;
 | 
			
		||||
	typedef std::function<void (const std::string&)> ThrowFunction;
 | 
			
		||||
	ThrowFunction GetThrowFunction ();
 | 
			
		||||
	void SetThrowFunction (ThrowFunction f);
 | 
			
		||||
} // log
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,7 +66,7 @@ namespace transport
 | 
			
		|||
	{
 | 
			
		||||
		MixHash (sessionRequest + 32, 32); // encrypted payload
 | 
			
		||||
 | 
			
		||||
		int paddingLength =  sessionRequestLen - 64;
 | 
			
		||||
		int paddingLength = sessionRequestLen - 64;
 | 
			
		||||
		if (paddingLength > 0)
 | 
			
		||||
			MixHash (sessionRequest + 64, paddingLength);
 | 
			
		||||
		MixHash (epub, 32);
 | 
			
		||||
| 
						 | 
				
			
			@ -130,7 +130,7 @@ namespace transport
 | 
			
		|||
		// m3p2Len
 | 
			
		||||
		auto bufLen = i2p::context.GetRouterInfo ().GetBufferLen ();
 | 
			
		||||
		m3p2Len = bufLen + 4 + 16; // (RI header + RI + MAC for now) TODO: implement options
 | 
			
		||||
		htobe16buf (options + 4,  m3p2Len);
 | 
			
		||||
		htobe16buf (options + 4, m3p2Len);
 | 
			
		||||
		// fill m3p2 payload (RouterInfo block)
 | 
			
		||||
		m_SessionConfirmedBuffer = new uint8_t[m3p2Len + 48]; // m3p1 is 48 bytes
 | 
			
		||||
		uint8_t * m3p2 = m_SessionConfirmedBuffer + 48;
 | 
			
		||||
| 
						 | 
				
			
			@ -231,11 +231,11 @@ namespace transport
 | 
			
		|||
				auto ts = i2p::util::GetSecondsSinceEpoch ();
 | 
			
		||||
				uint32_t tsA = bufbe32toh (options + 8);
 | 
			
		||||
				if (tsA < ts - NTCP2_CLOCK_SKEW || tsA > ts + NTCP2_CLOCK_SKEW)
 | 
			
		||||
				{	
 | 
			
		||||
				{
 | 
			
		||||
					LogPrint (eLogWarning, "NTCP2: SessionRequest time difference ", (int)(ts - tsA), " exceeds clock skew");
 | 
			
		||||
					clockSkew = true;
 | 
			
		||||
					// we send SessionCreate to let Alice know our time and then close session
 | 
			
		||||
				}	
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -320,7 +320,7 @@ namespace transport
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	NTCP2Session::NTCP2Session (NTCP2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter,
 | 
			
		||||
	    	std::shared_ptr<const i2p::data::RouterInfo::Address> addr):
 | 
			
		||||
		std::shared_ptr<const i2p::data::RouterInfo::Address> addr):
 | 
			
		||||
		TransportSession (in_RemoteRouter, NTCP2_ESTABLISH_TIMEOUT),
 | 
			
		||||
		m_Server (server), m_Socket (m_Server.GetService ()),
 | 
			
		||||
		m_IsEstablished (false), m_IsTerminated (false),
 | 
			
		||||
| 
						 | 
				
			
			@ -418,7 +418,7 @@ namespace transport
 | 
			
		|||
	void NTCP2Session::DeleteNextReceiveBuffer (uint64_t ts)
 | 
			
		||||
	{
 | 
			
		||||
		if (m_NextReceivedBuffer && !m_IsReceiving &&
 | 
			
		||||
		    ts > m_LastActivityTimestamp + NTCP2_RECEIVE_BUFFER_DELETION_TIMEOUT)
 | 
			
		||||
			ts > m_LastActivityTimestamp + NTCP2_RECEIVE_BUFFER_DELETION_TIMEOUT)
 | 
			
		||||
		{
 | 
			
		||||
			delete[] m_NextReceivedBuffer;
 | 
			
		||||
			m_NextReceivedBuffer = nullptr;
 | 
			
		||||
| 
						 | 
				
			
			@ -484,9 +484,9 @@ namespace transport
 | 
			
		|||
				if (clockSkew)
 | 
			
		||||
				{
 | 
			
		||||
					// we don't care about padding, send SessionCreated and close session
 | 
			
		||||
					SendSessionCreated (); 
 | 
			
		||||
					SendSessionCreated ();
 | 
			
		||||
					m_Server.GetService ().post (std::bind (&NTCP2Session::Terminate, shared_from_this ()));
 | 
			
		||||
				}	
 | 
			
		||||
				}
 | 
			
		||||
				else if (paddingLen > 0)
 | 
			
		||||
				{
 | 
			
		||||
					if (paddingLen <= NTCP2_SESSION_REQUEST_MAX_SIZE - 64) // session request is 287 bytes max
 | 
			
		||||
| 
						 | 
				
			
			@ -496,7 +496,7 @@ namespace transport
 | 
			
		|||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						LogPrint (eLogWarning, "NTCP2: SessionRequest padding length ", (int)paddingLen,  " is too long");
 | 
			
		||||
						LogPrint (eLogWarning, "NTCP2: SessionRequest padding length ", (int)paddingLen, " is too long");
 | 
			
		||||
						Terminate ();
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -549,7 +549,7 @@ namespace transport
 | 
			
		|||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						LogPrint (eLogWarning, "NTCP2: SessionCreated padding length ", (int)paddingLen,  " is too long");
 | 
			
		||||
						LogPrint (eLogWarning, "NTCP2: SessionCreated padding length ", (int)paddingLen, " is too long");
 | 
			
		||||
						Terminate ();
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -1126,11 +1126,11 @@ namespace transport
 | 
			
		|||
	{
 | 
			
		||||
		if (!m_SendKey ||
 | 
			
		||||
#if OPENSSL_SIPHASH
 | 
			
		||||
		    !m_SendMDCtx
 | 
			
		||||
			!m_SendMDCtx
 | 
			
		||||
#else
 | 
			
		||||
		    !m_SendSipKey
 | 
			
		||||
			!m_SendSipKey
 | 
			
		||||
#endif
 | 
			
		||||
		    ) return;
 | 
			
		||||
		) return;
 | 
			
		||||
		m_NextSendBuffer = new uint8_t[49]; // 49 = 12 bytes message + 16 bytes MAC + 2 bytes size + up to 19 padding block
 | 
			
		||||
		// termination block
 | 
			
		||||
		m_NextSendBuffer[2] = eNTCP2BlkTermination;
 | 
			
		||||
| 
						 | 
				
			
			@ -1164,7 +1164,7 @@ namespace transport
 | 
			
		|||
		else if (m_SendQueue.size () > NTCP2_MAX_OUTGOING_QUEUE_SIZE)
 | 
			
		||||
		{
 | 
			
		||||
			LogPrint (eLogWarning, "NTCP2: Outgoing messages queue size to ",
 | 
			
		||||
			   	GetIdentHashBase64(), " exceeds ",  NTCP2_MAX_OUTGOING_QUEUE_SIZE);
 | 
			
		||||
				GetIdentHashBase64(), " exceeds ", NTCP2_MAX_OUTGOING_QUEUE_SIZE);
 | 
			
		||||
			Terminate ();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -1177,7 +1177,7 @@ namespace transport
 | 
			
		|||
 | 
			
		||||
	NTCP2Server::NTCP2Server ():
 | 
			
		||||
		RunnableServiceWithWork ("NTCP2"), m_TerminationTimer (GetService ()),
 | 
			
		||||
		 m_ProxyType(eNoProxy), m_Resolver(GetService ())
 | 
			
		||||
			m_ProxyType(eNoProxy), m_Resolver(GetService ())
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -489,7 +489,7 @@ namespace data
 | 
			
		|||
	{
 | 
			
		||||
		auto r = std::make_shared<RouterInfo>(path);
 | 
			
		||||
		if (r->GetRouterIdentity () && !r->IsUnreachable () && r->HasValidAddresses () &&
 | 
			
		||||
		    ts < r->GetTimestamp () + 24*60*60*NETDB_MAX_OFFLINE_EXPIRATION_TIMEOUT*1000LL)
 | 
			
		||||
			ts < r->GetTimestamp () + 24*60*60*NETDB_MAX_OFFLINE_EXPIRATION_TIMEOUT*1000LL)
 | 
			
		||||
		{
 | 
			
		||||
			r->DeleteBuffer ();
 | 
			
		||||
			if (m_RouterInfos.emplace (r->GetIdentHash (), r).second)
 | 
			
		||||
| 
						 | 
				
			
			@ -620,7 +620,7 @@ namespace data
 | 
			
		|||
			}
 | 
			
		||||
			// make router reachable back if too few routers or floodfills
 | 
			
		||||
			if (it.second->IsUnreachable () && (total - deletedCount < NETDB_MIN_ROUTERS ||
 | 
			
		||||
			    (it.second->IsFloodfill () && totalFloodfills - deletedFloodfillsCount < NETDB_MIN_FLOODFILLS)))
 | 
			
		||||
				(it.second->IsFloodfill () && totalFloodfills - deletedFloodfillsCount < NETDB_MIN_FLOODFILLS)))
 | 
			
		||||
				it.second->SetUnreachable (false);
 | 
			
		||||
			// find & mark expired routers
 | 
			
		||||
			if (!it.second->IsReachable () && it.second->IsSSU (false))
 | 
			
		||||
| 
						 | 
				
			
			@ -643,7 +643,7 @@ namespace data
 | 
			
		|||
		} // m_RouterInfos iteration
 | 
			
		||||
 | 
			
		||||
		m_RouterInfoBuffersPool.CleanUpMt ();
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
		if (updatedCount > 0)
 | 
			
		||||
			LogPrint (eLogInfo, "NetDb: Saved ", updatedCount, " new/updated routers");
 | 
			
		||||
		if (deletedCount > 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -672,7 +672,7 @@ namespace data
 | 
			
		|||
					else
 | 
			
		||||
						++it;
 | 
			
		||||
			}
 | 
			
		||||
		}	
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void NetDb::RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete, bool direct)
 | 
			
		||||
| 
						 | 
				
			
			@ -688,7 +688,7 @@ namespace data
 | 
			
		|||
		if (floodfill)
 | 
			
		||||
		{
 | 
			
		||||
			if (direct && !floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) &&
 | 
			
		||||
			    !i2p::transport::transports.IsConnected (floodfill->GetIdentHash ()))
 | 
			
		||||
				!i2p::transport::transports.IsConnected (floodfill->GetIdentHash ()))
 | 
			
		||||
				direct = false; // floodfill can't be reached directly
 | 
			
		||||
			if (direct)
 | 
			
		||||
				transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ()));
 | 
			
		||||
| 
						 | 
				
			
			@ -971,7 +971,7 @@ namespace data
 | 
			
		|||
		else
 | 
			
		||||
		{
 | 
			
		||||
			if (lookupType == DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP ||
 | 
			
		||||
			    lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP)
 | 
			
		||||
				lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP)
 | 
			
		||||
			{
 | 
			
		||||
				auto router = FindRouter (ident);
 | 
			
		||||
				if (router)
 | 
			
		||||
| 
						 | 
				
			
			@ -1136,7 +1136,7 @@ namespace data
 | 
			
		|||
			m_PublishExcluded.insert (floodfill->GetIdentHash ());
 | 
			
		||||
			m_PublishReplyToken = replyToken;
 | 
			
		||||
			if (floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) || // are we able to connect?
 | 
			
		||||
			    i2p::transport::transports.IsConnected (floodfill->GetIdentHash ()))  // already connected ?
 | 
			
		||||
				i2p::transport::transports.IsConnected (floodfill->GetIdentHash ())) // already connected ?
 | 
			
		||||
				// send directly
 | 
			
		||||
				transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken));
 | 
			
		||||
			else
 | 
			
		||||
| 
						 | 
				
			
			@ -1377,7 +1377,7 @@ namespace data
 | 
			
		|||
		return res;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	std::shared_ptr<const RouterInfo> NetDb::GetRandomRouterInFamily (FamilyID fam) const 
 | 
			
		||||
	std::shared_ptr<const RouterInfo> NetDb::GetRandomRouterInFamily (FamilyID fam) const
 | 
			
		||||
	{
 | 
			
		||||
		return GetRandomRouter(
 | 
			
		||||
			[fam](std::shared_ptr<const RouterInfo> router)->bool
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -123,7 +123,7 @@ namespace data
 | 
			
		|||
 | 
			
		||||
			void ClearRouterInfos () { m_RouterInfos.clear (); };
 | 
			
		||||
			std::shared_ptr<RouterInfo::Buffer> NewRouterInfoBuffer () { return m_RouterInfoBuffersPool.AcquireSharedMt (); };
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			uint32_t GetPublishReplyToken () const { return m_PublishReplyToken; };
 | 
			
		||||
 | 
			
		||||
		private:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,7 +60,7 @@ namespace data
 | 
			
		|||
			void Start ();
 | 
			
		||||
			void Stop ();
 | 
			
		||||
 | 
			
		||||
			 std::shared_ptr<RequestedDestination> CreateRequest (const IdentHash& destination, bool isExploratory, RequestedDestination::RequestComplete requestComplete = nullptr);
 | 
			
		||||
			std::shared_ptr<RequestedDestination> CreateRequest (const IdentHash& destination, bool isExploratory, RequestedDestination::RequestComplete requestComplete = nullptr);
 | 
			
		||||
			void RequestComplete (const IdentHash& ident, std::shared_ptr<RouterInfo> r);
 | 
			
		||||
			std::shared_ptr<RequestedDestination> FindRequest (const IdentHash& ident) const;
 | 
			
		||||
			void ManageRequests ();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,12 +1,13 @@
 | 
			
		|||
#include "Poly1305.h"
 | 
			
		||||
/**
 | 
			
		||||
   This code is licensed under the MCGSI Public License
 | 
			
		||||
   Copyright 2018 Jeff Becker
 | 
			
		||||
 | 
			
		||||
   Kovri go write your own code
 | 
			
		||||
 | 
			
		||||
 * This code is licensed under the MCGSI Public License
 | 
			
		||||
 * Copyright 2018 Jeff Becker
 | 
			
		||||
 *
 | 
			
		||||
 *Kovri go write your own code
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "Poly1305.h"
 | 
			
		||||
 | 
			
		||||
#if !OPENSSL_AEAD_CHACHA20_POLY1305
 | 
			
		||||
namespace i2p
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@
 | 
			
		|||
 * Kovri go write your own code
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef LIBI2PD_POLY1305_H
 | 
			
		||||
#define LIBI2PD_POLY1305_H
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,7 +28,7 @@ namespace util
 | 
			
		|||
 | 
			
		||||
			void Put (Element e)
 | 
			
		||||
			{
 | 
			
		||||
				std::unique_lock<std::mutex>  l(m_QueueMutex);
 | 
			
		||||
				std::unique_lock<std::mutex> l(m_QueueMutex);
 | 
			
		||||
				m_Queue.push (std::move(e));
 | 
			
		||||
				m_NonEmpty.notify_one ();
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +38,7 @@ namespace util
 | 
			
		|||
			{
 | 
			
		||||
				if (!vec.empty ())
 | 
			
		||||
				{
 | 
			
		||||
					std::unique_lock<std::mutex>  l(m_QueueMutex);
 | 
			
		||||
					std::unique_lock<std::mutex> l(m_QueueMutex);
 | 
			
		||||
					for (const auto& it: vec)
 | 
			
		||||
						m_Queue.push (std::move(it));
 | 
			
		||||
					m_NonEmpty.notify_one ();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -187,31 +187,31 @@ namespace data
 | 
			
		|||
		}
 | 
			
		||||
		s.seekg (1, std::ios::cur); // su3 file format version
 | 
			
		||||
		SigningKeyType signatureType;
 | 
			
		||||
		s.read ((char *)&signatureType, 2);  // signature type
 | 
			
		||||
		s.read ((char *)&signatureType, 2); // signature type
 | 
			
		||||
		signatureType = be16toh (signatureType);
 | 
			
		||||
		uint16_t signatureLength;
 | 
			
		||||
		s.read ((char *)&signatureLength, 2);  // signature length
 | 
			
		||||
		s.read ((char *)&signatureLength, 2); // signature length
 | 
			
		||||
		signatureLength = be16toh (signatureLength);
 | 
			
		||||
		s.seekg (1, std::ios::cur); // unused
 | 
			
		||||
		uint8_t versionLength;
 | 
			
		||||
		s.read ((char *)&versionLength, 1);  // version length
 | 
			
		||||
		s.read ((char *)&versionLength, 1); // version length
 | 
			
		||||
		s.seekg (1, std::ios::cur); // unused
 | 
			
		||||
		uint8_t signerIDLength;
 | 
			
		||||
		s.read ((char *)&signerIDLength, 1);  // signer ID length
 | 
			
		||||
		s.read ((char *)&signerIDLength, 1); // signer ID length
 | 
			
		||||
		uint64_t contentLength;
 | 
			
		||||
		s.read ((char *)&contentLength, 8);  // content length
 | 
			
		||||
		s.read ((char *)&contentLength, 8); // content length
 | 
			
		||||
		contentLength = be64toh (contentLength);
 | 
			
		||||
		s.seekg (1, std::ios::cur); // unused
 | 
			
		||||
		uint8_t fileType;
 | 
			
		||||
		s.read ((char *)&fileType, 1);  // file type
 | 
			
		||||
		if (fileType != 0x00) //  zip file
 | 
			
		||||
		s.read ((char *)&fileType, 1); // file type
 | 
			
		||||
		if (fileType != 0x00) // zip file
 | 
			
		||||
		{
 | 
			
		||||
			LogPrint (eLogError, "Reseed: Can't handle file type ", (int)fileType);
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		s.seekg (1, std::ios::cur); // unused
 | 
			
		||||
		uint8_t contentType;
 | 
			
		||||
		s.read ((char *)&contentType, 1);  // content type
 | 
			
		||||
		s.read ((char *)&contentType, 1); // content type
 | 
			
		||||
		if (contentType != 0x03) // reseed data
 | 
			
		||||
		{
 | 
			
		||||
			LogPrint (eLogError, "Reseed: Unexpected content type ", (int)contentType);
 | 
			
		||||
| 
						 | 
				
			
			@ -688,7 +688,7 @@ namespace data
 | 
			
		|||
				{
 | 
			
		||||
					boost::asio::ip::tcp::endpoint ep = *it;
 | 
			
		||||
					if ((ep.address ().is_v4 () && i2p::context.SupportsV4 ()) ||
 | 
			
		||||
					    (ep.address ().is_v6 () && i2p::context.SupportsV6 ()))
 | 
			
		||||
						(ep.address ().is_v6 () && i2p::context.SupportsV6 ()))
 | 
			
		||||
					{
 | 
			
		||||
						s.lowest_layer().connect (ep, ecode);
 | 
			
		||||
						if (!ecode)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,13 +65,13 @@ namespace i2p
 | 
			
		|||
			port = rand () % (30777 - 9111) + 9111; // I2P network ports range
 | 
			
		||||
			if (port == 9150) port = 9151; // Tor browser
 | 
			
		||||
		}
 | 
			
		||||
		bool ipv4;           i2p::config::GetOption("ipv4", ipv4);
 | 
			
		||||
		bool ipv6;           i2p::config::GetOption("ipv6", ipv6);
 | 
			
		||||
		bool ssu;            i2p::config::GetOption("ssu", ssu);
 | 
			
		||||
		bool ntcp2;          i2p::config::GetOption("ntcp2.enabled", ntcp2);
 | 
			
		||||
		bool ssu2;			 i2p::config::GetOption("ssu2.enabled", ssu2);
 | 
			
		||||
		bool ygg;            i2p::config::GetOption("meshnets.yggdrasil", ygg);
 | 
			
		||||
		bool nat;            i2p::config::GetOption("nat", nat);
 | 
			
		||||
		bool ipv4;  i2p::config::GetOption("ipv4", ipv4);
 | 
			
		||||
		bool ipv6;  i2p::config::GetOption("ipv6", ipv6);
 | 
			
		||||
		bool ssu;   i2p::config::GetOption("ssu", ssu);
 | 
			
		||||
		bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
 | 
			
		||||
		bool ssu2;  i2p::config::GetOption("ssu2.enabled", ssu2);
 | 
			
		||||
		bool ygg;   i2p::config::GetOption("meshnets.yggdrasil", ygg);
 | 
			
		||||
		bool nat;   i2p::config::GetOption("nat", nat);
 | 
			
		||||
 | 
			
		||||
		if ((ntcp2 || ygg) && !m_NTCP2Keys)
 | 
			
		||||
			NewNTCP2Keys ();
 | 
			
		||||
| 
						 | 
				
			
			@ -123,11 +123,11 @@ namespace i2p
 | 
			
		|||
				if (ssu2Published)
 | 
			
		||||
					routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v4::from_string (host), port);
 | 
			
		||||
				else
 | 
			
		||||
				{	
 | 
			
		||||
				{
 | 
			
		||||
					addressCaps |= i2p::data::RouterInfo::AddressCaps::eV4;
 | 
			
		||||
					routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro);
 | 
			
		||||
				}	
 | 
			
		||||
			}	
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (ipv6)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -168,12 +168,12 @@ namespace i2p
 | 
			
		|||
				if (ssu2Published)
 | 
			
		||||
					routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v6::from_string (host), port);
 | 
			
		||||
				else
 | 
			
		||||
				{	
 | 
			
		||||
				{
 | 
			
		||||
					if (!ipv4) // no other ssu2 addresses yet
 | 
			
		||||
						routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro);
 | 
			
		||||
					addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6;
 | 
			
		||||
				}	
 | 
			
		||||
			}	
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (ygg)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -224,7 +224,7 @@ namespace i2p
 | 
			
		|||
		std::ofstream fk (i2p::fs::DataDirPath (SSU2_KEYS), std::ofstream::binary | std::ofstream::out);
 | 
			
		||||
		fk.write ((char *)m_SSU2Keys.get (), sizeof (SSU2PrivateKeys));
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
	void RouterContext::SetStatus (RouterStatus status)
 | 
			
		||||
	{
 | 
			
		||||
		if (status != m_Status)
 | 
			
		||||
| 
						 | 
				
			
			@ -313,7 +313,7 @@ namespace i2p
 | 
			
		|||
		if (updated)
 | 
			
		||||
			UpdateRouterInfo ();
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
	void RouterContext::UpdateNTCP2Address (bool enable)
 | 
			
		||||
	{
 | 
			
		||||
		auto& addresses = m_RouterInfo.GetAddresses ();
 | 
			
		||||
| 
						 | 
				
			
			@ -360,8 +360,8 @@ namespace i2p
 | 
			
		|||
		}
 | 
			
		||||
		if (updated)
 | 
			
		||||
			UpdateRouterInfo ();
 | 
			
		||||
	}	
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void RouterContext::UpdateSSU2Address (bool enable)
 | 
			
		||||
	{
 | 
			
		||||
		auto& addresses = m_RouterInfo.GetAddresses ();
 | 
			
		||||
| 
						 | 
				
			
			@ -392,14 +392,14 @@ namespace i2p
 | 
			
		|||
		if (updated)
 | 
			
		||||
			UpdateRouterInfo ();
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
	void RouterContext::UpdateAddress (const boost::asio::ip::address& host)
 | 
			
		||||
	{
 | 
			
		||||
		bool updated = false;
 | 
			
		||||
		for (auto& address : m_RouterInfo.GetAddresses ())
 | 
			
		||||
		{
 | 
			
		||||
			if (address->host != host && address->IsCompatible (host) &&
 | 
			
		||||
			    !i2p::util::net::IsYggdrasilAddress (address->host))
 | 
			
		||||
				!i2p::util::net::IsYggdrasilAddress (address->host))
 | 
			
		||||
			{
 | 
			
		||||
				address->host = host;
 | 
			
		||||
				if (host.is_v6 () && address->transportStyle == i2p::data::RouterInfo::eTransportSSU)
 | 
			
		||||
| 
						 | 
				
			
			@ -643,12 +643,12 @@ namespace i2p
 | 
			
		|||
						break;
 | 
			
		||||
						case i2p::data::RouterInfo::eTransportNTCP:
 | 
			
		||||
							foundNTCP2 = true;
 | 
			
		||||
						break;	
 | 
			
		||||
						break;
 | 
			
		||||
						case i2p::data::RouterInfo::eTransportSSU2:
 | 
			
		||||
							foundSSU2 = true;
 | 
			
		||||
						break;	
 | 
			
		||||
						break;
 | 
			
		||||
						default: ;
 | 
			
		||||
					}	
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				port = addr->port;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -690,17 +690,17 @@ namespace i2p
 | 
			
		|||
			{
 | 
			
		||||
				bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
 | 
			
		||||
				if (ssu2)
 | 
			
		||||
				{	
 | 
			
		||||
				{
 | 
			
		||||
					bool ssu2Published; i2p::config::GetOption("ssu2.published", ssu2Published);
 | 
			
		||||
					if (ssu2Published)
 | 
			
		||||
					{
 | 
			
		||||
						uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port);
 | 
			
		||||
						m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address::from_string ("::1"), ssu2Port);
 | 
			
		||||
					}	
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
						m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::eV6);
 | 
			
		||||
				}	
 | 
			
		||||
			}	
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			m_RouterInfo.EnableV6 ();
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
| 
						 | 
				
			
			@ -731,12 +731,12 @@ namespace i2p
 | 
			
		|||
						break;
 | 
			
		||||
						case i2p::data::RouterInfo::eTransportNTCP:
 | 
			
		||||
							foundNTCP2 = true;
 | 
			
		||||
						break;	
 | 
			
		||||
						break;
 | 
			
		||||
						case i2p::data::RouterInfo::eTransportSSU2:
 | 
			
		||||
							foundSSU2 = true;
 | 
			
		||||
						break;	
 | 
			
		||||
						break;
 | 
			
		||||
						default: ;
 | 
			
		||||
					}	
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if (addr->port) port = addr->port;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -776,11 +776,11 @@ namespace i2p
 | 
			
		|||
					{
 | 
			
		||||
						uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port);
 | 
			
		||||
						m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address::from_string ("127.0.0.1"), ssu2Port);
 | 
			
		||||
					}	
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
						m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::eV6);
 | 
			
		||||
				}	
 | 
			
		||||
			}	
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			m_RouterInfo.EnableV4 ();
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
| 
						 | 
				
			
			@ -883,7 +883,7 @@ namespace i2p
 | 
			
		|||
		}
 | 
			
		||||
		std::shared_ptr<const i2p::data::IdentityEx> oldIdentity;
 | 
			
		||||
		if (m_Keys.GetPublic ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1 ||
 | 
			
		||||
		    m_Keys.GetPublic ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)
 | 
			
		||||
			m_Keys.GetPublic ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ELGAMAL)
 | 
			
		||||
		{
 | 
			
		||||
			// update keys
 | 
			
		||||
			LogPrint (eLogInfo, "Router: router keys are obsolete. Creating new");
 | 
			
		||||
| 
						 | 
				
			
			@ -935,7 +935,7 @@ namespace i2p
 | 
			
		|||
			UpdateNTCP2Address (true); // enable NTCP2
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			UpdateNTCP2Address (false);	 // disable NTCP2
 | 
			
		||||
			UpdateNTCP2Address (false); // disable NTCP2
 | 
			
		||||
 | 
			
		||||
		// read SSU2
 | 
			
		||||
		bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
 | 
			
		||||
| 
						 | 
				
			
			@ -960,7 +960,7 @@ namespace i2p
 | 
			
		|||
		}
 | 
			
		||||
		else
 | 
			
		||||
			UpdateSSU2Address (false); // disable SSU2
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1103,5 +1103,5 @@ namespace i2p
 | 
			
		|||
				delete x;
 | 
			
		||||
		}
 | 
			
		||||
		return *m_SSU2StaticKeys;
 | 
			
		||||
	}	
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,7 +68,7 @@ namespace garlic
 | 
			
		|||
				uint8_t staticPrivateKey[32];
 | 
			
		||||
				uint8_t intro[32];
 | 
			
		||||
			};
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
		public:
 | 
			
		||||
 | 
			
		||||
			RouterContext ();
 | 
			
		||||
| 
						 | 
				
			
			@ -86,7 +86,7 @@ namespace garlic
 | 
			
		|||
				return std::shared_ptr<i2p::garlic::GarlicDestination> (this,
 | 
			
		||||
					[](i2p::garlic::GarlicDestination *) {});
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			const uint8_t * GetNTCP2StaticPublicKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPublicKey : nullptr; };
 | 
			
		||||
			const uint8_t * GetNTCP2StaticPrivateKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPrivateKey : nullptr; };
 | 
			
		||||
			const uint8_t * GetNTCP2IV () const { return m_NTCP2Keys ? m_NTCP2Keys->iv : nullptr; };
 | 
			
		||||
| 
						 | 
				
			
			@ -96,7 +96,7 @@ namespace garlic
 | 
			
		|||
			const uint8_t * GetSSU2StaticPrivateKey () const { return m_SSU2Keys ? m_SSU2Keys->staticPrivateKey : nullptr; };
 | 
			
		||||
			const uint8_t * GetSSU2IntroKey () const { return m_SSU2Keys ? m_SSU2Keys->intro : nullptr; };
 | 
			
		||||
			i2p::crypto::X25519Keys& GetSSU2StaticKeys ();
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			uint32_t GetUptime () const; // in seconds
 | 
			
		||||
			uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; };
 | 
			
		||||
			uint64_t GetBandwidthLimit () const { return m_BandwidthLimit; };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,16 +33,16 @@ namespace data
 | 
			
		|||
	{
 | 
			
		||||
		if (len > size ()) len = size ();
 | 
			
		||||
		memcpy (data (), buf, len);
 | 
			
		||||
	}		
 | 
			
		||||
	
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	RouterInfo::RouterInfo (): m_Buffer (nullptr)
 | 
			
		||||
	{
 | 
			
		||||
		m_Addresses = boost::make_shared<Addresses>(); // create empty list
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	RouterInfo::RouterInfo (const std::string& fullPath):
 | 
			
		||||
		m_FamilyID (0), m_IsUpdated (false), m_IsUnreachable (false), 
 | 
			
		||||
		m_SupportedTransports (0),m_ReachableTransports (0), 
 | 
			
		||||
		m_FamilyID (0), m_IsUpdated (false), m_IsUnreachable (false),
 | 
			
		||||
		m_SupportedTransports (0),m_ReachableTransports (0),
 | 
			
		||||
		m_Caps (0), m_Version (0)
 | 
			
		||||
	{
 | 
			
		||||
		m_Addresses = boost::make_shared<Addresses>(); // create empty list
 | 
			
		||||
| 
						 | 
				
			
			@ -51,8 +51,8 @@ namespace data
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	RouterInfo::RouterInfo (std::shared_ptr<Buffer>&& buf, size_t len):
 | 
			
		||||
		m_FamilyID (0), m_IsUpdated (true), m_IsUnreachable (false), 
 | 
			
		||||
		m_SupportedTransports (0), m_ReachableTransports (0), 
 | 
			
		||||
		m_FamilyID (0), m_IsUpdated (true), m_IsUnreachable (false),
 | 
			
		||||
		m_SupportedTransports (0), m_ReachableTransports (0),
 | 
			
		||||
		m_Caps (0), m_Version (0)
 | 
			
		||||
	{
 | 
			
		||||
		if (len <= MAX_RI_BUFFER_SIZE)
 | 
			
		||||
| 
						 | 
				
			
			@ -68,12 +68,12 @@ namespace data
 | 
			
		|||
			m_Buffer = nullptr;
 | 
			
		||||
			m_IsUnreachable = true;
 | 
			
		||||
		}
 | 
			
		||||
	}	
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	RouterInfo::RouterInfo (const uint8_t * buf, size_t len):
 | 
			
		||||
		RouterInfo (std::make_shared<Buffer> (buf, len), len)
 | 
			
		||||
	{
 | 
			
		||||
	}		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	RouterInfo::~RouterInfo ()
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -160,7 +160,7 @@ namespace data
 | 
			
		|||
		{
 | 
			
		||||
			m_IsUnreachable = true;
 | 
			
		||||
			return;
 | 
			
		||||
		}	
 | 
			
		||||
		}
 | 
			
		||||
		m_RouterIdentity = std::make_shared<IdentityEx>(m_Buffer->data (), m_BufferLen);
 | 
			
		||||
		size_t identityLen = m_RouterIdentity->GetFullLen ();
 | 
			
		||||
		if (identityLen >= m_BufferLen)
 | 
			
		||||
| 
						 | 
				
			
			@ -241,7 +241,7 @@ namespace data
 | 
			
		|||
				// skip unknown address
 | 
			
		||||
				s.seekg (size, std::ios_base::cur);
 | 
			
		||||
				if (s) continue; else return;
 | 
			
		||||
			}	
 | 
			
		||||
			}
 | 
			
		||||
			while (r < size)
 | 
			
		||||
			{
 | 
			
		||||
				char key[255], value[255];
 | 
			
		||||
| 
						 | 
				
			
			@ -288,7 +288,7 @@ namespace data
 | 
			
		|||
					}
 | 
			
		||||
					else if (address->IsSSU2 ())
 | 
			
		||||
						Base64ToByteStream (value, strlen (value), address->i, 32);
 | 
			
		||||
					else	
 | 
			
		||||
					else
 | 
			
		||||
						Base64ToByteStream (value, strlen (value), iV2, 32);
 | 
			
		||||
				}
 | 
			
		||||
				else if (!strcmp (key, "v"))
 | 
			
		||||
| 
						 | 
				
			
			@ -297,7 +297,7 @@ namespace data
 | 
			
		|||
						isV2 = true;
 | 
			
		||||
					else
 | 
			
		||||
						LogPrint (eLogWarning, "RouterInfo: Unexpected value ", value, " for v");
 | 
			
		||||
				}	
 | 
			
		||||
				}
 | 
			
		||||
				else if (key[0] == 'i')
 | 
			
		||||
				{
 | 
			
		||||
					// introducers
 | 
			
		||||
| 
						 | 
				
			
			@ -344,7 +344,7 @@ namespace data
 | 
			
		|||
					if (isHost)
 | 
			
		||||
					{
 | 
			
		||||
						if (address->host.is_v6 ())
 | 
			
		||||
							supportedTransports |= (i2p::util::net::IsYggdrasilAddress (address->host) ? eNTCP2V6Mesh :  eNTCP2V6);
 | 
			
		||||
							supportedTransports |= (i2p::util::net::IsYggdrasilAddress (address->host) ? eNTCP2V6Mesh : eNTCP2V6);
 | 
			
		||||
						else
 | 
			
		||||
							supportedTransports |= eNTCP2V4;
 | 
			
		||||
						m_ReachableTransports |= supportedTransports;
 | 
			
		||||
| 
						 | 
				
			
			@ -366,7 +366,7 @@ namespace data
 | 
			
		|||
				if (isIntroKey)
 | 
			
		||||
				{
 | 
			
		||||
					if (isHost)
 | 
			
		||||
						supportedTransports |= address->host.is_v4 () ? eSSUV4 :  eSSUV6;
 | 
			
		||||
						supportedTransports |= address->host.is_v4 () ? eSSUV4 : eSSUV6;
 | 
			
		||||
					else if (address->caps & AddressCaps::eV6)
 | 
			
		||||
					{
 | 
			
		||||
						supportedTransports |= eSSUV6;
 | 
			
		||||
| 
						 | 
				
			
			@ -383,7 +383,7 @@ namespace data
 | 
			
		|||
						{
 | 
			
		||||
							if (!it.iExp) it.iExp = m_Timestamp/1000 + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT;
 | 
			
		||||
							if (ts <= it.iExp && it.iPort > 0 &&
 | 
			
		||||
							    ((it.iHost.is_v4 () && address->IsV4 ()) || (it.iHost.is_v6 () && address->IsV6 ())))
 | 
			
		||||
								((it.iHost.is_v4 () && address->IsV4 ()) || (it.iHost.is_v6 () && address->IsV6 ())))
 | 
			
		||||
								numValid++;
 | 
			
		||||
							else
 | 
			
		||||
								it.iPort = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -408,12 +408,12 @@ namespace data
 | 
			
		|||
				{
 | 
			
		||||
					if (address->host.is_v4 ()) m_ReachableTransports |= eSSU2V4;
 | 
			
		||||
					if (address->host.is_v6 ()) m_ReachableTransports |= eSSU2V6;
 | 
			
		||||
				}	
 | 
			
		||||
			}	
 | 
			
		||||
			if (supportedTransports) 
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if (supportedTransports)
 | 
			
		||||
			{
 | 
			
		||||
				if (!(m_SupportedTransports & supportedTransports)) // avoid duplicates
 | 
			
		||||
				{	
 | 
			
		||||
				{
 | 
			
		||||
					addresses->push_back(address);
 | 
			
		||||
					if (address->transportStyle == eTransportSSU && isV2)
 | 
			
		||||
					{
 | 
			
		||||
| 
						 | 
				
			
			@ -427,10 +427,10 @@ namespace data
 | 
			
		|||
						ssu2addr->ssu.reset (new SSUExt ()); ssu2addr->ssu->mtu = address->ssu->mtu;
 | 
			
		||||
						for (const auto& introducer: address->ssu->introducers)
 | 
			
		||||
							if (!introducer.iPort) // SSU2
 | 
			
		||||
								ssu2addr->ssu->introducers.push_back (introducer);	
 | 
			
		||||
								ssu2addr->ssu->introducers.push_back (introducer);
 | 
			
		||||
						addresses->push_back(ssu2addr);
 | 
			
		||||
					}	
 | 
			
		||||
				}	
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				m_SupportedTransports |= supportedTransports;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -483,10 +483,10 @@ namespace data
 | 
			
		|||
			{
 | 
			
		||||
				isNetId = true;
 | 
			
		||||
				if (atoi (value) != i2p::context.GetNetID ())
 | 
			
		||||
				{	
 | 
			
		||||
				{
 | 
			
		||||
					LogPrint (eLogError, "RouterInfo: Unexpected ", ROUTER_INFO_PROPERTY_NETID, "=", value);
 | 
			
		||||
					m_IsUnreachable = true;
 | 
			
		||||
				}	
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			// family
 | 
			
		||||
			else if (!strcmp (key, ROUTER_INFO_PROPERTY_FAMILY))
 | 
			
		||||
| 
						 | 
				
			
			@ -498,7 +498,7 @@ namespace data
 | 
			
		|||
			{
 | 
			
		||||
				if (netdb.GetFamilies ().VerifyFamily (family, GetIdentHash (), value))
 | 
			
		||||
					m_FamilyID = netdb.GetFamilies ().GetFamilyID (family);
 | 
			
		||||
				else	
 | 
			
		||||
				else
 | 
			
		||||
					LogPrint (eLogWarning, "RouterInfo: Family ", family, " signature verification failed");
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -689,7 +689,7 @@ namespace data
 | 
			
		|||
		if (addr->IsV4 ()) m_SupportedTransports |= eSSU2V4;
 | 
			
		||||
		if (addr->IsV6 ()) m_SupportedTransports |= eSSU2V6;
 | 
			
		||||
		m_Addresses->push_back(std::move(addr));
 | 
			
		||||
	}	
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void RouterInfo::AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey,
 | 
			
		||||
		const boost::asio::ip::address& host, int port)
 | 
			
		||||
| 
						 | 
				
			
			@ -706,24 +706,24 @@ namespace data
 | 
			
		|||
		memcpy (addr->s, staticKey, 32);
 | 
			
		||||
		memcpy (addr->i, introKey, 32);
 | 
			
		||||
		if (addr->IsV4 ())
 | 
			
		||||
		{	
 | 
			
		||||
		{
 | 
			
		||||
			m_SupportedTransports |= eSSU2V4;
 | 
			
		||||
			m_ReachableTransports |= eSSU2V4;
 | 
			
		||||
		}	
 | 
			
		||||
		}
 | 
			
		||||
		if (addr->IsV6 ())
 | 
			
		||||
		{	
 | 
			
		||||
		{
 | 
			
		||||
			m_SupportedTransports |= eSSU2V6;
 | 
			
		||||
			m_ReachableTransports |= eSSU2V6;
 | 
			
		||||
		}	
 | 
			
		||||
		}
 | 
			
		||||
		m_Addresses->push_back(std::move(addr));
 | 
			
		||||
	}	
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool RouterInfo::AddIntroducer (const Introducer& introducer)
 | 
			
		||||
	{
 | 
			
		||||
		for (auto& addr : *m_Addresses)
 | 
			
		||||
		{
 | 
			
		||||
			if (addr->transportStyle == eTransportSSU &&
 | 
			
		||||
			   ((addr->IsV4 () && introducer.iHost.is_v4 ()) || (addr->IsV6 () && introducer.iHost.is_v6 ())))
 | 
			
		||||
				((addr->IsV4 () && introducer.iHost.is_v4 ()) || (addr->IsV6 () && introducer.iHost.is_v6 ())))
 | 
			
		||||
			{
 | 
			
		||||
				for (auto& intro: addr->ssu->introducers)
 | 
			
		||||
					if (intro.iTag == introducer.iTag) return false; // already presented
 | 
			
		||||
| 
						 | 
				
			
			@ -740,7 +740,7 @@ namespace data
 | 
			
		|||
		for (auto& addr: *m_Addresses)
 | 
			
		||||
		{
 | 
			
		||||
			if (addr->transportStyle == eTransportSSU &&
 | 
			
		||||
			   ((addr->IsV4 () && e.address ().is_v4 ()) || (addr->IsV6 () && e.address ().is_v6 ())))
 | 
			
		||||
				((addr->IsV4 () && e.address ().is_v4 ()) || (addr->IsV6 () && e.address ().is_v6 ())))
 | 
			
		||||
			{
 | 
			
		||||
				for (auto it = addr->ssu->introducers.begin (); it != addr->ssu->introducers.end (); ++it)
 | 
			
		||||
					if (boost::asio::ip::udp::endpoint (it->iHost, it->iPort) == e)
 | 
			
		||||
| 
						 | 
				
			
			@ -894,8 +894,8 @@ namespace data
 | 
			
		|||
			{
 | 
			
		||||
				return (address->transportStyle == eTransportSSU2) && address->IsV4();
 | 
			
		||||
			});
 | 
			
		||||
	}	
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	std::shared_ptr<const RouterInfo::Address> RouterInfo::GetSSU2V6Address () const
 | 
			
		||||
	{
 | 
			
		||||
		return GetAddress (
 | 
			
		||||
| 
						 | 
				
			
			@ -903,8 +903,8 @@ namespace data
 | 
			
		|||
			{
 | 
			
		||||
				return (address->transportStyle == eTransportSSU2) && address->IsV6();
 | 
			
		||||
			});
 | 
			
		||||
	}	
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	template<typename Filter>
 | 
			
		||||
	std::shared_ptr<const RouterInfo::Address> RouterInfo::GetAddress (Filter filter) const
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -939,7 +939,7 @@ namespace data
 | 
			
		|||
				return address->IsSSU2 () && !memcmp (address->s, key, 32) && address->IsV6 () == isV6;
 | 
			
		||||
			});
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
	std::shared_ptr<const RouterInfo::Address> RouterInfo::GetPublishedNTCP2V4Address () const
 | 
			
		||||
	{
 | 
			
		||||
		return GetAddress (
 | 
			
		||||
| 
						 | 
				
			
			@ -1057,17 +1057,17 @@ namespace data
 | 
			
		|||
		if (len > m_Buffer->size ()) len = m_Buffer->size ();
 | 
			
		||||
		memcpy (m_Buffer->data (), buf, len);
 | 
			
		||||
		m_BufferLen = len;
 | 
			
		||||
	}	
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	std::shared_ptr<RouterInfo::Buffer> RouterInfo::NewBuffer () const
 | 
			
		||||
	{
 | 
			
		||||
		return netdb.NewRouterInfoBuffer ();
 | 
			
		||||
	}	
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void RouterInfo::RefreshTimestamp ()
 | 
			
		||||
	{
 | 
			
		||||
		m_Timestamp = i2p::util::GetMillisecondsSinceEpoch (); 
 | 
			
		||||
	}	
 | 
			
		||||
		m_Timestamp = i2p::util::GetMillisecondsSinceEpoch ();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void LocalRouterInfo::CreateBuffer (const PrivateKeys& privateKeys)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -1088,13 +1088,13 @@ namespace data
 | 
			
		|||
		}
 | 
			
		||||
		else
 | 
			
		||||
			LogPrint (eLogError, "RouterInfo: Our RouterInfo is too long ", len + signatureLen);
 | 
			
		||||
	}	
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void LocalRouterInfo::UpdateCaps (uint8_t caps)
 | 
			
		||||
	{
 | 
			
		||||
		SetCaps (caps);
 | 
			
		||||
		UpdateCapsProperty ();
 | 
			
		||||
	}	
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void LocalRouterInfo::UpdateCapsProperty ()
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -1153,7 +1153,7 @@ namespace data
 | 
			
		|||
				{
 | 
			
		||||
					WriteString ("NTCP2", s);
 | 
			
		||||
					if (address.IsPublishedNTCP2 () && !address.host.is_unspecified () && address.port)
 | 
			
		||||
						 isPublished = true;
 | 
			
		||||
						isPublished = true;
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						WriteString ("caps", properties);
 | 
			
		||||
| 
						 | 
				
			
			@ -1212,12 +1212,12 @@ namespace data
 | 
			
		|||
				// caps
 | 
			
		||||
				std::string caps;
 | 
			
		||||
				if (address.published)
 | 
			
		||||
				{	
 | 
			
		||||
				{
 | 
			
		||||
					isPublished = true;
 | 
			
		||||
					if (address.IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER;
 | 
			
		||||
				}	
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{	
 | 
			
		||||
				{
 | 
			
		||||
					if (address.IsV4 ()) caps += CAPS_FLAG_V4;
 | 
			
		||||
					if (address.IsV6 ()) caps += CAPS_FLAG_V6;
 | 
			
		||||
					if (caps.empty ()) caps += CAPS_FLAG_V4;
 | 
			
		||||
| 
						 | 
				
			
			@ -1228,8 +1228,8 @@ namespace data
 | 
			
		|||
					properties << '=';
 | 
			
		||||
					WriteString (caps, properties);
 | 
			
		||||
					properties << ';';
 | 
			
		||||
				}	
 | 
			
		||||
			}	
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
				WriteString ("", s);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1265,7 +1265,7 @@ namespace data
 | 
			
		|||
						i++;
 | 
			
		||||
					}
 | 
			
		||||
					if (address.transportStyle == eTransportSSU)
 | 
			
		||||
					{	
 | 
			
		||||
					{
 | 
			
		||||
						i = 0;
 | 
			
		||||
						for (const auto& introducer: address.ssu->introducers)
 | 
			
		||||
						{
 | 
			
		||||
| 
						 | 
				
			
			@ -1275,13 +1275,13 @@ namespace data
 | 
			
		|||
							properties << ';';
 | 
			
		||||
							i++;
 | 
			
		||||
						}
 | 
			
		||||
					}	
 | 
			
		||||
					}
 | 
			
		||||
					i = 0;
 | 
			
		||||
					for (const auto& introducer: address.ssu->introducers)
 | 
			
		||||
					{
 | 
			
		||||
						if (address.IsSSU2 ())
 | 
			
		||||
							WriteString ("ih" + boost::lexical_cast<std::string>(i), properties);
 | 
			
		||||
						else	
 | 
			
		||||
						else
 | 
			
		||||
							WriteString ("ikey" + boost::lexical_cast<std::string>(i), properties);
 | 
			
		||||
						properties << '=';
 | 
			
		||||
						char value[64];
 | 
			
		||||
| 
						 | 
				
			
			@ -1302,7 +1302,7 @@ namespace data
 | 
			
		|||
							properties << ';';
 | 
			
		||||
							i++;
 | 
			
		||||
						}
 | 
			
		||||
					}	
 | 
			
		||||
					}
 | 
			
		||||
					i = 0;
 | 
			
		||||
					for (const auto& introducer: address.ssu->introducers)
 | 
			
		||||
					{
 | 
			
		||||
| 
						 | 
				
			
			@ -1326,7 +1326,7 @@ namespace data
 | 
			
		|||
				properties << ';';
 | 
			
		||||
			}
 | 
			
		||||
			if (address.transportStyle == eTransportSSU || address.IsSSU2 ())
 | 
			
		||||
			{	
 | 
			
		||||
			{
 | 
			
		||||
				// write mtu
 | 
			
		||||
				if (address.ssu && address.ssu->mtu)
 | 
			
		||||
				{
 | 
			
		||||
| 
						 | 
				
			
			@ -1373,7 +1373,7 @@ namespace data
 | 
			
		|||
		uint16_t size = htobe16 (properties.str ().size ());
 | 
			
		||||
		s.write ((char *)&size, sizeof (size));
 | 
			
		||||
		s.write (properties.str ().c_str (), properties.str ().size ());
 | 
			
		||||
	}	
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void LocalRouterInfo::SetProperty (const std::string& key, const std::string& value)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -1391,18 +1391,18 @@ namespace data
 | 
			
		|||
		if (it != m_Properties.end ())
 | 
			
		||||
			return it->second;
 | 
			
		||||
		return "";
 | 
			
		||||
	}	
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void LocalRouterInfo::WriteString (const std::string& str, std::ostream& s) const
 | 
			
		||||
	{
 | 
			
		||||
		uint8_t len = str.size ();
 | 
			
		||||
		s.write ((char *)&len, 1);
 | 
			
		||||
		s.write (str.c_str (), len);
 | 
			
		||||
	}	
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	std::shared_ptr<RouterInfo::Buffer> LocalRouterInfo::NewBuffer () const
 | 
			
		||||
	{
 | 
			
		||||
		return std::make_shared<Buffer> ();
 | 
			
		||||
	}		
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,7 +56,7 @@ namespace data
 | 
			
		|||
	const uint8_t COST_SSU_DIRECT = 9;
 | 
			
		||||
	const uint8_t COST_SSU_THROUGH_INTRODUCERS = 11;
 | 
			
		||||
	const uint8_t COST_SSU2_NON_PUBLISHED = 15;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	const size_t MAX_RI_BUFFER_SIZE = 3072; // if RouterInfo exceeds 3K we consider it as malformed, might extend later
 | 
			
		||||
	class RouterInfo: public RoutingDestination
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -146,11 +146,11 @@ namespace data
 | 
			
		|||
					return !(*this == other);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				bool IsNTCP2 () const { return  transportStyle == eTransportNTCP; };
 | 
			
		||||
				bool IsSSU2 () const { return  transportStyle == eTransportSSU2; };
 | 
			
		||||
				bool IsNTCP2 () const { return transportStyle == eTransportNTCP; };
 | 
			
		||||
				bool IsSSU2 () const { return transportStyle == eTransportSSU2; };
 | 
			
		||||
				bool IsPublishedNTCP2 () const { return IsNTCP2 () && published; };
 | 
			
		||||
				bool IsReachableSSU () const { return (bool)ssu && (published || UsesIntroducer ()); };
 | 
			
		||||
				bool UsesIntroducer () const { return  (bool)ssu && !ssu->introducers.empty (); };
 | 
			
		||||
				bool UsesIntroducer () const { return (bool)ssu && !ssu->introducers.empty (); };
 | 
			
		||||
 | 
			
		||||
				bool IsIntroducer () const { return caps & eSSUIntroducer; };
 | 
			
		||||
				bool IsPeerTesting () const { return caps & eSSUTesting; };
 | 
			
		||||
| 
						 | 
				
			
			@ -166,7 +166,7 @@ namespace data
 | 
			
		|||
					Buffer () = default;
 | 
			
		||||
					Buffer (const uint8_t * buf, size_t len);
 | 
			
		||||
			};
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
			typedef std::vector<std::shared_ptr<Address> > Addresses;
 | 
			
		||||
 | 
			
		||||
			RouterInfo (const std::string& fullPath);
 | 
			
		||||
| 
						 | 
				
			
			@ -181,7 +181,7 @@ namespace data
 | 
			
		|||
			std::string GetIdentHashBase64 () const { return GetIdentHash ().ToBase64 (); };
 | 
			
		||||
			uint64_t GetTimestamp () const { return m_Timestamp; };
 | 
			
		||||
			int GetVersion () const { return m_Version; };
 | 
			
		||||
			virtual void SetProperty (const std::string& key, const std::string& value) {}; 
 | 
			
		||||
			virtual void SetProperty (const std::string& key, const std::string& value) {};
 | 
			
		||||
			virtual void ClearProperties () {};
 | 
			
		||||
			Addresses& GetAddresses () { return *m_Addresses; }; // should be called for local RI only, otherwise must return shared_ptr
 | 
			
		||||
			std::shared_ptr<const Address> GetNTCP2AddressWithStaticKey (const uint8_t * key) const;
 | 
			
		||||
| 
						 | 
				
			
			@ -272,7 +272,7 @@ namespace data
 | 
			
		|||
			void SetBufferLen (size_t len) { m_BufferLen = len; };
 | 
			
		||||
			void RefreshTimestamp ();
 | 
			
		||||
			const Addresses& GetAddresses () const { return *m_Addresses; };
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		private:
 | 
			
		||||
 | 
			
		||||
			bool LoadFile (const std::string& fullPath);
 | 
			
		||||
| 
						 | 
				
			
			@ -285,7 +285,7 @@ namespace data
 | 
			
		|||
			template<typename Filter>
 | 
			
		||||
			std::shared_ptr<const Address> GetAddress (Filter filter) const;
 | 
			
		||||
			virtual std::shared_ptr<Buffer> NewBuffer () const;
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		private:
 | 
			
		||||
 | 
			
		||||
			FamilyID m_FamilyID;
 | 
			
		||||
| 
						 | 
				
			
			@ -309,22 +309,22 @@ namespace data
 | 
			
		|||
			void CreateBuffer (const PrivateKeys& privateKeys);
 | 
			
		||||
			void UpdateCaps (uint8_t caps);
 | 
			
		||||
 | 
			
		||||
			void SetProperty (const std::string& key, const std::string& value) override; 
 | 
			
		||||
			void DeleteProperty (const std::string& key); 
 | 
			
		||||
			std::string GetProperty (const std::string& key) const; 
 | 
			
		||||
			void SetProperty (const std::string& key, const std::string& value) override;
 | 
			
		||||
			void DeleteProperty (const std::string& key);
 | 
			
		||||
			std::string GetProperty (const std::string& key) const;
 | 
			
		||||
			void ClearProperties () override { m_Properties.clear (); };
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
		private:
 | 
			
		||||
 | 
			
		||||
			void WriteToStream (std::ostream& s) const;
 | 
			
		||||
			void UpdateCapsProperty ();
 | 
			
		||||
			void WriteString (const std::string& str, std::ostream& s) const;
 | 
			
		||||
			std::shared_ptr<Buffer> NewBuffer () const override;
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
		private:
 | 
			
		||||
 | 
			
		||||
			std::map<std::string, std::string> m_Properties;		
 | 
			
		||||
	};	
 | 
			
		||||
			std::map<std::string, std::string> m_Properties;
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -273,14 +273,14 @@ namespace transport
 | 
			
		|||
	void SSUServer::HandleReceivedFrom (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet)
 | 
			
		||||
	{
 | 
			
		||||
		if (!ecode
 | 
			
		||||
		    || ecode == boost::asio::error::connection_refused
 | 
			
		||||
		    || ecode == boost::asio::error::connection_reset
 | 
			
		||||
		    || ecode == boost::asio::error::network_unreachable
 | 
			
		||||
		    || ecode == boost::asio::error::host_unreachable
 | 
			
		||||
			|| ecode == boost::asio::error::connection_refused
 | 
			
		||||
			|| ecode == boost::asio::error::connection_reset
 | 
			
		||||
			|| ecode == boost::asio::error::network_unreachable
 | 
			
		||||
			|| ecode == boost::asio::error::host_unreachable
 | 
			
		||||
#ifdef _WIN32 // windows can throw WinAPI error, which is not handled by ASIO
 | 
			
		||||
		    || ecode.value() == boost::winapi::ERROR_CONNECTION_REFUSED_
 | 
			
		||||
		    || ecode.value() == boost::winapi::ERROR_NETWORK_UNREACHABLE_
 | 
			
		||||
		    || ecode.value() == boost::winapi::ERROR_HOST_UNREACHABLE_
 | 
			
		||||
			|| ecode.value() == boost::winapi::ERROR_CONNECTION_REFUSED_
 | 
			
		||||
			|| ecode.value() == boost::winapi::ERROR_NETWORK_UNREACHABLE_
 | 
			
		||||
			|| ecode.value() == boost::winapi::ERROR_HOST_UNREACHABLE_
 | 
			
		||||
#endif
 | 
			
		||||
		)
 | 
			
		||||
		// just try continue reading when received ICMP response otherwise socket can crash,
 | 
			
		||||
| 
						 | 
				
			
			@ -332,14 +332,14 @@ namespace transport
 | 
			
		|||
	void SSUServer::HandleReceivedFromV6 (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet)
 | 
			
		||||
	{
 | 
			
		||||
		if (!ecode
 | 
			
		||||
		    || ecode == boost::asio::error::connection_refused
 | 
			
		||||
		    || ecode == boost::asio::error::connection_reset
 | 
			
		||||
		    || ecode == boost::asio::error::network_unreachable
 | 
			
		||||
		    || ecode == boost::asio::error::host_unreachable
 | 
			
		||||
			|| ecode == boost::asio::error::connection_refused
 | 
			
		||||
			|| ecode == boost::asio::error::connection_reset
 | 
			
		||||
			|| ecode == boost::asio::error::network_unreachable
 | 
			
		||||
			|| ecode == boost::asio::error::host_unreachable
 | 
			
		||||
#ifdef _WIN32 // windows can throw WinAPI error, which is not handled by ASIO
 | 
			
		||||
		    || ecode.value() == boost::winapi::ERROR_CONNECTION_REFUSED_
 | 
			
		||||
		    || ecode.value() == boost::winapi::ERROR_NETWORK_UNREACHABLE_
 | 
			
		||||
		    || ecode.value() == boost::winapi::ERROR_HOST_UNREACHABLE_
 | 
			
		||||
			|| ecode.value() == boost::winapi::ERROR_CONNECTION_REFUSED_
 | 
			
		||||
			|| ecode.value() == boost::winapi::ERROR_NETWORK_UNREACHABLE_
 | 
			
		||||
			|| ecode.value() == boost::winapi::ERROR_HOST_UNREACHABLE_
 | 
			
		||||
#endif
 | 
			
		||||
		)
 | 
			
		||||
		// just try continue reading when received ICMP response otherwise socket can crash,
 | 
			
		||||
| 
						 | 
				
			
			@ -582,7 +582,7 @@ namespace transport
 | 
			
		|||
							"] through introducer ", introducer->iHost, ":", introducer->iPort);
 | 
			
		||||
					session->WaitForIntroduction ();
 | 
			
		||||
					if ((address->host.is_v4 () && i2p::context.GetStatus () == eRouterStatusFirewalled) ||
 | 
			
		||||
					    (address->host.is_v6 () && i2p::context.GetStatusV6 () == eRouterStatusFirewalled))
 | 
			
		||||
						(address->host.is_v6 () && i2p::context.GetStatusV6 () == eRouterStatusFirewalled))
 | 
			
		||||
					{
 | 
			
		||||
						uint8_t buf[1];
 | 
			
		||||
						Send (buf, 0, remoteEndpoint); // send HolePunch
 | 
			
		||||
| 
						 | 
				
			
			@ -676,7 +676,7 @@ namespace transport
 | 
			
		|||
		for (const auto& s : sessions)
 | 
			
		||||
		{
 | 
			
		||||
			if (s.second->GetRelayTag () && s.second->GetState () == eSessionStateEstablished &&
 | 
			
		||||
			    ts < s.second->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_EXPIRATION)
 | 
			
		||||
				ts < s.second->GetCreationTime () + SSU_TO_INTRODUCER_SESSION_EXPIRATION)
 | 
			
		||||
				ret.push_back (s.second);
 | 
			
		||||
			else if (s.second->GetRemoteIdentity ())
 | 
			
		||||
				excluded.insert (s.second->GetRemoteIdentity ()->GetIdentHash ());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										764
									
								
								libi2pd/SSU2.cpp
									
										
									
									
									
								
							
							
						
						
									
										764
									
								
								libi2pd/SSU2.cpp
									
										
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -35,9 +35,9 @@ namespace transport
 | 
			
		|||
	const size_t SSU2_MAX_PAYLOAD_SIZE = SSU2_MTU - 32;
 | 
			
		||||
	const int SSU2_RESEND_INTERVAL = 3; // in seconds
 | 
			
		||||
	const int SSU2_MAX_NUM_RESENDS = 5;
 | 
			
		||||
	const int SSU2_INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT = 30; // in seconds	
 | 
			
		||||
	const int SSU2_INCOMPLETE_MESSAGES_CLEANUP_TIMEOUT = 30; // in seconds
 | 
			
		||||
	const size_t SSU2_MAX_WINDOW_SIZE = 128; // in packets
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	enum SSU2MessageType
 | 
			
		||||
	{
 | 
			
		||||
		eSSU2SessionRequest = 0,
 | 
			
		||||
| 
						 | 
				
			
			@ -94,17 +94,17 @@ namespace transport
 | 
			
		|||
			size_t len;
 | 
			
		||||
			bool isLast;
 | 
			
		||||
		};
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		std::shared_ptr<I2NPMessage> msg;
 | 
			
		||||
		int nextFragmentNum;
 | 
			
		||||
		uint32_t lastFragmentInsertTime; // in seconds
 | 
			
		||||
		std::map<int, std::shared_ptr<Fragment> > outOfSequenceFragments; 
 | 
			
		||||
	};	
 | 
			
		||||
	
 | 
			
		||||
		std::map<int, std::shared_ptr<Fragment> > outOfSequenceFragments;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	// RouterInfo flags
 | 
			
		||||
	const uint8_t SSU2_ROUTER_INFO_FLAG_REQUEST_FLOOD = 0x01;
 | 
			
		||||
	const uint8_t SSU2_ROUTER_INFO_FLAG_GZIP = 0x02;	
 | 
			
		||||
	
 | 
			
		||||
	const uint8_t SSU2_ROUTER_INFO_FLAG_GZIP = 0x02;
 | 
			
		||||
 | 
			
		||||
	class SSU2Server;
 | 
			
		||||
	class SSU2Session: public TransportSession, public std::enable_shared_from_this<SSU2Session>
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -124,20 +124,20 @@ namespace transport
 | 
			
		|||
		struct SentPacket
 | 
			
		||||
		{
 | 
			
		||||
			uint8_t payload[SSU2_MAX_PAYLOAD_SIZE];
 | 
			
		||||
			size_t payloadSize = 0;    
 | 
			
		||||
			size_t payloadSize = 0;
 | 
			
		||||
			uint32_t nextResendTime; // in seconds
 | 
			
		||||
			int numResends = 0;
 | 
			
		||||
		};	
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		struct SessionConfirmedFragment
 | 
			
		||||
		{
 | 
			
		||||
			Header header;
 | 
			
		||||
			uint8_t payload[SSU2_MAX_PAYLOAD_SIZE];
 | 
			
		||||
			size_t payloadSize;
 | 
			
		||||
		};	
 | 
			
		||||
		
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		typedef std::function<void ()> OnEstablished;
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		public:
 | 
			
		||||
 | 
			
		||||
			SSU2Session (SSU2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter = nullptr,
 | 
			
		||||
| 
						 | 
				
			
			@ -147,7 +147,7 @@ namespace transport
 | 
			
		|||
			void SetRemoteEndpoint (const boost::asio::ip::udp::endpoint& ep) { m_RemoteEndpoint = ep; };
 | 
			
		||||
			const boost::asio::ip::udp::endpoint& GetRemoteEndpoint () const { return m_RemoteEndpoint; };
 | 
			
		||||
			void SetOnEstablished (OnEstablished e) { m_OnEstablished = e; };
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			void Connect ();
 | 
			
		||||
			bool Introduce (std::shared_ptr<SSU2Session> session, uint32_t relayTag);
 | 
			
		||||
			void Terminate ();
 | 
			
		||||
| 
						 | 
				
			
			@ -161,7 +161,7 @@ namespace transport
 | 
			
		|||
			uint64_t GetConnID () const { return m_SourceConnID; };
 | 
			
		||||
			SSU2SessionState GetState () const { return m_State; };
 | 
			
		||||
			void SetState (SSU2SessionState state) { m_State = state; };
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			bool ProcessFirstIncomingMessage (uint64_t connID, uint8_t * buf, size_t len);
 | 
			
		||||
			bool ProcessSessionCreated (uint8_t * buf, size_t len);
 | 
			
		||||
			bool ProcessSessionConfirmed (uint8_t * buf, size_t len);
 | 
			
		||||
| 
						 | 
				
			
			@ -169,17 +169,17 @@ namespace transport
 | 
			
		|||
			bool ProcessHolePunch (uint8_t * buf, size_t len);
 | 
			
		||||
			bool ProcessPeerTest (uint8_t * buf, size_t len);
 | 
			
		||||
			void ProcessData (uint8_t * buf, size_t len);
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
		private:
 | 
			
		||||
 | 
			
		||||
			void Established ();
 | 
			
		||||
			void PostI2NPMessages (std::vector<std::shared_ptr<I2NPMessage> > msgs);
 | 
			
		||||
			bool SendQueue ();
 | 
			
		||||
			void SendFragmentedMessage (std::shared_ptr<I2NPMessage> msg);
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			void ProcessSessionRequest (Header& header, uint8_t * buf, size_t len);
 | 
			
		||||
			void ProcessTokenRequest (Header& header, uint8_t * buf, size_t len);
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			void SendSessionRequest (uint64_t token = 0);
 | 
			
		||||
			void SendSessionCreated (const uint8_t * X);
 | 
			
		||||
			void SendSessionConfirmed (const uint8_t * Y);
 | 
			
		||||
| 
						 | 
				
			
			@ -190,8 +190,8 @@ namespace transport
 | 
			
		|||
			void SendQuickAck ();
 | 
			
		||||
			void SendTermination ();
 | 
			
		||||
			void SendHolePunch (uint32_t nonce, const boost::asio::ip::udp::endpoint& ep, const uint8_t * introKey);
 | 
			
		||||
			
 | 
			
		||||
			void HandlePayload (const uint8_t * buf, size_t len); 
 | 
			
		||||
 | 
			
		||||
			void HandlePayload (const uint8_t * buf, size_t len);
 | 
			
		||||
			void HandleAck (const uint8_t * buf, size_t len);
 | 
			
		||||
			void HandleAckRange (uint32_t firstPacketNum, uint32_t lastPacketNum);
 | 
			
		||||
			bool ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep);
 | 
			
		||||
| 
						 | 
				
			
			@ -206,7 +206,7 @@ namespace transport
 | 
			
		|||
			void HandleRelayIntro (const uint8_t * buf, size_t len);
 | 
			
		||||
			void HandleRelayResponse (const uint8_t * buf, size_t len);
 | 
			
		||||
			void HandlePeerTest (const uint8_t * buf, size_t len);
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			size_t CreateAddressBlock (uint8_t * buf, size_t len, const boost::asio::ip::udp::endpoint& ep);
 | 
			
		||||
			size_t CreateRouterInfoBlock (uint8_t * buf, size_t len, std::shared_ptr<const i2p::data::RouterInfo> r);
 | 
			
		||||
			size_t CreateAckBlock (uint8_t * buf, size_t len);
 | 
			
		||||
| 
						 | 
				
			
			@ -217,7 +217,7 @@ namespace transport
 | 
			
		|||
			size_t CreateRelayIntroBlock (uint8_t * buf, size_t len, const uint8_t * introData, size_t introDataLen);
 | 
			
		||||
			size_t CreateRelayResponseBlock (uint8_t * buf, size_t len, uint32_t nonce); // Charlie
 | 
			
		||||
			size_t CreatePeerTestBlock (uint8_t * buf, size_t len, uint8_t msg, const uint8_t * routerHash, const uint8_t * signedData, size_t signedDataLen);
 | 
			
		||||
						
 | 
			
		||||
 | 
			
		||||
		private:
 | 
			
		||||
 | 
			
		||||
			SSU2Server& m_Server;
 | 
			
		||||
| 
						 | 
				
			
			@ -228,12 +228,12 @@ namespace transport
 | 
			
		|||
			boost::asio::ip::udp::endpoint m_RemoteEndpoint;
 | 
			
		||||
			uint64_t m_DestConnID, m_SourceConnID;
 | 
			
		||||
			SSU2SessionState m_State;
 | 
			
		||||
			uint8_t m_KeyDataSend[64], m_KeyDataReceive[64]; 
 | 
			
		||||
			uint8_t m_KeyDataSend[64], m_KeyDataReceive[64];
 | 
			
		||||
			uint32_t m_SendPacketNum, m_ReceivePacketNum;
 | 
			
		||||
			std::set<uint32_t> m_OutOfSequencePackets; // packet nums > receive packet num
 | 
			
		||||
			std::map<uint32_t, std::shared_ptr<SentPacket> > m_SentPackets; // packetNum -> packet
 | 
			
		||||
			std::map<uint32_t, std::shared_ptr<SSU2IncompleteMessage> > m_IncompleteMessages; // I2NP
 | 
			
		||||
			std::map<uint32_t, std::pair <std::shared_ptr<SSU2Session>, uint64_t > > m_RelaySessions; // nonce->(Alice, timestamp) for Bob or nonce->(Charlie, timestamp) for Alice 
 | 
			
		||||
			std::map<uint32_t, std::pair <std::shared_ptr<SSU2Session>, uint64_t > > m_RelaySessions; // nonce->(Alice, timestamp) for Bob or nonce->(Charlie, timestamp) for Alice
 | 
			
		||||
			std::map<uint32_t, std::pair <std::shared_ptr<SSU2Session>, uint64_t > > m_PeerTests; // same as for relay sessions
 | 
			
		||||
			std::list<std::shared_ptr<I2NPMessage> > m_SendQueue;
 | 
			
		||||
			i2p::I2NPMessagesHandler m_Handler;
 | 
			
		||||
| 
						 | 
				
			
			@ -243,14 +243,14 @@ namespace transport
 | 
			
		|||
			OnEstablished m_OnEstablished; // callback from Established
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	class SSU2Server:  private i2p::util::RunnableServiceWithWork
 | 
			
		||||
	class SSU2Server: private i2p::util::RunnableServiceWithWork
 | 
			
		||||
	{
 | 
			
		||||
		struct Packet
 | 
			
		||||
		{
 | 
			
		||||
			uint8_t buf[SSU2_MTU]; 
 | 
			
		||||
			uint8_t buf[SSU2_MTU];
 | 
			
		||||
			size_t len;
 | 
			
		||||
			boost::asio::ip::udp::endpoint from;
 | 
			
		||||
		};	
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		class ReceiveService: public i2p::util::RunnableService
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -260,8 +260,8 @@ namespace transport
 | 
			
		|||
				boost::asio::io_service& GetService () { return GetIOService (); };
 | 
			
		||||
				void Start () { StartIOService (); };
 | 
			
		||||
				void Stop () { StopIOService (); };
 | 
			
		||||
		};	
 | 
			
		||||
		
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		public:
 | 
			
		||||
 | 
			
		||||
			SSU2Server ();
 | 
			
		||||
| 
						 | 
				
			
			@ -270,33 +270,33 @@ namespace transport
 | 
			
		|||
			void Start ();
 | 
			
		||||
			void Stop ();
 | 
			
		||||
			boost::asio::io_service& GetService () { return GetIOService (); };
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			void AddSession (std::shared_ptr<SSU2Session> session);
 | 
			
		||||
			void RemoveSession (uint64_t connID);
 | 
			
		||||
			void AddSessionByRouterHash (std::shared_ptr<SSU2Session> session);
 | 
			
		||||
			void AddPendingOutgoingSession (std::shared_ptr<SSU2Session> session);
 | 
			
		||||
 | 
			
		||||
			void AddRelay (uint32_t tag, std::shared_ptr<SSU2Session> relay);
 | 
			
		||||
			void RemoveRelay (uint32_t tag);	
 | 
			
		||||
			void RemoveRelay (uint32_t tag);
 | 
			
		||||
			std::shared_ptr<SSU2Session> FindRelaySession (uint32_t tag);
 | 
			
		||||
			
 | 
			
		||||
			void Send (const uint8_t * header, size_t headerLen, const uint8_t * payload, size_t payloadLen, 
 | 
			
		||||
 | 
			
		||||
			void Send (const uint8_t * header, size_t headerLen, const uint8_t * payload, size_t payloadLen,
 | 
			
		||||
				const boost::asio::ip::udp::endpoint& to);
 | 
			
		||||
			void Send (const uint8_t * header, size_t headerLen, const uint8_t * headerX, size_t headerXLen, 
 | 
			
		||||
			void Send (const uint8_t * header, size_t headerLen, const uint8_t * headerX, size_t headerXLen,
 | 
			
		||||
				const uint8_t * payload, size_t payloadLen, const boost::asio::ip::udp::endpoint& to);
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			bool CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router,
 | 
			
		||||
				std::shared_ptr<const i2p::data::RouterInfo::Address> address);
 | 
			
		||||
 | 
			
		||||
			void UpdateOutgoingToken (const boost::asio::ip::udp::endpoint& ep, uint64_t token, uint32_t exp);
 | 
			
		||||
			uint64_t FindOutgoingToken (const boost::asio::ip::udp::endpoint& ep) const;
 | 
			
		||||
			uint64_t GetIncomingToken (const boost::asio::ip::udp::endpoint& ep);
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
		private:
 | 
			
		||||
 | 
			
		||||
			boost::asio::ip::udp::socket& OpenSocket (const boost::asio::ip::udp::endpoint& localEndpoint);
 | 
			
		||||
			void Receive (boost::asio::ip::udp::socket& socket);
 | 
			
		||||
			void HandleReceivedFrom (const boost::system::error_code& ecode, size_t bytes_transferred, 
 | 
			
		||||
			void HandleReceivedFrom (const boost::system::error_code& ecode, size_t bytes_transferred,
 | 
			
		||||
				Packet * packet, boost::asio::ip::udp::socket& socket);
 | 
			
		||||
			void HandleReceivedPacket (Packet * packet);
 | 
			
		||||
			void HandleReceivedPackets (std::vector<Packet *> packets);
 | 
			
		||||
| 
						 | 
				
			
			@ -310,16 +310,16 @@ namespace transport
 | 
			
		|||
 | 
			
		||||
			void ConnectThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router,
 | 
			
		||||
				std::shared_ptr<const i2p::data::RouterInfo::Address> address);
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
		private:
 | 
			
		||||
 | 
			
		||||
			ReceiveService m_ReceiveService; 
 | 
			
		||||
			ReceiveService m_ReceiveService;
 | 
			
		||||
			boost::asio::ip::udp::socket m_SocketV4, m_SocketV6;
 | 
			
		||||
			std::unordered_map<uint64_t, std::shared_ptr<SSU2Session> > m_Sessions;
 | 
			
		||||
			std::map<i2p::data::IdentHash, std::shared_ptr<SSU2Session> > m_SessionsByRouterHash;
 | 
			
		||||
			std::map<boost::asio::ip::udp::endpoint, std::shared_ptr<SSU2Session> > m_PendingOutgoingSessions;
 | 
			
		||||
			std::map<boost::asio::ip::udp::endpoint, std::pair<uint64_t, uint32_t> > m_IncomingTokens, m_OutgoingTokens; // remote endpoint -> (token, expires in seconds)
 | 
			
		||||
			std::map<uint32_t, std::shared_ptr<SSU2Session> > m_Relays; // we are introducer, relay tag -> session 
 | 
			
		||||
			std::map<uint32_t, std::shared_ptr<SSU2Session> > m_Relays; // we are introducer, relay tag -> session
 | 
			
		||||
			i2p::util::MemoryPoolMt<Packet> m_PacketsPool;
 | 
			
		||||
			boost::asio::deadline_timer m_TerminationTimer, m_ResendTimer;
 | 
			
		||||
			std::shared_ptr<SSU2Session> m_LastSession;
 | 
			
		||||
| 
						 | 
				
			
			@ -327,8 +327,8 @@ namespace transport
 | 
			
		|||
		public:
 | 
			
		||||
 | 
			
		||||
			// for HTTP/I2PControl
 | 
			
		||||
			const decltype(m_Sessions)& GetSSU2Sessions () const { return m_Sessions; };	
 | 
			
		||||
	};	
 | 
			
		||||
			const decltype(m_Sessions)& GetSSU2Sessions () const { return m_Sessions; };
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -171,7 +171,7 @@ namespace transport
 | 
			
		|||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			//  find message with msgID
 | 
			
		||||
			// find message with msgID
 | 
			
		||||
			auto it = m_IncompleteMessages.find (msgID);
 | 
			
		||||
			if (it == m_IncompleteMessages.end ())
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -318,7 +318,7 @@ namespace transport
 | 
			
		|||
			sentMessage->numResends = 0;
 | 
			
		||||
		}
 | 
			
		||||
		auto& fragments = sentMessage->fragments;
 | 
			
		||||
		size_t payloadSize = m_PacketSize - sizeof (SSUHeader) - 9; // 9  =  flag + #frg(1) + messageID(4) + frag info (3)
 | 
			
		||||
		size_t payloadSize = m_PacketSize - sizeof (SSUHeader) - 9; // 9 = flag + #frg(1) + messageID(4) + frag info (3)
 | 
			
		||||
		size_t len = msg->GetLength ();
 | 
			
		||||
		uint8_t * msgBuf = msg->GetSSUHeader ();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -296,8 +296,8 @@ namespace transport
 | 
			
		|||
					{
 | 
			
		||||
						LogPrint (eLogWarning, "SSU: Clock adjusted by ", -offset, " seconds");
 | 
			
		||||
						i2p::util::AdjustTimeOffset (-offset);
 | 
			
		||||
					}	
 | 
			
		||||
				}	
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else if (std::abs (offset) > SSU_CLOCK_SKEW)
 | 
			
		||||
				{
 | 
			
		||||
					LogPrint (eLogError, "SSU: Clock skew detected ", offset, ". Check your clock");
 | 
			
		||||
| 
						 | 
				
			
			@ -388,11 +388,11 @@ namespace transport
 | 
			
		|||
		// fill extended options, 3 bytes extended options don't change message size
 | 
			
		||||
		bool isV4 = m_RemoteEndpoint.address ().is_v4 ();
 | 
			
		||||
		if ((isV4 && i2p::context.GetStatus () == eRouterStatusOK) ||
 | 
			
		||||
		    (!isV4 && i2p::context.GetStatusV6 () == eRouterStatusOK)) // we don't need relays
 | 
			
		||||
			(!isV4 && i2p::context.GetStatusV6 () == eRouterStatusOK)) // we don't need relays
 | 
			
		||||
		{
 | 
			
		||||
			// tell out peer to now assign relay tag
 | 
			
		||||
			flag = SSU_HEADER_EXTENDED_OPTIONS_INCLUDED;
 | 
			
		||||
			*payload = 2; payload++; //  1 byte length
 | 
			
		||||
			*payload = 2; payload++; // 1 byte length
 | 
			
		||||
			uint16_t flags = 0; // clear EXTENDED_OPTIONS_FLAG_REQUEST_RELAY_TAG
 | 
			
		||||
			htobe16buf (payload, flags);
 | 
			
		||||
			payload += 2;
 | 
			
		||||
| 
						 | 
				
			
			@ -1020,7 +1020,7 @@ namespace transport
 | 
			
		|||
		for (auto it = m_RelayRequests.begin (); it != m_RelayRequests.end ();)
 | 
			
		||||
		{
 | 
			
		||||
			if (ts > it->second.second + SSU_CONNECT_TIMEOUT)
 | 
			
		||||
				it =  m_RelayRequests.erase (it);
 | 
			
		||||
				it = m_RelayRequests.erase (it);
 | 
			
		||||
			else
 | 
			
		||||
				++it;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -130,7 +130,7 @@ namespace crypto
 | 
			
		|||
		else
 | 
			
		||||
		{
 | 
			
		||||
			size_t l = 64;
 | 
			
		||||
			uint8_t sig[64];  // temporary buffer for signature. openssl issue #7232
 | 
			
		||||
			uint8_t sig[64]; // temporary buffer for signature. openssl issue #7232
 | 
			
		||||
			EVP_DigestSign (m_MDCtx, sig, &l, buf, len);
 | 
			
		||||
			memcpy (signature, sig, 64);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1249,7 +1249,7 @@ namespace stream
 | 
			
		|||
		return s;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void  StreamingDestination::SendPing (std::shared_ptr<const i2p::data::LeaseSet> remote)
 | 
			
		||||
	void StreamingDestination::SendPing (std::shared_ptr<const i2p::data::LeaseSet> remote)
 | 
			
		||||
	{
 | 
			
		||||
		auto s = std::make_shared<Stream> (m_Owner->GetService (), *this, remote, 0);
 | 
			
		||||
		s->SendPing ();
 | 
			
		||||
| 
						 | 
				
			
			@ -1277,7 +1277,7 @@ namespace stream
 | 
			
		|||
		{
 | 
			
		||||
			m_PacketsPool.CleanUp ();
 | 
			
		||||
			m_I2NPMsgsPool.CleanUp ();
 | 
			
		||||
		}	
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool StreamingDestination::DeleteStream (uint32_t recvStreamID)
 | 
			
		||||
| 
						 | 
				
			
			@ -1287,7 +1287,7 @@ namespace stream
 | 
			
		|||
			return false;
 | 
			
		||||
		auto s = it->second;
 | 
			
		||||
		m_Owner->GetService ().post ([this, s] ()
 | 
			
		||||
			{    
 | 
			
		||||
			{
 | 
			
		||||
				s->Close (); // try to send FIN
 | 
			
		||||
				s->Terminate (false);
 | 
			
		||||
				DeleteStream (s);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -254,6 +254,6 @@ namespace util
 | 
			
		|||
	void AdjustTimeOffset (int64_t offset)
 | 
			
		||||
	{
 | 
			
		||||
		g_TimeOffset += offset;
 | 
			
		||||
	}	
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,7 +27,7 @@ namespace util
 | 
			
		|||
	void GetCurrentDate (char * date); // returns date as YYYYMMDD string, 9 bytes
 | 
			
		||||
	void GetDateString (uint64_t timestamp, char * date); // timestap is seconds since epoch, returns date as YYYYMMDD string, 9 bytes
 | 
			
		||||
	void AdjustTimeOffset (int64_t offset); // in seconds from current
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	class NTPTimeSync
 | 
			
		||||
	{
 | 
			
		||||
		public:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -219,7 +219,7 @@ namespace transport
 | 
			
		|||
		}
 | 
			
		||||
		// create SSU2 server
 | 
			
		||||
		if (enableSSU2) m_SSU2Server = new SSU2Server ();
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		// bind to interfaces
 | 
			
		||||
		bool ipv4; i2p::config::GetOption("ipv4", ipv4);
 | 
			
		||||
		if (ipv4)
 | 
			
		||||
| 
						 | 
				
			
			@ -285,7 +285,7 @@ namespace transport
 | 
			
		|||
			if (m_SSUServer) DetectExternalIP ();
 | 
			
		||||
		}
 | 
			
		||||
		if (m_SSU2Server) m_SSU2Server->Start ();
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT));
 | 
			
		||||
		m_PeerCleanupTimer->async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -307,14 +307,14 @@ namespace transport
 | 
			
		|||
			delete m_SSUServer;
 | 
			
		||||
			m_SSUServer = nullptr;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		if (m_SSU2Server)
 | 
			
		||||
		{
 | 
			
		||||
			m_SSU2Server->Stop ();
 | 
			
		||||
			delete m_SSU2Server;
 | 
			
		||||
			m_SSU2Server = nullptr;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
		if (m_NTCP2Server)
 | 
			
		||||
		{
 | 
			
		||||
			m_NTCP2Server->Stop ();
 | 
			
		||||
| 
						 | 
				
			
			@ -569,7 +569,7 @@ namespace transport
 | 
			
		|||
				}
 | 
			
		||||
				else
 | 
			
		||||
					peer.numAttempts += 2;
 | 
			
		||||
			}	
 | 
			
		||||
			}
 | 
			
		||||
			LogPrint (eLogInfo, "Transports: No compatble NTCP2 or SSU addresses available");
 | 
			
		||||
			i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed
 | 
			
		||||
			peer.Done ();
 | 
			
		||||
| 
						 | 
				
			
			@ -829,18 +829,18 @@ namespace transport
 | 
			
		|||
		}
 | 
			
		||||
		return i2p::data::netdb.FindRouter (ident);
 | 
			
		||||
	}
 | 
			
		||||
		
 | 
			
		||||
 | 
			
		||||
	void Transports::RestrictRoutesToFamilies(const std::set<std::string>& families)
 | 
			
		||||
	{
 | 
			
		||||
		std::lock_guard<std::mutex> lock(m_FamilyMutex);
 | 
			
		||||
		m_TrustedFamilies.clear();
 | 
			
		||||
		for (auto fam : families)
 | 
			
		||||
		{	
 | 
			
		||||
		{
 | 
			
		||||
			boost::to_lower (fam);
 | 
			
		||||
			auto id = i2p::data::netdb.GetFamilies ().GetFamilyID (fam);
 | 
			
		||||
			if (id)	
 | 
			
		||||
			if (id)
 | 
			
		||||
				m_TrustedFamilies.push_back (id);
 | 
			
		||||
		}	
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void Transports::RestrictRoutesToRouters(std::set<i2p::data::IdentHash> routers)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -108,7 +108,7 @@ namespace tunnel
 | 
			
		|||
		else
 | 
			
		||||
		{
 | 
			
		||||
			if (m_Config->IsShort () && m_Config->GetLastHop () &&
 | 
			
		||||
			    m_Config->GetLastHop ()->ident->GetIdentHash () != m_Config->GetLastHop ()->nextIdent)
 | 
			
		||||
				m_Config->GetLastHop ()->ident->GetIdentHash () != m_Config->GetLastHop ()->nextIdent)
 | 
			
		||||
			{
 | 
			
		||||
				// add garlic key/tag for reply
 | 
			
		||||
				uint8_t key[32];
 | 
			
		||||
| 
						 | 
				
			
			@ -403,7 +403,7 @@ namespace tunnel
 | 
			
		|||
		return tunnel;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	std::shared_ptr<TunnelPool> Tunnels::CreateTunnelPool (int numInboundHops, int numOutboundHops, 
 | 
			
		||||
	std::shared_ptr<TunnelPool> Tunnels::CreateTunnelPool (int numInboundHops, int numOutboundHops,
 | 
			
		||||
		int numInboundTunnels, int numOutboundTunnels, int inboundVariance, int outboundVariance)
 | 
			
		||||
	{
 | 
			
		||||
		auto pool = std::make_shared<TunnelPool> (numInboundHops, numOutboundHops, numInboundTunnels, numOutboundTunnels, inboundVariance, outboundVariance);
 | 
			
		||||
| 
						 | 
				
			
			@ -822,7 +822,7 @@ namespace tunnel
 | 
			
		|||
 | 
			
		||||
	template<class TTunnel>
 | 
			
		||||
	std::shared_ptr<TTunnel> Tunnels::CreateTunnel (std::shared_ptr<TunnelConfig> config,
 | 
			
		||||
	    std::shared_ptr<TunnelPool> pool, std::shared_ptr<OutboundTunnel> outboundTunnel)
 | 
			
		||||
		std::shared_ptr<TunnelPool> pool, std::shared_ptr<OutboundTunnel> outboundTunnel)
 | 
			
		||||
	{
 | 
			
		||||
		auto newTunnel = std::make_shared<TTunnel> (config);
 | 
			
		||||
		newTunnel->SetTunnelPool (pool);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -215,7 +215,7 @@ namespace tunnel
 | 
			
		|||
			void PostTunnelData (const std::vector<std::shared_ptr<I2NPMessage> >& msgs);
 | 
			
		||||
			void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr<InboundTunnel> tunnel);
 | 
			
		||||
			void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr<OutboundTunnel> tunnel);
 | 
			
		||||
			std::shared_ptr<TunnelPool> CreateTunnelPool (int numInboundHops, int numOuboundHops, 
 | 
			
		||||
			std::shared_ptr<TunnelPool> CreateTunnelPool (int numInboundHops, int numOuboundHops,
 | 
			
		||||
				int numInboundTunnels, int numOutboundTunnels, int inboundVariance, int outboundVariance);
 | 
			
		||||
			void DeleteTunnelPool (std::shared_ptr<TunnelPool> pool);
 | 
			
		||||
			void StopTunnelPool (std::shared_ptr<TunnelPool> pool);
 | 
			
		||||
| 
						 | 
				
			
			@ -226,7 +226,7 @@ namespace tunnel
 | 
			
		|||
 | 
			
		||||
			template<class TTunnel>
 | 
			
		||||
			std::shared_ptr<TTunnel> CreateTunnel (std::shared_ptr<TunnelConfig> config,
 | 
			
		||||
			    std::shared_ptr<TunnelPool> pool, std::shared_ptr<OutboundTunnel> outboundTunnel = nullptr);
 | 
			
		||||
				std::shared_ptr<TunnelPool> pool, std::shared_ptr<OutboundTunnel> outboundTunnel = nullptr);
 | 
			
		||||
 | 
			
		||||
			template<class TTunnel>
 | 
			
		||||
			std::shared_ptr<TTunnel> GetPendingTunnel (uint32_t replyMsgID, const std::map<uint32_t, std::shared_ptr<TTunnel> >& pendingTunnels);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -167,7 +167,7 @@ namespace tunnel
 | 
			
		|||
		memset (clearText + SHORT_REQUEST_RECORD_MORE_FLAGS_OFFSET, 0, 2);
 | 
			
		||||
		clearText[SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE] = 0; // AES
 | 
			
		||||
		htobe32buf (clearText + SHORT_REQUEST_RECORD_REQUEST_TIME_OFFSET, i2p::util::GetMinutesSinceEpoch ());
 | 
			
		||||
        htobe32buf (clearText + SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET , 600); // +10 minutes
 | 
			
		||||
		htobe32buf (clearText + SHORT_REQUEST_RECORD_REQUEST_EXPIRATION_OFFSET , 600); // +10 minutes
 | 
			
		||||
		htobe32buf (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET, replyMsgID);
 | 
			
		||||
		memset (clearText + SHORT_REQUEST_RECORD_PADDING_OFFSET, 0, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE - SHORT_REQUEST_RECORD_PADDING_OFFSET);
 | 
			
		||||
		// encrypt
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -91,7 +91,7 @@ namespace tunnel
 | 
			
		|||
 | 
			
		||||
			TunnelConfig (const std::vector<std::shared_ptr<const i2p::data::IdentityEx> >& peers,
 | 
			
		||||
				uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent, bool isShort,
 | 
			
		||||
			    i2p::data::RouterInfo::CompatibleTransports farEndTransports = i2p::data::RouterInfo::eAllTransports): // outbound
 | 
			
		||||
				i2p::data::RouterInfo::CompatibleTransports farEndTransports = i2p::data::RouterInfo::eAllTransports): // outbound
 | 
			
		||||
				m_IsShort (isShort), m_FarEndTransports (farEndTransports)
 | 
			
		||||
			{
 | 
			
		||||
				CreatePeers (peers);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ namespace tunnel
 | 
			
		|||
		{
 | 
			
		||||
			peers.push_back (r->GetRouterIdentity ());
 | 
			
		||||
			if (r->GetVersion () < i2p::data::NETDB_MIN_SHORT_TUNNEL_BUILD_VERSION ||
 | 
			
		||||
			    r->GetRouterIdentity ()->GetCryptoKeyType () != i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)
 | 
			
		||||
				r->GetRouterIdentity ()->GetCryptoKeyType () != i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)
 | 
			
		||||
				isShort = false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -40,11 +40,11 @@ namespace tunnel
 | 
			
		|||
		std::reverse (peers.begin (), peers.end ());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, 
 | 
			
		||||
	TunnelPool::TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels,
 | 
			
		||||
		int numOutboundTunnels, int inboundVariance, int outboundVariance):
 | 
			
		||||
		m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops),
 | 
			
		||||
		m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels),
 | 
			
		||||
		m_InboundVariance (inboundVariance), m_OutboundVariance (outboundVariance), 
 | 
			
		||||
		m_InboundVariance (inboundVariance), m_OutboundVariance (outboundVariance),
 | 
			
		||||
		m_IsActive (true), m_CustomPeerSelector(nullptr)
 | 
			
		||||
	{
 | 
			
		||||
		if (m_NumInboundTunnels > TUNNEL_POOL_MAX_INBOUND_TUNNELS_QUANTITY)
 | 
			
		||||
| 
						 | 
				
			
			@ -54,11 +54,11 @@ namespace tunnel
 | 
			
		|||
		if (m_InboundVariance < 0 && m_NumInboundHops + m_InboundVariance <= 0)
 | 
			
		||||
			m_InboundVariance = m_NumInboundHops ? -m_NumInboundHops + 1 : 0;
 | 
			
		||||
		if (m_OutboundVariance < 0 && m_NumOutboundHops + m_OutboundVariance <= 0)
 | 
			
		||||
			m_OutboundVariance = m_NumOutboundHops ? -m_NumOutboundHops + 1 : 0;	
 | 
			
		||||
			m_OutboundVariance = m_NumOutboundHops ? -m_NumOutboundHops + 1 : 0;
 | 
			
		||||
		if (m_InboundVariance > 0 && m_NumInboundHops + m_InboundVariance > STANDARD_NUM_RECORDS)
 | 
			
		||||
			m_InboundVariance = (m_NumInboundHops < STANDARD_NUM_RECORDS) ? STANDARD_NUM_RECORDS - m_NumInboundHops : 0;
 | 
			
		||||
		if (m_OutboundVariance > 0 && m_NumOutboundHops + m_OutboundVariance > STANDARD_NUM_RECORDS)
 | 
			
		||||
			m_OutboundVariance = (m_NumOutboundHops < STANDARD_NUM_RECORDS) ? STANDARD_NUM_RECORDS - m_NumOutboundHops : 0;	
 | 
			
		||||
			m_OutboundVariance = (m_NumOutboundHops < STANDARD_NUM_RECORDS) ? STANDARD_NUM_RECORDS - m_NumOutboundHops : 0;
 | 
			
		||||
		m_NextManageTime = i2p::util::GetSecondsSinceEpoch () + rand () % TUNNEL_POOL_MANAGE_INTERVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -227,7 +227,7 @@ namespace tunnel
 | 
			
		|||
			if (it->IsEstablished () && it != excluded && (compatible & it->GetFarEndTransports ()))
 | 
			
		||||
			{
 | 
			
		||||
				if (it->IsSlow () || (HasLatencyRequirement() && it->LatencyIsKnown() &&
 | 
			
		||||
				    !it->LatencyFitsRange(m_MinLatency, m_MaxLatency)))
 | 
			
		||||
					!it->LatencyFitsRange(m_MinLatency, m_MaxLatency)))
 | 
			
		||||
				{
 | 
			
		||||
					i++; skipped = true;
 | 
			
		||||
					continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -423,7 +423,7 @@ namespace tunnel
 | 
			
		|||
			LogPrint (eLogDebug, "Tunnels: Test of ", msgID, " successful. ", dlt, " milliseconds");
 | 
			
		||||
			int numHops = 0;
 | 
			
		||||
			if (test.first) numHops += test.first->GetNumHops ();
 | 
			
		||||
			if (test.second) numHops += test.second->GetNumHops ();	
 | 
			
		||||
			if (test.second) numHops += test.second->GetNumHops ();
 | 
			
		||||
			// restore from test failed state if any
 | 
			
		||||
			if (test.first)
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -431,7 +431,7 @@ namespace tunnel
 | 
			
		|||
					test.first->SetState (eTunnelStateEstablished);
 | 
			
		||||
				// update latency
 | 
			
		||||
				uint64_t latency = 0;
 | 
			
		||||
				if (numHops) latency = dlt*test.first->GetNumHops ()/numHops; 
 | 
			
		||||
				if (numHops) latency = dlt*test.first->GetNumHops ()/numHops;
 | 
			
		||||
				if (!latency) latency = dlt/2;
 | 
			
		||||
				test.first->AddLatencySample(latency);
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -441,7 +441,7 @@ namespace tunnel
 | 
			
		|||
					test.second->SetState (eTunnelStateEstablished);
 | 
			
		||||
				// update latency
 | 
			
		||||
				uint64_t latency = 0;
 | 
			
		||||
				if (numHops) latency = dlt*test.second->GetNumHops ()/numHops; 
 | 
			
		||||
				if (numHops) latency = dlt*test.second->GetNumHops ()/numHops;
 | 
			
		||||
				if (!latency) latency = dlt/2;
 | 
			
		||||
				test.second->AddLatencySample(latency);
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -511,7 +511,7 @@ namespace tunnel
 | 
			
		|||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
			if ((i == numHops - 1) && (!hop->IsV4 () || // doesn't support ipv4
 | 
			
		||||
				(inbound && !hop->IsReachable ())))  // IBGW is not reachable
 | 
			
		||||
				(inbound && !hop->IsReachable ()))) // IBGW is not reachable
 | 
			
		||||
			{
 | 
			
		||||
				auto hop1 = nextHop (prevHop, true);
 | 
			
		||||
				if (hop1) hop = hop1;
 | 
			
		||||
| 
						 | 
				
			
			@ -530,25 +530,25 @@ namespace tunnel
 | 
			
		|||
		// calculate num hops
 | 
			
		||||
		int numHops;
 | 
			
		||||
		if (isInbound)
 | 
			
		||||
		{	
 | 
			
		||||
			numHops = m_NumInboundHops; 
 | 
			
		||||
		{
 | 
			
		||||
			numHops = m_NumInboundHops;
 | 
			
		||||
			if (m_InboundVariance)
 | 
			
		||||
			{
 | 
			
		||||
				int offset = rand () % (std::abs (m_InboundVariance) + 1);
 | 
			
		||||
				if (m_InboundVariance < 0) offset = -offset;
 | 
			
		||||
				numHops += offset;
 | 
			
		||||
			}	
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{	
 | 
			
		||||
		{
 | 
			
		||||
			numHops = m_NumOutboundHops;
 | 
			
		||||
			if (m_OutboundVariance)
 | 
			
		||||
			{
 | 
			
		||||
				int offset = rand () % (std::abs (m_OutboundVariance) + 1);
 | 
			
		||||
				if (m_OutboundVariance < 0) offset = -offset;
 | 
			
		||||
				numHops += offset;
 | 
			
		||||
			}	
 | 
			
		||||
		}	
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		// peers is empty
 | 
			
		||||
		if (numHops <= 0) return true;
 | 
			
		||||
		// custom peer selector in use ?
 | 
			
		||||
| 
						 | 
				
			
			@ -715,7 +715,7 @@ namespace tunnel
 | 
			
		|||
		auto tunnel = tunnels.CreateInboundTunnel (
 | 
			
		||||
			m_NumOutboundHops > 0 ? std::make_shared<TunnelConfig>(outboundTunnel->GetInvertedPeers (),
 | 
			
		||||
				outboundTunnel->IsShortBuildMessage ()) : nullptr,
 | 
			
		||||
		    shared_from_this (), outboundTunnel);
 | 
			
		||||
				shared_from_this (), outboundTunnel);
 | 
			
		||||
		if (tunnel->IsEstablished ()) // zero hops
 | 
			
		||||
			TunnelCreated (tunnel);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,7 +61,7 @@ namespace tunnel
 | 
			
		|||
	{
 | 
			
		||||
		public:
 | 
			
		||||
 | 
			
		||||
			TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, 
 | 
			
		||||
			TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels,
 | 
			
		||||
				int numOutboundTunnels, int inboundVariance, int outboundVariance);
 | 
			
		||||
			~TunnelPool ();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -131,7 +131,7 @@ namespace tunnel
 | 
			
		|||
		private:
 | 
			
		||||
 | 
			
		||||
			std::shared_ptr<i2p::garlic::GarlicDestination> m_LocalDestination;
 | 
			
		||||
			int m_NumInboundHops, m_NumOutboundHops, m_NumInboundTunnels, m_NumOutboundTunnels, 
 | 
			
		||||
			int m_NumInboundHops, m_NumOutboundHops, m_NumInboundTunnels, m_NumOutboundTunnels,
 | 
			
		||||
				m_InboundVariance, m_OutboundVariance;
 | 
			
		||||
			std::shared_ptr<std::vector<i2p::data::IdentHash> > m_ExplicitPeers;
 | 
			
		||||
			mutable std::mutex m_InboundTunnelsMutex;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -517,7 +517,7 @@ namespace net
 | 
			
		|||
 | 
			
		||||
	bool IsLocalAddress (const boost::asio::ip::address& addr)
 | 
			
		||||
	{
 | 
			
		||||
		auto mtu =  // TODO: implement better
 | 
			
		||||
		auto mtu = // TODO: implement better
 | 
			
		||||
#ifdef _WIN32
 | 
			
		||||
		GetMTUWindows(addr, 0);
 | 
			
		||||
#else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -372,7 +372,7 @@ namespace client
 | 
			
		|||
			{
 | 
			
		||||
				auto addr = FindAddress (address);
 | 
			
		||||
				if (!addr)
 | 
			
		||||
					 LookupAddress (address); // TODO:
 | 
			
		||||
					LookupAddress (address); // TODO:
 | 
			
		||||
				return addr;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -494,7 +494,7 @@ namespace client
 | 
			
		|||
				auto it = m_Addresses.find (name);
 | 
			
		||||
				if (it != m_Addresses.end ()) // already exists ?
 | 
			
		||||
				{
 | 
			
		||||
					if (it->second->IsIdentHash () && it->second->identHash != ident->GetIdentHash () &&  // address changed?
 | 
			
		||||
					if (it->second->IsIdentHash () && it->second->identHash != ident->GetIdentHash () && // address changed?
 | 
			
		||||
						ident->GetSigningKeyType () != i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) // don't replace by DSA
 | 
			
		||||
					{
 | 
			
		||||
						it->second->identHash = ident->GetIdentHash ();
 | 
			
		||||
| 
						 | 
				
			
			@ -858,9 +858,9 @@ namespace client
 | 
			
		|||
		if (!m_LastModified.empty())
 | 
			
		||||
			req.AddHeader("If-Modified-Since", m_LastModified);
 | 
			
		||||
		/* convert url to relative */
 | 
			
		||||
		url.schema = "";
 | 
			
		||||
		url.host   = "";
 | 
			
		||||
		req.uri    = url.to_string();
 | 
			
		||||
		url.schema  = "";
 | 
			
		||||
		url.host    = "";
 | 
			
		||||
		req.uri     = url.to_string();
 | 
			
		||||
		req.version = "HTTP/1.1";
 | 
			
		||||
		auto stream = i2p::client::context.GetSharedLocalDestination ()->CreateStream (leaseSet, dest_port);
 | 
			
		||||
		std::string request = req.to_string();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -116,7 +116,7 @@ namespace client
 | 
			
		|||
		private:
 | 
			
		||||
 | 
			
		||||
			std::mutex m_AddressBookMutex;
 | 
			
		||||
			std::map<std::string, std::shared_ptr<Address> >  m_Addresses;
 | 
			
		||||
			std::map<std::string, std::shared_ptr<Address> > m_Addresses;
 | 
			
		||||
			std::map<i2p::data::IdentHash, std::shared_ptr<AddressResolver> > m_Resolvers; // local destination->resolver
 | 
			
		||||
			std::mutex m_LookupsMutex;
 | 
			
		||||
			std::map<uint32_t, std::string> m_Lookups; // nonce -> address
 | 
			
		||||
| 
						 | 
				
			
			@ -162,7 +162,7 @@ namespace client
 | 
			
		|||
		private:
 | 
			
		||||
 | 
			
		||||
			std::shared_ptr<ClientDestination> m_LocalDestination;
 | 
			
		||||
			std::map<std::string, i2p::data::IdentHash>  m_LocalAddresses;
 | 
			
		||||
			std::map<std::string, i2p::data::IdentHash> m_LocalAddresses;
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -898,7 +898,7 @@ namespace client
 | 
			
		|||
		bool socksproxy; i2p::config::GetOption("socksproxy.enabled", socksproxy);
 | 
			
		||||
		if (socksproxy)
 | 
			
		||||
		{
 | 
			
		||||
			std::string httpProxyKeys;         i2p::config::GetOption("httpproxy.keys",          httpProxyKeys);
 | 
			
		||||
			std::string httpProxyKeys;         i2p::config::GetOption("httpproxy.keys",              httpProxyKeys);
 | 
			
		||||
			// we still need httpProxyKeys to compare with sockProxyKeys
 | 
			
		||||
			std::string socksProxyKeys;        i2p::config::GetOption("socksproxy.keys",             socksProxyKeys);
 | 
			
		||||
			std::string socksProxyAddr;        i2p::config::GetOption("socksproxy.address",          socksProxyAddr);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,7 @@ namespace client
 | 
			
		|||
{
 | 
			
		||||
 | 
			
		||||
	I2CPDestination::I2CPDestination (boost::asio::io_service& service, std::shared_ptr<I2CPSession> owner,
 | 
			
		||||
	    std::shared_ptr<const i2p::data::IdentityEx> identity, bool isPublic, const std::map<std::string, std::string>& params):
 | 
			
		||||
		std::shared_ptr<const i2p::data::IdentityEx> identity, bool isPublic, const std::map<std::string, std::string>& params):
 | 
			
		||||
		LeaseSetDestination (service, isPublic, ¶ms),
 | 
			
		||||
		m_Owner (owner), m_Identity (identity), m_EncryptionKeyType (m_Identity->GetCryptoKeyType ()),
 | 
			
		||||
		m_IsCreatingLeaseSet (false), m_LeaseSetCreationTimer (service)
 | 
			
		||||
| 
						 | 
				
			
			@ -208,12 +208,12 @@ namespace client
 | 
			
		|||
			if (leases.empty ())
 | 
			
		||||
				leases = remote->GetNonExpiredLeases (true); // with threshold
 | 
			
		||||
			if (!leases.empty ())
 | 
			
		||||
			{	
 | 
			
		||||
			{
 | 
			
		||||
				remoteLease = leases[rand () % leases.size ()];
 | 
			
		||||
				auto leaseRouter = i2p::data::netdb.FindRouter (remoteLease->tunnelGateway);
 | 
			
		||||
				outboundTunnel = GetTunnelPool ()->GetNextOutboundTunnel (nullptr,
 | 
			
		||||
					leaseRouter ? leaseRouter->GetCompatibleTransports (false) : (i2p::data::RouterInfo::CompatibleTransports)i2p::data::RouterInfo::eAllTransports);
 | 
			
		||||
			}	
 | 
			
		||||
			}
 | 
			
		||||
			if (remoteLease && outboundTunnel)
 | 
			
		||||
				remoteSession->SetSharedRoutingPath (std::make_shared<i2p::garlic::GarlicRoutingPath> (
 | 
			
		||||
					i2p::garlic::GarlicRoutingPath{outboundTunnel, remoteLease, 10000, 0, 0})); // 10 secs RTT
 | 
			
		||||
| 
						 | 
				
			
			@ -453,8 +453,8 @@ namespace client
 | 
			
		|||
			{
 | 
			
		||||
				auto len = m_SendQueue.Get (m_SendBuffer, I2CP_MAX_MESSAGE_LENGTH);
 | 
			
		||||
				boost::asio::async_write (*socket, boost::asio::buffer (m_SendBuffer, len),
 | 
			
		||||
				    boost::asio::transfer_all (),std::bind(&I2CPSession::HandleI2CPMessageSent,
 | 
			
		||||
				    shared_from_this (), std::placeholders::_1, std::placeholders::_2));
 | 
			
		||||
					boost::asio::transfer_all (),std::bind(&I2CPSession::HandleI2CPMessageSent,
 | 
			
		||||
					shared_from_this (), std::placeholders::_1, std::placeholders::_2));
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
				m_IsSending = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -538,7 +538,7 @@ namespace client
 | 
			
		|||
			LogPrint (eLogError, "I2CP: Create session duplicate address ", identity->GetIdentHash ().ToBase32 ());
 | 
			
		||||
			SendSessionStatusMessage (eI2CPSessionStatusInvalid); // invalid
 | 
			
		||||
			return;
 | 
			
		||||
		}	
 | 
			
		||||
		}
 | 
			
		||||
		uint16_t optionsSize = bufbe16toh (buf + offset);
 | 
			
		||||
		offset += 2;
 | 
			
		||||
		if (optionsSize > len - offset)
 | 
			
		||||
| 
						 | 
				
			
			@ -561,16 +561,16 @@ namespace client
 | 
			
		|||
					std::make_shared<I2CPDestination>(m_Owner.GetService (), shared_from_this (), identity, true, params):
 | 
			
		||||
					std::make_shared<RunnableI2CPDestination>(shared_from_this (), identity, true, params);
 | 
			
		||||
				if (m_Owner.InsertSession (shared_from_this ()))
 | 
			
		||||
				{		
 | 
			
		||||
				{
 | 
			
		||||
					SendSessionStatusMessage (eI2CPSessionStatusCreated); // created
 | 
			
		||||
					LogPrint (eLogDebug, "I2CP: Session ", m_SessionID, " created");
 | 
			
		||||
					m_Destination->Start ();
 | 
			
		||||
				}	
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					LogPrint (eLogError, "I2CP: Session already exists");
 | 
			
		||||
					SendSessionStatusMessage (eI2CPSessionStatusRefused);
 | 
			
		||||
				}	
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -712,7 +712,7 @@ namespace client
 | 
			
		|||
				{
 | 
			
		||||
					if (offset + 4 > len) return;
 | 
			
		||||
					uint16_t keyType = bufbe16toh (buf + offset); offset += 2; // encryption type
 | 
			
		||||
					uint16_t keyLen = bufbe16toh (buf + offset); offset += 2;  // private key length
 | 
			
		||||
					uint16_t keyLen = bufbe16toh (buf + offset); offset += 2; // private key length
 | 
			
		||||
					if (offset + keyLen > len) return;
 | 
			
		||||
					if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)
 | 
			
		||||
						m_Destination->SetECIESx25519EncryptionPrivateKey (buf + offset);
 | 
			
		||||
| 
						 | 
				
			
			@ -1030,13 +1030,13 @@ namespace client
 | 
			
		|||
		for (const auto& it: m_Sessions)
 | 
			
		||||
		{
 | 
			
		||||
			if (it.second)
 | 
			
		||||
			{	
 | 
			
		||||
			{
 | 
			
		||||
				auto dest = it.second->GetDestination ();
 | 
			
		||||
				if (dest && dest->GetIdentHash () == ident)
 | 
			
		||||
					return it.second;
 | 
			
		||||
			}	
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return nullptr;
 | 
			
		||||
	}	
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -69,7 +69,7 @@ namespace client
 | 
			
		|||
		eI2CPSessionStatusInvalid = 3,
 | 
			
		||||
		eI2CPSessionStatusRefused = 4
 | 
			
		||||
	};
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	// params
 | 
			
		||||
	const char I2CP_PARAM_MESSAGE_RELIABILITY[] = "i2cp.messageReliability";
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,7 +31,7 @@ namespace client
 | 
			
		|||
	const int I2P_TUNNEL_CONNECTION_MAX_IDLE = 3600; // in seconds
 | 
			
		||||
	const int I2P_TUNNEL_DESTINATION_REQUEST_TIMEOUT = 10; // in seconds
 | 
			
		||||
	// for HTTP tunnels
 | 
			
		||||
	const char X_I2P_DEST_HASH[] = "X-I2P-DestHash"; // hash  in base64
 | 
			
		||||
	const char X_I2P_DEST_HASH[] = "X-I2P-DestHash"; // hash in base64
 | 
			
		||||
	const char X_I2P_DEST_B64[] = "X-I2P-DestB64"; // full address in base64
 | 
			
		||||
	const char X_I2P_DEST_B32[] = "X-I2P-DestB32"; // .b32.i2p address
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +43,7 @@ namespace client
 | 
			
		|||
				std::shared_ptr<const i2p::data::LeaseSet> leaseSet, int port = 0); // to I2P
 | 
			
		||||
			I2PTunnelConnection (I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
 | 
			
		||||
				std::shared_ptr<i2p::stream::Stream> stream); // to I2P using simplified API
 | 
			
		||||
			I2PTunnelConnection (I2PService * owner, std::shared_ptr<i2p::stream::Stream> stream,  std::shared_ptr<boost::asio::ip::tcp::socket> socket,
 | 
			
		||||
			I2PTunnelConnection (I2PService * owner, std::shared_ptr<i2p::stream::Stream> stream, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
 | 
			
		||||
				const boost::asio::ip::tcp::endpoint& target, bool quiet = true); // from I2P
 | 
			
		||||
			~I2PTunnelConnection ();
 | 
			
		||||
			void I2PConnect (const uint8_t * msg = nullptr, size_t len = 0);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1078,7 +1078,7 @@ namespace client
 | 
			
		|||
			auto s = shared_from_this ();
 | 
			
		||||
			newSocket->GetSocket ().async_connect (ep,
 | 
			
		||||
				[s, newSocket, stream](const boost::system::error_code& ecode)
 | 
			
		||||
			    {
 | 
			
		||||
				{
 | 
			
		||||
					if (!ecode)
 | 
			
		||||
					{
 | 
			
		||||
						s->m_Owner.AddSocket (newSocket);
 | 
			
		||||
| 
						 | 
				
			
			@ -1446,8 +1446,8 @@ namespace client
 | 
			
		|||
	void SAMBridge::SendTo (const std::vector<boost::asio::const_buffer>& bufs, const boost::asio::ip::udp::endpoint& ep)
 | 
			
		||||
	{
 | 
			
		||||
		m_DatagramSocket.send_to (bufs, ep);
 | 
			
		||||
	}	
 | 
			
		||||
		
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void SAMBridge::ReceiveDatagram ()
 | 
			
		||||
	{
 | 
			
		||||
		m_DatagramSocket.async_receive_from (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -250,7 +250,7 @@ namespace client
 | 
			
		|||
 | 
			
		||||
			/** send raw data to remote endpoint from our UDP Socket */
 | 
			
		||||
			void SendTo (const std::vector<boost::asio::const_buffer>& bufs, const boost::asio::ip::udp::endpoint& ep);
 | 
			
		||||
			
 | 
			
		||||
 | 
			
		||||
			void AddSocket(std::shared_ptr<SAMSocket> socket);
 | 
			
		||||
			void RemoveSocket(const std::shared_ptr<SAMSocket> & socket);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue