mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-22 13:27:17 +01:00
cleanup code (spaces, tabs)
Signed-off-by: R4SAS <r4sas@i2pmail.org>
This commit is contained in:
parent
d31cd2e5d6
commit
6b4ffcff5a
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 ());
|
||||||
|
@ -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;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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 ())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
|
@ -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
|
||||||
|
|
|
@ -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 ();
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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 ();
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 ();
|
||||||
|
@ -399,7 +399,7 @@ namespace i2p
|
||||||
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)
|
||||||
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -723,7 +723,7 @@ namespace data
|
||||||
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)
|
||||||
|
@ -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);
|
||||||
|
|
|
@ -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; };
|
||||||
|
|
|
@ -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 ());
|
||||||
|
|
|
@ -280,7 +280,7 @@ namespace transport
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type);
|
LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -478,7 +478,7 @@ namespace transport
|
||||||
size_t payloadSize = CreateRouterInfoBlock (payload, maxPayloadSize, i2p::context.GetSharedRouterInfo ());
|
size_t payloadSize = CreateRouterInfoBlock (payload, maxPayloadSize, i2p::context.GetSharedRouterInfo ());
|
||||||
// TODO: check is RouterInfo doesn't fit and split by two fragments
|
// TODO: check is RouterInfo doesn't fit and split by two fragments
|
||||||
if (payloadSize < maxPayloadSize)
|
if (payloadSize < maxPayloadSize)
|
||||||
payloadSize += CreatePaddingBlock (payload + payloadSize, maxPayloadSize - payloadSize);
|
payloadSize += CreatePaddingBlock (payload + payloadSize, maxPayloadSize - payloadSize);
|
||||||
// KDF for Session Confirmed part 1
|
// KDF for Session Confirmed part 1
|
||||||
m_NoiseState->MixHash (header.buf, 16); // h = SHA256(h || header)
|
m_NoiseState->MixHash (header.buf, 16); // h = SHA256(h || header)
|
||||||
// Encrypt part 1
|
// Encrypt part 1
|
||||||
|
@ -515,7 +515,7 @@ namespace transport
|
||||||
header.ll[1] ^= CreateHeaderMask (kh2, buf + (len - 12));
|
header.ll[1] ^= CreateHeaderMask (kh2, buf + (len - 12));
|
||||||
if (header.h.type != eSSU2SessionConfirmed)
|
if (header.h.type != eSSU2SessionConfirmed)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type);
|
LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// check if fragmented
|
// check if fragmented
|
||||||
|
@ -722,7 +722,7 @@ namespace transport
|
||||||
header.ll[1] ^= CreateHeaderMask (m_Address->i, buf + (len - 12));
|
header.ll[1] ^= CreateHeaderMask (m_Address->i, buf + (len - 12));
|
||||||
if (header.h.type != eSSU2Retry)
|
if (header.h.type != eSSU2Retry)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type);
|
LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
uint8_t nonce[12] = {0};
|
uint8_t nonce[12] = {0};
|
||||||
|
@ -795,7 +795,7 @@ namespace transport
|
||||||
header.ll[1] ^= CreateHeaderMask (i2p::context.GetSSU2IntroKey (), buf + (len - 12));
|
header.ll[1] ^= CreateHeaderMask (i2p::context.GetSSU2IntroKey (), buf + (len - 12));
|
||||||
if (header.h.type != eSSU2HolePunch)
|
if (header.h.type != eSSU2HolePunch)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type);
|
LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
uint8_t nonce[12] = {0};
|
uint8_t nonce[12] = {0};
|
||||||
|
@ -835,7 +835,7 @@ namespace transport
|
||||||
header.ll[1] ^= CreateHeaderMask (i2p::context.GetSSU2IntroKey (), buf + (len - 12));
|
header.ll[1] ^= CreateHeaderMask (i2p::context.GetSSU2IntroKey (), buf + (len - 12));
|
||||||
if (header.h.type != eSSU2PeerTest)
|
if (header.h.type != eSSU2PeerTest)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type);
|
LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
uint8_t nonce[12] = {0};
|
uint8_t nonce[12] = {0};
|
||||||
|
@ -891,7 +891,7 @@ namespace transport
|
||||||
header.ll[1] ^= CreateHeaderMask (m_KeyDataReceive + 32, buf + (len - 12));
|
header.ll[1] ^= CreateHeaderMask (m_KeyDataReceive + 32, buf + (len - 12));
|
||||||
if (header.h.type != eSSU2Data)
|
if (header.h.type != eSSU2Data)
|
||||||
{
|
{
|
||||||
LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type);
|
LogPrint (eLogWarning, "SSU2: Unexpected message type ", (int)header.h.type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint8_t payload[SSU2_MTU];
|
uint8_t payload[SSU2_MTU];
|
||||||
|
@ -1260,7 +1260,7 @@ namespace transport
|
||||||
{
|
{
|
||||||
// update Charlie's endpoint and connect
|
// update Charlie's endpoint and connect
|
||||||
if (it->second.first->m_State == eSSU2SessionStateIntroduced &&
|
if (it->second.first->m_State == eSSU2SessionStateIntroduced &&
|
||||||
ExtractEndpoint (buf + 12, csz, it->second.first->m_RemoteEndpoint))
|
ExtractEndpoint (buf + 12, csz, it->second.first->m_RemoteEndpoint))
|
||||||
{
|
{
|
||||||
it->second.first->m_State = eSSU2SessionStateUnknown;
|
it->second.first->m_State = eSSU2SessionStateUnknown;
|
||||||
it->second.first->Connect ();
|
it->second.first->Connect ();
|
||||||
|
@ -1523,7 +1523,7 @@ namespace transport
|
||||||
{
|
{
|
||||||
buf[0] = eSSU2BlkRelayResponse;
|
buf[0] = eSSU2BlkRelayResponse;
|
||||||
buf[3] = 0; // flag
|
buf[3] = 0; // flag
|
||||||
buf[4] = 0; // code, accept
|
buf[4] = 0; // code, accept
|
||||||
htobe32buf (buf + 5, nonce); // nonce
|
htobe32buf (buf + 5, nonce); // nonce
|
||||||
htobe32buf (buf + 9, i2p::util::GetSecondsSinceEpoch ()); // timestamp
|
htobe32buf (buf + 9, i2p::util::GetSecondsSinceEpoch ()); // timestamp
|
||||||
buf[13] = 2; // ver
|
buf[13] = 2; // ver
|
||||||
|
@ -1710,7 +1710,7 @@ namespace transport
|
||||||
found = true;
|
found = true;
|
||||||
OpenSocket (boost::asio::ip::udp::endpoint (boost::asio::ip::udp::v4(), port));
|
OpenSocket (boost::asio::ip::udp::endpoint (boost::asio::ip::udp::v4(), port));
|
||||||
m_ReceiveService.GetService ().post(
|
m_ReceiveService.GetService ().post(
|
||||||
[this]()
|
[this]()
|
||||||
{
|
{
|
||||||
Receive (m_SocketV4);
|
Receive (m_SocketV4);
|
||||||
});
|
});
|
||||||
|
@ -1720,7 +1720,7 @@ namespace transport
|
||||||
found = true;
|
found = true;
|
||||||
OpenSocket (boost::asio::ip::udp::endpoint (boost::asio::ip::udp::v6(), port));
|
OpenSocket (boost::asio::ip::udp::endpoint (boost::asio::ip::udp::v6(), port));
|
||||||
m_ReceiveService.GetService ().post(
|
m_ReceiveService.GetService ().post(
|
||||||
[this]()
|
[this]()
|
||||||
{
|
{
|
||||||
Receive (m_SocketV6);
|
Receive (m_SocketV6);
|
||||||
});
|
});
|
||||||
|
@ -1762,7 +1762,7 @@ namespace transport
|
||||||
}
|
}
|
||||||
catch (std::exception& ex )
|
catch (std::exception& ex )
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "SSU2: Failed to bind to ", localEndpoint, ": ", ex.what());
|
LogPrint (eLogError, "SSU2: Failed to bind to ", localEndpoint, ": ", ex.what());
|
||||||
ThrowFatal ("Unable to start SSU2 transport on ", localEndpoint, ": ", ex.what ());
|
ThrowFatal ("Unable to start SSU2 transport on ", localEndpoint, ": ", ex.what ());
|
||||||
}
|
}
|
||||||
return socket;
|
return socket;
|
||||||
|
@ -1866,7 +1866,7 @@ namespace transport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SSU2Server::AddSessionByRouterHash (std::shared_ptr<SSU2Session> session)
|
void SSU2Server::AddSessionByRouterHash (std::shared_ptr<SSU2Session> session)
|
||||||
{
|
{
|
||||||
if (session)
|
if (session)
|
||||||
{
|
{
|
||||||
|
@ -2065,7 +2065,7 @@ namespace transport
|
||||||
{
|
{
|
||||||
if (relayTag)
|
if (relayTag)
|
||||||
{
|
{
|
||||||
// introducer and tag found connect to it through SSU2
|
// introducer and tag found connect to it through SSU2
|
||||||
auto addr = address->IsV6 () ? r->GetSSU2V6Address () : r->GetSSU2V4Address ();
|
auto addr = address->IsV6 () ? r->GetSSU2V6Address () : r->GetSSU2V4Address ();
|
||||||
if (addr)
|
if (addr)
|
||||||
{
|
{
|
||||||
|
@ -2117,7 +2117,7 @@ namespace transport
|
||||||
if (it->second->IsEstablished ())
|
if (it->second->IsEstablished ())
|
||||||
it->second->TerminateByTimeout ();
|
it->second->TerminateByTimeout ();
|
||||||
if (it->second == m_LastSession)
|
if (it->second == m_LastSession)
|
||||||
m_LastSession = nullptr;
|
m_LastSession = nullptr;
|
||||||
it = m_Sessions.erase (it);
|
it = m_Sessions.erase (it);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -243,7 +243,7 @@ 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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 ();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ();
|
||||||
|
|
|
@ -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];
|
||||||
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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, ¶ms),
|
LeaseSetDestination (service, isPublic, ¶ms),
|
||||||
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)
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue