0
0
mirror of https://github.com/monero-project/kovri synced 2025-10-06 00:32:51 +02:00

Core: use IPv6 address object when expected

This commit is contained in:
anonimal
2018-07-17 06:55:41 +00:00
parent 5fcee5f949
commit 9b553ae514
11 changed files with 107 additions and 51 deletions

View File

@@ -140,7 +140,7 @@ void RouterContext::Initialize(const boost::program_options::variables_map& map)
const auto& address = boost::asio::ip::address::from_string(host); const auto& address = boost::asio::ip::address::from_string(host);
// NTCP // NTCP
if (has_ntcp && !router.GetNTCPAddress(address.is_v6())) if (has_ntcp && !router.GetAddress(address.is_v6(), Transport::NTCP))
{ {
LOG(debug) LOG(debug)
<< "RouterContext: NTCP was expected but no transport " << "RouterContext: NTCP was expected but no transport "
@@ -149,7 +149,7 @@ void RouterContext::Initialize(const boost::program_options::variables_map& map)
router.AddAddress(std::make_tuple(Transport::NTCP, host, port)); router.AddAddress(std::make_tuple(Transport::NTCP, host, port));
} }
// SSU // SSU
if (has_ssu && !router.GetSSUAddress(address.is_v6())) if (has_ssu && !router.GetAddress(address.is_v6(), Transport::SSU))
{ {
LOG(debug) LOG(debug)
<< "RouterContext: SSU was expected but no transport " << "RouterContext: SSU was expected but no transport "
@@ -278,7 +278,7 @@ bool RouterContext::AddIntroducer(
const kovri::core::RouterInfo& routerInfo, const kovri::core::RouterInfo& routerInfo,
std::uint32_t tag) { std::uint32_t tag) {
bool ret = false; bool ret = false;
auto address = routerInfo.GetSSUAddress(); const auto* address = routerInfo.GetV4Address(Transport::SSU);
if (address) { if (address) {
ret = m_RouterInfo.AddIntroducer(address, tag); ret = m_RouterInfo.AddIntroducer(address, tag);
if (ret) if (ret)

View File

@@ -915,26 +915,61 @@ std::shared_ptr<RouterProfile> RouterInfo::GetProfile() const
return m_Profile; return m_Profile;
} }
const RouterInfo::Address* RouterInfo::GetNTCPAddress(bool has_v6) const const RouterInfo::Address* RouterInfo::GetAnyAddress(
const bool prefer_v6,
const Transport transport) const
{ {
if (!has_v6) if (prefer_v6)
return GetAddress(SupportedTransport::NTCPv4); {
return GetAddress(SupportedTransport::NTCPv4 | SupportedTransport::NTCPv6); const Address* address = GetAddress(prefer_v6, transport);
} if (address)
return address;
}
const RouterInfo::Address* RouterInfo::GetSSUAddress(bool has_v6) const return GetAddress(false, transport);
{
if (!has_v6)
return GetAddress(SupportedTransport::SSUv4);
return GetAddress(SupportedTransport::SSUv4 | SupportedTransport::SSUv6);
} }
const RouterInfo::Address* RouterInfo::GetAddress( const RouterInfo::Address* RouterInfo::GetAddress(
const std::uint8_t transports) const const bool require_v6,
const Transport transport) const
{
return require_v6 ? GetV6Address(transport) : GetV4Address(transport);
}
const RouterInfo::Address* RouterInfo::GetV6Address(
const Transport transport) const
{
switch (transport)
{
case Transport::NTCP:
return GetAddress(SupportedTransport::NTCPv6);
case Transport::SSU:
return GetAddress(SupportedTransport::SSUv6);
default:
return nullptr;
}
}
const RouterInfo::Address* RouterInfo::GetV4Address(
const Transport transport) const
{
switch (transport)
{
case Transport::NTCP:
return GetAddress(SupportedTransport::NTCPv4);
case Transport::SSU:
return GetAddress(SupportedTransport::SSUv4);
default:
return nullptr;
}
}
const RouterInfo::Address* RouterInfo::GetAddress(
const std::uint8_t requested) const
{ {
// Ensures supported transports // Ensures supported transports
auto has_transport = [transports](const std::uint8_t supported) -> bool { auto has_transport = [requested](const std::uint8_t supported) -> bool {
return transports & supported; return requested & supported;
}; };
Transport transport(Transport::Unknown); Transport transport(Transport::Unknown);
@@ -957,8 +992,8 @@ const RouterInfo::Address* RouterInfo::GetAddress(
{ {
if (address.transport == transport) if (address.transport == transport)
{ {
// Ensurew we return v6 capable address if selected if ((address.host.is_v4() && !has_v6)
if (address.host.is_v4() || (has_v6 && address.host.is_v6())) || (address.host.is_v6() && has_v6))
{ {
LOG(debug) << "RouterInfo: " << __func__ << GetTrait(transport) LOG(debug) << "RouterInfo: " << __func__ << GetTrait(transport)
<< " " << address.host; << " " << address.host;

View File

@@ -546,13 +546,27 @@ class RouterInfo : public RouterInfoTraits, public RoutingDestination
// TODO(anonimal): template address getter // TODO(anonimal): template address getter
/// @return Address object capable of NTCP /// @return V6-only address object
/// @param has_v6 Address should have v6 capability /// @param transport Given transport (NTCP or SSU)
const Address* GetNTCPAddress(bool has_v6 = false) const; const Address* GetV6Address(const Transport transport) const;
/// @return Address object capable of SSU /// @return V4-only address object
/// @param has_v6 Address should have v6 capability /// @param transport Given transport (NTCP or SSU)
const Address* GetSSUAddress(bool has_v6 = false) const; const Address* GetV4Address(const Transport transport) const;
/// @return Any available address object
/// @param prefer_v6 Give preference to IPv6 object but return IPv4 if IPv6 is unavailable
/// @param transport Given transport (NTCP or SSU)
const Address* GetAnyAddress(
const bool prefer_v6,
const Transport transport) const;
/// @return Address object, IPv4 only unless otherwise specified
/// @param require_v6 Require that an IPv6-only object is returned
/// @param transport Given transport (NTCP or SSU)
const Address* GetAddress(
const bool require_v6,
const Transport transport) const;
public: public:
/// @return Pointer to RI buffer /// @return Pointer to RI buffer

View File

@@ -366,13 +366,15 @@ bool Transports::ConnectToPeerNTCP(Peer& peer)
LOG(debug) LOG(debug)
<< "Transports: attempting NTCP for peer" << "Transports: attempting NTCP for peer"
<< GetFormattedSessionInfo(peer.router); << GetFormattedSessionInfo(peer.router);
const auto* address = peer.router->GetNTCPAddress(context.SupportsV6());
// No NTCP address found
if (!address)
return false;
// TODO(anonimal): We should expect to have an address specified when NTCP is enabled/allowed const auto* address =
assert(!address->host.is_unspecified()); peer.router->GetAnyAddress(context.SupportsV6(), Transport::NTCP);
if (!address)
{
LOG(warning) << "Transports: no NTCP address found";
return false;
}
if (!address->host.is_unspecified()) { if (!address->host.is_unspecified()) {
if (!peer.router->UsesIntroducer() && !peer.router->IsUnreachable()) { if (!peer.router->UsesIntroducer() && !peer.router->IsUnreachable()) {

View File

@@ -115,7 +115,7 @@ const std::uint32_t LOW_BANDWIDTH_LIMIT = 32 * 1024; // 32KBps
/// @class Transports /// @class Transports
/// @brief Provides functions to pass messages to a given peer. /// @brief Provides functions to pass messages to a given peer.
/// Manages the SSU and NTCP transports. /// Manages the SSU and NTCP transports.
class Transports { class Transports : public core::RouterInfoTraits {
public: public:
Transports(); Transports();

View File

@@ -35,6 +35,7 @@
#include <boost/bind.hpp> #include <boost/bind.hpp>
#include <boost/endian/conversion.hpp> #include <boost/endian/conversion.hpp>
#include "core/router/info.h"
#include "core/router/net_db/impl.h" #include "core/router/net_db/impl.h"
#include "core/router/transports/ssu/server.h" #include "core/router/transports/ssu/server.h"
@@ -94,7 +95,10 @@ void SSUData::Stop() {
void SSUData::AdjustPacketSize( void SSUData::AdjustPacketSize(
const kovri::core::RouterInfo& remote_router) { const kovri::core::RouterInfo& remote_router) {
LOG(debug) << "SSUData: adjusting packet size"; LOG(debug) << "SSUData: adjusting packet size";
auto ssu_address = remote_router.GetSSUAddress();
const auto* ssu_address =
remote_router.GetAddress(m_Session.IsV6(), Transport::SSU);
if (ssu_address && ssu_address->mtu) { if (ssu_address && ssu_address->mtu) {
if (m_Session.IsV6 ()) if (m_Session.IsV6 ())
m_PacketSize = m_PacketSize =

View File

@@ -117,7 +117,7 @@ struct SentMessage {
}; };
class SSUSession; class SSUSession;
class SSUData { class SSUData : public RouterInfoTraits {
public: public:
SSUData( SSUData(
SSUSession& session); SSUSession& session);

View File

@@ -388,7 +388,7 @@ std::shared_ptr<SSUSession> SSUServer::FindSession(
LOG(debug) << "SSUServer: finding session from RI"; LOG(debug) << "SSUServer: finding session from RI";
if (!router) if (!router)
return nullptr; return nullptr;
auto address = router->GetSSUAddress(); // v4 only auto* address = router->GetV4Address(Transport::SSU);
if (!address) if (!address)
return nullptr; return nullptr;
auto session = auto session =
@@ -396,7 +396,7 @@ std::shared_ptr<SSUSession> SSUServer::FindSession(
if (session || !context.SupportsV6()) if (session || !context.SupportsV6())
return session; return session;
// try v6 // try v6
address = router->GetSSUAddress(true); address = router->GetV6Address(Transport::SSU);
if (!address) if (!address)
return nullptr; return nullptr;
return FindSession(boost::asio::ip::udp::endpoint(address->host, address->port)); return FindSession(boost::asio::ip::udp::endpoint(address->host, address->port));
@@ -419,7 +419,7 @@ std::shared_ptr<SSUSession> SSUServer::GetSession(
LOG(debug) << "SSUServer: getting session"; LOG(debug) << "SSUServer: getting session";
std::shared_ptr<SSUSession> session; std::shared_ptr<SSUSession> session;
if (router) { if (router) {
auto address = router->GetSSUAddress(context.SupportsV6()); const auto* address = router->GetAnyAddress(context.SupportsV6(), Transport::SSU);
if (address) { if (address) {
boost::asio::ip::udp::endpoint remote_endpoint( boost::asio::ip::udp::endpoint remote_endpoint(
address->host, address->host,

View File

@@ -63,7 +63,7 @@ struct RawSSUPacket {
std::size_t len{}; std::size_t len{};
}; };
class SSUServer { class SSUServer : public core::RouterInfoTraits {
public: public:
SSUServer(boost::asio::io_service& service, const std::size_t port); SSUServer(boost::asio::io_service& service, const std::size_t port);

View File

@@ -41,6 +41,7 @@
#include "core/crypto/util/misc.h" #include "core/crypto/util/misc.h"
#include "core/router/context.h" #include "core/router/context.h"
#include "core/router/info.h"
#include "core/router/transports/ssu/packet.h" #include "core/router/transports/ssu/packet.h"
#include "core/router/transports/ssu/server.h" #include "core/router/transports/ssu/server.h"
#include "core/router/transports/impl.h" #include "core/router/transports/impl.h"
@@ -507,9 +508,8 @@ void SSUSession::SendSessionCreated(const std::uint8_t* dh_x)
// Get our (Bob's) intro key and SSU address // Get our (Bob's) intro key and SSU address
// TODO(anonimal): we can get/set this sooner. Redesign. // TODO(anonimal): we can get/set this sooner. Redesign.
const std::uint8_t* intro_key = GetIntroKey(); const std::uint8_t* intro_key = GetIntroKey();
auto* address = m_RemoteEndpoint.address().is_v6() const auto* address = context.GetRouterInfo().GetAddress(
? context.GetRouterInfo().GetSSUAddress(true) m_RemoteEndpoint.address().is_v6(), Transport::SSU);
: context.GetRouterInfo().GetSSUAddress();
// If we don't support SSU, we shouldn't reach this stage in the session // If we don't support SSU, we shouldn't reach this stage in the session
assert(intro_key || address); // TODO(anonimal): redesign assert(intro_key || address); // TODO(anonimal): redesign
@@ -782,7 +782,7 @@ void SSUSession::SendRelayRequest(
const std::uint32_t introducer_tag, const std::uint32_t introducer_tag,
const std::uint8_t* introducer_key) const std::uint8_t* introducer_key)
{ {
auto* const address = context.GetRouterInfo().GetSSUAddress(); const auto* address = context.GetRouterInfo().GetV4Address(Transport::SSU);
if (!address) if (!address)
{ {
LOG(error) << "SSUSession:" << GetFormattedSessionInfo() << __func__ LOG(error) << "SSUSession:" << GetFormattedSessionInfo() << __func__
@@ -1212,8 +1212,8 @@ void SSUSession::SendPeerTest(
if (to_address) if (to_address)
{ {
// Our (Alice's) intro key // Our (Alice's) intro key
auto* const addr = context.GetRouterInfo().GetSSUAddress( const auto* addr = context.GetRouterInfo().GetAnyAddress(
context.GetRouterInfo().HasV6()); context.GetRouterInfo().HasV6(), Transport::SSU);
assert(addr); assert(addr);
message.WriteData(addr->key, sizeof(addr->key)); message.WriteData(addr->key, sizeof(addr->key));
} }
@@ -1250,8 +1250,8 @@ void SSUSession::SendPeerTest(
void SSUSession::SendPeerTest() { void SSUSession::SendPeerTest() {
// we are Alice // we are Alice
LOG(debug) << "SSUSession: <--" << GetFormattedSessionInfo() << "sending PeerTest"; LOG(debug) << "SSUSession: <--" << GetFormattedSessionInfo() << "sending PeerTest";
auto* const address = const auto* address = context.GetRouterInfo().GetAnyAddress(
context.GetRouterInfo().GetSSUAddress(context.GetRouterInfo().HasV6()); context.GetRouterInfo().HasV6(), Transport::SSU);
assert(address); assert(address);
auto nonce = kovri::core::Rand<std::uint32_t>(); auto nonce = kovri::core::Rand<std::uint32_t>();
if (!nonce) if (!nonce)
@@ -1655,15 +1655,15 @@ const std::uint8_t* SSUSession::GetIntroKey() const
{ {
LOG(debug) << "SSUSession: " << __func__ << ": using remote's key"; LOG(debug) << "SSUSession: " << __func__ << ": using remote's key";
auto* const address = auto* const address =
m_RemoteRouter->GetSSUAddress(m_RemoteRouter->HasV6()); m_RemoteRouter->GetAddress(m_RemoteRouter->HasV6(), Transport::SSU);
assert(address); // TODO(anonimal): SSU should be guaranteed assert(address); // TODO(anonimal): SSU should be guaranteed
return address->key; return address->key;
} }
// Use our key if we are server // Use our key if we are server
LOG(debug) << "SSUSession: " << __func__ << ": using our key"; LOG(debug) << "SSUSession: " << __func__ << ": using our key";
auto* const address = const auto* address = context.GetRouterInfo().GetAnyAddress(
context.GetRouterInfo().GetSSUAddress(context.GetRouterInfo().HasV6()); context.GetRouterInfo().HasV6(), Transport::SSU);
assert(address); // TODO(anonimal): SSU should be guaranteed assert(address); // TODO(anonimal): SSU should be guaranteed
return address->key; return address->key;
} }

View File

@@ -127,9 +127,10 @@ struct SSUSessionPacket // TODO(unassigned): finish
}; };
class SSUServer; class SSUServer;
class SSUSession class SSUSession : public RouterInfoTraits,
: public TransportSession, public TransportSession,
public std::enable_shared_from_this<SSUSession> { public std::enable_shared_from_this<SSUSession>
{
public: public:
SSUSession( SSUSession(
SSUServer& server, SSUServer& server,