Browse Source

cleanup code (spaces, tabs)

Signed-off-by: R4SAS <r4sas@i2pmail.org>
pull/1763/head
R4SAS 3 years ago committed by R4SAS
parent
commit
6b4ffcff5a
  1. 14
      daemon/Daemon.cpp
  2. 4
      daemon/HTTPServer.cpp
  3. 4
      daemon/HTTPServer.h
  4. 53
      daemon/I2PControl.cpp
  5. 2
      daemon/UPnP.cpp
  6. 4
      daemon/UPnP.h
  7. 4
      libi2pd/Base.h
  8. 6
      libi2pd/Blinding.cpp
  9. 4
      libi2pd/Blinding.h
  10. 2
      libi2pd/Config.cpp
  11. 30
      libi2pd/Config.h
  12. 10
      libi2pd/Crypto.cpp
  13. 30
      libi2pd/Crypto.h
  14. 2
      libi2pd/Datagram.cpp
  15. 18
      libi2pd/Destination.cpp
  16. 4
      libi2pd/ECIESX25519AEADRatchetSession.h
  17. 18
      libi2pd/Ed25519.cpp
  18. 4
      libi2pd/Ed25519.h
  19. 2
      libi2pd/Elligator.cpp
  20. 12
      libi2pd/FS.h
  21. 4
      libi2pd/Family.cpp
  22. 12
      libi2pd/Garlic.cpp
  23. 6
      libi2pd/Gost.cpp
  24. 10
      libi2pd/HTTP.cpp
  25. 2
      libi2pd/HTTP.h
  26. 6
      libi2pd/I2NPProtocol.cpp
  27. 6
      libi2pd/I2NPProtocol.h
  28. 4
      libi2pd/Identity.cpp
  29. 4
      libi2pd/Identity.h
  30. 10
      libi2pd/LeaseSet.cpp
  31. 4
      libi2pd/LeaseSet.h
  32. 14
      libi2pd/Log.cpp
  33. 34
      libi2pd/Log.h
  34. 30
      libi2pd/NTCP2.cpp
  35. 16
      libi2pd/NetDb.cpp
  36. 2
      libi2pd/NetDb.hpp
  37. 2
      libi2pd/NetDbRequests.h
  38. 13
      libi2pd/Poly1305.cpp
  39. 1
      libi2pd/Poly1305.h
  40. 4
      libi2pd/Queue.h
  41. 18
      libi2pd/Reseed.cpp
  42. 72
      libi2pd/RouterContext.cpp
  43. 6
      libi2pd/RouterContext.h
  44. 124
      libi2pd/RouterInfo.cpp
  45. 30
      libi2pd/RouterInfo.h
  46. 32
      libi2pd/SSU.cpp
  47. 764
      libi2pd/SSU2.cpp
  48. 84
      libi2pd/SSU2.h
  49. 4
      libi2pd/SSUData.cpp
  50. 10
      libi2pd/SSUSession.cpp
  51. 2
      libi2pd/Signature.cpp
  52. 6
      libi2pd/Streaming.cpp
  53. 2
      libi2pd/Timestamp.cpp
  54. 2
      libi2pd/Timestamp.h
  55. 18
      libi2pd/Transports.cpp
  56. 6
      libi2pd/Tunnel.cpp
  57. 4
      libi2pd/Tunnel.h
  58. 2
      libi2pd/TunnelConfig.cpp
  59. 2
      libi2pd/TunnelConfig.h
  60. 34
      libi2pd/TunnelPool.cpp
  61. 4
      libi2pd/TunnelPool.h
  62. 2
      libi2pd/util.cpp
  63. 10
      libi2pd_client/AddressBook.cpp
  64. 4
      libi2pd_client/AddressBook.h
  65. 2
      libi2pd_client/ClientContext.cpp
  66. 26
      libi2pd_client/I2CP.cpp
  67. 2
      libi2pd_client/I2CP.h
  68. 4
      libi2pd_client/I2PTunnel.h
  69. 6
      libi2pd_client/SAM.cpp
  70. 2
      libi2pd_client/SAM.h

14
daemon/Daemon.cpp

@ -79,7 +79,7 @@ namespace util
i2p::config::Init(); i2p::config::Init();
i2p::config::ParseCmdline(argc, argv); i2p::config::ParseCmdline(argc, argv);
std::string config; i2p::config::GetOption("conf", config); std::string config; i2p::config::GetOption("conf", config);
std::string datadir; std::string datadir;
if(DaemonDataDir != "") { if(DaemonDataDir != "") {
datadir = DaemonDataDir; datadir = DaemonDataDir;
@ -111,9 +111,9 @@ namespace util
certsdir = i2p::fs::GetCertsDir(); certsdir = i2p::fs::GetCertsDir();
std::string logs = ""; i2p::config::GetOption("log", logs); std::string logs = ""; i2p::config::GetOption("log", logs);
std::string logfile = ""; i2p::config::GetOption("logfile", logfile); std::string logfile = ""; i2p::config::GetOption("logfile", logfile);
std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel); std::string loglevel = ""; i2p::config::GetOption("loglevel", loglevel);
bool logclftime; i2p::config::GetOption("logclftime", logclftime); bool logclftime; i2p::config::GetOption("logclftime", logclftime);
/* setup logging */ /* setup logging */
@ -254,17 +254,17 @@ namespace util
} }
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
if (ssu2) if (ssu2)
{ {
bool published; i2p::config::GetOption("ssu2.published", published); bool published; i2p::config::GetOption("ssu2.published", published);
if (published) if (published)
{ {
uint16_t ssu2port; i2p::config::GetOption("ssu2.port", ssu2port); uint16_t ssu2port; i2p::config::GetOption("ssu2.port", ssu2port);
i2p::context.PublishSSU2Address (ssu2port, true, ipv4, ipv6); // publish i2p::context.PublishSSU2Address (ssu2port, true, ipv4, ipv6); // publish
} }
else else
i2p::context.PublishSSU2Address (0, false, ipv4, ipv6); // unpublish i2p::context.PublishSSU2Address (0, false, ipv4, ipv6); // unpublish
} }
bool transit; i2p::config::GetOption("notransit", transit); bool transit; i2p::config::GetOption("notransit", transit);
i2p::context.SetAcceptsTunnels (!transit); i2p::context.SetAcceptsTunnels (!transit);
uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels); uint16_t transitTunnels; i2p::config::GetOption("limits.transittunnels", transitTunnels);

4
daemon/HTTPServer.cpp

@ -324,9 +324,9 @@ namespace http {
default: default:
s << tr("Unknown"); s << tr("Unknown");
} }
if (address->IsV6 ()) if (address->IsV6 ())
{ {
if (address->IsV4 ()) s << "v4"; if (address->IsV4 ()) s << "v4";
s << "v6"; s << "v6";
} }
s << "</td>\r\n"; s << "</td>\r\n";

4
daemon/HTTPServer.h

@ -98,8 +98,8 @@ namespace http
void ShowSAMSessions (std::stringstream& s); void ShowSAMSessions (std::stringstream& s);
void ShowI2PTunnels (std::stringstream& s); void ShowI2PTunnels (std::stringstream& s);
void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token); void ShowLocalDestination (std::stringstream& s, const std::string& b32, uint32_t token);
void ShowSAMSession (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); void ShowI2CPLocalDestination (std::stringstream& s, const std::string& id);
} // http } // http
} // i2p } // i2p

53
daemon/I2PControl.cpp

@ -66,29 +66,28 @@ namespace client
m_SSLContext.use_private_key_file (i2pcp_key, boost::asio::ssl::context::pem); m_SSLContext.use_private_key_file (i2pcp_key, boost::asio::ssl::context::pem);
// handlers // handlers
m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler; m_MethodHandlers["Authenticate"] = &I2PControlService::AuthenticateHandler;
m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler; m_MethodHandlers["Echo"] = &I2PControlService::EchoHandler;
m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler; m_MethodHandlers["I2PControl"] = &I2PControlService::I2PControlHandler;
m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler; m_MethodHandlers["RouterInfo"] = &I2PControlService::RouterInfoHandler;
m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler; m_MethodHandlers["RouterManager"] = &I2PControlService::RouterManagerHandler;
m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler; m_MethodHandlers["NetworkSetting"] = &I2PControlService::NetworkSettingHandler;
m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler; m_MethodHandlers["ClientServicesInfo"] = &I2PControlService::ClientServicesInfoHandler;
// I2PControl // I2PControl
m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler; m_I2PControlHandlers["i2pcontrol.password"] = &I2PControlService::PasswordHandler;
// RouterInfo // RouterInfo
m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler; m_RouterInfoHandlers["i2p.router.uptime"] = &I2PControlService::UptimeHandler;
m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler; m_RouterInfoHandlers["i2p.router.version"] = &I2PControlService::VersionHandler;
m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler; m_RouterInfoHandlers["i2p.router.status"] = &I2PControlService::StatusHandler;
m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler; m_RouterInfoHandlers["i2p.router.netdb.knownpeers"] = &I2PControlService::NetDbKnownPeersHandler;
m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler; m_RouterInfoHandlers["i2p.router.netdb.activepeers"] = &I2PControlService::NetDbActivePeersHandler;
m_RouterInfoHandlers["i2p.router.net.bw.inbound.1s"] = &I2PControlService::InboundBandwidth1S; 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.bw.outbound.1s"] = &I2PControlService::OutboundBandwidth1S;
m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler; m_RouterInfoHandlers["i2p.router.net.status"] = &I2PControlService::NetStatusHandler;
m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler; m_RouterInfoHandlers["i2p.router.net.tunnels.participating"] = &I2PControlService::TunnelsParticipatingHandler;
m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = m_RouterInfoHandlers["i2p.router.net.tunnels.successrate"] = &I2PControlService::TunnelsSuccessRateHandler;
&I2PControlService::TunnelsSuccessRateHandler;
m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes; m_RouterInfoHandlers["i2p.router.net.total.received.bytes"] = &I2PControlService::NetTotalReceivedBytes;
m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes; m_RouterInfoHandlers["i2p.router.net.total.sent.bytes"] = &I2PControlService::NetTotalSentBytes;
@ -104,10 +103,10 @@ namespace client
// ClientServicesInfo // ClientServicesInfo
m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlService::I2PTunnelInfoHandler; m_ClientServicesInfoHandlers["I2PTunnel"] = &I2PControlService::I2PTunnelInfoHandler;
m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlService::HTTPProxyInfoHandler; m_ClientServicesInfoHandlers["HTTPProxy"] = &I2PControlService::HTTPProxyInfoHandler;
m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler; m_ClientServicesInfoHandlers["SOCKS"] = &I2PControlService::SOCKSInfoHandler;
m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler; m_ClientServicesInfoHandlers["SAM"] = &I2PControlService::SAMInfoHandler;
m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler; m_ClientServicesInfoHandlers["BOB"] = &I2PControlService::BOBInfoHandler;
m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler; m_ClientServicesInfoHandlers["I2CP"] = &I2PControlService::I2CPInfoHandler;
} }
I2PControlService::~I2PControlService () I2PControlService::~I2PControlService ()
@ -168,7 +167,7 @@ namespace client
Accept (); Accept ();
if (ecode) { if (ecode) {
LogPrint (eLogError, "I2PControl: Accept error: ", ecode.message ()); LogPrint (eLogError, "I2PControl: Accept error: ", ecode.message ());
return; return;
} }
LogPrint (eLogDebug, "I2PControl: New request from ", socket->lowest_layer ().remote_endpoint ()); LogPrint (eLogDebug, "I2PControl: New request from ", socket->lowest_layer ().remote_endpoint ());
@ -290,12 +289,12 @@ namespace client
{ {
ss << "\"" << name << "\":"; ss << "\"" << name << "\":";
if (value.length () > 0) if (value.length () > 0)
{ {
if (quotes) if (quotes)
ss << "\"" << value << "\""; ss << "\"" << value << "\"";
else else
ss << value; ss << value;
} }
else else
ss << "null"; ss << "null";
} }
@ -479,7 +478,7 @@ namespace client
void I2PControlService::NetTotalSentBytes (std::ostringstream& results) 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.expires_from_now (boost::posix_time::seconds(1)); // 1 second to make sure response has been sent
m_ShutdownTimer.async_wait ( m_ShutdownTimer.async_wait (
[](const boost::system::error_code& ecode) [](const boost::system::error_code& ecode)
{ {
Daemon.running = 0; Daemon.running = 0;
}); });
} }
@ -521,7 +520,7 @@ namespace client
m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(timeout + 1)); // + 1 second m_ShutdownTimer.expires_from_now (boost::posix_time::seconds(timeout + 1)); // + 1 second
m_ShutdownTimer.async_wait ( m_ShutdownTimer.async_wait (
[](const boost::system::error_code& ecode) [](const boost::system::error_code& ecode)
{ {
Daemon.running = 0; Daemon.running = 0;
}); });
} }

2
daemon/UPnP.cpp

@ -93,7 +93,7 @@ namespace transport
#endif #endif
isError = err != UPNPDISCOVER_SUCCESS; isError = err != UPNPDISCOVER_SUCCESS;
#else // MINIUPNPC_API_VERSION >= 8 #else // MINIUPNPC_API_VERSION >= 8
err = 0; err = 0;
m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0); m_Devlist = upnpDiscover (UPNP_RESPONSE_TIMEOUT, NULL, NULL, 0);
isError = m_Devlist == NULL; isError = m_Devlist == NULL;

4
daemon/UPnP.h

@ -51,7 +51,7 @@ namespace transport
private: private:
void Discover (); void Discover ();
int CheckMapping (const char* port, const char* type); int CheckMapping (const char* port, const char* type);
void PortMapping (); void PortMapping ();
void TryPortMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address); void TryPortMapping (std::shared_ptr<i2p::data::RouterInfo::Address> address);
void CloseMapping (); void CloseMapping ();
@ -80,7 +80,7 @@ namespace transport
} }
} }
#else // USE_UPNP #else // USE_UPNP
namespace i2p { namespace i2p {
namespace transport { namespace transport {
/* class stub */ /* class stub */

4
libi2pd/Base.h

@ -24,8 +24,8 @@ namespace data {
size_t ByteStreamToBase32 (const uint8_t * InBuf, size_t len, char * outBuf, size_t outLen); 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); size_t Base64EncodingBufferSize(const size_t input_size);
std::string ToBase64Standard (const std::string& in); // using standard table, for Proxy-Authorization std::string ToBase64Standard (const std::string& in); // using standard table, for Proxy-Authorization

6
libi2pd/Blinding.cpp

@ -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) 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 // blind is BlindEncodedPublicKeyECDSA or BlindEncodedPrivateKeyECDSA
{ {
size_t publicKeyLength = 0; size_t publicKeyLength = 0;
EC_GROUP * group = nullptr; EC_GROUP * group = nullptr;
switch (sigType) switch (sigType)
{ {
@ -147,8 +147,8 @@ namespace data
memcpy (m_PublicKey.data (), identity->GetSigningPublicKeyBuffer (), len); memcpy (m_PublicKey.data (), identity->GetSigningPublicKeyBuffer (), len);
m_SigType = identity->GetSigningKeyType (); m_SigType = identity->GetSigningKeyType ();
if (m_SigType == i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519) if (m_SigType == i2p::data::SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519)
m_BlindedSigType = i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519; // 7 -> 11 m_BlindedSigType = i2p::data::SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519; // 7 -> 11
else else
m_BlindedSigType = m_SigType; m_BlindedSigType = m_SigType;
} }

4
libi2pd/Blinding.h

@ -28,8 +28,8 @@ namespace data
const uint8_t * GetPublicKey () const { return m_PublicKey.data (); }; const uint8_t * GetPublicKey () const { return m_PublicKey.data (); };
size_t GetPublicKeyLen () const { return m_PublicKey.size (); }; size_t GetPublicKeyLen () const { return m_PublicKey.size (); };
SigningKeyType GetSigType () const { return m_SigType; }; SigningKeyType GetSigType () const { return m_SigType; };
SigningKeyType GetBlindedSigType () const { return m_BlindedSigType; }; SigningKeyType GetBlindedSigType () const { return m_BlindedSigType; };
bool IsValid () const { return GetSigType (); }; // signature type 0 means invalid 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 void GetSubcredential (const uint8_t * blinded, size_t len, uint8_t * subcredential) const; // 32 bytes

2
libi2pd/Config.cpp

@ -277,7 +277,7 @@ namespace config {
("ssu2.published", value<bool>()->default_value(false), "Publish SSU2 (default: disabled)") ("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)") ("ssu2.port", value<uint16_t>()->default_value(0), "Port to listen for incoming SSU2 packets (default: auto)")
; ;
options_description nettime("Time sync options"); options_description nettime("Time sync options");
nettime.add_options() nettime.add_options()
("nettime.enabled", value<bool>()->default_value(false), "Disable time sync (default: disabled)") ("nettime.enabled", value<bool>()->default_value(false), "Disable time sync (default: disabled)")

30
libi2pd/Config.h

@ -29,16 +29,16 @@ namespace config {
extern boost::program_options::variables_map m_Options; 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. * Should be called before any Parse* functions.
*/ */
void Init(); void Init();
/** /**
* @brief Parse cmdline parameters, and show help if requested * @brief Parse cmdline parameters, and show help if requested
* @param argc Cmdline arguments count, should be passed from main(). * @param argc Cmdline arguments count, should be passed from main().
* @param argv Cmdline parameters array, 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 * If --help is given in parameters, shows its list with description
* and terminates the program with exitcode 0. * and terminates the program with exitcode 0.
@ -52,8 +52,8 @@ namespace config {
void ParseCmdline(int argc, char* argv[], bool ignoreUnknown = false); void ParseCmdline(int argc, char* argv[], bool ignoreUnknown = false);
/** /**
* @brief Load and parse given config file * @brief Load and parse given config file
* @param path Path to config file * @param path Path to config file
* *
* If error occurred when opening file path is points to, * If error occurred when opening file path is points to,
* we show the error message and terminate program. * we show the error message and terminate program.
@ -67,14 +67,14 @@ namespace config {
void ParseConfig(const std::string& path); 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(); void Finalize();
/** /**
* @brief Accessor to parameters by name * @brief Accessor to parameters by name
* @param name Name of the requested parameter * @param name Name of the requested parameter
* @param value Variable where to store option * @param value Variable where to store option
* @return this function returns false if parameter not found * @return this function returns false if parameter not found
* *
* Example: uint16_t port; GetOption("sam.port", port); * Example: uint16_t port; GetOption("sam.port", port);
@ -98,9 +98,9 @@ namespace config {
bool GetOptionAsAny(const std::string& name, boost::any& value); bool GetOptionAsAny(const std::string& name, boost::any& value);
/** /**
* @brief Set value of given parameter * @brief Set value of given parameter
* @param name Name of settable parameter * @param name Name of settable parameter
* @param value New parameter value * @param value New parameter value
* @return true if value set up successful, false otherwise * @return true if value set up successful, false otherwise
* *
* Example: uint16_t port = 2827; SetOption("bob.port", port); * Example: uint16_t port = 2827; SetOption("bob.port", port);
@ -116,8 +116,8 @@ namespace config {
} }
/** /**
* @brief Check is value explicitly given or default * @brief Check is value explicitly given or default
* @param name Name of checked parameter * @param name Name of checked parameter
* @return true if value set to default, false otherwise * @return true if value set to default, false otherwise
*/ */
bool IsDefault(const char *name); bool IsDefault(const char *name);

10
libi2pd/Crypto.cpp

@ -1313,8 +1313,8 @@ namespace crypto
for (const auto& it: bufs) for (const auto& it: bufs)
SHA256_Update (&ctx, it.first, it.second); SHA256_Update (&ctx, it.first, it.second);
SHA256_Final (m_H, &ctx); SHA256_Final (m_H, &ctx);
} }
void NoiseSymmetricState::MixKey (const uint8_t * sharedSecret) void NoiseSymmetricState::MixKey (const uint8_t * sharedSecret)
{ {
HKDF (m_CK, sharedSecret, 32, "", m_CK); HKDF (m_CK, sharedSecret, 32, "", m_CK);
@ -1330,7 +1330,7 @@ namespace crypto
SHA256_Init (&ctx); SHA256_Init (&ctx);
SHA256_Update (&ctx, hh, 32); SHA256_Update (&ctx, hh, 32);
SHA256_Update (&ctx, pub, 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) void InitNoiseNState (NoiseSymmetricState& state, const uint8_t * pub)
@ -1368,12 +1368,12 @@ namespace crypto
}; // SHA256 ("Noise_XKchaobfse+hs1+hs2+hs3_25519_ChaChaPoly_SHA256") }; // SHA256 ("Noise_XKchaobfse+hs1+hs2+hs3_25519_ChaChaPoly_SHA256")
static const uint8_t hh[32] = 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 0xa7, 0xcf, 0x6d, 0xbf, 0xbd, 0x52, 0x5e, 0xa5, 0xb5, 0x79, 0x1c, 0x47, 0xb3, 0x5e, 0xbc, 0x33
}; // SHA256 (protocolNameHash) }; // SHA256 (protocolNameHash)
InitNoiseState (state, protocolNameHash, hh, pub); InitNoiseState (state, protocolNameHash, hh, pub);
} }
void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub) void InitNoiseIKState (NoiseSymmetricState& state, const uint8_t * pub)
{ {
static const uint8_t protocolNameHash[32] = static const uint8_t protocolNameHash[32] =

30
libi2pd/Crypto.h

@ -30,24 +30,24 @@
// recognize openssl version and features // recognize openssl version and features
#if (defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER >= 0x3050200fL)) // LibreSSL 3.5.2 and above #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 #elif ((OPENSSL_VERSION_NUMBER < 0x010100000) || defined(LIBRESSL_VERSION_NUMBER)) // 1.0.2 and below or LibreSSL
# define LEGACY_OPENSSL 1 # define LEGACY_OPENSSL 1
# define X509_getm_notBefore X509_get_notBefore # define X509_getm_notBefore X509_get_notBefore
# define X509_getm_notAfter X509_get_notAfter # define X509_getm_notAfter X509_get_notAfter
#else #else
# define LEGACY_OPENSSL 0 # define LEGACY_OPENSSL 0
# if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1 # if (OPENSSL_VERSION_NUMBER >= 0x010101000) // 1.1.1
# define OPENSSL_HKDF 1 # define OPENSSL_HKDF 1
# define OPENSSL_EDDSA 1 # define OPENSSL_EDDSA 1
# define OPENSSL_X25519 1 # define OPENSSL_X25519 1
# if (OPENSSL_VERSION_NUMBER != 0x030000000) // 3.0.0, regression in SipHash # if (OPENSSL_VERSION_NUMBER != 0x030000000) // 3.0.0, regression in SipHash
# define OPENSSL_SIPHASH 1 # define OPENSSL_SIPHASH 1
# endif # endif
# endif # endif
# if !defined OPENSSL_NO_CHACHA && !defined OPENSSL_NO_POLY1305 // some builds might not include them # if !defined OPENSSL_NO_CHACHA && !defined OPENSSL_NO_POLY1305 // some builds might not include them
# define OPENSSL_AEAD_CHACHA20_POLY1305 1 # define OPENSSL_AEAD_CHACHA20_POLY1305 1
# endif # endif
#endif #endif
namespace i2p 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->p) BN_free (dh->p);
if (dh->q) BN_free (dh->q); if (dh->q) BN_free (dh->q);
if (dh->g) BN_free (dh->g); 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) inline int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
{ {

2
libi2pd/Datagram.cpp

@ -324,7 +324,7 @@ namespace datagram
auto path = m_RoutingSession->GetSharedRoutingPath(); auto path = m_RoutingSession->GetSharedRoutingPath();
if (path && m_RoutingSession->IsRatchets () && if (path && m_RoutingSession->IsRatchets () &&
m_LastUse > m_RoutingSession->GetLastActivityTimestamp ()*1000 + DATAGRAM_SESSION_PATH_TIMEOUT) m_LastUse > m_RoutingSession->GetLastActivityTimestamp ()*1000 + DATAGRAM_SESSION_PATH_TIMEOUT)
{ {
m_RoutingSession->SetSharedRoutingPath (nullptr); m_RoutingSession->SetSharedRoutingPath (nullptr);
path = nullptr; path = nullptr;

18
libi2pd/Destination.cpp

@ -350,8 +350,8 @@ namespace client
{ {
s->AddECIESx25519Key (data.k, data.t); s->AddECIESx25519Key (data.k, data.t);
}); });
} }
void LeaseSetDestination::ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg) void LeaseSetDestination::ProcessGarlicMessage (std::shared_ptr<I2NPMessage> msg)
{ {
m_Service.post (std::bind (&LeaseSetDestination::HandleGarlicMessage, shared_from_this (), 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); std::lock_guard<std::mutex> lock(m_RemoteLeaseSetsMutex);
auto it = m_RemoteLeaseSets.find (key); auto it = m_RemoteLeaseSets.find (key);
if (it != m_RemoteLeaseSets.end () && 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; leaseSet = it->second;
if (leaseSet->IsNewer (buf + offset, len - offset)) if (leaseSet->IsNewer (buf + offset, len - offset))
@ -587,7 +587,7 @@ namespace client
LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found"); LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found");
m_ExcludedFloodfills.clear (); m_ExcludedFloodfills.clear ();
return; return;
} }
auto outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false)); auto outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false));
auto inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true)); auto inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true));
if (!outbound || !inbound) if (!outbound || !inbound)
@ -599,22 +599,22 @@ namespace client
{ {
outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false)); outbound = m_Pool->GetNextOutboundTunnel (nullptr, floodfill->GetCompatibleTransports (false));
if (outbound) if (outbound)
{ {
inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true)); inbound = m_Pool->GetNextInboundTunnel (nullptr, floodfill->GetCompatibleTransports (true));
if (!inbound) if (!inbound)
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels"); LogPrint (eLogError, "Destination: Can't publish LeaseSet. No inbound tunnels");
} }
else else
LogPrint (eLogError, "Destination: Can't publish LeaseSet. No outbound tunnels"); LogPrint (eLogError, "Destination: Can't publish LeaseSet. No outbound tunnels");
} }
else else
LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found"); LogPrint (eLogError, "Destination: Can't publish LeaseSet, no more floodfills found");
if (!floodfill || !outbound || !inbound) if (!floodfill || !outbound || !inbound)
{ {
m_ExcludedFloodfills.clear (); m_ExcludedFloodfills.clear ();
return; return;
} }
} }
m_ExcludedFloodfills.insert (floodfill->GetIdentHash ()); m_ExcludedFloodfills.insert (floodfill->GetIdentHash ());
LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ()); LogPrint (eLogDebug, "Destination: Publish LeaseSet of ", GetIdentHash ().ToBase32 ());
RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4); RAND_bytes ((uint8_t *)&m_PublishReplyToken, 4);

4
libi2pd/ECIESX25519AEADRatchetSession.h

@ -212,7 +212,7 @@ namespace garlic
uint8_t m_NSREncodedKey[32], m_NSRH[32], m_NSRKey[32]; // new session reply, for incoming only 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; std::shared_ptr<i2p::crypto::X25519Keys> m_EphemeralKeys;
SessionState m_State = eSessionStateNew; 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 m_LastSentTimestamp = 0; // in milliseconds
std::shared_ptr<RatchetTagSet> m_SendTagset, m_NSRSendTagset; std::shared_ptr<RatchetTagSet> m_SendTagset, m_NSRSendTagset;
std::unique_ptr<i2p::data::IdentHash> m_Destination;// TODO: might not need it 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 (); return m_Destination ? *m_Destination : i2p::data::IdentHash ();
} }
}; };
// single session for all incoming messages // single session for all incoming messages
class RouterIncomingRatchetSession: public ECIESX25519AEADRatchetSession class RouterIncomingRatchetSession: public ECIESX25519AEADRatchetSession

18
libi2pd/Ed25519.cpp

@ -33,7 +33,7 @@ namespace crypto
BN_add (l, l, tmp); BN_add (l, l, tmp);
BN_sub_word (two_252_2, 2); // 2^252 - 2 BN_sub_word (two_252_2, 2); // 2^252 - 2
// -121665*inv(121666) // -121665*inv(121666)
d = BN_new (); d = BN_new ();
BN_set_word (tmp, 121666); BN_set_word (tmp, 121666);
BN_mod_inverse (tmp, tmp, q, ctx); BN_mod_inverse (tmp, tmp, q, ctx);
@ -61,7 +61,7 @@ namespace crypto
BN_mod (By, By, q, ctx); // % q BN_mod (By, By, q, ctx); // % q
// precalculate Bi256 table // precalculate Bi256 table
Bi256Carry = { Bx, By }; // B Bi256Carry = { Bx, By }; // B
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++)
{ {
Bi256[i][0] = Bi256Carry; // first point 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 (!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); } if (!t2) { t2 = BN_CTX_get (ctx); BN_mul (t2, p2.x, p2.y, ctx); }
BN_mul (t3, t1, t2, 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) if (p1.z)
{ {
@ -264,9 +264,9 @@ namespace crypto
else else
{ {
BN_mul (t2, p.x, p.y, ctx); // t = x*y 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) if (p.z)
BN_sqr (z2, p.z, ctx); // z2 = D = z^2 BN_sqr (z2, p.z, ctx); // z2 = D = z^2
else else
@ -349,7 +349,7 @@ namespace crypto
BN_mod_inverse (y, p.z, q, ctx); BN_mod_inverse (y, p.z, q, ctx);
BN_mod_mul (x, p.x, y, q, ctx); // x = x/z BN_mod_mul (x, p.x, y, q, ctx); // x = x/z
BN_mod_mul (y, p.y, y, q, ctx); // y = y/z BN_mod_mul (y, p.y, y, q, ctx); // y = y/z
return EDDSAPoint{x, y}; return EDDSAPoint{x, y};
} }
else else
return EDDSAPoint{BN_dup (p.x), BN_dup (p.y)}; return EDDSAPoint{BN_dup (p.x), BN_dup (p.y)};
@ -506,13 +506,13 @@ namespace crypto
std::swap (z2, z3); std::swap (z2, z3);
} }
BN_mod_inverse (z2, z2, q, ctx); 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_mod_mul(res, x2, z2, q, ctx);
BN_CTX_end (ctx); BN_CTX_end (ctx);
return res; 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); BIGNUM * p1 = DecodeBN<32> (p);
uint8_t k[32]; uint8_t k[32];
@ -524,7 +524,7 @@ namespace crypto
BN_free (p1); BN_free (n); BN_free (q1); 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); BIGNUM *p1 = BN_new (); BN_set_word (p1, 9);
uint8_t k[32]; uint8_t k[32];

4
libi2pd/Ed25519.h

@ -85,8 +85,8 @@ namespace crypto
EDDSAPoint DecodePublicKey (const uint8_t * buf, BN_CTX * ctx) const; EDDSAPoint DecodePublicKey (const uint8_t * buf, BN_CTX * ctx) const;
void EncodePublicKey (const EDDSAPoint& publicKey, uint8_t * buf, BN_CTX * ctx) const; void EncodePublicKey (const EDDSAPoint& publicKey, uint8_t * buf, BN_CTX * ctx) const;
#if !OPENSSL_X25519 #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 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 ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const;
#endif #endif
void BlindPublicKey (const uint8_t * pub, const uint8_t * seed, uint8_t * blinded); // for encrypted LeaseSet2, pub - 32, seed - 64, blinded - 32 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 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

2
libi2pd/Elligator.cpp

@ -189,7 +189,7 @@ namespace crypto
// assume a < p, so don't check for a % p = 0, but a = 0 only // assume a < p, so don't check for a % p = 0, but a = 0 only
if (BN_is_zero(a)) return 0; if (BN_is_zero(a)) return 0;
BIGNUM * r = BN_CTX_get (ctx); 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)) if (BN_is_word(r, 1))
return 1; return 1;
else if (BN_is_zero(r)) else if (BN_is_zero(r))

12
libi2pd/FS.h

@ -83,8 +83,8 @@ namespace fs {
/** /**
* @brief Set datadir either from cmdline option or using autodetection * @brief Set datadir either from cmdline option or using autodetection
* @param cmdline_param Value of cmdline parameter --datadir=<something> * @param cmdline_param Value of cmdline parameter --datadir=<something>
* @param isService Value of cmdline parameter --service * @param isService Value of cmdline parameter --service
* *
* Examples of autodetected paths: * Examples of autodetected paths:
* *
@ -93,11 +93,11 @@ namespace fs {
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/ * Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/
* Unix: /var/lib/i2pd/ (system=1) >> ~/.i2pd/ or /tmp/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 * @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: * Examples of autodetected paths:
* *
@ -106,7 +106,7 @@ namespace fs {
* Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/certificates * Mac: /Library/Application Support/i2pd/ or ~/Library/Application Support/i2pd/certificates
* Unix: /var/lib/i2pd/certificates (system=1) >> ~/.i2pd/ or /tmp/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 * @brief Create subdirectories inside datadir
@ -115,7 +115,7 @@ namespace fs {
/** /**
* @brief Get list of files in directory * @brief Get list of files in directory
* @param path Path to directory * @param path Path to directory
* @param files Vector to store found files * @param files Vector to store found files
* @return true on success and false if directory not exists * @return true on success and false if directory not exists
*/ */

4
libi2pd/Family.cpp

@ -148,8 +148,8 @@ namespace data
if (it != m_SigningKeys.end ()) if (it != m_SigningKeys.end ())
return it->second.second; return it->second.second;
return 0; return 0;
} }
std::string CreateFamilySignature (const std::string& family, const IdentHash& ident) std::string CreateFamilySignature (const std::string& family, const IdentHash& ident)
{ {
auto filename = i2p::fs::DataDirPath("family", (family + ".key")); auto filename = i2p::fs::DataDirPath("family", (family + ".key"));

12
libi2pd/Garlic.cpp

@ -293,14 +293,14 @@ namespace garlic
size_t size = 0; size_t size = 0;
if (isDestination) if (isDestination)
{ {
buf[size] = eGarlicDeliveryTypeDestination << 5;// delivery instructions flag destination buf[size] = eGarlicDeliveryTypeDestination << 5;// delivery instructions flag destination
size++; size++;
memcpy (buf + size, m_Destination->GetIdentHash (), 32); memcpy (buf + size, m_Destination->GetIdentHash (), 32);
size += 32; size += 32;
} }
else else
{ {
buf[size] = 0;// delivery instructions flag local buf[size] = 0;// delivery instructions flag local
size++; size++;
} }
@ -487,8 +487,8 @@ namespace garlic
void GarlicDestination::SubmitECIESx25519Key (const uint8_t * key, uint64_t tag) void GarlicDestination::SubmitECIESx25519Key (const uint8_t * key, uint64_t tag)
{ {
AddECIESx25519Key (key, tag); AddECIESx25519Key (key, tag);
} }
void GarlicDestination::HandleGarlicMessage (std::shared_ptr<I2NPMessage> msg) void GarlicDestination::HandleGarlicMessage (std::shared_ptr<I2NPMessage> msg)
{ {
uint8_t * buf = msg->GetPayload (); uint8_t * buf = msg->GetPayload ();
@ -744,7 +744,7 @@ namespace garlic
LogPrint (eLogError, "Garlic: Message is too short"); LogPrint (eLogError, "Garlic: Message is too short");
break; break;
} }
buf += GetI2NPMessageLength (buf, len - offset); // I2NP buf += GetI2NPMessageLength (buf, len - offset); // I2NP
buf += 4; // CloveID buf += 4; // CloveID
buf += 8; // Date buf += 8; // Date
buf += 3; // Certificate buf += 3; // Certificate
@ -1024,7 +1024,7 @@ namespace garlic
uint32_t ts = i2p::util::GetSecondsSinceEpoch (); uint32_t ts = i2p::util::GetSecondsSinceEpoch ();
for (auto it: files) for (auto it: files)
if (ts >= i2p::fs::GetLastUpdateTime (it) + INCOMING_TAGS_EXPIRATION_TIMEOUT) 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) void GarlicDestination::HandleECIESx25519GarlicClove (const uint8_t * buf, size_t len)

6
libi2pd/Gost.cpp

@ -96,7 +96,7 @@ namespace crypto
EC_POINT * C = EC_POINT_new (m_Group); EC_POINT * C = EC_POINT_new (m_Group);
EC_POINT_mul (m_Group, C, z1, pub, z2, ctx); // z1*P + z2*pub EC_POINT_mul (m_Group, C, z1, pub, z2, ctx); // z1*P + z2*pub
BIGNUM * x = BN_CTX_get (ctx); BIGNUM * x = BN_CTX_get (ctx);
GetXY (C, x, nullptr); // Cx GetXY (C, x, nullptr); // Cx
BN_mod (x, x, q, ctx); // Cx % q BN_mod (x, x, q, ctx); // Cx % q
bool ret = !BN_cmp (x, r); // Cx = r ? bool ret = !BN_cmp (x, r); // Cx = r ?
EC_POINT_free (C); EC_POINT_free (C);
@ -111,8 +111,8 @@ namespace crypto
BN_CTX * ctx = BN_CTX_new (); BN_CTX * ctx = BN_CTX_new ();
BN_CTX_start (ctx); BN_CTX_start (ctx);
EC_POINT * C = EC_POINT_new (m_Group); // C = k*P = (rx, ry) EC_POINT * C = EC_POINT_new (m_Group); // C = k*P = (rx, ry)
EC_POINT * Q = nullptr; EC_POINT * Q = nullptr;
if (EC_POINT_set_compressed_coordinates_GFp (m_Group, C, r, isNegativeY ? 1 : 0, ctx)) 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 * S = EC_POINT_new (m_Group); // S = s*P
EC_POINT_mul (m_Group, S, s, nullptr, nullptr, ctx); EC_POINT_mul (m_Group, S, s, nullptr, nullptr, ctx);

10
libi2pd/HTTP.cpp

@ -279,7 +279,7 @@ namespace http
method = tokens[0]; method = tokens[0];
uri = tokens[1]; uri = tokens[1];
version = tokens[2]; version = tokens[2];
expect = HEADER_LINE; expect = HEADER_LINE;
} }
else else
{ {
@ -363,7 +363,7 @@ namespace http
return false; /* no header */ return false; /* no header */
if (it->second.find("gzip") != std::string::npos) if (it->second.find("gzip") != std::string::npos)
return true; /* gotcha! */ 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 true;
return false; return false;
} }
@ -409,7 +409,7 @@ namespace http
/* all ok */ /* all ok */
version = tokens[0]; version = tokens[0];
status = tokens[2]; status = tokens[2];
expect = HEADER_LINE; expect = HEADER_LINE;
} else { } else {
std::string line = str.substr(pos, eol - pos); std::string line = str.substr(pos, eol - pos);
auto p = parse_header_line(line); auto p = parse_header_line(line);
@ -460,7 +460,7 @@ namespace http
case 304: ptr = "Not Modified"; break; case 304: ptr = "Not Modified"; break;
case 307: ptr = "Temporary Redirect"; break; case 307: ptr = "Temporary Redirect"; break;
/* client error */ /* client error */
case 400: ptr = "Bad Request"; break; case 400: ptr = "Bad Request"; break;
case 401: ptr = "Unauthorized"; break; case 401: ptr = "Unauthorized"; break;
case 403: ptr = "Forbidden"; break; case 403: ptr = "Forbidden"; break;
case 404: ptr = "Not Found"; break; case 404: ptr = "Not Found"; break;
@ -471,7 +471,7 @@ namespace http
case 502: ptr = "Bad Gateway"; break; case 502: ptr = "Bad Gateway"; break;
case 503: ptr = "Not Implemented"; break; case 503: ptr = "Not Implemented"; break;
case 504: ptr = "Gateway Timeout"; break; case 504: ptr = "Gateway Timeout"; break;
default: ptr = "Unknown Status"; break; default: ptr = "Unknown Status"; break;
} }
return ptr; return ptr;
} }

2
libi2pd/HTTP.h

@ -161,7 +161,7 @@ namespace http
/** /**
* @brief Merge HTTP response content with Transfer-Encoding: chunked * @brief Merge HTTP response content with Transfer-Encoding: chunked
* @param in Input stream * @param in Input stream
* @param out Output stream * @param out Output stream
* @return true on success, false otherwise * @return true on success, false otherwise
*/ */

6
libi2pd/I2NPProtocol.cpp

@ -171,7 +171,7 @@ namespace i2p
std::shared_ptr<I2NPMessage> CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest, std::shared_ptr<I2NPMessage> CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest,
const std::set<i2p::data::IdentHash>& excludedFloodfills, const std::set<i2p::data::IdentHash>& excludedFloodfills,
std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel, const uint8_t * replyKey, 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 (); int cnt = excludedFloodfills.size ();
auto m = cnt > 7 ? NewI2NPMessage () : NewI2NPShortMessage (); 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, 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 if (!router) // we send own RouterInfo
router = context.GetSharedRouterInfo (); router = context.GetSharedRouterInfo ();
@ -629,7 +629,7 @@ namespace i2p
// we send it to reply tunnel // we send it to reply tunnel
transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET, transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET,
CreateTunnelGatewayMsg (bufbe32toh (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_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 else
{ {

6
libi2pd/I2NPProtocol.h

@ -150,7 +150,7 @@ namespace tunnel
std::shared_ptr<i2p::tunnel::InboundTunnel> from; std::shared_ptr<i2p::tunnel::InboundTunnel> from;
I2NPMessage (): buf (nullptr),len (I2NP_HEADER_SIZE + 2), 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 // header accessors
uint8_t * GetHeader () { return GetBuffer (); }; uint8_t * GetHeader () { return GetBuffer (); };
@ -274,8 +274,8 @@ namespace tunnel
uint32_t replyTunnelID, bool exploratory = false, std::set<i2p::data::IdentHash> * excludedPeers = nullptr); uint32_t replyTunnelID, bool exploratory = false, std::set<i2p::data::IdentHash> * excludedPeers = nullptr);
std::shared_ptr<I2NPMessage> CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest, std::shared_ptr<I2NPMessage> CreateLeaseSetDatabaseLookupMsg (const i2p::data::IdentHash& dest,
const std::set<i2p::data::IdentHash>& excludedFloodfills, const std::set<i2p::data::IdentHash>& excludedFloodfills,
std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel, std::shared_ptr<const i2p::tunnel::InboundTunnel> replyTunnel,
const uint8_t * replyKey, const uint8_t * replyTag, bool replyECIES = false); 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> 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); 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);

4
libi2pd/Identity.cpp

@ -64,7 +64,7 @@ namespace data
{ {
case SIGNING_KEY_TYPE_ECDSA_SHA256_P256: 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); RAND_bytes (m_StandardIdentity.signingKey, padding);
memcpy (m_StandardIdentity.signingKey + padding, signingKey, i2p::crypto::ECDSAP256_KEY_LENGTH); memcpy (m_StandardIdentity.signingKey + padding, signingKey, i2p::crypto::ECDSAP256_KEY_LENGTH);
break; break;
@ -788,7 +788,7 @@ namespace data
keys.m_OfflineSignature.resize (pubKeyLen + m_Public->GetSignatureLen () + 6); keys.m_OfflineSignature.resize (pubKeyLen + m_Public->GetSignatureLen () + 6);
htobe32buf (keys.m_OfflineSignature.data (), expires); // expires htobe32buf (keys.m_OfflineSignature.data (), expires); // expires
htobe16buf (keys.m_OfflineSignature.data () + 4, type); // type 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 Sign (keys.m_OfflineSignature.data (), pubKeyLen + 6, keys.m_OfflineSignature.data () + 6 + pubKeyLen); // signature
// recreate signer // recreate signer
keys.m_Signer = nullptr; keys.m_Signer = nullptr;

4
libi2pd/Identity.h

@ -120,7 +120,7 @@ namespace data
CryptoKeyType GetCryptoKeyType () const; CryptoKeyType GetCryptoKeyType () const;
void DropVerifier () const; // to save memory 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); void RecalculateIdentHash(uint8_t * buff=nullptr);
static i2p::crypto::Verifier * CreateVerifier (SigningKeyType keyType); static i2p::crypto::Verifier * CreateVerifier (SigningKeyType keyType);
@ -222,7 +222,7 @@ namespace data
RoutingDestination () {}; RoutingDestination () {};
virtual ~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 void Encrypt (const uint8_t * data, uint8_t * encrypted) const = 0; // encrypt data for
virtual bool IsDestination () const = 0; // for garlic virtual bool IsDestination () const = 0; // for garlic

10
libi2pd/LeaseSet.cpp

@ -582,7 +582,7 @@ namespace data
// helper for ExtractClientAuthData // helper for ExtractClientAuthData
static inline bool GetAuthCookie (const uint8_t * authClients, int numClients, const uint8_t * okm, uint8_t * authCookie) 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++) for (int i = 0; i < numClients; i++)
{ {
if (!memcmp (okm + 44, authClients + i*40, 8)) // clientID_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 const uint8_t * ephemeralPublicKey = buf + offset; offset += 32; // ephemeralPublicKey
uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients 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) if (offset > len)
{ {
LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in DH auth data"); 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 const uint8_t * authSalt = buf + offset; offset += 32; // authSalt
uint16_t numClients = bufbe16toh (buf + offset); offset += 2; // clients 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) if (offset > len)
{ {
LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in PSK auth data"); LogPrint (eLogError, "LeaseSet2: Too many clients ", numClients, " in PSK auth data");
@ -737,7 +737,7 @@ namespace data
htobe64buf (m_Buffer + offset, ts); htobe64buf (m_Buffer + offset, ts);
offset += 8; // end date 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): 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 ek.GenerateKeys (); // esk and epk
memcpy (authData, ek.GetPublicKey (), 32); authData += 32; // epk memcpy (authData, ek.GetPublicKey (), 32); authData += 32; // epk
htobe16buf (authData, authKeys->size ()); authData += 2; // num clients 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); memcpy (authInput + 64, subcredential, 36);
for (auto& it: *authKeys) for (auto& it: *authKeys)
{ {

4
libi2pd/LeaseSet.h

@ -128,8 +128,8 @@ namespace data
}; };
/** /**
validate lease set buffer signature and extract expiration timestamp * validate lease set buffer signature and extract expiration timestamp
@returns true if the leaseset is well formed and signature is valid * @returns true if the leaseset is well formed and signature is valid
*/ */
bool LeaseSetBufferValidate(const uint8_t * ptr, size_t sz, uint64_t & expires); bool LeaseSetBufferValidate(const uint8_t * ptr, size_t sz, uint64_t & expires);

14
libi2pd/Log.cpp

@ -46,7 +46,7 @@ namespace log {
#ifndef _WIN32 #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 * @return syslog priority LOG_*, as defined in syslog.h
*/ */
static inline int GetSyslogPrio (enum LogLevel l) { static inline int GetSyslogPrio (enum LogLevel l) {
@ -113,11 +113,11 @@ namespace log {
std::string str_tolower(std::string s) { std::string str_tolower(std::string s) {
std::transform(s.begin(), s.end(), s.begin(), std::transform(s.begin(), s.end(), s.begin(),
// static_cast<int(*)(int)>(std::tolower) // wrong // static_cast<int(*)(int)>(std::tolower) // wrong
// [](int c){ return std::tolower(c); } // wrong // [](int c){ return std::tolower(c); } // wrong
// [](char c){ return std::tolower(c); } // wrong // [](char c){ return std::tolower(c); } // wrong
[](unsigned char c){ return std::tolower(c); } // correct [](unsigned char c){ return std::tolower(c); } // correct
); );
return s; return s;
} }
@ -170,7 +170,7 @@ namespace log {
break; break;
case eLogStdout: case eLogStdout:
default: default:
std::cout << TimeAsString(msg->timestamp) std::cout << TimeAsString(msg->timestamp)
<< "@" << short_tid << "@" << short_tid
<< "/" << LogMsgColors[msg->level] << g_LogLevelStr[msg->level] << LogMsgColors[eNumLogLevels] << "/" << LogMsgColors[msg->level] << g_LogLevelStr[msg->level] << LogMsgColors[eNumLogLevels]
<< " - " << msg->text << std::endl; << " - " << msg->text << std::endl;

34
libi2pd/Log.h

@ -52,7 +52,7 @@ namespace log {
{ {
private: private:
enum LogType m_Destination; enum LogType m_Destination;
enum LogLevel m_MinLevel; enum LogLevel m_MinLevel;
std::shared_ptr<std::ostream> m_LogStream; std::shared_ptr<std::ostream> m_LogStream;
std::string m_Logfile; std::string m_Logfile;
@ -75,7 +75,7 @@ namespace log {
/** /**
* @brief Makes formatted string from unix timestamp * @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 * This function internally caches the result for last provided value
*/ */
@ -86,52 +86,52 @@ namespace log {
Log (); Log ();
~Log (); ~Log ();
LogType GetLogType () { return m_Destination; }; LogType GetLogType () { return m_Destination; };
LogLevel GetLogLevel () { return m_MinLevel; }; LogLevel GetLogLevel () { return m_MinLevel; };
void Start (); void Start ();
void Stop (); void Stop ();
/** /**
* @brief Sets minimal allowed level for log messages * @brief Sets minimal allowed level for log messages
* @param level String with wanted minimal msg level * @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 * @brief Sets log destination to logfile
* @param path Path to logfile * @param path Path to logfile
*/ */
void SendTo (const std::string &path); void SendTo (const std::string &path);
/** /**
* @brief Sets log destination to given output stream * @brief Sets log destination to given output stream
* @param os Output stream * @param os Output stream
*/ */
void SendTo (std::shared_ptr<std::ostream> os); void SendTo (std::shared_ptr<std::ostream> os);
/** /**
* @brief Sets format for timestamps in log * @brief Sets format for timestamps in log
* @param format String with timestamp format * @param format String with timestamp format
*/ */
void SetTimeFormat (std::string format) { m_TimeFormat = format; }; void SetTimeFormat (std::string format) { m_TimeFormat = format; };
#ifndef _WIN32 #ifndef _WIN32
/** /**
* @brief Sets log destination to syslog * @brief Sets log destination to syslog
* @param name Wanted program name * @param name Wanted program name
* @param facility Wanted log category * @param facility Wanted log category
*/ */
void SendTo (const char *name, int facility); void SendTo (const char *name, int facility);
#endif #endif
/** /**
* @brief Format log message and write to output stream/syslog * @brief Format log message and write to output stream/syslog
* @param msg Pointer to processed message * @param msg Pointer to processed message
*/ */
void Append(std::shared_ptr<i2p::log::LogMsg> &); void Append(std::shared_ptr<i2p::log::LogMsg> &);
/** @brief Reopen log file */ /** @brief Reopen log file */
void Reopen(); void Reopen();
}; };
@ -144,8 +144,8 @@ namespace log {
*/ */
struct LogMsg { struct LogMsg {
std::time_t timestamp; std::time_t timestamp;
std::string text; /**< message text as single string */ std::string text; /**< message text as single string */
LogLevel level; /**< message level */ LogLevel level; /**< message level */
std::thread::id tid; /**< id of thread that generated message */ 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) {} 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(); Log & Logger();
typedef std::function<void (const std::string&)> ThrowFunction; typedef std::function<void (const std::string&)> ThrowFunction;
ThrowFunction GetThrowFunction (); ThrowFunction GetThrowFunction ();
void SetThrowFunction (ThrowFunction f); void SetThrowFunction (ThrowFunction f);
} // log } // log

30
libi2pd/NTCP2.cpp

@ -66,7 +66,7 @@ namespace transport
{ {
MixHash (sessionRequest + 32, 32); // encrypted payload MixHash (sessionRequest + 32, 32); // encrypted payload
int paddingLength = sessionRequestLen - 64; int paddingLength = sessionRequestLen - 64;
if (paddingLength > 0) if (paddingLength > 0)
MixHash (sessionRequest + 64, paddingLength); MixHash (sessionRequest + 64, paddingLength);
MixHash (epub, 32); MixHash (epub, 32);
@ -130,7 +130,7 @@ namespace transport
// m3p2Len // m3p2Len
auto bufLen = i2p::context.GetRouterInfo ().GetBufferLen (); auto bufLen = i2p::context.GetRouterInfo ().GetBufferLen ();
m3p2Len = bufLen + 4 + 16; // (RI header + RI + MAC for now) TODO: implement options 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) // fill m3p2 payload (RouterInfo block)
m_SessionConfirmedBuffer = new uint8_t[m3p2Len + 48]; // m3p1 is 48 bytes m_SessionConfirmedBuffer = new uint8_t[m3p2Len + 48]; // m3p1 is 48 bytes
uint8_t * m3p2 = m_SessionConfirmedBuffer + 48; uint8_t * m3p2 = m_SessionConfirmedBuffer + 48;
@ -231,11 +231,11 @@ namespace transport
auto ts = i2p::util::GetSecondsSinceEpoch (); auto ts = i2p::util::GetSecondsSinceEpoch ();
uint32_t tsA = bufbe32toh (options + 8); uint32_t tsA = bufbe32toh (options + 8);
if (tsA < ts - NTCP2_CLOCK_SKEW || tsA > ts + NTCP2_CLOCK_SKEW) if (tsA < ts - NTCP2_CLOCK_SKEW || tsA > ts + NTCP2_CLOCK_SKEW)
{ {
LogPrint (eLogWarning, "NTCP2: SessionRequest time difference ", (int)(ts - tsA), " exceeds clock skew"); LogPrint (eLogWarning, "NTCP2: SessionRequest time difference ", (int)(ts - tsA), " exceeds clock skew");
clockSkew = true; clockSkew = true;
// we send SessionCreate to let Alice know our time and then close session // we send SessionCreate to let Alice know our time and then close session
} }
} }
else else
{ {
@ -320,7 +320,7 @@ namespace transport
} }
NTCP2Session::NTCP2Session (NTCP2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter, 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), TransportSession (in_RemoteRouter, NTCP2_ESTABLISH_TIMEOUT),
m_Server (server), m_Socket (m_Server.GetService ()), m_Server (server), m_Socket (m_Server.GetService ()),
m_IsEstablished (false), m_IsTerminated (false), m_IsEstablished (false), m_IsTerminated (false),
@ -418,7 +418,7 @@ namespace transport
void NTCP2Session::DeleteNextReceiveBuffer (uint64_t ts) void NTCP2Session::DeleteNextReceiveBuffer (uint64_t ts)
{ {
if (m_NextReceivedBuffer && !m_IsReceiving && if (m_NextReceivedBuffer && !m_IsReceiving &&
ts > m_LastActivityTimestamp + NTCP2_RECEIVE_BUFFER_DELETION_TIMEOUT) ts > m_LastActivityTimestamp + NTCP2_RECEIVE_BUFFER_DELETION_TIMEOUT)
{ {
delete[] m_NextReceivedBuffer; delete[] m_NextReceivedBuffer;
m_NextReceivedBuffer = nullptr; m_NextReceivedBuffer = nullptr;
@ -484,9 +484,9 @@ namespace transport
if (clockSkew) if (clockSkew)
{ {
// we don't care about padding, send SessionCreated and close session // we don't care about padding, send SessionCreated and close session
SendSessionCreated (); SendSessionCreated ();
m_Server.GetService ().post (std::bind (&NTCP2Session::Terminate, shared_from_this ())); m_Server.GetService ().post (std::bind (&NTCP2Session::Terminate, shared_from_this ()));
} }
else if (paddingLen > 0) else if (paddingLen > 0)
{ {
if (paddingLen <= NTCP2_SESSION_REQUEST_MAX_SIZE - 64) // session request is 287 bytes max if (paddingLen <= NTCP2_SESSION_REQUEST_MAX_SIZE - 64) // session request is 287 bytes max
@ -496,7 +496,7 @@ namespace transport
} }
else else
{ {
LogPrint (eLogWarning, "NTCP2: SessionRequest padding length ", (int)paddingLen, " is too long"); LogPrint (eLogWarning, "NTCP2: SessionRequest padding length ", (int)paddingLen, " is too long");
Terminate (); Terminate ();
} }
} }
@ -549,7 +549,7 @@ namespace transport
} }
else else
{ {
LogPrint (eLogWarning, "NTCP2: SessionCreated padding length ", (int)paddingLen, " is too long"); LogPrint (eLogWarning, "NTCP2: SessionCreated padding length ", (int)paddingLen, " is too long");
Terminate (); Terminate ();
} }
} }
@ -1126,11 +1126,11 @@ namespace transport
{ {
if (!m_SendKey || if (!m_SendKey ||
#if OPENSSL_SIPHASH #if OPENSSL_SIPHASH
!m_SendMDCtx !m_SendMDCtx
#else #else
!m_SendSipKey !m_SendSipKey
#endif #endif
) return; ) return;
m_NextSendBuffer = new uint8_t[49]; // 49 = 12 bytes message + 16 bytes MAC + 2 bytes size + up to 19 padding block m_NextSendBuffer = new uint8_t[49]; // 49 = 12 bytes message + 16 bytes MAC + 2 bytes size + up to 19 padding block
// termination block // termination block
m_NextSendBuffer[2] = eNTCP2BlkTermination; m_NextSendBuffer[2] = eNTCP2BlkTermination;
@ -1164,7 +1164,7 @@ namespace transport
else if (m_SendQueue.size () > NTCP2_MAX_OUTGOING_QUEUE_SIZE) else if (m_SendQueue.size () > NTCP2_MAX_OUTGOING_QUEUE_SIZE)
{ {
LogPrint (eLogWarning, "NTCP2: Outgoing messages queue size to ", LogPrint (eLogWarning, "NTCP2: Outgoing messages queue size to ",
GetIdentHashBase64(), " exceeds ", NTCP2_MAX_OUTGOING_QUEUE_SIZE); GetIdentHashBase64(), " exceeds ", NTCP2_MAX_OUTGOING_QUEUE_SIZE);
Terminate (); Terminate ();
} }
} }
@ -1177,7 +1177,7 @@ namespace transport
NTCP2Server::NTCP2Server (): NTCP2Server::NTCP2Server ():
RunnableServiceWithWork ("NTCP2"), m_TerminationTimer (GetService ()), RunnableServiceWithWork ("NTCP2"), m_TerminationTimer (GetService ()),
m_ProxyType(eNoProxy), m_Resolver(GetService ()) m_ProxyType(eNoProxy), m_Resolver(GetService ())
{ {
} }

16
libi2pd/NetDb.cpp

@ -489,7 +489,7 @@ namespace data
{ {
auto r = std::make_shared<RouterInfo>(path); auto r = std::make_shared<RouterInfo>(path);
if (r->GetRouterIdentity () && !r->IsUnreachable () && r->HasValidAddresses () && 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 (); r->DeleteBuffer ();
if (m_RouterInfos.emplace (r->GetIdentHash (), r).second) if (m_RouterInfos.emplace (r->GetIdentHash (), r).second)
@ -620,7 +620,7 @@ namespace data
} }
// make router reachable back if too few routers or floodfills // make router reachable back if too few routers or floodfills
if (it.second->IsUnreachable () && (total - deletedCount < NETDB_MIN_ROUTERS || 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); it.second->SetUnreachable (false);
// find & mark expired routers // find & mark expired routers
if (!it.second->IsReachable () && it.second->IsSSU (false)) if (!it.second->IsReachable () && it.second->IsSSU (false))
@ -643,7 +643,7 @@ namespace data
} // m_RouterInfos iteration } // m_RouterInfos iteration
m_RouterInfoBuffersPool.CleanUpMt (); m_RouterInfoBuffersPool.CleanUpMt ();
if (updatedCount > 0) if (updatedCount > 0)
LogPrint (eLogInfo, "NetDb: Saved ", updatedCount, " new/updated routers"); LogPrint (eLogInfo, "NetDb: Saved ", updatedCount, " new/updated routers");
if (deletedCount > 0) if (deletedCount > 0)
@ -672,7 +672,7 @@ namespace data
else else
++it; ++it;
} }
} }
} }
void NetDb::RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete, bool direct) void NetDb::RequestDestination (const IdentHash& destination, RequestedDestination::RequestComplete requestComplete, bool direct)
@ -688,7 +688,7 @@ namespace data
if (floodfill) if (floodfill)
{ {
if (direct && !floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) && 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 direct = false; // floodfill can't be reached directly
if (direct) if (direct)
transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ())); transports.SendMessage (floodfill->GetIdentHash (), dest->CreateRequestMessage (floodfill->GetIdentHash ()));
@ -971,7 +971,7 @@ namespace data
else else
{ {
if (lookupType == DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP || if (lookupType == DATABASE_LOOKUP_TYPE_ROUTERINFO_LOOKUP ||
lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP) lookupType == DATABASE_LOOKUP_TYPE_NORMAL_LOOKUP)
{ {
auto router = FindRouter (ident); auto router = FindRouter (ident);
if (router) if (router)
@ -1136,7 +1136,7 @@ namespace data
m_PublishExcluded.insert (floodfill->GetIdentHash ()); m_PublishExcluded.insert (floodfill->GetIdentHash ());
m_PublishReplyToken = replyToken; m_PublishReplyToken = replyToken;
if (floodfill->IsReachableFrom (i2p::context.GetRouterInfo ()) || // are we able to connect? 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 // send directly
transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken)); transports.SendMessage (floodfill->GetIdentHash (), CreateDatabaseStoreMsg (i2p::context.GetSharedRouterInfo (), replyToken));
else else
@ -1377,7 +1377,7 @@ namespace data
return res; return res;
} }
std::shared_ptr<const RouterInfo> NetDb::GetRandomRouterInFamily (FamilyID fam) const std::shared_ptr<const RouterInfo> NetDb::GetRandomRouterInFamily (FamilyID fam) const
{ {
return GetRandomRouter( return GetRandomRouter(
[fam](std::shared_ptr<const RouterInfo> router)->bool [fam](std::shared_ptr<const RouterInfo> router)->bool

2
libi2pd/NetDb.hpp

@ -123,7 +123,7 @@ namespace data
void ClearRouterInfos () { m_RouterInfos.clear (); }; void ClearRouterInfos () { m_RouterInfos.clear (); };
std::shared_ptr<RouterInfo::Buffer> NewRouterInfoBuffer () { return m_RouterInfoBuffersPool.AcquireSharedMt (); }; std::shared_ptr<RouterInfo::Buffer> NewRouterInfoBuffer () { return m_RouterInfoBuffersPool.AcquireSharedMt (); };
uint32_t GetPublishReplyToken () const { return m_PublishReplyToken; }; uint32_t GetPublishReplyToken () const { return m_PublishReplyToken; };
private: private:

2
libi2pd/NetDbRequests.h

@ -60,7 +60,7 @@ namespace data
void Start (); void Start ();
void Stop (); 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); void RequestComplete (const IdentHash& ident, std::shared_ptr<RouterInfo> r);
std::shared_ptr<RequestedDestination> FindRequest (const IdentHash& ident) const; std::shared_ptr<RequestedDestination> FindRequest (const IdentHash& ident) const;
void ManageRequests (); void ManageRequests ();

13
libi2pd/Poly1305.cpp

@ -1,12 +1,13 @@
#include "Poly1305.h"
/** /**
This code is licensed under the MCGSI Public License * This code is licensed under the MCGSI Public License
Copyright 2018 Jeff Becker * Copyright 2018 Jeff Becker
*
Kovri go write your own code *Kovri go write your own code
*
*/ */
#include "Poly1305.h"
#if !OPENSSL_AEAD_CHACHA20_POLY1305 #if !OPENSSL_AEAD_CHACHA20_POLY1305
namespace i2p namespace i2p
{ {

1
libi2pd/Poly1305.h

@ -5,6 +5,7 @@
* Kovri go write your own code * Kovri go write your own code
* *
*/ */
#ifndef LIBI2PD_POLY1305_H #ifndef LIBI2PD_POLY1305_H
#define LIBI2PD_POLY1305_H #define LIBI2PD_POLY1305_H
#include <cstdint> #include <cstdint>

4
libi2pd/Queue.h

@ -28,7 +28,7 @@ namespace util
void Put (Element e) 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_Queue.push (std::move(e));
m_NonEmpty.notify_one (); m_NonEmpty.notify_one ();
} }
@ -38,7 +38,7 @@ namespace util
{ {
if (!vec.empty ()) if (!vec.empty ())
{ {
std::unique_lock<std::mutex> l(m_QueueMutex); std::unique_lock<std::mutex> l(m_QueueMutex);
for (const auto& it: vec) for (const auto& it: vec)
m_Queue.push (std::move(it)); m_Queue.push (std::move(it));
m_NonEmpty.notify_one (); m_NonEmpty.notify_one ();

18
libi2pd/Reseed.cpp

@ -187,31 +187,31 @@ namespace data
} }
s.seekg (1, std::ios::cur); // su3 file format version s.seekg (1, std::ios::cur); // su3 file format version
SigningKeyType signatureType; SigningKeyType signatureType;
s.read ((char *)&signatureType, 2); // signature type s.read ((char *)&signatureType, 2); // signature type
signatureType = be16toh (signatureType); signatureType = be16toh (signatureType);
uint16_t signatureLength; uint16_t signatureLength;
s.read ((char *)&signatureLength, 2); // signature length s.read ((char *)&signatureLength, 2); // signature length
signatureLength = be16toh (signatureLength); signatureLength = be16toh (signatureLength);
s.seekg (1, std::ios::cur); // unused s.seekg (1, std::ios::cur); // unused
uint8_t versionLength; uint8_t versionLength;
s.read ((char *)&versionLength, 1); // version length s.read ((char *)&versionLength, 1); // version length
s.seekg (1, std::ios::cur); // unused s.seekg (1, std::ios::cur); // unused
uint8_t signerIDLength; uint8_t signerIDLength;
s.read ((char *)&signerIDLength, 1); // signer ID length s.read ((char *)&signerIDLength, 1); // signer ID length
uint64_t contentLength; uint64_t contentLength;
s.read ((char *)&contentLength, 8); // content length s.read ((char *)&contentLength, 8); // content length
contentLength = be64toh (contentLength); contentLength = be64toh (contentLength);
s.seekg (1, std::ios::cur); // unused s.seekg (1, std::ios::cur); // unused
uint8_t fileType; uint8_t fileType;
s.read ((char *)&fileType, 1); // file type s.read ((char *)&fileType, 1); // file type
if (fileType != 0x00) // zip file if (fileType != 0x00) // zip file
{ {
LogPrint (eLogError, "Reseed: Can't handle file type ", (int)fileType); LogPrint (eLogError, "Reseed: Can't handle file type ", (int)fileType);
return 0; return 0;
} }
s.seekg (1, std::ios::cur); // unused s.seekg (1, std::ios::cur); // unused
uint8_t contentType; uint8_t contentType;
s.read ((char *)&contentType, 1); // content type s.read ((char *)&contentType, 1); // content type
if (contentType != 0x03) // reseed data if (contentType != 0x03) // reseed data
{ {
LogPrint (eLogError, "Reseed: Unexpected content type ", (int)contentType); LogPrint (eLogError, "Reseed: Unexpected content type ", (int)contentType);
@ -688,7 +688,7 @@ namespace data
{ {
boost::asio::ip::tcp::endpoint ep = *it; boost::asio::ip::tcp::endpoint ep = *it;
if ((ep.address ().is_v4 () && i2p::context.SupportsV4 ()) || 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); s.lowest_layer().connect (ep, ecode);
if (!ecode) if (!ecode)

72
libi2pd/RouterContext.cpp

@ -65,13 +65,13 @@ namespace i2p
port = rand () % (30777 - 9111) + 9111; // I2P network ports range port = rand () % (30777 - 9111) + 9111; // I2P network ports range
if (port == 9150) port = 9151; // Tor browser if (port == 9150) port = 9151; // Tor browser
} }
bool ipv4; i2p::config::GetOption("ipv4", ipv4); bool ipv4; i2p::config::GetOption("ipv4", ipv4);
bool ipv6; i2p::config::GetOption("ipv6", ipv6); bool ipv6; i2p::config::GetOption("ipv6", ipv6);
bool ssu; i2p::config::GetOption("ssu", ssu); bool ssu; i2p::config::GetOption("ssu", ssu);
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2); bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg); bool ygg; i2p::config::GetOption("meshnets.yggdrasil", ygg);
bool nat; i2p::config::GetOption("nat", nat); bool nat; i2p::config::GetOption("nat", nat);
if ((ntcp2 || ygg) && !m_NTCP2Keys) if ((ntcp2 || ygg) && !m_NTCP2Keys)
NewNTCP2Keys (); NewNTCP2Keys ();
@ -123,11 +123,11 @@ namespace i2p
if (ssu2Published) if (ssu2Published)
routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v4::from_string (host), port); routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v4::from_string (host), port);
else else
{ {
addressCaps |= i2p::data::RouterInfo::AddressCaps::eV4; addressCaps |= i2p::data::RouterInfo::AddressCaps::eV4;
routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro); routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro);
} }
} }
} }
if (ipv6) if (ipv6)
{ {
@ -168,12 +168,12 @@ namespace i2p
if (ssu2Published) if (ssu2Published)
routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v6::from_string (host), port); routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address_v6::from_string (host), port);
else else
{ {
if (!ipv4) // no other ssu2 addresses yet if (!ipv4) // no other ssu2 addresses yet
routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro); routerInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro);
addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6; addressCaps |= i2p::data::RouterInfo::AddressCaps::eV6;
} }
} }
} }
if (ygg) if (ygg)
{ {
@ -224,7 +224,7 @@ namespace i2p
std::ofstream fk (i2p::fs::DataDirPath (SSU2_KEYS), std::ofstream::binary | std::ofstream::out); std::ofstream fk (i2p::fs::DataDirPath (SSU2_KEYS), std::ofstream::binary | std::ofstream::out);
fk.write ((char *)m_SSU2Keys.get (), sizeof (SSU2PrivateKeys)); fk.write ((char *)m_SSU2Keys.get (), sizeof (SSU2PrivateKeys));
} }
void RouterContext::SetStatus (RouterStatus status) void RouterContext::SetStatus (RouterStatus status)
{ {
if (status != m_Status) if (status != m_Status)
@ -313,7 +313,7 @@ namespace i2p
if (updated) if (updated)
UpdateRouterInfo (); UpdateRouterInfo ();
} }
void RouterContext::UpdateNTCP2Address (bool enable) void RouterContext::UpdateNTCP2Address (bool enable)
{ {
auto& addresses = m_RouterInfo.GetAddresses (); auto& addresses = m_RouterInfo.GetAddresses ();
@ -360,8 +360,8 @@ namespace i2p
} }
if (updated) if (updated)
UpdateRouterInfo (); UpdateRouterInfo ();
} }
void RouterContext::UpdateSSU2Address (bool enable) void RouterContext::UpdateSSU2Address (bool enable)
{ {
auto& addresses = m_RouterInfo.GetAddresses (); auto& addresses = m_RouterInfo.GetAddresses ();
@ -392,14 +392,14 @@ namespace i2p
if (updated) if (updated)
UpdateRouterInfo (); UpdateRouterInfo ();
} }
void RouterContext::UpdateAddress (const boost::asio::ip::address& host) void RouterContext::UpdateAddress (const boost::asio::ip::address& host)
{ {
bool updated = false; bool updated = false;
for (auto& address : m_RouterInfo.GetAddresses ()) for (auto& address : m_RouterInfo.GetAddresses ())
{ {
if (address->host != host && address->IsCompatible (host) && if (address->host != host && address->IsCompatible (host) &&
!i2p::util::net::IsYggdrasilAddress (address->host)) !i2p::util::net::IsYggdrasilAddress (address->host))
{ {
address->host = host; address->host = host;
if (host.is_v6 () && address->transportStyle == i2p::data::RouterInfo::eTransportSSU) if (host.is_v6 () && address->transportStyle == i2p::data::RouterInfo::eTransportSSU)
@ -643,12 +643,12 @@ namespace i2p
break; break;
case i2p::data::RouterInfo::eTransportNTCP: case i2p::data::RouterInfo::eTransportNTCP:
foundNTCP2 = true; foundNTCP2 = true;
break; break;
case i2p::data::RouterInfo::eTransportSSU2: case i2p::data::RouterInfo::eTransportSSU2:
foundSSU2 = true; foundSSU2 = true;
break; break;
default: ; default: ;
} }
} }
port = addr->port; port = addr->port;
} }
@ -690,17 +690,17 @@ namespace i2p
{ {
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
if (ssu2) if (ssu2)
{ {
bool ssu2Published; i2p::config::GetOption("ssu2.published", ssu2Published); bool ssu2Published; i2p::config::GetOption("ssu2.published", ssu2Published);
if (ssu2Published) if (ssu2Published)
{ {
uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); 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); m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address::from_string ("::1"), ssu2Port);
} }
else else
m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::eV6); m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::eV6);
} }
} }
m_RouterInfo.EnableV6 (); m_RouterInfo.EnableV6 ();
} }
else else
@ -731,12 +731,12 @@ namespace i2p
break; break;
case i2p::data::RouterInfo::eTransportNTCP: case i2p::data::RouterInfo::eTransportNTCP:
foundNTCP2 = true; foundNTCP2 = true;
break; break;
case i2p::data::RouterInfo::eTransportSSU2: case i2p::data::RouterInfo::eTransportSSU2:
foundSSU2 = true; foundSSU2 = true;
break; break;
default: ; default: ;
} }
} }
if (addr->port) port = addr->port; if (addr->port) port = addr->port;
} }
@ -776,11 +776,11 @@ namespace i2p
{ {
uint16_t ssu2Port; i2p::config::GetOption ("ssu2.port", ssu2Port); 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); m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, boost::asio::ip::address::from_string ("127.0.0.1"), ssu2Port);
} }
else else
m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::eV6); m_RouterInfo.AddSSU2Address (m_SSU2Keys->staticPublicKey, m_SSU2Keys->intro, i2p::data::RouterInfo::eV6);
} }
} }
m_RouterInfo.EnableV4 (); m_RouterInfo.EnableV4 ();
} }
else else
@ -883,7 +883,7 @@ namespace i2p
} }
std::shared_ptr<const i2p::data::IdentityEx> oldIdentity; std::shared_ptr<const i2p::data::IdentityEx> oldIdentity;
if (m_Keys.GetPublic ()->GetSigningKeyType () == i2p::data::SIGNING_KEY_TYPE_DSA_SHA1 || 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 // update keys
LogPrint (eLogInfo, "Router: router keys are obsolete. Creating new"); LogPrint (eLogInfo, "Router: router keys are obsolete. Creating new");
@ -935,7 +935,7 @@ namespace i2p
UpdateNTCP2Address (true); // enable NTCP2 UpdateNTCP2Address (true); // enable NTCP2
} }
else else
UpdateNTCP2Address (false); // disable NTCP2 UpdateNTCP2Address (false); // disable NTCP2
// read SSU2 // read SSU2
bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2); bool ssu2; i2p::config::GetOption("ssu2.enabled", ssu2);
@ -960,7 +960,7 @@ namespace i2p
} }
else else
UpdateSSU2Address (false); // disable SSU2 UpdateSSU2Address (false); // disable SSU2
return true; return true;
} }
@ -1103,5 +1103,5 @@ namespace i2p
delete x; delete x;
} }
return *m_SSU2StaticKeys; return *m_SSU2StaticKeys;
} }
} }

6
libi2pd/RouterContext.h

@ -68,7 +68,7 @@ namespace garlic
uint8_t staticPrivateKey[32]; uint8_t staticPrivateKey[32];
uint8_t intro[32]; uint8_t intro[32];
}; };
public: public:
RouterContext (); RouterContext ();
@ -86,7 +86,7 @@ namespace garlic
return std::shared_ptr<i2p::garlic::GarlicDestination> (this, return std::shared_ptr<i2p::garlic::GarlicDestination> (this,
[](i2p::garlic::GarlicDestination *) {}); [](i2p::garlic::GarlicDestination *) {});
} }
const uint8_t * GetNTCP2StaticPublicKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPublicKey : nullptr; }; 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 * GetNTCP2StaticPrivateKey () const { return m_NTCP2Keys ? m_NTCP2Keys->staticPrivateKey : nullptr; };
const uint8_t * GetNTCP2IV () const { return m_NTCP2Keys ? m_NTCP2Keys->iv : 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 * GetSSU2StaticPrivateKey () const { return m_SSU2Keys ? m_SSU2Keys->staticPrivateKey : nullptr; };
const uint8_t * GetSSU2IntroKey () const { return m_SSU2Keys ? m_SSU2Keys->intro : nullptr; }; const uint8_t * GetSSU2IntroKey () const { return m_SSU2Keys ? m_SSU2Keys->intro : nullptr; };
i2p::crypto::X25519Keys& GetSSU2StaticKeys (); i2p::crypto::X25519Keys& GetSSU2StaticKeys ();
uint32_t GetUptime () const; // in seconds uint32_t GetUptime () const; // in seconds
uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; }; uint64_t GetLastUpdateTime () const { return m_LastUpdateTime; };
uint64_t GetBandwidthLimit () const { return m_BandwidthLimit; }; uint64_t GetBandwidthLimit () const { return m_BandwidthLimit; };

124
libi2pd/RouterInfo.cpp

@ -33,16 +33,16 @@ namespace data
{ {
if (len > size ()) len = size (); if (len > size ()) len = size ();
memcpy (data (), buf, len); memcpy (data (), buf, len);
} }
RouterInfo::RouterInfo (): m_Buffer (nullptr) RouterInfo::RouterInfo (): m_Buffer (nullptr)
{ {
m_Addresses = boost::make_shared<Addresses>(); // create empty list m_Addresses = boost::make_shared<Addresses>(); // create empty list
} }
RouterInfo::RouterInfo (const std::string& fullPath): RouterInfo::RouterInfo (const std::string& fullPath):
m_FamilyID (0), m_IsUpdated (false), m_IsUnreachable (false), m_FamilyID (0), m_IsUpdated (false), m_IsUnreachable (false),
m_SupportedTransports (0),m_ReachableTransports (0), m_SupportedTransports (0),m_ReachableTransports (0),
m_Caps (0), m_Version (0) m_Caps (0), m_Version (0)
{ {
m_Addresses = boost::make_shared<Addresses>(); // create empty list 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): RouterInfo::RouterInfo (std::shared_ptr<Buffer>&& buf, size_t len):
m_FamilyID (0), m_IsUpdated (true), m_IsUnreachable (false), m_FamilyID (0), m_IsUpdated (true), m_IsUnreachable (false),
m_SupportedTransports (0), m_ReachableTransports (0), m_SupportedTransports (0), m_ReachableTransports (0),
m_Caps (0), m_Version (0) m_Caps (0), m_Version (0)
{ {
if (len <= MAX_RI_BUFFER_SIZE) if (len <= MAX_RI_BUFFER_SIZE)
@ -68,12 +68,12 @@ namespace data
m_Buffer = nullptr; m_Buffer = nullptr;
m_IsUnreachable = true; m_IsUnreachable = true;
} }
} }
RouterInfo::RouterInfo (const uint8_t * buf, size_t len): RouterInfo::RouterInfo (const uint8_t * buf, size_t len):
RouterInfo (std::make_shared<Buffer> (buf, len), len) RouterInfo (std::make_shared<Buffer> (buf, len), len)
{ {
} }
RouterInfo::~RouterInfo () RouterInfo::~RouterInfo ()
{ {
@ -160,7 +160,7 @@ namespace data
{ {
m_IsUnreachable = true; m_IsUnreachable = true;
return; return;
} }
m_RouterIdentity = std::make_shared<IdentityEx>(m_Buffer->data (), m_BufferLen); m_RouterIdentity = std::make_shared<IdentityEx>(m_Buffer->data (), m_BufferLen);
size_t identityLen = m_RouterIdentity->GetFullLen (); size_t identityLen = m_RouterIdentity->GetFullLen ();
if (identityLen >= m_BufferLen) if (identityLen >= m_BufferLen)
@ -241,7 +241,7 @@ namespace data
// skip unknown address // skip unknown address
s.seekg (size, std::ios_base::cur); s.seekg (size, std::ios_base::cur);
if (s) continue; else return; if (s) continue; else return;
} }
while (r < size) while (r < size)
{ {
char key[255], value[255]; char key[255], value[255];
@ -288,7 +288,7 @@ namespace data
} }
else if (address->IsSSU2 ()) else if (address->IsSSU2 ())
Base64ToByteStream (value, strlen (value), address->i, 32); Base64ToByteStream (value, strlen (value), address->i, 32);
else else
Base64ToByteStream (value, strlen (value), iV2, 32); Base64ToByteStream (value, strlen (value), iV2, 32);
} }
else if (!strcmp (key, "v")) else if (!strcmp (key, "v"))
@ -297,7 +297,7 @@ namespace data
isV2 = true; isV2 = true;
else else
LogPrint (eLogWarning, "RouterInfo: Unexpected value ", value, " for v"); LogPrint (eLogWarning, "RouterInfo: Unexpected value ", value, " for v");
} }
else if (key[0] == 'i') else if (key[0] == 'i')
{ {
// introducers // introducers
@ -344,7 +344,7 @@ namespace data
if (isHost) if (isHost)
{ {
if (address->host.is_v6 ()) if (address->host.is_v6 ())
supportedTransports |= (i2p::util::net::IsYggdrasilAddress (address->host) ? eNTCP2V6Mesh : eNTCP2V6); supportedTransports |= (i2p::util::net::IsYggdrasilAddress (address->host) ? eNTCP2V6Mesh : eNTCP2V6);
else else
supportedTransports |= eNTCP2V4; supportedTransports |= eNTCP2V4;
m_ReachableTransports |= supportedTransports; m_ReachableTransports |= supportedTransports;
@ -366,7 +366,7 @@ namespace data
if (isIntroKey) if (isIntroKey)
{ {
if (isHost) if (isHost)
supportedTransports |= address->host.is_v4 () ? eSSUV4 : eSSUV6; supportedTransports |= address->host.is_v4 () ? eSSUV4 : eSSUV6;
else if (address->caps & AddressCaps::eV6) else if (address->caps & AddressCaps::eV6)
{ {
supportedTransports |= eSSUV6; supportedTransports |= eSSUV6;
@ -383,7 +383,7 @@ namespace data
{ {
if (!it.iExp) it.iExp = m_Timestamp/1000 + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT; if (!it.iExp) it.iExp = m_Timestamp/1000 + NETDB_INTRODUCEE_EXPIRATION_TIMEOUT;
if (ts <= it.iExp && it.iPort > 0 && 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++; numValid++;
else else
it.iPort = 0; it.iPort = 0;
@ -408,12 +408,12 @@ namespace data
{ {
if (address->host.is_v4 ()) m_ReachableTransports |= eSSU2V4; if (address->host.is_v4 ()) m_ReachableTransports |= eSSU2V4;
if (address->host.is_v6 ()) m_ReachableTransports |= eSSU2V6; if (address->host.is_v6 ()) m_ReachableTransports |= eSSU2V6;
} }
} }
if (supportedTransports) if (supportedTransports)
{ {
if (!(m_SupportedTransports & supportedTransports)) // avoid duplicates if (!(m_SupportedTransports & supportedTransports)) // avoid duplicates
{ {
addresses->push_back(address); addresses->push_back(address);
if (address->transportStyle == eTransportSSU && isV2) if (address->transportStyle == eTransportSSU && isV2)
{ {
@ -427,10 +427,10 @@ namespace data
ssu2addr->ssu.reset (new SSUExt ()); ssu2addr->ssu->mtu = address->ssu->mtu; ssu2addr->ssu.reset (new SSUExt ()); ssu2addr->ssu->mtu = address->ssu->mtu;
for (const auto& introducer: address->ssu->introducers) for (const auto& introducer: address->ssu->introducers)
if (!introducer.iPort) // SSU2 if (!introducer.iPort) // SSU2
ssu2addr->ssu->introducers.push_back (introducer); ssu2addr->ssu->introducers.push_back (introducer);
addresses->push_back(ssu2addr); addresses->push_back(ssu2addr);
} }
} }
m_SupportedTransports |= supportedTransports; m_SupportedTransports |= supportedTransports;
} }
} }
@ -483,10 +483,10 @@ namespace data
{ {
isNetId = true; isNetId = true;
if (atoi (value) != i2p::context.GetNetID ()) if (atoi (value) != i2p::context.GetNetID ())
{ {
LogPrint (eLogError, "RouterInfo: Unexpected ", ROUTER_INFO_PROPERTY_NETID, "=", value); LogPrint (eLogError, "RouterInfo: Unexpected ", ROUTER_INFO_PROPERTY_NETID, "=", value);
m_IsUnreachable = true; m_IsUnreachable = true;
} }
} }
// family // family
else if (!strcmp (key, ROUTER_INFO_PROPERTY_FAMILY)) else if (!strcmp (key, ROUTER_INFO_PROPERTY_FAMILY))
@ -498,7 +498,7 @@ namespace data
{ {
if (netdb.GetFamilies ().VerifyFamily (family, GetIdentHash (), value)) if (netdb.GetFamilies ().VerifyFamily (family, GetIdentHash (), value))
m_FamilyID = netdb.GetFamilies ().GetFamilyID (family); m_FamilyID = netdb.GetFamilies ().GetFamilyID (family);
else else
LogPrint (eLogWarning, "RouterInfo: Family ", family, " signature verification failed"); LogPrint (eLogWarning, "RouterInfo: Family ", family, " signature verification failed");
} }
@ -689,7 +689,7 @@ namespace data
if (addr->IsV4 ()) m_SupportedTransports |= eSSU2V4; if (addr->IsV4 ()) m_SupportedTransports |= eSSU2V4;
if (addr->IsV6 ()) m_SupportedTransports |= eSSU2V6; if (addr->IsV6 ()) m_SupportedTransports |= eSSU2V6;
m_Addresses->push_back(std::move(addr)); m_Addresses->push_back(std::move(addr));
} }
void RouterInfo::AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey, void RouterInfo::AddSSU2Address (const uint8_t * staticKey, const uint8_t * introKey,
const boost::asio::ip::address& host, int port) const boost::asio::ip::address& host, int port)
@ -706,24 +706,24 @@ namespace data
memcpy (addr->s, staticKey, 32); memcpy (addr->s, staticKey, 32);
memcpy (addr->i, introKey, 32); memcpy (addr->i, introKey, 32);
if (addr->IsV4 ()) if (addr->IsV4 ())
{ {
m_SupportedTransports |= eSSU2V4; m_SupportedTransports |= eSSU2V4;
m_ReachableTransports |= eSSU2V4; m_ReachableTransports |= eSSU2V4;
} }
if (addr->IsV6 ()) if (addr->IsV6 ())
{ {
m_SupportedTransports |= eSSU2V6; m_SupportedTransports |= eSSU2V6;
m_ReachableTransports |= eSSU2V6; m_ReachableTransports |= eSSU2V6;
} }
m_Addresses->push_back(std::move(addr)); m_Addresses->push_back(std::move(addr));
} }
bool RouterInfo::AddIntroducer (const Introducer& introducer) bool RouterInfo::AddIntroducer (const Introducer& introducer)
{ {
for (auto& addr : *m_Addresses) for (auto& addr : *m_Addresses)
{ {
if (addr->transportStyle == eTransportSSU && 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) for (auto& intro: addr->ssu->introducers)
if (intro.iTag == introducer.iTag) return false; // already presented if (intro.iTag == introducer.iTag) return false; // already presented
@ -740,7 +740,7 @@ namespace data
for (auto& addr: *m_Addresses) for (auto& addr: *m_Addresses)
{ {
if (addr->transportStyle == eTransportSSU && 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) for (auto it = addr->ssu->introducers.begin (); it != addr->ssu->introducers.end (); ++it)
if (boost::asio::ip::udp::endpoint (it->iHost, it->iPort) == e) if (boost::asio::ip::udp::endpoint (it->iHost, it->iPort) == e)
@ -894,8 +894,8 @@ namespace data
{ {
return (address->transportStyle == eTransportSSU2) && address->IsV4(); return (address->transportStyle == eTransportSSU2) && address->IsV4();
}); });
} }
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetSSU2V6Address () const std::shared_ptr<const RouterInfo::Address> RouterInfo::GetSSU2V6Address () const
{ {
return GetAddress ( return GetAddress (
@ -903,8 +903,8 @@ namespace data
{ {
return (address->transportStyle == eTransportSSU2) && address->IsV6(); return (address->transportStyle == eTransportSSU2) && address->IsV6();
}); });
} }
template<typename Filter> template<typename Filter>
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetAddress (Filter filter) const 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; return address->IsSSU2 () && !memcmp (address->s, key, 32) && address->IsV6 () == isV6;
}); });
} }
std::shared_ptr<const RouterInfo::Address> RouterInfo::GetPublishedNTCP2V4Address () const std::shared_ptr<const RouterInfo::Address> RouterInfo::GetPublishedNTCP2V4Address () const
{ {
return GetAddress ( return GetAddress (
@ -1057,17 +1057,17 @@ namespace data
if (len > m_Buffer->size ()) len = m_Buffer->size (); if (len > m_Buffer->size ()) len = m_Buffer->size ();
memcpy (m_Buffer->data (), buf, len); memcpy (m_Buffer->data (), buf, len);
m_BufferLen = len; m_BufferLen = len;
} }
std::shared_ptr<RouterInfo::Buffer> RouterInfo::NewBuffer () const std::shared_ptr<RouterInfo::Buffer> RouterInfo::NewBuffer () const
{ {
return netdb.NewRouterInfoBuffer (); return netdb.NewRouterInfoBuffer ();
} }
void RouterInfo::RefreshTimestamp () void RouterInfo::RefreshTimestamp ()
{ {
m_Timestamp = i2p::util::GetMillisecondsSinceEpoch (); m_Timestamp = i2p::util::GetMillisecondsSinceEpoch ();
} }
void LocalRouterInfo::CreateBuffer (const PrivateKeys& privateKeys) void LocalRouterInfo::CreateBuffer (const PrivateKeys& privateKeys)
{ {
@ -1088,13 +1088,13 @@ namespace data
} }
else else
LogPrint (eLogError, "RouterInfo: Our RouterInfo is too long ", len + signatureLen); LogPrint (eLogError, "RouterInfo: Our RouterInfo is too long ", len + signatureLen);
} }
void LocalRouterInfo::UpdateCaps (uint8_t caps) void LocalRouterInfo::UpdateCaps (uint8_t caps)
{ {
SetCaps (caps); SetCaps (caps);
UpdateCapsProperty (); UpdateCapsProperty ();
} }
void LocalRouterInfo::UpdateCapsProperty () void LocalRouterInfo::UpdateCapsProperty ()
{ {
@ -1153,7 +1153,7 @@ namespace data
{ {
WriteString ("NTCP2", s); WriteString ("NTCP2", s);
if (address.IsPublishedNTCP2 () && !address.host.is_unspecified () && address.port) if (address.IsPublishedNTCP2 () && !address.host.is_unspecified () && address.port)
isPublished = true; isPublished = true;
else else
{ {
WriteString ("caps", properties); WriteString ("caps", properties);
@ -1212,12 +1212,12 @@ namespace data
// caps // caps
std::string caps; std::string caps;
if (address.published) if (address.published)
{ {
isPublished = true; isPublished = true;
if (address.IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER; if (address.IsIntroducer ()) caps += CAPS_FLAG_SSU_INTRODUCER;
} }
else else
{ {
if (address.IsV4 ()) caps += CAPS_FLAG_V4; if (address.IsV4 ()) caps += CAPS_FLAG_V4;
if (address.IsV6 ()) caps += CAPS_FLAG_V6; if (address.IsV6 ()) caps += CAPS_FLAG_V6;
if (caps.empty ()) caps += CAPS_FLAG_V4; if (caps.empty ()) caps += CAPS_FLAG_V4;
@ -1228,8 +1228,8 @@ namespace data
properties << '='; properties << '=';
WriteString (caps, properties); WriteString (caps, properties);
properties << ';'; properties << ';';
} }
} }
else else
WriteString ("", s); WriteString ("", s);
@ -1265,7 +1265,7 @@ namespace data
i++; i++;
} }
if (address.transportStyle == eTransportSSU) if (address.transportStyle == eTransportSSU)
{ {
i = 0; i = 0;
for (const auto& introducer: address.ssu->introducers) for (const auto& introducer: address.ssu->introducers)
{ {
@ -1275,13 +1275,13 @@ namespace data
properties << ';'; properties << ';';
i++; i++;
} }
} }
i = 0; i = 0;
for (const auto& introducer: address.ssu->introducers) for (const auto& introducer: address.ssu->introducers)
{ {
if (address.IsSSU2 ()) if (address.IsSSU2 ())
WriteString ("ih" + boost::lexical_cast<std::string>(i), properties); WriteString ("ih" + boost::lexical_cast<std::string>(i), properties);
else else
WriteString ("ikey" + boost::lexical_cast<std::string>(i), properties); WriteString ("ikey" + boost::lexical_cast<std::string>(i), properties);
properties << '='; properties << '=';
char value[64]; char value[64];
@ -1302,7 +1302,7 @@ namespace data
properties << ';'; properties << ';';
i++; i++;
} }
} }
i = 0; i = 0;
for (const auto& introducer: address.ssu->introducers) for (const auto& introducer: address.ssu->introducers)
{ {
@ -1326,7 +1326,7 @@ namespace data
properties << ';'; properties << ';';
} }
if (address.transportStyle == eTransportSSU || address.IsSSU2 ()) if (address.transportStyle == eTransportSSU || address.IsSSU2 ())
{ {
// write mtu // write mtu
if (address.ssu && address.ssu->mtu) if (address.ssu && address.ssu->mtu)
{ {
@ -1373,7 +1373,7 @@ namespace data
uint16_t size = htobe16 (properties.str ().size ()); uint16_t size = htobe16 (properties.str ().size ());
s.write ((char *)&size, sizeof (size)); s.write ((char *)&size, sizeof (size));
s.write (properties.str ().c_str (), properties.str ().size ()); s.write (properties.str ().c_str (), properties.str ().size ());
} }
void LocalRouterInfo::SetProperty (const std::string& key, const std::string& value) void LocalRouterInfo::SetProperty (const std::string& key, const std::string& value)
{ {
@ -1391,18 +1391,18 @@ namespace data
if (it != m_Properties.end ()) if (it != m_Properties.end ())
return it->second; return it->second;
return ""; return "";
} }
void LocalRouterInfo::WriteString (const std::string& str, std::ostream& s) const void LocalRouterInfo::WriteString (const std::string& str, std::ostream& s) const
{ {
uint8_t len = str.size (); uint8_t len = str.size ();
s.write ((char *)&len, 1); s.write ((char *)&len, 1);
s.write (str.c_str (), len); s.write (str.c_str (), len);
} }
std::shared_ptr<RouterInfo::Buffer> LocalRouterInfo::NewBuffer () const std::shared_ptr<RouterInfo::Buffer> LocalRouterInfo::NewBuffer () const
{ {
return std::make_shared<Buffer> (); return std::make_shared<Buffer> ();
} }
} }
} }

