mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-04-27 11:17:49 +02:00
Merge remote-tracking branch 'purple/openssl' into openssl
This commit is contained in:
commit
16b3108719
66 changed files with 741 additions and 224 deletions
|
@ -7,6 +7,8 @@
|
|||
Kovri go write your own code
|
||||
|
||||
*/
|
||||
|
||||
#if LEGACY_OPENSSL
|
||||
namespace i2p
|
||||
{
|
||||
namespace crypto
|
||||
|
@ -144,4 +146,6 @@ void chacha20(uint8_t * buf, size_t sz, const uint8_t * nonce, const uint8_t * k
|
|||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
#define LIBI2PD_CHACHA20_H
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include "Crypto.h"
|
||||
|
||||
#if LEGACY_OPENSSL
|
||||
namespace i2p
|
||||
{
|
||||
namespace crypto
|
||||
|
@ -22,5 +24,6 @@ namespace crypto
|
|||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace config {
|
|||
options_description general("General options");
|
||||
general.add_options()
|
||||
("help", "Show this message")
|
||||
("version", "Show i2pd version")
|
||||
("conf", value<std::string>()->default_value(""), "Path to main i2pd config file (default: try ~/.i2pd/i2pd.conf or /var/lib/i2pd/i2pd.conf)")
|
||||
("tunconf", value<std::string>()->default_value(""), "Path to config with tunnels list and options (default: try ~/.i2pd/tunnels.conf or /var/lib/i2pd/tunnels.conf)")
|
||||
("tunnelsdir", value<std::string>()->default_value(""), "Path to extra tunnels' configs folder (default: ~/.i2pd/tunnels.d or /var/lib/i2pd/tunnels.d")
|
||||
|
@ -87,6 +88,7 @@ namespace config {
|
|||
("http.pass", value<std::string>()->default_value(""), "Password for basic auth (default: random, see logs)")
|
||||
("http.strictheaders", value<bool>()->default_value(true), "Enable strict host checking on WebUI")
|
||||
("http.hostname", value<std::string>()->default_value("localhost"), "Expected hostname for WebUI")
|
||||
("http.webroot", value<std::string>()->default_value("/"), "WebUI root path (default: / )")
|
||||
;
|
||||
|
||||
options_description httpproxy("HTTP Proxy options");
|
||||
|
@ -235,10 +237,27 @@ namespace config {
|
|||
options_description ntcp2("NTCP2 Options");
|
||||
ntcp2.add_options()
|
||||
("ntcp2.enabled", value<bool>()->default_value(true), "Enable NTCP2 (default: enabled)")
|
||||
("ntcp2.published", value<bool>()->default_value(false), "Publish NTCP2 (default: disabled)")
|
||||
("ntcp2.published", value<bool>()->default_value(false), "Publish NTCP2 (default: disabled)")
|
||||
("ntcp2.port", value<uint16_t>()->default_value(0), "Port to listen for incoming NTCP2 connections (default: auto)")
|
||||
;
|
||||
|
||||
options_description nettime("Time sync options");
|
||||
nettime.add_options()
|
||||
("nettime.enabled", value<bool>()->default_value(false), "Disable time sync (default: disabled)")
|
||||
("nettime.ntpservers", value<std::string>()->default_value(
|
||||
"0.pool.ntp.org,"
|
||||
"1.pool.ntp.org,"
|
||||
"2.pool.ntp.org,"
|
||||
"3.pool.ntp.org"
|
||||
), "Comma separated list of NTCP servers")
|
||||
("nettime.ntpsyncinterval", value<int>()->default_value(72), "NTP sync interval in hours (default: 72)")
|
||||
;
|
||||
|
||||
options_description persist("Network information persisting options");
|
||||
persist.add_options()
|
||||
("persist.profiles", value<bool>()->default_value(true), "Persist peer profiles (default: true)")
|
||||
;
|
||||
|
||||
m_OptionsDesc
|
||||
.add(general)
|
||||
.add(limits)
|
||||
|
@ -257,6 +276,8 @@ namespace config {
|
|||
.add(websocket)
|
||||
.add(exploratory)
|
||||
.add(ntcp2)
|
||||
.add(nettime)
|
||||
.add(persist)
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -282,6 +303,23 @@ namespace config {
|
|||
{
|
||||
std::cout << "i2pd version " << I2PD_VERSION << " (" << I2P_VERSION << ")" << std::endl;
|
||||
std::cout << m_OptionsDesc;
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
else if (m_Options.count("version"))
|
||||
{
|
||||
std::cout << "i2pd version " << I2PD_VERSION << " (" << I2P_VERSION << ")" << std::endl;
|
||||
std::cout << "Boost version "
|
||||
<< BOOST_VERSION / 100000 << "." // maj. version
|
||||
<< BOOST_VERSION / 100 % 1000 << "." // min. version
|
||||
<< BOOST_VERSION % 100 // patch version
|
||||
<< std::endl;
|
||||
#if defined(OPENSSL_VERSION_TEXT)
|
||||
std::cout << OPENSSL_VERSION_TEXT << std::endl;
|
||||
#endif
|
||||
#if defined(LIBRESSL_VERSION_TEXT)
|
||||
std::cout << LIBRESSL_VERSION_TEXT << std::endl;
|
||||
#endif
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -341,6 +341,16 @@ namespace crypto
|
|||
#endif
|
||||
}
|
||||
|
||||
void X25519Keys::GetPrivateKey (uint8_t * priv) const
|
||||
{
|
||||
#if OPENSSL_X25519
|
||||
size_t len = 32;
|
||||
EVP_PKEY_get_raw_private_key (m_Pkey, priv, &len);
|
||||
#else
|
||||
memcpy (priv, m_PrivateKey, 32);
|
||||
#endif
|
||||
}
|
||||
|
||||
// ElGamal
|
||||
void ElGamalEncrypt (const uint8_t * key, const uint8_t * data, uint8_t * encrypted, BN_CTX * ctx, bool zeroPadding)
|
||||
{
|
||||
|
|
|
@ -72,6 +72,7 @@ namespace crypto
|
|||
|
||||
void GenerateKeys ();
|
||||
const uint8_t * GetPublicKey () const { return m_PublicKey; };
|
||||
void GetPrivateKey (uint8_t * priv) const;
|
||||
void Agree (const uint8_t * pub, uint8_t * shared);
|
||||
|
||||
private:
|
||||
|
@ -122,11 +123,32 @@ namespace crypto
|
|||
);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
// TODO: implement it better
|
||||
for (int i = 0; i < 16; i++)
|
||||
buf[i] ^= other.buf[i];
|
||||
#if defined(__SSE__) // SSE
|
||||
__asm__
|
||||
(
|
||||
"movups (%[buf]), %%xmm0 \n"
|
||||
"movups (%[other]), %%xmm1 \n"
|
||||
"pxor %%xmm1, %%xmm0 \n"
|
||||
"movups %%xmm0, (%[buf]) \n"
|
||||
:
|
||||
: [buf]"r"(buf), [other]"r"(other.buf)
|
||||
: "%xmm0", "%xmm1", "memory"
|
||||
);
|
||||
#else
|
||||
if (!(((size_t)buf | (size_t)other.buf) & 0x03)) // multiple of 4 ?
|
||||
{
|
||||
// we are good to cast to uint32_t *
|
||||
for (int i = 0; i < 4; i++)
|
||||
((uint32_t *)buf)[i] ^= ((uint32_t *)other.buf)[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
buf[i] ^= other.buf[i];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -411,6 +411,7 @@ namespace crypto
|
|||
}
|
||||
}
|
||||
|
||||
#if !OPENSSL_X25519
|
||||
BIGNUM * Ed25519::ScalarMul (const BIGNUM * u, const BIGNUM * k, BN_CTX * ctx) const
|
||||
{
|
||||
BN_CTX_start (ctx);
|
||||
|
@ -488,6 +489,7 @@ namespace crypto
|
|||
EncodeBN (q1, buf, 32);
|
||||
BN_free (p1); BN_free (n); BN_free (q1);
|
||||
}
|
||||
#endif
|
||||
|
||||
void Ed25519::ExpandPrivateKey (const uint8_t * key, uint8_t * expandedKey)
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include <memory>
|
||||
#include <openssl/bn.h>
|
||||
#include "Crypto.h"
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
|
@ -75,8 +76,10 @@ namespace crypto
|
|||
EDDSAPoint GeneratePublicKey (const uint8_t * expandedPrivateKey, 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;
|
||||
#if !OPENSSL_X25519
|
||||
void ScalarMul (const uint8_t * p, const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const; // p is point, e is number for x25519
|
||||
void ScalarMulB (const uint8_t * e, uint8_t * buf, BN_CTX * ctx) const;
|
||||
#endif
|
||||
|
||||
bool Verify (const EDDSAPoint& publicKey, const uint8_t * digest, const uint8_t * signature) const;
|
||||
void Sign (const uint8_t * expandedPrivateKey, const uint8_t * publicKeyEncoded, const uint8_t * buf, size_t len, uint8_t * signature) const;
|
||||
|
@ -100,8 +103,10 @@ namespace crypto
|
|||
BIGNUM * DecodeBN (const uint8_t * buf) const;
|
||||
void EncodeBN (const BIGNUM * bn, uint8_t * buf, size_t len) const;
|
||||
|
||||
#if !OPENSSL_X25519
|
||||
// for x25519
|
||||
BIGNUM * ScalarMul (const BIGNUM * p, const BIGNUM * e, BN_CTX * ctx) const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@ namespace i2p
|
|||
|
||||
enum I2NPMessageType
|
||||
{
|
||||
eI2NPDummyMsg = 0,
|
||||
eI2NPDatabaseStore = 1,
|
||||
eI2NPDatabaseLookup = 2,
|
||||
eI2NPDatabaseSearchReply = 3,
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace transport
|
|||
delete[] m_SessionConfirmedBuffer;
|
||||
}
|
||||
|
||||
void NTCP2Establisher::MixKey (const uint8_t * inputKeyMaterial, uint8_t * derived)
|
||||
void NTCP2Establisher::MixKey (const uint8_t * inputKeyMaterial)
|
||||
{
|
||||
// temp_key = HMAC-SHA256(ck, input_key_material)
|
||||
uint8_t tempKey[32]; unsigned int len;
|
||||
|
@ -50,7 +50,16 @@ namespace transport
|
|||
HMAC(EVP_sha256(), tempKey, 32, one, 1, m_CK, &len);
|
||||
// derived = HMAC-SHA256(temp_key, ck || byte(0x02))
|
||||
m_CK[32] = 2;
|
||||
HMAC(EVP_sha256(), tempKey, 32, m_CK, 33, derived, &len);
|
||||
HMAC(EVP_sha256(), tempKey, 32, m_CK, 33, m_K, &len);
|
||||
}
|
||||
|
||||
void NTCP2Establisher::MixHash (const uint8_t * buf, size_t len)
|
||||
{
|
||||
SHA256_CTX ctx;
|
||||
SHA256_Init (&ctx);
|
||||
SHA256_Update (&ctx, m_H, 32);
|
||||
SHA256_Update (&ctx, buf, len);
|
||||
SHA256_Final (m_H, &ctx);
|
||||
}
|
||||
|
||||
void NTCP2Establisher::KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub)
|
||||
|
@ -73,14 +82,11 @@ namespace transport
|
|||
SHA256_Update (&ctx, rs, 32);
|
||||
SHA256_Final (m_H, &ctx);
|
||||
// h = SHA256(h || epub)
|
||||
SHA256_Init (&ctx);
|
||||
SHA256_Update (&ctx, m_H, 32);
|
||||
SHA256_Update (&ctx, epub, 32);
|
||||
SHA256_Final (m_H, &ctx);
|
||||
MixHash (epub, 32);
|
||||
// x25519 between pub and priv
|
||||
uint8_t inputKeyMaterial[32];
|
||||
priv.Agree (pub, inputKeyMaterial);
|
||||
MixKey (inputKeyMaterial, m_K);
|
||||
MixKey (inputKeyMaterial);
|
||||
}
|
||||
|
||||
void NTCP2Establisher::KDF1Alice ()
|
||||
|
@ -95,30 +101,18 @@ namespace transport
|
|||
|
||||
void NTCP2Establisher::KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub)
|
||||
{
|
||||
SHA256_CTX ctx;
|
||||
SHA256_Init (&ctx);
|
||||
SHA256_Update (&ctx, m_H, 32);
|
||||
SHA256_Update (&ctx, sessionRequest + 32, 32); // encrypted payload
|
||||
SHA256_Final (m_H, &ctx);
|
||||
MixHash (sessionRequest + 32, 32); // encrypted payload
|
||||
|
||||
int paddingLength = sessionRequestLen - 64;
|
||||
if (paddingLength > 0)
|
||||
{
|
||||
SHA256_Init (&ctx);
|
||||
SHA256_Update (&ctx, m_H, 32);
|
||||
SHA256_Update (&ctx, sessionRequest + 64, paddingLength);
|
||||
SHA256_Final (m_H, &ctx);
|
||||
}
|
||||
SHA256_Init (&ctx);
|
||||
SHA256_Update (&ctx, m_H, 32);
|
||||
SHA256_Update (&ctx, epub, 32);
|
||||
SHA256_Final (m_H, &ctx);
|
||||
MixHash (sessionRequest + 64, paddingLength);
|
||||
MixHash (epub, 32);
|
||||
|
||||
// x25519 between remote pub and ephemaral priv
|
||||
uint8_t inputKeyMaterial[32];
|
||||
m_EphemeralKeys.Agree (GetRemotePub (), inputKeyMaterial);
|
||||
|
||||
MixKey (inputKeyMaterial, m_K);
|
||||
MixKey (inputKeyMaterial);
|
||||
}
|
||||
|
||||
void NTCP2Establisher::KDF2Alice ()
|
||||
|
@ -135,14 +129,14 @@ namespace transport
|
|||
{
|
||||
uint8_t inputKeyMaterial[32];
|
||||
i2p::context.GetStaticKeys ().Agree (GetRemotePub (), inputKeyMaterial);
|
||||
MixKey (inputKeyMaterial, m_K);
|
||||
MixKey (inputKeyMaterial);
|
||||
}
|
||||
|
||||
void NTCP2Establisher::KDF3Bob ()
|
||||
{
|
||||
uint8_t inputKeyMaterial[32];
|
||||
m_EphemeralKeys.Agree (m_RemoteStaticKey, inputKeyMaterial);
|
||||
MixKey (inputKeyMaterial, m_K);
|
||||
MixKey (inputKeyMaterial);
|
||||
}
|
||||
|
||||
void NTCP2Establisher::CreateEphemeralKey ()
|
||||
|
@ -170,8 +164,17 @@ namespace transport
|
|||
memset (options, 0, 16);
|
||||
options[1] = 2; // ver
|
||||
htobe16buf (options + 2, paddingLength); // padLen
|
||||
m3p2Len = i2p::context.GetRouterInfo ().GetBufferLen () + 20; // (RI header + RI + MAC for now) TODO: implement options
|
||||
// m3p2Len
|
||||
auto bufLen = i2p::context.GetRouterInfo ().GetBufferLen ();
|
||||
m3p2Len = bufLen + 4 + 16; // (RI header + RI + MAC for now) TODO: implement options
|
||||
htobe16buf (options + 4, m3p2Len);
|
||||
// fill m3p2 payload (RouterInfo block)
|
||||
m_SessionConfirmedBuffer = new uint8_t[m3p2Len + 48]; // m3p1 is 48 bytes
|
||||
uint8_t * m3p2 = m_SessionConfirmedBuffer + 48;
|
||||
m3p2[0] = eNTCP2BlkRouterInfo; // block
|
||||
htobe16buf (m3p2 + 1, bufLen + 1); // flag + RI
|
||||
m3p2[3] = 0; // flag
|
||||
memcpy (m3p2 + 4, i2p::context.GetRouterInfo ().GetBuffer (), bufLen); // TODO: own RI should be protected by mutex
|
||||
// 2 bytes reserved
|
||||
htobe32buf (options + 8, i2p::util::GetSecondsSinceEpoch ()); // tsA
|
||||
// 4 bytes reserved
|
||||
|
@ -208,23 +211,12 @@ namespace transport
|
|||
void NTCP2Establisher::CreateSessionConfirmedMessagePart1 (const uint8_t * nonce)
|
||||
{
|
||||
// update AD
|
||||
SHA256_CTX ctx;
|
||||
SHA256_Init (&ctx);
|
||||
SHA256_Update (&ctx, m_H, 32);
|
||||
SHA256_Update (&ctx, m_SessionCreatedBuffer + 32, 32); // encrypted payload
|
||||
SHA256_Final (m_H, &ctx);
|
||||
|
||||
MixHash (m_SessionCreatedBuffer + 32, 32); // encrypted payload
|
||||
int paddingLength = m_SessionCreatedBufferLen - 64;
|
||||
if (paddingLength > 0)
|
||||
{
|
||||
SHA256_CTX ctx1;
|
||||
SHA256_Init (&ctx1);
|
||||
SHA256_Update (&ctx1, m_H, 32);
|
||||
SHA256_Update (&ctx1, m_SessionCreatedBuffer + 64, paddingLength);
|
||||
SHA256_Final (m_H, &ctx1);
|
||||
}
|
||||
// part1 48 bytes
|
||||
m_SessionConfirmedBuffer = new uint8_t[m3p2Len + 48];
|
||||
MixHash (m_SessionCreatedBuffer + 64, paddingLength);
|
||||
|
||||
// part1 48 bytes
|
||||
i2p::crypto::AEADChaCha20Poly1305 (i2p::context.GetNTCP2StaticPublicKey (), 32, m_H, 32, m_K, nonce, m_SessionConfirmedBuffer, 48, true); // encrypt
|
||||
}
|
||||
|
||||
|
@ -232,24 +224,13 @@ namespace transport
|
|||
{
|
||||
// part 2
|
||||
// update AD again
|
||||
SHA256_CTX ctx;
|
||||
SHA256_Init (&ctx);
|
||||
SHA256_Update (&ctx, m_H, 32);
|
||||
SHA256_Update (&ctx, m_SessionConfirmedBuffer, 48);
|
||||
SHA256_Final (m_H, &ctx);
|
||||
// fill and encrypt
|
||||
uint8_t * buf = m_SessionConfirmedBuffer + 48;
|
||||
buf[0] = eNTCP2BlkRouterInfo; // block
|
||||
htobe16buf (buf + 1, i2p::context.GetRouterInfo ().GetBufferLen () + 1); // flag + RI
|
||||
buf[3] = 0; // flag
|
||||
memcpy (buf + 4, i2p::context.GetRouterInfo ().GetBuffer (), i2p::context.GetRouterInfo ().GetBufferLen ());
|
||||
MixHash (m_SessionConfirmedBuffer, 48);
|
||||
// encrypt m3p2, it must be filled in SessionRequest
|
||||
KDF3Alice ();
|
||||
i2p::crypto::AEADChaCha20Poly1305 (buf, m3p2Len - 16, m_H, 32, m_K, nonce, buf, m3p2Len, true); // encrypt
|
||||
uint8_t * m3p2 = m_SessionConfirmedBuffer + 48;
|
||||
i2p::crypto::AEADChaCha20Poly1305 (m3p2, m3p2Len - 16, m_H, 32, m_K, nonce, m3p2, m3p2Len, true); // encrypt
|
||||
// update h again
|
||||
SHA256_Init (&ctx);
|
||||
SHA256_Update (&ctx, m_H, 32);
|
||||
SHA256_Update (&ctx, buf, m3p2Len);
|
||||
SHA256_Final (m_H, &ctx); //h = SHA256(h || ciphertext)
|
||||
MixHash (m3p2, m3p2Len); //h = SHA256(h || ciphertext)
|
||||
}
|
||||
|
||||
bool NTCP2Establisher::ProcessSessionRequestMessage (uint16_t& paddingLen)
|
||||
|
@ -339,21 +320,11 @@ namespace transport
|
|||
bool NTCP2Establisher::ProcessSessionConfirmedMessagePart1 (const uint8_t * nonce)
|
||||
{
|
||||
// update AD
|
||||
SHA256_CTX ctx;
|
||||
SHA256_Init (&ctx);
|
||||
SHA256_Update (&ctx, m_H, 32);
|
||||
SHA256_Update (&ctx, m_SessionCreatedBuffer + 32, 32); // encrypted payload
|
||||
SHA256_Final (m_H, &ctx);
|
||||
|
||||
MixHash (m_SessionCreatedBuffer + 32, 32); // encrypted payload
|
||||
int paddingLength = m_SessionCreatedBufferLen - 64;
|
||||
if (paddingLength > 0)
|
||||
{
|
||||
SHA256_CTX ctx1;
|
||||
SHA256_Init (&ctx1);
|
||||
SHA256_Update (&ctx1, m_H, 32);
|
||||
SHA256_Update (&ctx1, m_SessionCreatedBuffer + 64, paddingLength);
|
||||
SHA256_Final (m_H, &ctx1);
|
||||
}
|
||||
MixHash (m_SessionCreatedBuffer + 64, paddingLength);
|
||||
|
||||
if (!i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer, 32, m_H, 32, m_K, nonce, m_RemoteStaticKey, 32, false)) // decrypt S
|
||||
{
|
||||
LogPrint (eLogWarning, "NTCP2: SessionConfirmed Part1 AEAD verification failed ");
|
||||
|
@ -365,11 +336,7 @@ namespace transport
|
|||
bool NTCP2Establisher::ProcessSessionConfirmedMessagePart2 (const uint8_t * nonce, uint8_t * m3p2Buf)
|
||||
{
|
||||
// update AD again
|
||||
SHA256_CTX ctx;
|
||||
SHA256_Init (&ctx);
|
||||
SHA256_Update (&ctx, m_H, 32);
|
||||
SHA256_Update (&ctx, m_SessionConfirmedBuffer, 48);
|
||||
SHA256_Final (m_H, &ctx);
|
||||
MixHash (m_SessionConfirmedBuffer, 48);
|
||||
|
||||
KDF3Bob ();
|
||||
if (i2p::crypto::AEADChaCha20Poly1305 (m_SessionConfirmedBuffer + 48, m3p2Len - 16, m_H, 32, m_K, nonce, m3p2Buf, m3p2Len - 16, false)) // decrypt
|
||||
|
@ -728,8 +695,7 @@ namespace transport
|
|||
SendTerminationAndTerminate (eNTCP2IncorrectSParameter);
|
||||
return;
|
||||
}
|
||||
|
||||
i2p::data::netdb.AddRouterInfo (buf.data () + 4, size - 1); // TODO: should insert ri and not parse it twice
|
||||
i2p::data::netdb.PostI2NPMsg (CreateI2NPMessage (eI2NPDummyMsg, buf.data () + 3, size)); // TODO: should insert ri and not parse it twice
|
||||
// TODO: process options
|
||||
|
||||
// ready to communicate
|
||||
|
@ -894,7 +860,7 @@ namespace transport
|
|||
case eNTCP2BlkRouterInfo:
|
||||
{
|
||||
LogPrint (eLogDebug, "NTCP2: RouterInfo flag=", (int)frame[offset]);
|
||||
i2p::data::netdb.AddRouterInfo (frame + offset + 1, size - 1);
|
||||
i2p::data::netdb.PostI2NPMsg (CreateI2NPMessage (eI2NPDummyMsg, frame + offset, size));
|
||||
break;
|
||||
}
|
||||
case eNTCP2BlkI2NPMessage:
|
||||
|
@ -1041,7 +1007,7 @@ namespace transport
|
|||
|
||||
void NTCP2Session::SendTermination (NTCP2TerminationReason reason)
|
||||
{
|
||||
if (!IsEstablished ()) return;
|
||||
if (!m_SendKey || !m_SendSipKey) return;
|
||||
uint8_t payload[12] = { eNTCP2BlkTermination, 0, 9 };
|
||||
htobe64buf (payload + 3, m_ReceiveSequenceNumber);
|
||||
payload[11] = (uint8_t)reason;
|
||||
|
|
|
@ -73,6 +73,8 @@ namespace transport
|
|||
eNTCP2Banned, // 17
|
||||
};
|
||||
|
||||
// RouterInfo flags
|
||||
const uint8_t NTCP2_ROUTER_INFO_FLAG_REQUEST_FLOOD = 0x01;
|
||||
|
||||
typedef std::array<uint8_t, NTCP2_UNENCRYPTED_FRAME_MAX_SIZE> NTCP2FrameBuffer;
|
||||
struct NTCP2Establisher
|
||||
|
@ -95,7 +97,8 @@ namespace transport
|
|||
void KDF3Alice (); // for SessionConfirmed part 2
|
||||
void KDF3Bob ();
|
||||
|
||||
void MixKey (const uint8_t * inputKeyMaterial, uint8_t * derived);
|
||||
void MixKey (const uint8_t * inputKeyMaterial);
|
||||
void MixHash (const uint8_t * buf, size_t len);
|
||||
void KeyDerivationFunction1 (const uint8_t * pub, i2p::crypto::X25519Keys& priv, const uint8_t * rs, const uint8_t * epub); // for SessionRequest, (pub, priv) for DH
|
||||
void KeyDerivationFunction2 (const uint8_t * sessionRequest, size_t sessionRequestLen, const uint8_t * epub); // for SessionCreate
|
||||
void CreateEphemeralKey ();
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "I2NPProtocol.h"
|
||||
#include "Tunnel.h"
|
||||
#include "Transports.h"
|
||||
#include "NTCP2.h"
|
||||
#include "RouterContext.h"
|
||||
#include "Garlic.h"
|
||||
#include "NetDb.hpp"
|
||||
|
@ -25,7 +26,7 @@ namespace data
|
|||
{
|
||||
NetDb netdb;
|
||||
|
||||
NetDb::NetDb (): m_IsRunning (false), m_Thread (nullptr), m_Reseeder (nullptr), m_Storage("netDb", "r", "routerInfo-", "dat"), m_FloodfillBootstrap(nullptr), m_HiddenMode(false)
|
||||
NetDb::NetDb (): m_IsRunning (false), m_Thread (nullptr), m_Reseeder (nullptr), m_Storage("netDb", "r", "routerInfo-", "dat"), m_PersistProfiles (true), m_HiddenMode(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -43,10 +44,12 @@ namespace data
|
|||
m_Families.LoadCertificates ();
|
||||
Load ();
|
||||
|
||||
uint16_t threshold; i2p::config::GetOption("reseed.threshold", threshold);
|
||||
uint16_t threshold; i2p::config::GetOption("reseed.threshold", threshold);
|
||||
if (m_RouterInfos.size () < threshold) // reseed if # of router less than threshold
|
||||
Reseed ();
|
||||
|
||||
i2p::config::GetOption("persist.profiles", m_PersistProfiles);
|
||||
|
||||
m_IsRunning = true;
|
||||
m_Thread = new std::thread (std::bind (&NetDb::Run, this));
|
||||
}
|
||||
|
@ -55,8 +58,9 @@ namespace data
|
|||
{
|
||||
if (m_IsRunning)
|
||||
{
|
||||
for (auto& it: m_RouterInfos)
|
||||
it.second->SaveProfile ();
|
||||
if (m_PersistProfiles)
|
||||
for (auto& it: m_RouterInfos)
|
||||
it.second->SaveProfile ();
|
||||
DeleteObsoleteProfiles ();
|
||||
m_RouterInfos.clear ();
|
||||
m_Floodfills.clear ();
|
||||
|
@ -98,6 +102,10 @@ namespace data
|
|||
case eI2NPDatabaseLookup:
|
||||
HandleDatabaseLookupMsg (msg);
|
||||
break;
|
||||
case eI2NPDummyMsg:
|
||||
// plain RouterInfo from NTCP2 with flags for now
|
||||
HandleNTCP2RouterInfoMsg (msg);
|
||||
break;
|
||||
default: // WTF?
|
||||
LogPrint (eLogError, "NetDb: unexpected message type ", (int) msg->GetTypeID ());
|
||||
//i2p::HandleI2NPMessage (msg);
|
||||
|
@ -162,22 +170,38 @@ namespace data
|
|||
}
|
||||
}
|
||||
|
||||
void NetDb::SetHidden(bool hide)
|
||||
{
|
||||
// TODO: remove reachable addresses from router info
|
||||
m_HiddenMode = hide;
|
||||
}
|
||||
|
||||
bool NetDb::AddRouterInfo (const uint8_t * buf, int len)
|
||||
{
|
||||
bool updated;
|
||||
AddRouterInfo (buf, len, updated);
|
||||
return updated;
|
||||
}
|
||||
|
||||
std::shared_ptr<const RouterInfo> NetDb::AddRouterInfo (const uint8_t * buf, int len, bool& updated)
|
||||
{
|
||||
IdentityEx identity;
|
||||
if (identity.FromBuffer (buf, len))
|
||||
return AddRouterInfo (identity.GetIdentHash (), buf, len);
|
||||
return false;
|
||||
return AddRouterInfo (identity.GetIdentHash (), buf, len, updated);
|
||||
updated = false;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void NetDb::SetHidden(bool hide) {
|
||||
// TODO: remove reachable addresses from router info
|
||||
m_HiddenMode = hide;
|
||||
}
|
||||
|
||||
bool NetDb::AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len)
|
||||
{
|
||||
bool updated = true;
|
||||
bool updated;
|
||||
AddRouterInfo (ident, buf, len, updated);
|
||||
return updated;
|
||||
}
|
||||
|
||||
std::shared_ptr<const RouterInfo> NetDb::AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len, bool& updated)
|
||||
{
|
||||
updated = true;
|
||||
auto r = FindRouter (ident);
|
||||
if (r)
|
||||
{
|
||||
|
@ -223,7 +247,7 @@ namespace data
|
|||
}
|
||||
// take care about requested destination
|
||||
m_Requests.RequestComplete (ident, r);
|
||||
return updated;
|
||||
return r;
|
||||
}
|
||||
|
||||
bool NetDb::AddLeaseSet (const IdentHash& ident, const uint8_t * buf, int len,
|
||||
|
@ -518,7 +542,7 @@ namespace data
|
|||
{
|
||||
if (it->second->IsUnreachable ())
|
||||
{
|
||||
it->second->SaveProfile ();
|
||||
if (m_PersistProfiles) it->second->SaveProfile ();
|
||||
it = m_RouterInfos.erase (it);
|
||||
continue;
|
||||
}
|
||||
|
@ -570,6 +594,17 @@ namespace data
|
|||
transports.SendMessage (from, dest->CreateRequestMessage (nullptr, nullptr));
|
||||
}
|
||||
|
||||
void NetDb::HandleNTCP2RouterInfoMsg (std::shared_ptr<const I2NPMessage> m)
|
||||
{
|
||||
uint8_t flood = m->GetPayload ()[0] & NTCP2_ROUTER_INFO_FLAG_REQUEST_FLOOD;
|
||||
bool updated;
|
||||
auto ri = AddRouterInfo (m->GetPayload () + 1, m->GetPayloadLength () - 1, updated); // without flags
|
||||
if (flood && updated && context.IsFloodfill () && ri)
|
||||
{
|
||||
auto floodMsg = CreateDatabaseStoreMsg (ri, 0); // replyToken = 0
|
||||
Flood (ri->GetIdentHash (), floodMsg);
|
||||
}
|
||||
}
|
||||
|
||||
void NetDb::HandleDatabaseStoreMsg (std::shared_ptr<const I2NPMessage> m)
|
||||
{
|
||||
|
@ -649,22 +684,7 @@ namespace data
|
|||
{
|
||||
memcpy (payload + DATABASE_STORE_HEADER_SIZE, buf + payloadOffset, msgLen);
|
||||
floodMsg->FillI2NPMessageHeader (eI2NPDatabaseStore);
|
||||
std::set<IdentHash> excluded;
|
||||
excluded.insert (i2p::context.GetIdentHash ()); // don't flood to itself
|
||||
excluded.insert (ident); // don't flood back
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
auto floodfill = GetClosestFloodfill (ident, excluded);
|
||||
if (floodfill)
|
||||
{
|
||||
auto h = floodfill->GetIdentHash();
|
||||
LogPrint(eLogDebug, "NetDb: Flood lease set for ", ident.ToBase32(), " to ", h.ToBase64());
|
||||
transports.SendMessage (h, CopyI2NPMessage(floodMsg));
|
||||
excluded.insert (h);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
Flood (ident, floodMsg);
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "NetDb: Database store message is too long ", floodMsg->len);
|
||||
|
@ -965,6 +985,26 @@ namespace data
|
|||
}
|
||||
}
|
||||
|
||||
void NetDb::Flood (const IdentHash& ident, std::shared_ptr<I2NPMessage> floodMsg)
|
||||
{
|
||||
std::set<IdentHash> excluded;
|
||||
excluded.insert (i2p::context.GetIdentHash ()); // don't flood to itself
|
||||
excluded.insert (ident); // don't flood back
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
auto floodfill = GetClosestFloodfill (ident, excluded);
|
||||
if (floodfill)
|
||||
{
|
||||
auto h = floodfill->GetIdentHash();
|
||||
LogPrint(eLogDebug, "NetDb: Flood lease set for ", ident.ToBase32(), " to ", h.ToBase64());
|
||||
transports.SendMessage (h, CopyI2NPMessage(floodMsg));
|
||||
excluded.insert (h);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<const RouterInfo> NetDb::GetRandomRouter () const
|
||||
{
|
||||
return GetRandomRouter (
|
||||
|
|
|
@ -65,7 +65,8 @@ namespace data
|
|||
void HandleDatabaseStoreMsg (std::shared_ptr<const I2NPMessage> msg);
|
||||
void HandleDatabaseSearchReplyMsg (std::shared_ptr<const I2NPMessage> msg);
|
||||
void HandleDatabaseLookupMsg (std::shared_ptr<const I2NPMessage> msg);
|
||||
|
||||
void HandleNTCP2RouterInfoMsg (std::shared_ptr<const I2NPMessage> m);
|
||||
|
||||
std::shared_ptr<const RouterInfo> GetRandomRouter () const;
|
||||
std::shared_ptr<const RouterInfo> GetRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith) const;
|
||||
std::shared_ptr<const RouterInfo> GetHighBandwidthRandomRouter (std::shared_ptr<const RouterInfo> compatibleWith) const;
|
||||
|
@ -110,13 +111,16 @@ namespace data
|
|||
void Run (); // exploratory thread
|
||||
void Explore (int numDestinations);
|
||||
void Publish ();
|
||||
void Flood (const IdentHash& ident, std::shared_ptr<I2NPMessage> floodMsg);
|
||||
void ManageLeaseSets ();
|
||||
void ManageRequests ();
|
||||
|
||||
void ReseedFromFloodfill(const RouterInfo & ri, int numRouters=40, int numFloodfills=20);
|
||||
void ReseedFromFloodfill(const RouterInfo & ri, int numRouters=40, int numFloodfills=20);
|
||||
|
||||
template<typename Filter>
|
||||
std::shared_ptr<const RouterInfo> GetRandomRouter (Filter filter) const;
|
||||
std::shared_ptr<const RouterInfo> AddRouterInfo (const uint8_t * buf, int len, bool& updated);
|
||||
std::shared_ptr<const RouterInfo> AddRouterInfo (const IdentHash& ident, const uint8_t * buf, int len, bool& updated);
|
||||
template<typename Filter>
|
||||
std::shared_ptr<const RouterInfo> GetRandomRouter (Filter filter) const;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -140,6 +144,8 @@ namespace data
|
|||
friend class NetDbRequests;
|
||||
NetDbRequests m_Requests;
|
||||
|
||||
bool m_PersistProfiles;
|
||||
|
||||
/** router info we are bootstrapping from or nullptr if we are not currently doing that*/
|
||||
std::shared_ptr<RouterInfo> m_FloodfillBootstrap;
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
Kovri go write your own code
|
||||
|
||||
*/
|
||||
|
||||
#if LEGACY_OPENSSL
|
||||
namespace i2p
|
||||
{
|
||||
namespace crypto
|
||||
|
@ -19,3 +21,5 @@ namespace crypto
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
#define LIBI2PD_POLY1305_H
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include "Crypto.h"
|
||||
|
||||
#if LEGACY_OPENSSL
|
||||
namespace i2p
|
||||
{
|
||||
namespace crypto
|
||||
|
@ -254,5 +256,6 @@ namespace crypto
|
|||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -116,12 +116,12 @@ namespace i2p
|
|||
|
||||
void RouterContext::NewNTCP2Keys ()
|
||||
{
|
||||
m_StaticKeys.reset (new i2p::crypto::X25519Keys ());
|
||||
m_StaticKeys->GenerateKeys ();
|
||||
m_NTCP2Keys.reset (new NTCP2PrivateKeys ());
|
||||
RAND_bytes (m_NTCP2Keys->staticPrivateKey, 32);
|
||||
m_StaticKeys->GetPrivateKey (m_NTCP2Keys->staticPrivateKey);
|
||||
memcpy (m_NTCP2Keys->staticPublicKey, m_StaticKeys->GetPublicKey (), 32);
|
||||
RAND_bytes (m_NTCP2Keys->iv, 16);
|
||||
BN_CTX * ctx = BN_CTX_new ();
|
||||
i2p::crypto::GetEd25519 ()->ScalarMulB (m_NTCP2Keys->staticPrivateKey, m_NTCP2Keys->staticPublicKey, ctx);
|
||||
BN_CTX_free (ctx);
|
||||
// save
|
||||
std::ofstream fk (i2p::fs::DataDirPath (NTCP2_KEYS), std::ofstream::binary | std::ofstream::out);
|
||||
fk.write ((char *)m_NTCP2Keys.get (), sizeof (NTCP2PrivateKeys));
|
||||
|
|
|
@ -9,7 +9,9 @@
|
|||
#define SIPHASH_H
|
||||
|
||||
#include <cstdint>
|
||||
#include "Crypto.h"
|
||||
|
||||
#if !OPENSSL_SIPHASH
|
||||
namespace i2p
|
||||
{
|
||||
namespace crypto
|
||||
|
@ -148,5 +150,6 @@ namespace crypto
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <chrono>
|
||||
#include <future>
|
||||
#include <boost/asio.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include "Config.h"
|
||||
#include "Log.h"
|
||||
#include "I2PEndian.h"
|
||||
#include "Timestamp.h"
|
||||
|
@ -15,10 +19,30 @@ namespace i2p
|
|||
{
|
||||
namespace util
|
||||
{
|
||||
static uint64_t GetLocalMillisecondsSinceEpoch ()
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch()).count ();
|
||||
}
|
||||
|
||||
static uint32_t GetLocalHoursSinceEpoch ()
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::hours>(
|
||||
std::chrono::system_clock::now().time_since_epoch()).count ();
|
||||
}
|
||||
|
||||
static uint64_t GetLocalSecondsSinceEpoch ()
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::seconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch()).count ();
|
||||
}
|
||||
|
||||
|
||||
static int64_t g_TimeOffset = 0; // in seconds
|
||||
|
||||
void SyncTimeWithNTP (const std::string& address)
|
||||
static void SyncTimeWithNTP (const std::string& address)
|
||||
{
|
||||
LogPrint (eLogInfo, "Timestamp: NTP request to ", address);
|
||||
boost::asio::io_service service;
|
||||
boost::asio::ip::udp::resolver::query query (boost::asio::ip::udp::v4 (), address, "ntp");
|
||||
boost::system::error_code ec;
|
||||
|
@ -48,18 +72,111 @@ namespace util
|
|||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LogPrint (eLogError, "NTP error: ", e.what ());
|
||||
LogPrint (eLogError, "Timestamp: NTP error: ", e.what ());
|
||||
}
|
||||
if (len >= 8)
|
||||
{
|
||||
auto ourTs = GetSecondsSinceEpoch ();
|
||||
auto ourTs = GetLocalSecondsSinceEpoch ();
|
||||
uint32_t ts = bufbe32toh (buf + 32);
|
||||
if (ts > 2208988800U) ts -= 2208988800U; // 1/1/1970 from 1/1/1900
|
||||
g_TimeOffset = ts - ourTs;
|
||||
LogPrint (eLogInfo, address, " time offset from system time is ", g_TimeOffset, " seconds");
|
||||
LogPrint (eLogInfo, "Timestamp: ", address, " time offset from system time is ", g_TimeOffset, " seconds");
|
||||
}
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "Timestamp: Couldn't open UDP socket");
|
||||
}
|
||||
else
|
||||
LogPrint (eLogError, "Timestamp: Couldn't resove address ", address);
|
||||
}
|
||||
|
||||
NTPTimeSync::NTPTimeSync (): m_IsRunning (false), m_Timer (m_Service)
|
||||
{
|
||||
i2p::config::GetOption("nettime.ntpsyncinterval", m_SyncInterval);
|
||||
std::string ntpservers; i2p::config::GetOption("nettime.ntpservers", ntpservers);
|
||||
boost::split (m_NTPServersList, ntpservers, boost::is_any_of(","), boost::token_compress_on);
|
||||
}
|
||||
|
||||
NTPTimeSync::~NTPTimeSync ()
|
||||
{
|
||||
Stop ();
|
||||
}
|
||||
|
||||
void NTPTimeSync::Start()
|
||||
{
|
||||
if (m_NTPServersList.size () > 0)
|
||||
{
|
||||
m_IsRunning = true;
|
||||
LogPrint(eLogInfo, "Timestamp: NTP time sync starting");
|
||||
m_Service.post (std::bind (&NTPTimeSync::Sync, this));
|
||||
m_Thread.reset (new std::thread (std::bind (&NTPTimeSync::Run, this)));
|
||||
}
|
||||
else
|
||||
LogPrint (eLogWarning, "Timestamp: No NTP server found");
|
||||
}
|
||||
|
||||
void NTPTimeSync::Stop ()
|
||||
{
|
||||
if (m_IsRunning)
|
||||
{
|
||||
LogPrint(eLogInfo, "Timestamp: NTP time sync stopping");
|
||||
m_IsRunning = false;
|
||||
m_Timer.cancel ();
|
||||
m_Service.stop ();
|
||||
if (m_Thread)
|
||||
{
|
||||
m_Thread->join ();
|
||||
m_Thread.reset (nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NTPTimeSync::Run ()
|
||||
{
|
||||
while (m_IsRunning)
|
||||
{
|
||||
try
|
||||
{
|
||||
m_Service.run ();
|
||||
}
|
||||
catch (std::exception& ex)
|
||||
{
|
||||
LogPrint (eLogError, "Timestamp: NTP time sync exception: ", ex.what ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NTPTimeSync::Sync ()
|
||||
{
|
||||
if (m_NTPServersList.size () > 0)
|
||||
SyncTimeWithNTP (m_NTPServersList[rand () % m_NTPServersList.size ()]);
|
||||
else
|
||||
m_IsRunning = false;
|
||||
|
||||
if (m_IsRunning)
|
||||
{
|
||||
m_Timer.expires_from_now (boost::posix_time::hours (m_SyncInterval));
|
||||
m_Timer.async_wait ([this](const boost::system::error_code& ecode)
|
||||
{
|
||||
if (ecode != boost::asio::error::operation_aborted)
|
||||
Sync ();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t GetMillisecondsSinceEpoch ()
|
||||
{
|
||||
return GetLocalMillisecondsSinceEpoch () + g_TimeOffset*1000;
|
||||
}
|
||||
|
||||
uint32_t GetHoursSinceEpoch ()
|
||||
{
|
||||
return GetLocalHoursSinceEpoch () + g_TimeOffset/3600;
|
||||
}
|
||||
|
||||
uint64_t GetSecondsSinceEpoch ()
|
||||
{
|
||||
return GetLocalSecondsSinceEpoch () + g_TimeOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,29 +2,43 @@
|
|||
#define TIMESTAMP_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
namespace i2p
|
||||
{
|
||||
namespace util
|
||||
{
|
||||
inline uint64_t GetMillisecondsSinceEpoch ()
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch()).count ();
|
||||
}
|
||||
uint64_t GetMillisecondsSinceEpoch ();
|
||||
uint32_t GetHoursSinceEpoch ();
|
||||
uint64_t GetSecondsSinceEpoch ();
|
||||
|
||||
inline uint32_t GetHoursSinceEpoch ()
|
||||
class NTPTimeSync
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::hours>(
|
||||
std::chrono::system_clock::now().time_since_epoch()).count ();
|
||||
}
|
||||
public:
|
||||
|
||||
inline uint64_t GetSecondsSinceEpoch ()
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::seconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch()).count ();
|
||||
}
|
||||
NTPTimeSync ();
|
||||
~NTPTimeSync ();
|
||||
|
||||
void Start ();
|
||||
void Stop ();
|
||||
|
||||
private:
|
||||
|
||||
void Run ();
|
||||
void Sync ();
|
||||
|
||||
private:
|
||||
|
||||
bool m_IsRunning;
|
||||
std::unique_ptr<std::thread> m_Thread;
|
||||
boost::asio::io_service m_Service;
|
||||
boost::asio::deadline_timer m_Timer;
|
||||
int m_SyncInterval;
|
||||
std::vector<std::string> m_NTPServersList;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,8 +35,11 @@ namespace transport
|
|||
|
||||
void DHKeysPairSupplier::Stop ()
|
||||
{
|
||||
m_IsRunning = false;
|
||||
m_Acquired.notify_one ();
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_AcquiredMutex);
|
||||
m_IsRunning = false;
|
||||
m_Acquired.notify_one ();
|
||||
}
|
||||
if (m_Thread)
|
||||
{
|
||||
m_Thread->join ();
|
||||
|
@ -50,19 +53,20 @@ namespace transport
|
|||
while (m_IsRunning)
|
||||
{
|
||||
int num, total = 0;
|
||||
while ((num = m_QueueSize - (int)m_Queue.size ()) > 0 && total < 20)
|
||||
while ((num = m_QueueSize - (int)m_Queue.size ()) > 0 && total < 10)
|
||||
{
|
||||
CreateDHKeysPairs (num);
|
||||
total += num;
|
||||
}
|
||||
if (total >= 20)
|
||||
if (total >= 10)
|
||||
{
|
||||
LogPrint (eLogWarning, "Transports: ", total, " DH keys generated at the time");
|
||||
std::this_thread::sleep_for (std::chrono::seconds(1)); // take a break
|
||||
}
|
||||
else
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_AcquiredMutex);
|
||||
std::unique_lock<std::mutex> l(m_AcquiredMutex);
|
||||
if (!m_IsRunning) break;
|
||||
m_Acquired.wait (l); // wait for element gets acquired
|
||||
}
|
||||
}
|
||||
|
@ -813,7 +817,6 @@ namespace transport
|
|||
if (profile)
|
||||
{
|
||||
profile->TunnelNonReplied();
|
||||
profile->Save(it->first);
|
||||
}
|
||||
std::unique_lock<std::mutex> l(m_PeersMutex);
|
||||
it = m_Peers.erase (it);
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
|
||||
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
|
||||
|
||||
/* // No more needed. Exists in MinGW.
|
||||
int inet_pton(int af, const char *src, void *dst)
|
||||
{ /* This function was written by Petar Korponai?. See
|
||||
http://stackoverflow.com/questions/15660203/inet-pton-identifier-not-found */
|
||||
{ // This function was written by Petar Korponai?. See http://stackoverflow.com/questions/15660203/inet-pton-identifier-not-found
|
||||
struct sockaddr_storage ss;
|
||||
int size = sizeof (ss);
|
||||
char src_copy[INET6_ADDRSTRLEN + 1];
|
||||
|
@ -45,7 +45,7 @@ http://stackoverflow.com/questions/15660203/inet-pton-identifier-not-found */
|
|||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}*/
|
||||
#else /* !WIN32 => UNIX */
|
||||
#include <sys/types.h>
|
||||
#include <ifaddrs.h>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#define MAKE_VERSION(a,b,c) STRINGIZE(a) "." STRINGIZE(b) "." STRINGIZE(c)
|
||||
|
||||
#define I2PD_VERSION_MAJOR 2
|
||||
#define I2PD_VERSION_MINOR 21
|
||||
#define I2PD_VERSION_MINOR 22
|
||||
#define I2PD_VERSION_MICRO 0
|
||||
#define I2PD_VERSION_PATCH 0
|
||||
#define I2PD_VERSION MAKE_VERSION(I2PD_VERSION_MAJOR, I2PD_VERSION_MINOR, I2PD_VERSION_MICRO)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue