mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-06-07 14:46:51 +02:00
Merge branch 'PurpleI2P:openssl' into c-wrapper-libi2pd-api
This commit is contained in:
commit
e575c6e94d
38 changed files with 1075 additions and 194 deletions
|
@ -221,7 +221,7 @@ namespace config {
|
|||
("addressbook.defaulturl", value<std::string>()->default_value(
|
||||
"http://shx5vqsw7usdaunyzr2qmes2fq37oumybpudrd4jjj4e4vk4uusa.b32.i2p/hosts.txt"
|
||||
), "AddressBook subscription URL for initial setup")
|
||||
("addressbook.subscriptions", value<std::string>()->default_value(""), "AddressBook subscriptions URLs, separated by comma")
|
||||
("addressbook.subscriptions", value<std::string>()->default_value("http://reg.i2p/hosts.txt"), "AddressBook subscriptions URLs, separated by comma")
|
||||
("addressbook.hostsfile", value<std::string>()->default_value(""), "File to dump addresses in hosts.txt format");
|
||||
|
||||
options_description trust("Trust options");
|
||||
|
|
|
@ -1109,21 +1109,22 @@ namespace garlic
|
|||
bool RouterIncomingRatchetSession::HandleNextMessage (const uint8_t * buf, size_t len)
|
||||
{
|
||||
if (!GetOwner ()) return false;
|
||||
i2p::crypto::NoiseSymmetricState state (GetNoiseState ());
|
||||
m_CurrentNoiseState = GetNoiseState ();
|
||||
// we are Bob
|
||||
state.MixHash (buf, 32);
|
||||
m_CurrentNoiseState.MixHash (buf, 32);
|
||||
uint8_t sharedSecret[32];
|
||||
if (!GetOwner ()->Decrypt (buf, sharedSecret, nullptr, i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD)) // x25519(bsk, aepk)
|
||||
{
|
||||
LogPrint (eLogWarning, "Garlic: Incorrect N ephemeral public key");
|
||||
return false;
|
||||
}
|
||||
state.MixKey (sharedSecret);
|
||||
m_CurrentNoiseState.MixKey (sharedSecret);
|
||||
buf += 32; len -= 32;
|
||||
uint8_t nonce[12];
|
||||
CreateNonce (0, nonce);
|
||||
std::vector<uint8_t> payload (len - 16);
|
||||
if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, state.m_H, 32, state.m_CK + 32, nonce, payload.data (), len - 16, false)) // decrypt
|
||||
if (!i2p::crypto::AEADChaCha20Poly1305 (buf, len - 16, m_CurrentNoiseState.m_H, 32,
|
||||
m_CurrentNoiseState.m_CK + 32, nonce, payload.data (), len - 16, false)) // decrypt
|
||||
{
|
||||
LogPrint (eLogWarning, "Garlic: Payload for router AEAD verification failed");
|
||||
return false;
|
||||
|
|
|
@ -249,6 +249,11 @@ namespace garlic
|
|||
|
||||
RouterIncomingRatchetSession (const i2p::crypto::NoiseSymmetricState& initState);
|
||||
bool HandleNextMessage (const uint8_t * buf, size_t len);
|
||||
i2p::crypto::NoiseSymmetricState& GetCurrentNoiseState () { return m_CurrentNoiseState; };
|
||||
|
||||
private:
|
||||
|
||||
i2p::crypto::NoiseSymmetricState m_CurrentNoiseState;
|
||||
};
|
||||
|
||||
std::shared_ptr<I2NPMessage> WrapECIESX25519AEADRatchetMessage (std::shared_ptr<const I2NPMessage> msg, const uint8_t * key, uint64_t tag);
|
||||
|
|
|
@ -426,8 +426,8 @@ namespace i2p
|
|||
uint8_t nonce[12];
|
||||
memset (nonce, 0, 12);
|
||||
auto& noiseState = i2p::context.GetCurrentNoiseState ();
|
||||
if (!noiseState || !i2p::crypto::AEADChaCha20Poly1305 (reply, TUNNEL_BUILD_RECORD_SIZE - 16,
|
||||
noiseState->m_H, 32, noiseState->m_CK, nonce, reply, TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt
|
||||
if (!i2p::crypto::AEADChaCha20Poly1305 (reply, TUNNEL_BUILD_RECORD_SIZE - 16,
|
||||
noiseState.m_H, 32, noiseState.m_CK, nonce, reply, TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt
|
||||
{
|
||||
LogPrint (eLogWarning, "I2NP: Reply AEAD encryption failed");
|
||||
return false;
|
||||
|
@ -611,13 +611,8 @@ namespace i2p
|
|||
return;
|
||||
}
|
||||
auto& noiseState = i2p::context.GetCurrentNoiseState ();
|
||||
if (!noiseState)
|
||||
{
|
||||
LogPrint (eLogWarning, "I2NP: Invalid Noise state for short reply encryption");
|
||||
return;
|
||||
}
|
||||
uint8_t layerKeys[64]; // (layer key, iv key)
|
||||
i2p::crypto::HKDF (noiseState->m_CK + 32, nullptr, 0, "LayerAndIVKeys", layerKeys); // TODO: correct domain
|
||||
i2p::crypto::HKDF (noiseState.m_CK + 32, nullptr, 0, "LayerAndIVKeys", layerKeys); // TODO: correct domain
|
||||
auto transitTunnel = i2p::tunnel::CreateTransitTunnel (
|
||||
bufbe32toh (clearText + SHORT_REQUEST_RECORD_RECEIVE_TUNNEL_OFFSET),
|
||||
clearText + SHORT_REQUEST_RECORD_NEXT_IDENT_OFFSET,
|
||||
|
@ -653,7 +648,7 @@ namespace i2p
|
|||
otbrm->len += (payload - otbrm->GetPayload ());
|
||||
otbrm->FillI2NPMessageHeader (eI2NPOutboundTunnelBuildReply, bufbe32toh (clearText + SHORT_REQUEST_RECORD_SEND_MSG_ID_OFFSET));
|
||||
uint8_t replyKeys[64]; // (reply key, tag)
|
||||
i2p::crypto::HKDF (noiseState->m_CK, nullptr, 0, "ReplyKeyAndTag", replyKeys); // TODO: correct domain
|
||||
i2p::crypto::HKDF (noiseState.m_CK, nullptr, 0, "ReplyKeyAndTag", replyKeys); // TODO: correct domain
|
||||
uint64_t tag;
|
||||
memcpy (&tag, replyKeys + 32, 8);
|
||||
// send garlic to reply tunnel
|
||||
|
@ -674,14 +669,14 @@ namespace i2p
|
|||
{
|
||||
// TODO: fill reply
|
||||
if (!i2p::crypto::AEADChaCha20Poly1305 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE - 16,
|
||||
noiseState->m_H, 32, noiseState->m_CK, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt
|
||||
noiseState.m_H, 32, noiseState.m_CK, nonce, reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, true)) // encrypt
|
||||
{
|
||||
LogPrint (eLogWarning, "I2NP: Short reply AEAD encryption failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, noiseState->m_CK, nonce, reply);
|
||||
i2p::crypto::ChaCha20 (reply, SHORT_TUNNEL_BUILD_RECORD_SIZE, noiseState.m_CK, nonce, reply);
|
||||
reply += SHORT_TUNNEL_BUILD_RECORD_SIZE;
|
||||
}
|
||||
transports.SendMessage (clearText + SHORT_REQUEST_RECORD_NEXT_TUNNEL_OFFSET,
|
||||
|
|
|
@ -1170,7 +1170,7 @@ namespace transport
|
|||
if (!address) continue;
|
||||
if (address->IsPublishedNTCP2 () && address->port)
|
||||
{
|
||||
if (address->host.is_v4())
|
||||
if (address->IsV4())
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -1189,7 +1189,7 @@ namespace transport
|
|||
auto conn = std::make_shared<NTCP2Session>(*this);
|
||||
m_NTCP2Acceptor->async_accept(conn->GetSocket (), std::bind (&NTCP2Server::HandleAccept, this, conn, std::placeholders::_1));
|
||||
}
|
||||
else if (address->host.is_v6() && (context.SupportsV6 () || context.SupportsMesh ()))
|
||||
else if (address->IsV6() && (context.SupportsV6 () || context.SupportsMesh ()))
|
||||
{
|
||||
m_NTCP2V6Acceptor.reset (new boost::asio::ip::tcp::acceptor (GetService ()));
|
||||
try
|
||||
|
@ -1201,7 +1201,11 @@ namespace transport
|
|||
if (!m_Address6 && !m_YggdrasilAddress) // only if not binded to address
|
||||
{
|
||||
// Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others
|
||||
#if (BOOST_VERSION >= 105500)
|
||||
typedef boost::asio::detail::socket_option::integer<BOOST_ASIO_OS_DEF(IPPROTO_IPV6), IPV6_ADDR_PREFERENCES> ipv6PreferAddr;
|
||||
#else
|
||||
typedef boost::asio::detail::socket_option::integer<IPPROTO_IPV6, IPV6_ADDR_PREFERENCES> ipv6PreferAddr;
|
||||
#endif
|
||||
m_NTCP2V6Acceptor->set_option (ipv6PreferAddr(IPV6_PREFER_SRC_PUBLIC | IPV6_PREFER_SRC_HOME | IPV6_PREFER_SRC_NONCGA));
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1187,7 +1187,11 @@ namespace data
|
|||
(reverse ? compatibleWith->IsReachableFrom (*router) :
|
||||
router->IsReachableFrom (*compatibleWith)) &&
|
||||
(router->GetCaps () & RouterInfo::eHighBandwidth) &&
|
||||
#if defined(__x86_64__)
|
||||
router->GetVersion () >= NETDB_MIN_HIGHBANDWIDTH_VERSION;
|
||||
#else
|
||||
router->GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD;
|
||||
#endif
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -45,10 +45,8 @@ namespace i2p
|
|||
UpdateRouterInfo ();
|
||||
if (IsECIES ())
|
||||
{
|
||||
auto initState = new i2p::crypto::NoiseSymmetricState ();
|
||||
i2p::crypto::InitNoiseNState (*initState, GetIdentity ()->GetEncryptionPublicKey ());
|
||||
m_InitialNoiseState.reset (initState);
|
||||
m_ECIESSession = std::make_shared<i2p::garlic::RouterIncomingRatchetSession>(*initState);
|
||||
i2p::crypto::InitNoiseNState (m_InitialNoiseState, GetIdentity ()->GetEncryptionPublicKey ());
|
||||
m_ECIESSession = std::make_shared<i2p::garlic::RouterIncomingRatchetSession>(m_InitialNoiseState);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,11 +484,12 @@ namespace i2p
|
|||
addr->ssu->introducers.clear ();
|
||||
port = addr->port;
|
||||
}
|
||||
// unpiblish NTCP2 addreeses
|
||||
// unpublish NTCP2 addreeses
|
||||
bool ntcp2; i2p::config::GetOption("ntcp2.enabled", ntcp2);
|
||||
if (ntcp2)
|
||||
PublishNTCP2Address (port, false, v4, v6, false);
|
||||
// update
|
||||
m_RouterInfo.UpdateSupportedTransports ();
|
||||
UpdateRouterInfo ();
|
||||
}
|
||||
|
||||
|
@ -530,6 +529,7 @@ namespace i2p
|
|||
}
|
||||
}
|
||||
// update
|
||||
m_RouterInfo.UpdateSupportedTransports ();
|
||||
UpdateRouterInfo ();
|
||||
}
|
||||
|
||||
|
@ -679,7 +679,7 @@ namespace i2p
|
|||
if (addr->IsPublishedNTCP2 ())
|
||||
{
|
||||
bool isYgg1 = i2p::util::net::IsYggdrasilAddress (addr->host);
|
||||
if (addr->host.is_v6 () && ((isYgg && isYgg1) || (!isYgg && !isYgg1)))
|
||||
if (addr->IsV6 () && ((isYgg && isYgg1) || (!isYgg && !isYgg1)))
|
||||
{
|
||||
if (addr->host != host)
|
||||
{
|
||||
|
@ -889,27 +889,26 @@ namespace i2p
|
|||
|
||||
bool RouterContext::DecryptECIESTunnelBuildRecord (const uint8_t * encrypted, uint8_t * data, size_t clearTextSize)
|
||||
{
|
||||
if (!m_InitialNoiseState || !m_TunnelDecryptor) return false;
|
||||
// m_InitialNoiseState is h = SHA256(h || hepk)
|
||||
m_CurrentNoiseState.reset (new i2p::crypto::NoiseSymmetricState (*m_InitialNoiseState));
|
||||
m_CurrentNoiseState->MixHash (encrypted, 32); // h = SHA256(h || sepk)
|
||||
m_CurrentNoiseState = m_InitialNoiseState;
|
||||
m_CurrentNoiseState.MixHash (encrypted, 32); // h = SHA256(h || sepk)
|
||||
uint8_t sharedSecret[32];
|
||||
if (!m_TunnelDecryptor->Decrypt (encrypted, sharedSecret, nullptr, false))
|
||||
{
|
||||
LogPrint (eLogWarning, "Router: Incorrect ephemeral public key");
|
||||
return false;
|
||||
}
|
||||
m_CurrentNoiseState->MixKey (sharedSecret);
|
||||
m_CurrentNoiseState.MixKey (sharedSecret);
|
||||
encrypted += 32;
|
||||
uint8_t nonce[12];
|
||||
memset (nonce, 0, 12);
|
||||
if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, clearTextSize, m_CurrentNoiseState->m_H, 32,
|
||||
m_CurrentNoiseState->m_CK + 32, nonce, data, clearTextSize, false)) // decrypt
|
||||
if (!i2p::crypto::AEADChaCha20Poly1305 (encrypted, clearTextSize, m_CurrentNoiseState.m_H, 32,
|
||||
m_CurrentNoiseState.m_CK + 32, nonce, data, clearTextSize, false)) // decrypt
|
||||
{
|
||||
LogPrint (eLogWarning, "Router: Tunnel record AEAD decryption failed");
|
||||
return false;
|
||||
}
|
||||
m_CurrentNoiseState->MixHash (encrypted, clearTextSize + 16); // h = SHA256(h || ciphertext)
|
||||
m_CurrentNoiseState.MixHash (encrypted, clearTextSize + 16); // h = SHA256(h || ciphertext)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ namespace garlic
|
|||
void SetSupportsV4 (bool supportsV4);
|
||||
void SetSupportsMesh (bool supportsmesh, const boost::asio::ip::address_v6& host);
|
||||
bool IsECIES () const { return GetIdentity ()->GetCryptoKeyType () == i2p::data::CRYPTO_KEY_TYPE_ECIES_X25519_AEAD; };
|
||||
std::unique_ptr<i2p::crypto::NoiseSymmetricState>& GetCurrentNoiseState () { return m_CurrentNoiseState; };
|
||||
i2p::crypto::NoiseSymmetricState& GetCurrentNoiseState () { return m_CurrentNoiseState; };
|
||||
|
||||
void UpdateNTCP2V6Address (const boost::asio::ip::address& host); // called from Daemon. TODO: remove
|
||||
void UpdateStats ();
|
||||
|
@ -185,7 +185,7 @@ namespace garlic
|
|||
std::unique_ptr<NTCP2PrivateKeys> m_NTCP2Keys;
|
||||
std::unique_ptr<i2p::crypto::X25519Keys> m_StaticKeys;
|
||||
// for ECIESx25519
|
||||
std::unique_ptr<i2p::crypto::NoiseSymmetricState> m_InitialNoiseState, m_CurrentNoiseState;
|
||||
i2p::crypto::NoiseSymmetricState m_InitialNoiseState, m_CurrentNoiseState;
|
||||
|
||||
// i18n
|
||||
std::shared_ptr<const i2p::i18n::Locale> m_Language;
|
||||
|
|
|
@ -554,7 +554,7 @@ namespace data
|
|||
if (address.IsNTCP2 ())
|
||||
{
|
||||
WriteString ("NTCP2", s);
|
||||
if (address.IsPublishedNTCP2 () && !address.host.is_unspecified ())
|
||||
if (address.IsPublishedNTCP2 () && !address.host.is_unspecified () && address.port)
|
||||
isPublished = true;
|
||||
else
|
||||
{
|
||||
|
@ -971,10 +971,10 @@ namespace data
|
|||
{
|
||||
if (!IsV6 ())
|
||||
{
|
||||
m_SupportedTransports |= eSSUV6 | eNTCP2V6;
|
||||
uint8_t addressCaps = AddressCaps::eV6;
|
||||
if (IsV4 ()) addressCaps |= AddressCaps::eV4;
|
||||
SetUnreachableAddressesTransportCaps (addressCaps);
|
||||
UpdateSupportedTransports ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -982,10 +982,10 @@ namespace data
|
|||
{
|
||||
if (!IsV4 ())
|
||||
{
|
||||
m_SupportedTransports |= eSSUV4 | eNTCP2V4;
|
||||
uint8_t addressCaps = AddressCaps::eV4;
|
||||
if (IsV6 ()) addressCaps |= AddressCaps::eV6;
|
||||
SetUnreachableAddressesTransportCaps (addressCaps);
|
||||
UpdateSupportedTransports ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -994,16 +994,23 @@ namespace data
|
|||
{
|
||||
if (IsV6 ())
|
||||
{
|
||||
m_SupportedTransports &= ~(eSSUV6 | eNTCP2V6);
|
||||
for (auto it = m_Addresses->begin (); it != m_Addresses->end ();)
|
||||
{
|
||||
auto addr = *it;
|
||||
addr->caps &= ~AddressCaps::eV6;
|
||||
if (addr->host.is_v6 ())
|
||||
it = m_Addresses->erase (it);
|
||||
if (addr->IsV6 ())
|
||||
{
|
||||
if (addr->IsV4 ())
|
||||
{
|
||||
addr->caps &= ~AddressCaps::eV6;
|
||||
++it;
|
||||
}
|
||||
else
|
||||
it = m_Addresses->erase (it);
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
UpdateSupportedTransports ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1011,23 +1018,33 @@ namespace data
|
|||
{
|
||||
if (IsV4 ())
|
||||
{
|
||||
m_SupportedTransports &= ~(eSSUV4 | eNTCP2V4);
|
||||
for (auto it = m_Addresses->begin (); it != m_Addresses->end ();)
|
||||
{
|
||||
auto addr = *it;
|
||||
addr->caps &= ~AddressCaps::eV4;
|
||||
if (addr->host.is_v4 ())
|
||||
it = m_Addresses->erase (it);
|
||||
if (addr->IsV4 ())
|
||||
{
|
||||
if (addr->IsV6 ())
|
||||
{
|
||||
addr->caps &= ~AddressCaps::eV4;
|
||||
++it;
|
||||
}
|
||||
else
|
||||
it = m_Addresses->erase (it);
|
||||
}
|
||||
else
|
||||
++it;
|
||||
}
|
||||
UpdateSupportedTransports ();
|
||||
}
|
||||
}
|
||||
|
||||
void RouterInfo::EnableMesh ()
|
||||
{
|
||||
if (!IsMesh ())
|
||||
{
|
||||
m_SupportedTransports |= eNTCP2V6Mesh;
|
||||
m_ReachableTransports |= eNTCP2V6Mesh;
|
||||
}
|
||||
}
|
||||
|
||||
void RouterInfo::DisableMesh ()
|
||||
|
@ -1035,6 +1052,7 @@ namespace data
|
|||
if (IsMesh ())
|
||||
{
|
||||
m_SupportedTransports &= ~eNTCP2V6Mesh;
|
||||
m_ReachableTransports &= ~eNTCP2V6Mesh;
|
||||
for (auto it = m_Addresses->begin (); it != m_Addresses->end ();)
|
||||
{
|
||||
auto addr = *it;
|
||||
|
@ -1161,34 +1179,12 @@ namespace data
|
|||
});
|
||||
}
|
||||
|
||||
bool RouterInfo::IsReachableFrom (const RouterInfo& other) const
|
||||
{
|
||||
auto commonTransports = m_SupportedTransports & other.m_SupportedTransports;
|
||||
if (!commonTransports) return false;
|
||||
if (commonTransports & eNTCP2V6Mesh) return true;
|
||||
return (bool)GetAddress (
|
||||
[commonTransports](std::shared_ptr<const RouterInfo::Address> address)->bool
|
||||
{
|
||||
if (address->IsPublishedNTCP2 ())
|
||||
{
|
||||
if ((commonTransports & eNTCP2V4) && address->IsV4 ()) return true;
|
||||
if ((commonTransports & eNTCP2V6) && address->IsV6 ()) return true;
|
||||
}
|
||||
else if (address->IsReachableSSU ())
|
||||
{
|
||||
if ((commonTransports & eSSUV4) && address->IsV4 ()) return true;
|
||||
if ((commonTransports & eSSUV6) && address->IsV6 ()) return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
void RouterInfo::SetUnreachableAddressesTransportCaps (uint8_t transports)
|
||||
{
|
||||
for (auto& addr: *m_Addresses)
|
||||
{
|
||||
// TODO: implement SSU
|
||||
if (addr->transportStyle == eTransportNTCP && (!addr->IsPublishedNTCP2 () || addr->port))
|
||||
if (addr->transportStyle == eTransportNTCP && !addr->IsPublishedNTCP2 ())
|
||||
{
|
||||
addr->caps &= ~(eV4 | eV6);
|
||||
addr->caps |= transports;
|
||||
|
|
|
@ -204,7 +204,8 @@ namespace data
|
|||
void EnableMesh ();
|
||||
void DisableMesh ();
|
||||
bool IsCompatible (const RouterInfo& other) const { return m_SupportedTransports & other.m_SupportedTransports; };
|
||||
bool IsReachableFrom (const RouterInfo& other) const;
|
||||
bool IsReachableFrom (const RouterInfo& other) const { return m_ReachableTransports & other.m_SupportedTransports; };
|
||||
bool IsReachableBy (SupportedTransports transport) const { return m_ReachableTransports & transport; };
|
||||
bool HasValidAddresses () const { return m_SupportedTransports; };
|
||||
bool IsHidden () const { return m_Caps & eHidden; };
|
||||
bool IsHighBandwidth () const { return m_Caps & RouterInfo::eHighBandwidth; };
|
||||
|
|
|
@ -70,7 +70,11 @@ namespace transport
|
|||
if (m_EndpointV6.address() == boost::asio::ip::address().from_string("::")) // only if not binded to address
|
||||
{
|
||||
// Set preference to use public IPv6 address -- tested on linux, not works on windows, and not tested on others
|
||||
#if (BOOST_VERSION >= 105500)
|
||||
typedef boost::asio::detail::socket_option::integer<BOOST_ASIO_OS_DEF(IPPROTO_IPV6), IPV6_ADDR_PREFERENCES> ipv6PreferAddr;
|
||||
#else
|
||||
typedef boost::asio::detail::socket_option::integer<IPPROTO_IPV6, IPV6_ADDR_PREFERENCES> ipv6PreferAddr;
|
||||
#endif
|
||||
m_SocketV6.set_option (ipv6PreferAddr(IPV6_PREFER_SRC_PUBLIC | IPV6_PREFER_SRC_HOME | IPV6_PREFER_SRC_NONCGA));
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -383,7 +383,7 @@ namespace transport
|
|||
{
|
||||
// tell out peer to now assign relay tag
|
||||
flag = SSU_HEADER_EXTENDED_OPTIONS_INCLUDED;
|
||||
*payload = 2; payload++; // 1 byte length
|
||||
*payload = 2; payload++; // 1 byte length
|
||||
uint16_t flags = 0; // clear EXTENDED_OPTIONS_FLAG_REQUEST_RELAY_TAG
|
||||
htobe16buf (payload, flags);
|
||||
payload += 2;
|
||||
|
@ -1073,7 +1073,10 @@ namespace transport
|
|||
LogPrint (eLogDebug, "SSU: peer test from Charlie. We are Bob");
|
||||
auto session = m_Server.GetPeerTestSession (nonce); // session with Alice from PeerTest
|
||||
if (session && session->m_State == eSessionStateEstablished)
|
||||
session->Send (PAYLOAD_TYPE_PEER_TEST, buf, len); // back to Alice
|
||||
{
|
||||
const auto& ep = session->GetRemoteEndpoint (); // Alice's endpoint as known to Bob
|
||||
session->SendPeerTest (nonce, ep.address (), ep.port (), introKey, false, true); // send back to Alice
|
||||
}
|
||||
m_Server.RemovePeerTest (nonce); // nonce has been used
|
||||
break;
|
||||
}
|
||||
|
@ -1093,9 +1096,12 @@ namespace transport
|
|||
if (port)
|
||||
{
|
||||
LogPrint (eLogDebug, "SSU: peer test from Bob. We are Charlie");
|
||||
m_Server.NewPeerTest (nonce, ePeerTestParticipantCharlie);
|
||||
Send (PAYLOAD_TYPE_PEER_TEST, buf, len); // back to Bob
|
||||
SendPeerTest (nonce, addr, port, introKey); // to Alice with her address received from Bob
|
||||
if (!addr.is_unspecified () && !i2p::util::net::IsInReservedRange(addr))
|
||||
{
|
||||
m_Server.NewPeerTest (nonce, ePeerTestParticipantCharlie);
|
||||
SendPeerTest (nonce, addr, port, introKey); // to Alice with her address received from Bob
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -401,7 +401,7 @@ namespace transport
|
|||
try
|
||||
{
|
||||
auto r = netdb.FindRouter (ident);
|
||||
if (!r || r->IsUnreachable () || !r->IsCompatible (i2p::context.GetRouterInfo ())) return;
|
||||
if (!r || r->IsUnreachable () || !r->IsReachableFrom (i2p::context.GetRouterInfo ())) return;
|
||||
{
|
||||
std::unique_lock<std::mutex> l(m_PeersMutex);
|
||||
it = m_Peers.insert (std::pair<i2p::data::IdentHash, Peer>(ident, { 0, r, {},
|
||||
|
@ -447,7 +447,7 @@ namespace transport
|
|||
std::shared_ptr<const RouterInfo::Address> address;
|
||||
if (!peer.numAttempts) // NTCP2 ipv6
|
||||
{
|
||||
if (context.GetRouterInfo ().IsNTCP2V6 () && peer.router->IsNTCP2V6 ())
|
||||
if (context.GetRouterInfo ().IsNTCP2V6 () && peer.router->IsReachableBy (RouterInfo::eNTCP2V6))
|
||||
{
|
||||
address = peer.router->GetPublishedNTCP2V6Address ();
|
||||
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
|
||||
|
@ -457,7 +457,7 @@ namespace transport
|
|||
}
|
||||
if (!address && peer.numAttempts == 1) // NTCP2 ipv4
|
||||
{
|
||||
if (context.GetRouterInfo ().IsNTCP2 (true) && peer.router->IsNTCP2 (true) && !peer.router->IsUnreachable ())
|
||||
if (context.GetRouterInfo ().IsNTCP2 (true) && peer.router->IsReachableBy (RouterInfo::eNTCP2V4))
|
||||
{
|
||||
address = peer.router->GetPublishedNTCP2V4Address ();
|
||||
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
|
||||
|
@ -485,7 +485,7 @@ namespace transport
|
|||
std::shared_ptr<const RouterInfo::Address> address;
|
||||
if (peer.numAttempts == 2) // SSU ipv6
|
||||
{
|
||||
if (context.GetRouterInfo ().IsSSUV6 () && peer.router->IsSSUV6 ())
|
||||
if (context.GetRouterInfo ().IsSSUV6 () && peer.router->IsReachableBy (RouterInfo::eSSUV6))
|
||||
{
|
||||
address = peer.router->GetSSUV6Address ();
|
||||
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
|
||||
|
@ -495,7 +495,7 @@ namespace transport
|
|||
}
|
||||
if (!address && peer.numAttempts == 3) // SSU ipv4
|
||||
{
|
||||
if (context.GetRouterInfo ().IsSSU (true) && peer.router->IsSSU (true))
|
||||
if (context.GetRouterInfo ().IsSSU (true) && peer.router->IsReachableBy (RouterInfo::eSSUV4))
|
||||
{
|
||||
address = peer.router->GetSSUAddress (true);
|
||||
if (address && m_CheckReserved && i2p::util::net::IsInReservedRange(address->host))
|
||||
|
|
|
@ -142,16 +142,24 @@ namespace tunnel
|
|||
{
|
||||
std::vector<std::shared_ptr<InboundTunnel> > v;
|
||||
int i = 0;
|
||||
std::shared_ptr<InboundTunnel> slowTunnel;
|
||||
std::unique_lock<std::mutex> l(m_InboundTunnelsMutex);
|
||||
for (const auto& it : m_InboundTunnels)
|
||||
{
|
||||
if (i >= num) break;
|
||||
if (it->IsEstablished ())
|
||||
{
|
||||
v.push_back (it);
|
||||
i++;
|
||||
if (it->IsSlow () && !slowTunnel)
|
||||
slowTunnel = it;
|
||||
else
|
||||
{
|
||||
v.push_back (it);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (slowTunnel && (int)v.size () < (num/2+1))
|
||||
v.push_back (slowTunnel);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue