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);
// NTCP
if (has_ntcp && !router.GetNTCPAddress(address.is_v6()))
if (has_ntcp && !router.GetAddress(address.is_v6(), Transport::NTCP))
{
LOG(debug)
<< "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));
}
// SSU
if (has_ssu && !router.GetSSUAddress(address.is_v6()))
if (has_ssu && !router.GetAddress(address.is_v6(), Transport::SSU))
{
LOG(debug)
<< "RouterContext: SSU was expected but no transport "
@@ -278,7 +278,7 @@ bool RouterContext::AddIntroducer(
const kovri::core::RouterInfo& routerInfo,
std::uint32_t tag) {
bool ret = false;
auto address = routerInfo.GetSSUAddress();
const auto* address = routerInfo.GetV4Address(Transport::SSU);
if (address) {
ret = m_RouterInfo.AddIntroducer(address, tag);
if (ret)

View File

@@ -915,26 +915,61 @@ std::shared_ptr<RouterProfile> RouterInfo::GetProfile() const
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)
return GetAddress(SupportedTransport::NTCPv4);
return GetAddress(SupportedTransport::NTCPv4 | SupportedTransport::NTCPv6);
}
if (prefer_v6)
{
const Address* address = GetAddress(prefer_v6, transport);
if (address)
return address;
}
const RouterInfo::Address* RouterInfo::GetSSUAddress(bool has_v6) const
{
if (!has_v6)
return GetAddress(SupportedTransport::SSUv4);
return GetAddress(SupportedTransport::SSUv4 | SupportedTransport::SSUv6);
return GetAddress(false, transport);
}
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
auto has_transport = [transports](const std::uint8_t supported) -> bool {
return transports & supported;
auto has_transport = [requested](const std::uint8_t supported) -> bool {
return requested & supported;
};
Transport transport(Transport::Unknown);
@@ -957,8 +992,8 @@ const RouterInfo::Address* RouterInfo::GetAddress(
{
if (address.transport == transport)
{
// Ensurew we return v6 capable address if selected
if (address.host.is_v4() || (has_v6 && address.host.is_v6()))
if ((address.host.is_v4() && !has_v6)
|| (address.host.is_v6() && has_v6))
{
LOG(debug) << "RouterInfo: " << __func__ << GetTrait(transport)
<< " " << address.host;

View File

@@ -546,13 +546,27 @@ class RouterInfo : public RouterInfoTraits, public RoutingDestination
// TODO(anonimal): template address getter
/// @return Address object capable of NTCP
/// @param has_v6 Address should have v6 capability
const Address* GetNTCPAddress(bool has_v6 = false) const;
/// @return V6-only address object
/// @param transport Given transport (NTCP or SSU)
const Address* GetV6Address(const Transport transport) const;
/// @return Address object capable of SSU
/// @param has_v6 Address should have v6 capability
const Address* GetSSUAddress(bool has_v6 = false) const;
/// @return V4-only address object
/// @param transport Given transport (NTCP or SSU)
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:
/// @return Pointer to RI buffer

View File

@@ -366,13 +366,15 @@ bool Transports::ConnectToPeerNTCP(Peer& peer)
LOG(debug)
<< "Transports: attempting NTCP for peer"
<< 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
assert(!address->host.is_unspecified());
const auto* address =
peer.router->GetAnyAddress(context.SupportsV6(), Transport::NTCP);
if (!address)
{
LOG(warning) << "Transports: no NTCP address found";
return false;
}
if (!address->host.is_unspecified()) {
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
/// @brief Provides functions to pass messages to a given peer.
/// Manages the SSU and NTCP transports.
class Transports {
class Transports : public core::RouterInfoTraits {
public:
Transports();

View File

@@ -35,6 +35,7 @@
#include <boost/bind.hpp>
#include <boost/endian/conversion.hpp>
#include "core/router/info.h"
#include "core/router/net_db/impl.h"
#include "core/router/transports/ssu/server.h"
@@ -94,7 +95,10 @@ void SSUData::Stop() {
void SSUData::AdjustPacketSize(
const kovri::core::RouterInfo& remote_router) {
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 (m_Session.IsV6 ())
m_PacketSize =

View File

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

View File

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

View File

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

View File

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