30
libi2pd/RouterInfo.h

@ -56,7 +56,7 @@ namespace data
const uint8_t COST_SSU_DIRECT = 9; const uint8_t COST_SSU_DIRECT = 9;
const uint8_t COST_SSU_THROUGH_INTRODUCERS = 11; const uint8_t COST_SSU_THROUGH_INTRODUCERS = 11;
const uint8_t COST_SSU2_NON_PUBLISHED = 15; 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 const size_t MAX_RI_BUFFER_SIZE = 3072; // if RouterInfo exceeds 3K we consider it as malformed, might extend later
class RouterInfo: public RoutingDestination class RouterInfo: public RoutingDestination
{ {
@ -146,11 +146,11 @@ namespace data
return !(*this == other); return !(*this == other);
} }
bool IsNTCP2 () const { return transportStyle == eTransportNTCP; }; bool IsNTCP2 () const { return transportStyle == eTransportNTCP; };
bool IsSSU2 () const { return transportStyle == eTransportSSU2; }; bool IsSSU2 () const { return transportStyle == eTransportSSU2; };
bool IsPublishedNTCP2 () const { return IsNTCP2 () && published; }; bool IsPublishedNTCP2 () const { return IsNTCP2 () && published; };
bool IsReachableSSU () const { return (bool)ssu && (published || UsesIntroducer ()); }; 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 IsIntroducer () const { return caps & eSSUIntroducer; };
bool IsPeerTesting () const { return caps & eSSUTesting; }; bool IsPeerTesting () const { return caps & eSSUTesting; };
@ -166,7 +166,7 @@ namespace data
Buffer () = default; Buffer () = default;
Buffer (const uint8_t * buf, size_t len); Buffer (const uint8_t * buf, size_t len);
}; };
typedef std::vector<std::shared_ptr<Address> > Addresses; typedef std::vector<std::shared_ptr<Address> > Addresses;
RouterInfo (const std::string& fullPath); RouterInfo (const std::string& fullPath);
@ -181,7 +181,7 @@ namespace data
std::string GetIdentHashBase64 () const { return GetIdentHash ().ToBase64 (); }; std::string GetIdentHashBase64 () const { return GetIdentHash ().ToBase64 (); };
uint64_t GetTimestamp () const { return m_Timestamp; }; uint64_t GetTimestamp () const { return m_Timestamp; };
int GetVersion () const { return m_Version; }; 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 () {}; virtual void ClearProperties () {};
Addresses& GetAddresses () { return *m_Addresses; }; // should be called for local RI only, otherwise must return shared_ptr 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; 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 SetBufferLen (size_t len) { m_BufferLen = len; };
void RefreshTimestamp (); void RefreshTimestamp ();
const Addresses& GetAddresses () const { return *m_Addresses; }; const Addresses& GetAddresses () const { return *m_Addresses; };
private: private:
bool LoadFile (const std::string& fullPath); bool LoadFile (const std::string& fullPath);
@ -285,7 +285,7 @@ namespace data
template<typename Filter> template<typename Filter>
std::shared_ptr<const Address> GetAddress (Filter filter) const; std::shared_ptr<const Address> GetAddress (Filter filter) const;
virtual std::shared_ptr<Buffer> NewBuffer () const; virtual std::shared_ptr<Buffer> NewBuffer () const;
private: private:
FamilyID m_FamilyID; FamilyID m_FamilyID;
@ -309,22 +309,22 @@ namespace data
void CreateBuffer (const PrivateKeys& privateKeys); void CreateBuffer (const PrivateKeys& privateKeys);
void UpdateCaps (uint8_t caps); void UpdateCaps (uint8_t caps);
void SetProperty (const std::string& key, const std::string& value) override; void SetProperty (const std::string& key, const std::string& value) override;
void DeleteProperty (const std::string& key); void DeleteProperty (const std::string& key);
std::string GetProperty (const std::string& key) const; std::string GetProperty (const std::string& key) const;
void ClearProperties () override { m_Properties.clear (); }; void ClearProperties () override { m_Properties.clear (); };
private: private:
void WriteToStream (std::ostream& s) const; void WriteToStream (std::ostream& s) const;
void UpdateCapsProperty (); void UpdateCapsProperty ();
void WriteString (const std::string& str, std::ostream& s) const; void WriteString (const std::string& str, std::ostream& s) const;
std::shared_ptr<Buffer> NewBuffer () const override; std::shared_ptr<Buffer> NewBuffer () const override;
private: private:
std::map<std::string, std::string> m_Properties; std::map<std::string, std::string> m_Properties;
}; };
} }
} }

32
libi2pd/SSU.cpp

@ -273,14 +273,14 @@ namespace transport
void SSUServer::HandleReceivedFrom (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet) void SSUServer::HandleReceivedFrom (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet)
{ {
if (!ecode if (!ecode
|| ecode == boost::asio::error::connection_refused || ecode == boost::asio::error::connection_refused
|| ecode == boost::asio::error::connection_reset || ecode == boost::asio::error::connection_reset
|| ecode == boost::asio::error::network_unreachable || ecode == boost::asio::error::network_unreachable
|| ecode == boost::asio::error::host_unreachable || ecode == boost::asio::error::host_unreachable
#ifdef _WIN32 // windows can throw WinAPI error, which is not handled by ASIO #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_CONNECTION_REFUSED_
|| ecode.value() == boost::winapi::ERROR_NETWORK_UNREACHABLE_ || ecode.value() == boost::winapi::ERROR_NETWORK_UNREACHABLE_
|| ecode.value() == boost::winapi::ERROR_HOST_UNREACHABLE_ || ecode.value() == boost::winapi::ERROR_HOST_UNREACHABLE_
#endif #endif
) )
// just try continue reading when received ICMP response otherwise socket can crash, // 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) void SSUServer::HandleReceivedFromV6 (const boost::system::error_code& ecode, std::size_t bytes_transferred, SSUPacket * packet)
{ {
if (!ecode if (!ecode
|| ecode == boost::asio::error::connection_refused || ecode == boost::asio::error::connection_refused
|| ecode == boost::asio::error::connection_reset || ecode == boost::asio::error::connection_reset
|| ecode == boost::asio::error::network_unreachable || ecode == boost::asio::error::network_unreachable
|| ecode == boost::asio::error::host_unreachable || ecode == boost::asio::error::host_unreachable
#ifdef _WIN32 // windows can throw WinAPI error, which is not handled by ASIO #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_CONNECTION_REFUSED_
|| ecode.value() == boost::winapi::ERROR_NETWORK_UNREACHABLE_ || ecode.value() == boost::winapi::ERROR_NETWORK_UNREACHABLE_
|| ecode.value() == boost::winapi::ERROR_HOST_UNREACHABLE_ || ecode.value() == boost::winapi::ERROR_HOST_UNREACHABLE_
#endif #endif
) )
// just try continue reading when received ICMP response otherwise socket can crash, // just try continue reading when received ICMP response otherwise socket can crash,
@ -582,7 +582,7 @@ namespace transport
"] through introducer ", introducer->iHost, ":", introducer->iPort); "] through introducer ", introducer->iHost, ":", introducer->iPort);
session->WaitForIntroduction (); session->WaitForIntroduction ();
if ((address->host.is_v4 () && i2p::context.GetStatus () == eRouterStatusFirewalled) || 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]; uint8_t buf[1];
Send (buf, 0, remoteEndpoint); // send HolePunch Send (buf, 0, remoteEndpoint); // send HolePunch
@ -676,7 +676,7 @@ namespace transport
for (const auto& s : sessions) for (const auto& s : sessions)
{ {
if (s.second->GetRelayTag () && s.second->GetState () == eSessionStateEstablished && 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); ret.push_back (s.second);
else if (s.second->GetRemoteIdentity ()) else if (s.second->GetRemoteIdentity ())
excluded.insert (s.second->GetRemoteIdentity ()->GetIdentHash ()); excluded.insert (s.second->GetRemoteIdentity ()->GetIdentHash ());

764
libi2pd/SSU2.cpp

File diff suppressed because it is too large Load Diff

84
libi2pd/SSU2.h

@ -35,9 +35,9 @@ namespace transport
const size_t SSU2_MAX_PAYLOAD_SIZE = SSU2_MTU - 32; const size_t SSU2_MAX_PAYLOAD_SIZE = SSU2_MTU - 32;
const int SSU2_RESEND_INTERVAL = 3; // in seconds const int SSU2_RESEND_INTERVAL = 3; // in seconds
const int SSU2_MAX_NUM_RESENDS = 5; 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 const size_t SSU2_MAX_WINDOW_SIZE = 128; // in packets
enum SSU2MessageType enum SSU2MessageType
{ {
eSSU2SessionRequest = 0, eSSU2SessionRequest = 0,
@ -94,17 +94,17 @@ namespace transport
size_t len; size_t len;
bool isLast; bool isLast;
}; };
std::shared_ptr<I2NPMessage> msg; std::shared_ptr<I2NPMessage> msg;
int nextFragmentNum; int nextFragmentNum;
uint32_t lastFragmentInsertTime; // in seconds uint32_t lastFragmentInsertTime; // in seconds
std::map<int, std::shared_ptr<Fragment> > outOfSequenceFragments; std::map<int, std::shared_ptr<Fragment> > outOfSequenceFragments;
}; };
// RouterInfo flags // RouterInfo flags
const uint8_t SSU2_ROUTER_INFO_FLAG_REQUEST_FLOOD = 0x01; 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 SSU2Server;
class SSU2Session: public TransportSession, public std::enable_shared_from_this<SSU2Session> class SSU2Session: public TransportSession, public std::enable_shared_from_this<SSU2Session>
{ {
@ -124,20 +124,20 @@ namespace transport
struct SentPacket struct SentPacket
{ {
uint8_t payload[SSU2_MAX_PAYLOAD_SIZE]; uint8_t payload[SSU2_MAX_PAYLOAD_SIZE];
size_t payloadSize = 0; size_t payloadSize = 0;
uint32_t nextResendTime; // in seconds uint32_t nextResendTime; // in seconds
int numResends = 0; int numResends = 0;
}; };
struct SessionConfirmedFragment struct SessionConfirmedFragment
{ {
Header header; Header header;
uint8_t payload[SSU2_MAX_PAYLOAD_SIZE]; uint8_t payload[SSU2_MAX_PAYLOAD_SIZE];
size_t payloadSize; size_t payloadSize;
}; };
typedef std::function<void ()> OnEstablished; typedef std::function<void ()> OnEstablished;
public: public:
SSU2Session (SSU2Server& server, std::shared_ptr<const i2p::data::RouterInfo> in_RemoteRouter = nullptr, 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; }; void SetRemoteEndpoint (const boost::asio::ip::udp::endpoint& ep) { m_RemoteEndpoint = ep; };
const boost::asio::ip::udp::endpoint& GetRemoteEndpoint () const { return m_RemoteEndpoint; }; const boost::asio::ip::udp::endpoint& GetRemoteEndpoint () const { return m_RemoteEndpoint; };
void SetOnEstablished (OnEstablished e) { m_OnEstablished = e; }; void SetOnEstablished (OnEstablished e) { m_OnEstablished = e; };
void Connect (); void Connect ();
bool Introduce (std::shared_ptr<SSU2Session> session, uint32_t relayTag); bool Introduce (std::shared_ptr<SSU2Session> session, uint32_t relayTag);
void Terminate (); void Terminate ();
@ -161,7 +161,7 @@ namespace transport
uint64_t GetConnID () const { return m_SourceConnID; }; uint64_t GetConnID () const { return m_SourceConnID; };
SSU2SessionState GetState () const { return m_State; }; SSU2SessionState GetState () const { return m_State; };
void SetState (SSU2SessionState state) { m_State = state; }; void SetState (SSU2SessionState state) { m_State = state; };
bool ProcessFirstIncomingMessage (uint64_t connID, uint8_t * buf, size_t len); bool ProcessFirstIncomingMessage (uint64_t connID, uint8_t * buf, size_t len);
bool ProcessSessionCreated (uint8_t * buf, size_t len); bool ProcessSessionCreated (uint8_t * buf, size_t len);
bool ProcessSessionConfirmed (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 ProcessHolePunch (uint8_t * buf, size_t len);
bool ProcessPeerTest (uint8_t * buf, size_t len); bool ProcessPeerTest (uint8_t * buf, size_t len);
void ProcessData (uint8_t * buf, size_t len); void ProcessData (uint8_t * buf, size_t len);
private: private:
void Established (); void Established ();
void PostI2NPMessages (std::vector<std::shared_ptr<I2NPMessage> > msgs); void PostI2NPMessages (std::vector<std::shared_ptr<I2NPMessage> > msgs);
bool SendQueue (); bool SendQueue ();
void SendFragmentedMessage (std::shared_ptr<I2NPMessage> msg); void SendFragmentedMessage (std::shared_ptr<I2NPMessage> msg);
void ProcessSessionRequest (Header& header, uint8_t * buf, size_t len); void ProcessSessionRequest (Header& header, uint8_t * buf, size_t len);
void ProcessTokenRequest (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 SendSessionRequest (uint64_t token = 0);
void SendSessionCreated (const uint8_t * X); void SendSessionCreated (const uint8_t * X);
void SendSessionConfirmed (const uint8_t * Y); void SendSessionConfirmed (const uint8_t * Y);
@ -190,8 +190,8 @@ namespace transport
void SendQuickAck (); void SendQuickAck ();
void SendTermination (); void SendTermination ();
void SendHolePunch (uint32_t nonce, const boost::asio::ip::udp::endpoint& ep, const uint8_t * introKey); 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 HandleAck (const uint8_t * buf, size_t len);
void HandleAckRange (uint32_t firstPacketNum, uint32_t lastPacketNum); void HandleAckRange (uint32_t firstPacketNum, uint32_t lastPacketNum);
bool ExtractEndpoint (const uint8_t * buf, size_t size, boost::asio::ip::udp::endpoint& ep); 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 HandleRelayIntro (const uint8_t * buf, size_t len);
void HandleRelayResponse (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); 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 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 CreateRouterInfoBlock (uint8_t * buf, size_t len, std::shared_ptr<const i2p::data::RouterInfo> r);
size_t CreateAckBlock (uint8_t * buf, size_t len); 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 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 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); size_t CreatePeerTestBlock (uint8_t * buf, size_t len, uint8_t msg, const uint8_t * routerHash, const uint8_t * signedData, size_t signedDataLen);
private: private:
SSU2Server& m_Server; SSU2Server& m_Server;
@ -228,12 +228,12 @@ namespace transport
boost::asio::ip::udp::endpoint m_RemoteEndpoint; boost::asio::ip::udp::endpoint m_RemoteEndpoint;
uint64_t m_DestConnID, m_SourceConnID; uint64_t m_DestConnID, m_SourceConnID;
SSU2SessionState m_State; 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; uint32_t m_SendPacketNum, m_ReceivePacketNum;
std::set<uint32_t> m_OutOfSequencePackets; // packet nums > receive packet num 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<SentPacket> > m_SentPackets; // packetNum -> packet
std::map<uint32_t, std::shared_ptr<SSU2IncompleteMessage> > m_IncompleteMessages; // I2NP 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::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; std::list<std::shared_ptr<I2NPMessage> > m_SendQueue;
i2p::I2NPMessagesHandler m_Handler; i2p::I2NPMessagesHandler m_Handler;
@ -243,14 +243,14 @@ namespace transport
OnEstablished m_OnEstablished; // callback from Established OnEstablished m_OnEstablished; // callback from Established
}; };
class SSU2Server: private i2p::util::RunnableServiceWithWork class SSU2Server: private i2p::util::RunnableServiceWithWork
{ {
struct Packet struct Packet
{ {
uint8_t buf[SSU2_MTU]; uint8_t buf[SSU2_MTU];
size_t len; size_t len;
boost::asio::ip::udp::endpoint from; boost::asio::ip::udp::endpoint from;
}; };
class ReceiveService: public i2p::util::RunnableService class ReceiveService: public i2p::util::RunnableService
{ {
@ -260,8 +260,8 @@ namespace transport
boost::asio::io_service& GetService () { return GetIOService (); }; boost::asio::io_service& GetService () { return GetIOService (); };
void Start () { StartIOService (); }; void Start () { StartIOService (); };
void Stop () { StopIOService (); }; void Stop () { StopIOService (); };
}; };
public: public:
SSU2Server (); SSU2Server ();
@ -270,33 +270,33 @@ namespace transport
void Start (); void Start ();
void Stop (); void Stop ();
boost::asio::io_service& GetService () { return GetIOService (); }; boost::asio::io_service& GetService () { return GetIOService (); };
void AddSession (std::shared_ptr<SSU2Session> session); void AddSession (std::shared_ptr<SSU2Session> session);
void RemoveSession (uint64_t connID); void RemoveSession (uint64_t connID);
void AddSessionByRouterHash (std::shared_ptr<SSU2Session> session); void AddSessionByRouterHash (std::shared_ptr<SSU2Session> session);
void AddPendingOutgoingSession (std::shared_ptr<SSU2Session> session); void AddPendingOutgoingSession (std::shared_ptr<SSU2Session> session);
void AddRelay (uint32_t tag, std::shared_ptr<SSU2Session> relay); 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); 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); 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); const uint8_t * payload, size_t payloadLen, const boost::asio::ip::udp::endpoint& to);
bool CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router, bool CreateSession (std::shared_ptr<const i2p::data::RouterInfo> router,
std::shared_ptr<const i2p::data::RouterInfo::Address> address); std::shared_ptr<const i2p::data::RouterInfo::Address> address);
void UpdateOutgoingToken (const boost::asio::ip::udp::endpoint& ep, uint64_t token, uint32_t exp); 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 FindOutgoingToken (const boost::asio::ip::udp::endpoint& ep) const;
uint64_t GetIncomingToken (const boost::asio::ip::udp::endpoint& ep); uint64_t GetIncomingToken (const boost::asio::ip::udp::endpoint& ep);
private: private:
boost::asio::ip::udp::socket& OpenSocket (const boost::asio::ip::udp::endpoint& localEndpoint); boost::asio::ip::udp::socket& OpenSocket (const boost::asio::ip::udp::endpoint& localEndpoint);
void Receive (boost::asio::ip::udp::socket& socket); 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); Packet * packet, boost::asio::ip::udp::socket& socket);
void HandleReceivedPacket (Packet * packet); void HandleReceivedPacket (Packet * packet);
void HandleReceivedPackets (std::vector<Packet *> packets); void HandleReceivedPackets (std::vector<Packet *> packets);
@ -310,16 +310,16 @@ namespace transport
void ConnectThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router, void ConnectThroughIntroducer (std::shared_ptr<const i2p::data::RouterInfo> router,
std::shared_ptr<const i2p::data::RouterInfo::Address> address); std::shared_ptr<const i2p::data::RouterInfo::Address> address);
private: private:
ReceiveService m_ReceiveService; ReceiveService m_ReceiveService;
boost::asio::ip::udp::socket m_SocketV4, m_SocketV6; boost::asio::ip::udp::socket m_SocketV4, m_SocketV6;
std::unordered_map<uint64_t, std::shared_ptr<SSU2Session> > m_Sessions; std::unordered_map<uint64_t, std::shared_ptr<SSU2Session> > m_Sessions;
std::map<i2p::data::IdentHash, std::shared_ptr<SSU2Session> > m_SessionsByRouterHash; 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::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<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; i2p::util::MemoryPoolMt<Packet> m_PacketsPool;
boost::asio::deadline_timer m_TerminationTimer, m_ResendTimer; boost::asio::deadline_timer m_TerminationTimer, m_ResendTimer;
std::shared_ptr<SSU2Session> m_LastSession; std::shared_ptr<SSU2Session> m_LastSession;
@ -327,8 +327,8 @@ namespace transport
public: public:
// for HTTP/I2PControl // for HTTP/I2PControl
const decltype(m_Sessions)& GetSSU2Sessions () const { return m_Sessions; }; const decltype(m_Sessions)& GetSSU2Sessions () const { return m_Sessions; };
}; };
} }
} }

4
libi2pd/SSUData.cpp

@ -171,7 +171,7 @@ namespace transport
return; return;
} }
// find message with msgID // find message with msgID
auto it = m_IncompleteMessages.find (msgID); auto it = m_IncompleteMessages.find (msgID);
if (it == m_IncompleteMessages.end ()) if (it == m_IncompleteMessages.end ())
{ {
@ -318,7 +318,7 @@ namespace transport
sentMessage->numResends = 0; sentMessage->numResends = 0;
} }
auto& fragments = sentMessage->fragments; 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 (); size_t len = msg->GetLength ();
uint8_t * msgBuf = msg->GetSSUHeader (); uint8_t * msgBuf = msg->GetSSUHeader ();

10
libi2pd/SSUSession.cpp

@ -296,8 +296,8 @@ namespace transport
{ {
LogPrint (eLogWarning, "SSU: Clock adjusted by ", -offset, " seconds"); LogPrint (eLogWarning, "SSU: Clock adjusted by ", -offset, " seconds");
i2p::util::AdjustTimeOffset (-offset); i2p::util::AdjustTimeOffset (-offset);
} }
} }
else if (std::abs (offset) > SSU_CLOCK_SKEW) else if (std::abs (offset) > SSU_CLOCK_SKEW)
{ {
LogPrint (eLogError, "SSU: Clock skew detected ", offset, ". Check your clock"); 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 // fill extended options, 3 bytes extended options don't change message size
bool isV4 = m_RemoteEndpoint.address ().is_v4 (); bool isV4 = m_RemoteEndpoint.address ().is_v4 ();
if ((isV4 && i2p::context.GetStatus () == eRouterStatusOK) || 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 // tell out peer to now assign relay tag
flag = SSU_HEADER_EXTENDED_OPTIONS_INCLUDED; 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 uint16_t flags = 0; // clear EXTENDED_OPTIONS_FLAG_REQUEST_RELAY_TAG
htobe16buf (payload, flags); htobe16buf (payload, flags);
payload += 2; payload += 2;
@ -1020,7 +1020,7 @@ namespace transport
for (auto it = m_RelayRequests.begin (); it != m_RelayRequests.end ();) for (auto it = m_RelayRequests.begin (); it != m_RelayRequests.end ();)
{ {
if (ts > it->second.second + SSU_CONNECT_TIMEOUT) if (ts > it->second.second + SSU_CONNECT_TIMEOUT)
it = m_RelayRequests.erase (it); it = m_RelayRequests.erase (it);
else else
++it; ++it;
} }

2
libi2pd/Signature.cpp

@ -130,7 +130,7 @@ namespace crypto
else else
{ {
size_t l = 64; 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); EVP_DigestSign (m_MDCtx, sig, &l, buf, len);
memcpy (signature, sig, 64); memcpy (signature, sig, 64);
} }

6
libi2pd/Streaming.cpp

@ -1249,7 +1249,7 @@ namespace stream
return s; 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); auto s = std::make_shared<Stream> (m_Owner->GetService (), *this, remote, 0);
s->SendPing (); s->SendPing ();
@ -1277,7 +1277,7 @@ namespace stream
{ {
m_PacketsPool.CleanUp (); m_PacketsPool.CleanUp ();
m_I2NPMsgsPool.CleanUp (); m_I2NPMsgsPool.CleanUp ();
} }
} }
bool StreamingDestination::DeleteStream (uint32_t recvStreamID) bool StreamingDestination::DeleteStream (uint32_t recvStreamID)
@ -1287,7 +1287,7 @@ namespace stream
return false; return false;
auto s = it->second; auto s = it->second;
m_Owner->GetService ().post ([this, s] () m_Owner->GetService ().post ([this, s] ()
{ {
s->Close (); // try to send FIN s->Close (); // try to send FIN
s->Terminate (false); s->Terminate (false);
DeleteStream (s); DeleteStream (s);

2
libi2pd/Timestamp.cpp

@ -254,6 +254,6 @@ namespace util
void AdjustTimeOffset (int64_t offset) void AdjustTimeOffset (int64_t offset)
{ {
g_TimeOffset += offset; g_TimeOffset += offset;
} }
} }
} }

2
libi2pd/Timestamp.h

@ -27,7 +27,7 @@ namespace util
void GetCurrentDate (char * date); // returns date as YYYYMMDD string, 9 bytes 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 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 void AdjustTimeOffset (int64_t offset); // in seconds from current
class NTPTimeSync class NTPTimeSync
{ {
public: public:

18
libi2pd/Transports.cpp

@ -219,7 +219,7 @@ namespace transport
} }
// create SSU2 server // create SSU2 server
if (enableSSU2) m_SSU2Server = new SSU2Server (); if (enableSSU2) m_SSU2Server = new SSU2Server ();
// bind to interfaces // bind to interfaces
bool ipv4; i2p::config::GetOption("ipv4", ipv4); bool ipv4; i2p::config::GetOption("ipv4", ipv4);
if (ipv4) if (ipv4)
@ -285,7 +285,7 @@ namespace transport
if (m_SSUServer) DetectExternalIP (); if (m_SSUServer) DetectExternalIP ();
} }
if (m_SSU2Server) m_SSU2Server->Start (); if (m_SSU2Server) m_SSU2Server->Start ();
m_PeerCleanupTimer->expires_from_now (boost::posix_time::seconds(5*SESSION_CREATION_TIMEOUT)); 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)); m_PeerCleanupTimer->async_wait (std::bind (&Transports::HandlePeerCleanupTimer, this, std::placeholders::_1));
@ -307,14 +307,14 @@ namespace transport
delete m_SSUServer; delete m_SSUServer;
m_SSUServer = nullptr; m_SSUServer = nullptr;
} }
if (m_SSU2Server) if (m_SSU2Server)
{ {
m_SSU2Server->Stop (); m_SSU2Server->Stop ();
delete m_SSU2Server; delete m_SSU2Server;
m_SSU2Server = nullptr; m_SSU2Server = nullptr;
} }
if (m_NTCP2Server) if (m_NTCP2Server)
{ {
m_NTCP2Server->Stop (); m_NTCP2Server->Stop ();
@ -569,7 +569,7 @@ namespace transport
} }
else else
peer.numAttempts += 2; peer.numAttempts += 2;
} }
LogPrint (eLogInfo, "Transports: No compatble NTCP2 or SSU addresses available"); LogPrint (eLogInfo, "Transports: No compatble NTCP2 or SSU addresses available");
i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed i2p::data::netdb.SetUnreachable (ident, true); // we are here because all connection attempts failed
peer.Done (); peer.Done ();
@ -829,18 +829,18 @@ namespace transport
} }
return i2p::data::netdb.FindRouter (ident); return i2p::data::netdb.FindRouter (ident);
} }
void Transports::RestrictRoutesToFamilies(const std::set<std::string>& families) void Transports::RestrictRoutesToFamilies(const std::set<std::string>& families)
{ {
std::lock_guard<std::mutex> lock(m_FamilyMutex); std::lock_guard<std::mutex> lock(m_FamilyMutex);
m_TrustedFamilies.clear(); m_TrustedFamilies.clear();
for (auto fam : families) for (auto fam : families)
{ {
boost::to_lower (fam); boost::to_lower (fam);
auto id = i2p::data::netdb.GetFamilies ().GetFamilyID (fam); auto id = i2p::data::netdb.GetFamilies ().GetFamilyID (fam);
if (id) if (id)
m_TrustedFamilies.push_back (id); m_TrustedFamilies.push_back (id);
} }
} }
void Transports::RestrictRoutesToRouters(std::set<i2p::data::IdentHash> routers) void Transports::RestrictRoutesToRouters(std::set<i2p::data::IdentHash> routers)

6
libi2pd/Tunnel.cpp

@ -108,7 +108,7 @@ namespace tunnel
else else
{ {
if (m_Config->IsShort () && m_Config->GetLastHop () && 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 // add garlic key/tag for reply
uint8_t key[32]; uint8_t key[32];
@ -403,7 +403,7 @@ namespace tunnel
return 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) int numInboundTunnels, int numOutboundTunnels, int inboundVariance, int outboundVariance)
{ {
auto pool = std::make_shared<TunnelPool> (numInboundHops, numOutboundHops, numInboundTunnels, numOutboundTunnels, inboundVariance, outboundVariance); auto pool = std::make_shared<TunnelPool> (numInboundHops, numOutboundHops, numInboundTunnels, numOutboundTunnels, inboundVariance, outboundVariance);
@ -822,7 +822,7 @@ namespace tunnel
template<class TTunnel> template<class TTunnel>
std::shared_ptr<TTunnel> Tunnels::CreateTunnel (std::shared_ptr<TunnelConfig> config, 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); auto newTunnel = std::make_shared<TTunnel> (config);
newTunnel->SetTunnelPool (pool); newTunnel->SetTunnelPool (pool);

4
libi2pd/Tunnel.h

@ -215,7 +215,7 @@ namespace tunnel
void PostTunnelData (const std::vector<std::shared_ptr<I2NPMessage> >& msgs); 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<InboundTunnel> tunnel);
void AddPendingTunnel (uint32_t replyMsgID, std::shared_ptr<OutboundTunnel> 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); int numInboundTunnels, int numOutboundTunnels, int inboundVariance, int outboundVariance);
void DeleteTunnelPool (std::shared_ptr<TunnelPool> pool); void DeleteTunnelPool (std::shared_ptr<TunnelPool> pool);
void StopTunnelPool (std::shared_ptr<TunnelPool> pool); void StopTunnelPool (std::shared_ptr<TunnelPool> pool);
@ -226,7 +226,7 @@ namespace tunnel
template<class TTunnel> template<class TTunnel>
std::shared_ptr<TTunnel> CreateTunnel (std::shared_ptr<TunnelConfig> config, 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> template<class TTunnel>
std::shared_ptr<TTunnel> GetPendingTunnel (uint32_t replyMsgID, const std::map<uint32_t, std::shared_ptr<TTunnel> >& pendingTunnels); std::shared_ptr<TTunnel> GetPendingTunnel (uint32_t replyMsgID, const std::map<uint32_t, std::shared_ptr<TTunnel> >& pendingTunnels);

2
libi2pd/TunnelConfig.cpp

@ -167,7 +167,7 @@ namespace tunnel
memset (clearText + SHORT_REQUEST_RECORD_MORE_FLAGS_OFFSET, 0, 2); memset (clearText + SHORT_REQUEST_RECORD_MORE_FLAGS_OFFSET, 0, 2);
clearText[SHORT_REQUEST_RECORD_LAYER_ENCRYPTION_TYPE] = 0; // AES 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_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); 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); memset (clearText + SHORT_REQUEST_RECORD_PADDING_OFFSET, 0, SHORT_REQUEST_RECORD_CLEAR_TEXT_SIZE - SHORT_REQUEST_RECORD_PADDING_OFFSET);
// encrypt // encrypt

2
libi2pd/TunnelConfig.h

@ -91,7 +91,7 @@ namespace tunnel
TunnelConfig (const std::vector<std::shared_ptr<const i2p::data::IdentityEx> >& peers, TunnelConfig (const std::vector<std::shared_ptr<const i2p::data::IdentityEx> >& peers,
uint32_t replyTunnelID, const i2p::data::IdentHash& replyIdent, bool isShort, 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) m_IsShort (isShort), m_FarEndTransports (farEndTransports)
{ {
CreatePeers (peers); CreatePeers (peers);

34
libi2pd/TunnelPool.cpp

@ -30,7 +30,7 @@ namespace tunnel
{ {
peers.push_back (r->GetRouterIdentity ()); peers.push_back (r->GetRouterIdentity ());
if (r->GetVersion () < i2p::data::NETDB_MIN_SHORT_TUNNEL_BUILD_VERSION || 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; isShort = false;
} }
} }
@ -40,11 +40,11 @@ namespace tunnel
std::reverse (peers.begin (), peers.end ()); 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): int numOutboundTunnels, int inboundVariance, int outboundVariance):
m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops), m_NumInboundHops (numInboundHops), m_NumOutboundHops (numOutboundHops),
m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels), m_NumInboundTunnels (numInboundTunnels), m_NumOutboundTunnels (numOutboundTunnels),
m_InboundVariance (inboundVariance), m_OutboundVariance (outboundVariance), m_InboundVariance (inboundVariance), m_OutboundVariance (outboundVariance),
m_IsActive (true), m_CustomPeerSelector(nullptr) m_IsActive (true), m_CustomPeerSelector(nullptr)
{ {
if (m_NumInboundTunnels > TUNNEL_POOL_MAX_INBOUND_TUNNELS_QUANTITY) if (m_NumInboundTunnels > TUNNEL_POOL_MAX_INBOUND_TUNNELS_QUANTITY)
@ -54,11 +54,11 @@ namespace tunnel
if (m_InboundVariance < 0 && m_NumInboundHops + m_InboundVariance <= 0) if (m_InboundVariance < 0 && m_NumInboundHops + m_InboundVariance <= 0)
m_InboundVariance = m_NumInboundHops ? -m_NumInboundHops + 1 : 0; m_InboundVariance = m_NumInboundHops ? -m_NumInboundHops + 1 : 0;
if (m_OutboundVariance < 0 && m_NumOutboundHops + m_OutboundVariance <= 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) if (m_InboundVariance > 0 && m_NumInboundHops + m_InboundVariance > STANDARD_NUM_RECORDS)
m_InboundVariance = (m_NumInboundHops < STANDARD_NUM_RECORDS) ? STANDARD_NUM_RECORDS - m_NumInboundHops : 0; m_InboundVariance = (m_NumInboundHops < STANDARD_NUM_RECORDS) ? STANDARD_NUM_RECORDS - m_NumInboundHops : 0;
if (m_OutboundVariance > 0 && m_NumOutboundHops + m_OutboundVariance > STANDARD_NUM_RECORDS) 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; 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->IsEstablished () && it != excluded && (compatible & it->GetFarEndTransports ()))
{ {
if (it->IsSlow () || (HasLatencyRequirement() && it->LatencyIsKnown() && if (it->IsSlow () || (HasLatencyRequirement() && it->LatencyIsKnown() &&
!it->LatencyFitsRange(m_MinLatency, m_MaxLatency))) !it->LatencyFitsRange(m_MinLatency, m_MaxLatency)))
{ {
i++; skipped = true; i++; skipped = true;
continue; continue;
@ -423,7 +423,7 @@ namespace tunnel
LogPrint (eLogDebug, "Tunnels: Test of ", msgID, " successful. ", dlt, " milliseconds"); LogPrint (eLogDebug, "Tunnels: Test of ", msgID, " successful. ", dlt, " milliseconds");
int numHops = 0; int numHops = 0;
if (test.first) numHops += test.first->GetNumHops (); 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 // restore from test failed state if any
if (test.first) if (test.first)
{ {
@ -431,7 +431,7 @@ namespace tunnel
test.first->SetState (eTunnelStateEstablished); test.first->SetState (eTunnelStateEstablished);
// update latency // update latency
uint64_t latency = 0; 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; if (!latency) latency = dlt/2;
test.first->AddLatencySample(latency); test.first->AddLatencySample(latency);
} }
@ -441,7 +441,7 @@ namespace tunnel
test.second->SetState (eTunnelStateEstablished); test.second->SetState (eTunnelStateEstablished);
// update latency // update latency
uint64_t latency = 0; 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; if (!latency) latency = dlt/2;
test.second->AddLatencySample(latency); test.second->AddLatencySample(latency);
} }
@ -511,7 +511,7 @@ namespace tunnel
return false; return false;
} }
if ((i == numHops - 1) && (!hop->IsV4 () || // doesn't support ipv4 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); auto hop1 = nextHop (prevHop, true);
if (hop1) hop = hop1; if (hop1) hop = hop1;
@ -530,25 +530,25 @@ namespace tunnel
// calculate num hops // calculate num hops
int numHops; int numHops;
if (isInbound) if (isInbound)
{ {
numHops = m_NumInboundHops; numHops = m_NumInboundHops;
if (m_InboundVariance) if (m_InboundVariance)
{ {
int offset = rand () % (std::abs (m_InboundVariance) + 1); int offset = rand () % (std::abs (m_InboundVariance) + 1);
if (m_InboundVariance < 0) offset = -offset; if (m_InboundVariance < 0) offset = -offset;
numHops += offset; numHops += offset;
} }
} }
else else
{ {
numHops = m_NumOutboundHops; numHops = m_NumOutboundHops;
if (m_OutboundVariance) if (m_OutboundVariance)
{ {
int offset = rand () % (std::abs (m_OutboundVariance) + 1); int offset = rand () % (std::abs (m_OutboundVariance) + 1);
if (m_OutboundVariance < 0) offset = -offset; if (m_OutboundVariance < 0) offset = -offset;
numHops += offset; numHops += offset;
} }
} }
// peers is empty // peers is empty
if (numHops <= 0) return true; if (numHops <= 0) return true;
// custom peer selector in use ? // custom peer selector in use ?
@ -715,7 +715,7 @@ namespace tunnel
auto tunnel = tunnels.CreateInboundTunnel ( auto tunnel = tunnels.CreateInboundTunnel (
m_NumOutboundHops > 0 ? std::make_shared<TunnelConfig>(outboundTunnel->GetInvertedPeers (), m_NumOutboundHops > 0 ? std::make_shared<TunnelConfig>(outboundTunnel->GetInvertedPeers (),
outboundTunnel->IsShortBuildMessage ()) : nullptr, outboundTunnel->IsShortBuildMessage ()) : nullptr,
shared_from_this (), outboundTunnel); shared_from_this (), outboundTunnel);
if (tunnel->IsEstablished ()) // zero hops if (tunnel->IsEstablished ()) // zero hops
TunnelCreated (tunnel); TunnelCreated (tunnel);
} }

4
libi2pd/TunnelPool.h

@ -61,7 +61,7 @@ namespace tunnel
{ {
public: public:
TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels, TunnelPool (int numInboundHops, int numOutboundHops, int numInboundTunnels,
int numOutboundTunnels, int inboundVariance, int outboundVariance); int numOutboundTunnels, int inboundVariance, int outboundVariance);
~TunnelPool (); ~TunnelPool ();
@ -131,7 +131,7 @@ namespace tunnel
private: private:
std::shared_ptr<i2p::garlic::GarlicDestination> m_LocalDestination; 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; m_InboundVariance, m_OutboundVariance;
std::shared_ptr<std::vector<i2p::data::IdentHash> > m_ExplicitPeers; std::shared_ptr<std::vector<i2p::data::IdentHash> > m_ExplicitPeers;
mutable std::mutex m_InboundTunnelsMutex; mutable std::mutex m_InboundTunnelsMutex;

2
libi2pd/util.cpp

@ -517,7 +517,7 @@ namespace net
bool IsLocalAddress (const boost::asio::ip::address& addr) bool IsLocalAddress (const boost::asio::ip::address& addr)
{ {
auto mtu = // TODO: implement better auto mtu = // TODO: implement better
#ifdef _WIN32 #ifdef _WIN32
GetMTUWindows(addr, 0); GetMTUWindows(addr, 0);
#else #else

10
libi2pd_client/AddressBook.cpp

@ -372,7 +372,7 @@ namespace client
{ {
auto addr = FindAddress (address); auto addr = FindAddress (address);
if (!addr) if (!addr)
LookupAddress (address); // TODO: LookupAddress (address); // TODO:
return addr; return addr;
} }
} }
@ -494,7 +494,7 @@ namespace client
auto it = m_Addresses.find (name); auto it = m_Addresses.find (name);
if (it != m_Addresses.end ()) // already exists ? 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 ident->GetSigningKeyType () != i2p::data::SIGNING_KEY_TYPE_DSA_SHA1) // don't replace by DSA
{ {
it->second->identHash = ident->GetIdentHash (); it->second->identHash = ident->GetIdentHash ();
@ -858,9 +858,9 @@ namespace client
if (!m_LastModified.empty()) if (!m_LastModified.empty())
req.AddHeader("If-Modified-Since", m_LastModified); req.AddHeader("If-Modified-Since", m_LastModified);
/* convert url to relative */ /* convert url to relative */
url.schema = ""; url.schema = "";
url.host = ""; url.host = "";
req.uri = url.to_string(); req.uri = url.to_string();
req.version = "HTTP/1.1"; req.version = "HTTP/1.1";
auto stream = i2p::client::context.GetSharedLocalDestination ()->CreateStream (leaseSet, dest_port); auto stream = i2p::client::context.GetSharedLocalDestination ()->CreateStream (leaseSet, dest_port);
std::string request = req.to_string(); std::string request = req.to_string();

4
libi2pd_client/AddressBook.h

@ -116,7 +116,7 @@ namespace client
private: private:
std::mutex m_AddressBookMutex; 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::map<i2p::data::IdentHash, std::shared_ptr<AddressResolver> > m_Resolvers; // local destination->resolver
std::mutex m_LookupsMutex; std::mutex m_LookupsMutex;
std::map<uint32_t, std::string> m_Lookups; // nonce -> address std::map<uint32_t, std::string> m_Lookups; // nonce -> address
@ -162,7 +162,7 @@ namespace client
private: private:
std::shared_ptr<ClientDestination> m_LocalDestination; std::shared_ptr<ClientDestination> m_LocalDestination;
std::map<std::string, i2p::data::IdentHash> m_LocalAddresses; std::map<std::string, i2p::data::IdentHash> m_LocalAddresses;
}; };
} }
} }

2
libi2pd_client/ClientContext.cpp

@ -898,7 +898,7 @@ namespace client
bool socksproxy; i2p::config::GetOption("socksproxy.enabled", socksproxy); bool socksproxy; i2p::config::GetOption("socksproxy.enabled", socksproxy);
if (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 // we still need httpProxyKeys to compare with sockProxyKeys
std::string socksProxyKeys; i2p::config::GetOption("socksproxy.keys", socksProxyKeys); std::string socksProxyKeys; i2p::config::GetOption("socksproxy.keys", socksProxyKeys);
std::string socksProxyAddr; i2p::config::GetOption("socksproxy.address", socksProxyAddr); std::string socksProxyAddr; i2p::config::GetOption("socksproxy.address", socksProxyAddr);

26
libi2pd_client/I2CP.cpp

@ -24,7 +24,7 @@ namespace client
{ {
I2CPDestination::I2CPDestination (boost::asio::io_service& service, std::shared_ptr<I2CPSession> owner, 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, &params), LeaseSetDestination (service, isPublic, &params),
m_Owner (owner), m_Identity (identity), m_EncryptionKeyType (m_Identity->GetCryptoKeyType ()), m_Owner (owner), m_Identity (identity), m_EncryptionKeyType (m_Identity->GetCryptoKeyType ()),
m_IsCreatingLeaseSet (false), m_LeaseSetCreationTimer (service) m_IsCreatingLeaseSet (false), m_LeaseSetCreationTimer (service)
@ -208,12 +208,12 @@ namespace client
if (leases.empty ()) if (leases.empty ())
leases = remote->GetNonExpiredLeases (true); // with threshold leases = remote->GetNonExpiredLeases (true); // with threshold
if (!leases.empty ()) if (!leases.empty ())
{ {
remoteLease = leases[rand () % leases.size ()]; remoteLease = leases[rand () % leases.size ()];
auto leaseRouter = i2p::data::netdb.FindRouter (remoteLease->tunnelGateway); auto leaseRouter = i2p::data::netdb.FindRouter (remoteLease->tunnelGateway);
outboundTunnel = GetTunnelPool ()->GetNextOutboundTunnel (nullptr, outboundTunnel = GetTunnelPool ()->GetNextOutboundTunnel (nullptr,
leaseRouter ? leaseRouter->GetCompatibleTransports (false) : (i2p::data::RouterInfo::CompatibleTransports)i2p::data::RouterInfo::eAllTransports); leaseRouter ? leaseRouter->GetCompatibleTransports (false) : (i2p::data::RouterInfo::CompatibleTransports)i2p::data::RouterInfo::eAllTransports);
} }
if (remoteLease && outboundTunnel) if (remoteLease && outboundTunnel)
remoteSession->SetSharedRoutingPath (std::make_shared<i2p::garlic::GarlicRoutingPath> ( remoteSession->SetSharedRoutingPath (std::make_shared<i2p::garlic::GarlicRoutingPath> (
i2p::garlic::GarlicRoutingPath{outboundTunnel, remoteLease, 10000, 0, 0})); // 10 secs RTT 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); auto len = m_SendQueue.Get (m_SendBuffer, I2CP_MAX_MESSAGE_LENGTH);
boost::asio::async_write (*socket, boost::asio::buffer (m_SendBuffer, len), boost::asio::async_write (*socket, boost::asio::buffer (m_SendBuffer, len),
boost::asio::transfer_all (),std::bind(&I2CPSession::HandleI2CPMessageSent, boost::asio::transfer_all (),std::bind(&I2CPSession::HandleI2CPMessageSent,
shared_from_this (), std::placeholders::_1, std::placeholders::_2)); shared_from_this (), std::placeholders::_1, std::placeholders::_2));
} }
else else
m_IsSending = false; m_IsSending = false;
@ -538,7 +538,7 @@ namespace client
LogPrint (eLogError, "I2CP: Create session duplicate address ", identity->GetIdentHash ().ToBase32 ()); LogPrint (eLogError, "I2CP: Create session duplicate address ", identity->GetIdentHash ().ToBase32 ());
SendSessionStatusMessage (eI2CPSessionStatusInvalid); // invalid SendSessionStatusMessage (eI2CPSessionStatusInvalid); // invalid
return; return;
} }
uint16_t optionsSize = bufbe16toh (buf + offset); uint16_t optionsSize = bufbe16toh (buf + offset);
offset += 2; offset += 2;
if (optionsSize > len - offset) 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<I2CPDestination>(m_Owner.GetService (), shared_from_this (), identity, true, params):
std::make_shared<RunnableI2CPDestination>(shared_from_this (), identity, true, params); std::make_shared<RunnableI2CPDestination>(shared_from_this (), identity, true, params);
if (m_Owner.InsertSession (shared_from_this ())) if (m_Owner.InsertSession (shared_from_this ()))
{ {
SendSessionStatusMessage (eI2CPSessionStatusCreated); // created SendSessionStatusMessage (eI2CPSessionStatusCreated); // created
LogPrint (eLogDebug, "I2CP: Session ", m_SessionID, " created"); LogPrint (eLogDebug, "I2CP: Session ", m_SessionID, " created");
m_Destination->Start (); m_Destination->Start ();
} }
else else
{ {
LogPrint (eLogError, "I2CP: Session already exists"); LogPrint (eLogError, "I2CP: Session already exists");
SendSessionStatusMessage (eI2CPSessionStatusRefused); SendSessionStatusMessage (eI2CPSessionStatusRefused);
} }
} }
else else
{ {
@ -712,7 +712,7 @@ namespace client
{ {
if (offset + 4 > len) return; if (offset + 4 > len) return;
uint16_t keyType = bufbe16toh (buf + offset); offset += 2; // encryption type 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 (offset + keyLen > len) return;
if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD) if (keyType == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)
m_Destination->SetECIESx25519EncryptionPrivateKey (buf + offset); m_Destination->SetECIESx25519EncryptionPrivateKey (buf + offset);
@ -1030,13 +1030,13 @@ namespace client
for (const auto& it: m_Sessions) for (const auto& it: m_Sessions)
{ {
if (it.second) if (it.second)
{ {
auto dest = it.second->GetDestination (); auto dest = it.second->GetDestination ();
if (dest && dest->GetIdentHash () == ident) if (dest && dest->GetIdentHash () == ident)
return it.second; return it.second;
} }
} }
return nullptr; return nullptr;
} }
} }
} }

2
libi2pd_client/I2CP.h

@ -69,7 +69,7 @@ namespace client
eI2CPSessionStatusInvalid = 3, eI2CPSessionStatusInvalid = 3,
eI2CPSessionStatusRefused = 4 eI2CPSessionStatusRefused = 4
}; };
// params // params
const char I2CP_PARAM_MESSAGE_RELIABILITY[] = "i2cp.messageReliability"; const char I2CP_PARAM_MESSAGE_RELIABILITY[] = "i2cp.messageReliability";

4
libi2pd_client/I2PTunnel.h

@ -31,7 +31,7 @@ namespace client
const int I2P_TUNNEL_CONNECTION_MAX_IDLE = 3600; // in seconds const int I2P_TUNNEL_CONNECTION_MAX_IDLE = 3600; // in seconds
const int I2P_TUNNEL_DESTINATION_REQUEST_TIMEOUT = 10; // in seconds const int I2P_TUNNEL_DESTINATION_REQUEST_TIMEOUT = 10; // in seconds
// for HTTP tunnels // 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_B64[] = "X-I2P-DestB64"; // full address in base64
const char X_I2P_DEST_B32[] = "X-I2P-DestB32"; // .b32.i2p address 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 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, I2PTunnelConnection (I2PService * owner, std::shared_ptr<boost::asio::ip::tcp::socket> socket,
std::shared_ptr<i2p::stream::Stream> stream); // to I2P using simplified API 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 const boost::asio::ip::tcp::endpoint& target, bool quiet = true); // from I2P
~I2PTunnelConnection (); ~I2PTunnelConnection ();
void I2PConnect (const uint8_t * msg = nullptr, size_t len = 0); void I2PConnect (const uint8_t * msg = nullptr, size_t len = 0);

6
libi2pd_client/SAM.cpp

@ -1078,7 +1078,7 @@ namespace client
auto s = shared_from_this (); auto s = shared_from_this ();
newSocket->GetSocket ().async_connect (ep, newSocket->GetSocket ().async_connect (ep,
[s, newSocket, stream](const boost::system::error_code& ecode) [s, newSocket, stream](const boost::system::error_code& ecode)
{ {
if (!ecode) if (!ecode)
{ {
s->m_Owner.AddSocket (newSocket); 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) void SAMBridge::SendTo (const std::vector<boost::asio::const_buffer>& bufs, const boost::asio::ip::udp::endpoint& ep)
{ {
m_DatagramSocket.send_to (bufs, ep); m_DatagramSocket.send_to (bufs, ep);
} }
void SAMBridge::ReceiveDatagram () void SAMBridge::ReceiveDatagram ()
{ {
m_DatagramSocket.async_receive_from ( m_DatagramSocket.async_receive_from (

2
libi2pd_client/SAM.h

@ -250,7 +250,7 @@ namespace client
/** send raw data to remote endpoint from our UDP Socket */ /** 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 SendTo (const std::vector<boost::asio::const_buffer>& bufs, const boost::asio::ip::udp::endpoint& ep);
void AddSocket(std::shared_ptr<SAMSocket> socket); void AddSocket(std::shared_ptr<SAMSocket> socket);
void RemoveSocket(const std::shared_ptr<SAMSocket> & socket); void RemoveSocket(const std::shared_ptr<SAMSocket> & socket);

Loading…
Cancel
Save