deprecated net/ip_address and path/path_context

This commit is contained in:
dr7ana 2024-02-07 08:57:02 -08:00
parent 76f720ef6d
commit 53552ad579
32 changed files with 423 additions and 255 deletions

View File

@ -104,21 +104,27 @@ add_dependencies(lokinet-utils genversion)
# Addressing and event loop files used by lokinet-core and other libraries
# needed by rpc/ link/ service/ config/ path/ dht/
lokinet_add_library(lokinet-time-place
address/address.cpp
address/ip_range.cpp
address/keys.cpp
ev/ev.cpp
ev/libuv.cpp
net/ip.cpp
net/ip_address.cpp
net/ip_packet.cpp
net/ip_range.cpp
# net/ip_address.cpp
# net/ip_range.cpp
net/net_int.cpp
net/sock_addr.cpp
router_contact.cpp
router_contact.cpp # TODO: move these + router_id.cpp to lokinet-core-utils..?
router_contact_local.cpp
router_contact_remote.cpp
router_id.cpp
router_version.cpp # to be deleted shortly
service/address.cpp
# service/intro_set.cpp
service/tag.cpp
)
@ -223,7 +229,7 @@ lokinet_add_library(lokinet-config
lokinet_add_library(lokinet-path
path/abstracthophandler.cpp
path/path.cpp
path/path_context.cpp
# path/path_context.cpp
path/pathhandler.cpp
path/transit_hop.cpp
)

View File

@ -0,0 +1,7 @@
#include "ip_packet.hpp"
namespace llarp
{
//
} // namespace llarp

View File

@ -0,0 +1,14 @@
#pragma once
#include <llarp/util/buffer.hpp>
#include <llarp/util/time.hpp>
#include <oxenc/endian.h>
#include <memory>
#include <utility>
namespace llarp
{
//
} // namespace llarp

View File

@ -4,24 +4,103 @@
namespace llarp
{
bool IPRange::from_string(std::string arg)
ip_net IPRange::init_ip()
{
if (_is_ipv4)
return ipv4_net{ipv4{oxenc::big_to_host<uint32_t>(_addr.in4().sin_addr.s_addr)}, _mask};
return ipv6_net{ipv6{_addr.in6().sin6_addr.s6_addr}, _mask};
}
std::optional<IPRange> IPRange::from_string(std::string arg)
{
std::optional<IPRange> range = std::nullopt;
oxen::quic::Address _addr;
uint8_t _mask;
if (auto pos = arg.find_first_of('/'); pos != std::string::npos)
{
try
{
auto [host, p] = parse_addr(arg.substr(0, pos), 0);
assert(p == 0);
addr = oxen::quic::Address{host, p};
return parse_int(arg.substr(pos), mask);
_addr = oxen::quic::Address{host, p};
if (parse_int(arg.substr(pos), _mask))
range = IPRange{std::move(_addr), std::move(_mask)};
else
log::warning(logcat, "Failed to construct IPRange from string input:{}", arg);
}
catch (const std::exception& e)
{
log::error(logcat, "Exception caught parsing IPRange:{}", e.what());
return false;
}
}
return range;
}
std::optional<ipv4_net> IPRange::get_ipv4_net() const
{
std::optional<ipv4_net> ret = std::nullopt;
if (auto* maybe = std::get_if<ipv4_net>(&_ip))
ret = *maybe;
return ret;
}
std::optional<ipv6_net> IPRange::get_ipv6_net() const
{
std::optional<ipv6_net> ret = std::nullopt;
if (auto* maybe = std::get_if<ipv6_net>(&_ip))
ret = *maybe;
return ret;
}
std::optional<ipv4> IPRange::get_ipv4() const
{
std::optional<ipv4> ret = std::nullopt;
if (auto ipv4 = get_ipv4_net())
ret = ipv4->base;
return ret;
}
std::optional<ipv6> IPRange::get_ipv6() const
{
std::optional<ipv6> ret = std::nullopt;
if (auto ipv6 = get_ipv6_net())
ret = ipv6->base;
return ret;
}
bool IPRange::contains(const IPRange& other) const
{
if (is_ipv4() ^ other.is_ipv4())
return false;
if (is_ipv4())
return get_ipv4_net()->contains(*other.get_ipv4());
return get_ipv6_net()->contains(*other.get_ipv6());
}
std::optional<IPRange> IPRange::find_private_range(const std::list<IPRange>& excluding)
{
auto filter = [&excluding](const IPRange& range) -> bool {
for (const auto& e : excluding)
if (e == range)
return false;
return true;
};
(void)filter;
return std::nullopt;
}
} // namespace llarp

View File

@ -3,35 +3,101 @@
#include <llarp/util/formattable.hpp>
#include <oxen/quic.hpp>
#include <oxenc/bt_serialize.h>
namespace llarp
{
using ipv4 = oxen::quic::ipv4;
using ipv6 = oxen::quic::ipv6;
using ipv4_net = oxen::quic::ipv4_net;
using ipv6_net = oxen::quic::ipv6_net;
using ip_net = std::variant<ipv4_net, ipv6_net>;
struct IPRange
{
private:
oxen::quic::Address addr;
uint8_t mask;
oxen::quic::Address _addr;
uint8_t _mask;
bool _is_ipv4;
ip_net _ip;
ip_net init_ip();
public:
IPRange() = default;
explicit IPRange(std::string a, uint8_t m) : addr{std::move(a), 0}, mask{m}, _is_ipv4{addr.is_ipv4()}
explicit IPRange(std::string a, uint8_t m)
: _addr{std::move(a), 0}, _mask{m}, _is_ipv4{_addr.is_ipv4()}, _ip{init_ip()}
{}
explicit IPRange(oxen::quic::Address a, uint8_t m) : addr{a}, mask{m}, _is_ipv4{addr.is_ipv4()}
explicit IPRange(oxen::quic::Address a, uint8_t m)
: _addr{a}, _mask{m}, _is_ipv4{_addr.is_ipv4()}, _ip{init_ip()}
{}
// TODO: finish this
static std::optional<IPRange> find_private_range(const std::list<IPRange>& excluding);
void bt_encode(oxenc::bt_list_producer& btlp) const
{
btlp.append(to_string());
}
std::string to_string() const
{
return addr.to_string() + "/" + std::to_string(mask);
return _addr.to_string() + "/" + std::to_string(_mask);
}
bool from_string(std::string arg);
static std::optional<IPRange> from_string(std::string arg);
bool contains(const IPRange& other) const;
bool is_ipv4() const
{
return _is_ipv4;
}
std::optional<ipv4_net> get_ipv4_net() const;
std::optional<ipv4> get_ipv4() const;
std::optional<ipv6_net> get_ipv6_net() const;
std::optional<ipv6> get_ipv6() const;
const ip_net& ip() const
{
return _ip;
}
const uint8_t& mask() const
{
return _mask;
}
uint8_t mask()
{
return _mask;
}
const oxen::quic::Address& address() const
{
return _addr;
}
oxen::quic::Address address()
{
return _addr;
}
bool operator<(const IPRange& other) const
{
return std::tie(_addr, _mask) < std::tie(other._addr, other._mask);
}
bool operator==(const IPRange& other) const
{
return std::tie(_addr, _mask) == std::tie(other._addr, other._mask);
}
};
template <>

View File

@ -1,4 +0,0 @@
#pragma once
namespace llarp
{} // namespace llarp

View File

@ -26,7 +26,7 @@ namespace llarp
return true;
}
std::pair<std::string, uint16_t> parse_addr(std::string_view addr, std::optional<uint16_t> default_port)
inline std::pair<std::string, uint16_t> parse_addr(std::string_view addr, std::optional<uint16_t> default_port)
{
std::pair<std::string, uint16_t> result;

View File

@ -420,12 +420,10 @@ namespace llarp
" owned-range=10.0.0.0/24",
},
[this](std::string arg) {
IPRange range;
if (not range.from_string(arg))
if (auto range = IPRange::from_string(arg))
_owned_ranges.insert(std::move(*range));
else
throw std::invalid_argument{"Bad IP range passed to owned-range:{}"_format(arg)};
_owned_ranges.insert(std::move(range));
});
conf.define_option<std::string>(
@ -471,20 +469,17 @@ namespace llarp
if (arg.empty())
return;
IPRange range;
std::optional<IPRange> range;
ClientAddress remote;
const auto pos = arg.find(":");
if (pos == std::string::npos)
{
// TODO: this is probably not necessary as these are the default constructed values
range.from_string("::/0");
}
else if (not range.from_string(arg.substr(pos + 1)))
{
std::string input = (pos == std::string::npos) ? "::/0"s : arg.substr(pos + 1);
range = IPRange::from_string(std::move(input));
if (not range.has_value())
throw std::invalid_argument("[network]:exit-node invalid ip range for exit provided");
}
if (pos != std::string::npos)
{
@ -493,7 +488,7 @@ namespace llarp
if (service::is_valid_name(arg))
{
_ons_range_map.emplace(std::move(arg), std::move(range));
_ons_range_map.emplace(std::move(arg), std::move(*range));
return;
}
@ -502,7 +497,7 @@ namespace llarp
throw std::invalid_argument{"[network]:exit-node bad address: {}"_format(arg)};
}
_range_map.emplace(std::move(remote), std::move(range));
_range_map.emplace(std::move(remote), std::move(*range));
});
conf.define_option<std::string>(
@ -1252,12 +1247,12 @@ namespace llarp
(void)params;
constexpr Default DefaultUniqueCIDR{32};
conf.define_option<int>(
conf.define_option<uint8_t>(
"paths",
"unique-range-size",
DefaultUniqueCIDR,
ClientOnly,
[=](int arg) {
[=](uint8_t arg) {
if (arg == 0)
{
unique_hop_netmask = arg;
@ -1294,16 +1289,15 @@ namespace llarp
{
if (unique_hop_netmask == 0)
return true;
const auto netmask = netmask_ipv6_bits(96 + unique_hop_netmask);
std::set<IP_range_deprecated> seenRanges;
std::set<IPRange> seen_ranges;
for (const auto& hop : rcs)
{
const auto network_addr = net::In6ToHUInt(hop.addr6()->in6().sin6_addr) & netmask;
if (auto [it, inserted] = seenRanges.emplace(network_addr, netmask); not inserted)
{
if (auto [it, b] = seen_ranges.emplace(hop.addr(), unique_hop_netmask); not b)
return false;
}
}
return true;
}

View File

@ -37,7 +37,6 @@ namespace llarp
using SectionValues = llarp::ConfigParser::SectionValues;
using ConfigMap = llarp::ConfigParser::ConfigMap;
inline const std::string QUAD_ZERO{"0.0.0.0"};
inline constexpr uint16_t DEFAULT_LISTEN_PORT{1090};
inline constexpr uint16_t DEFAULT_DNS_PORT{53};
inline constexpr int CLIENT_ROUTER_CONNECTIONS = 4;
@ -93,8 +92,7 @@ namespace llarp
{
/// in our hops what netmask will we use for unique ips for hops
/// i.e. 32 for every hop unique ip, 24 unique /24 per hop, etc
///
int unique_hop_netmask;
uint8_t unique_hop_netmask;
/// set of countrys to exclude from path building (2 char country code)
std::unordered_set<std::string> exclude_countries;
@ -105,6 +103,8 @@ namespace llarp
bool check_rcs(const std::set<RemoteRC>& hops) const;
};
/** TODO: unfuck the config in regards to tun mapping vs exit/service mapping
*/
struct NetworkConfig
{
std::optional<bool> enable_profiling;
@ -154,12 +154,12 @@ namespace llarp
std::set<IPRange> _owned_ranges;
// DEPRECATED
IP_range_deprecated if_addr;
std::optional<huint128_t> base_ipv6_range = std::nullopt;
// IP_range_deprecated if_addr;
// std::optional<huint128_t> base_ipv6_range = std::nullopt;
std::unordered_map<huint128_t, service::Address> addr_map;
net::IPRangeMap<service::Address> range_map;
net::IPRangeMap<std::string> ons_range_map;
std::set<IP_range_deprecated> owned_ranges;
// std::set<IP_range_deprecated> owned_ranges;
/*************************************/
bool enable_route_poker;

View File

@ -46,7 +46,7 @@ namespace llarp::dht
ISNode(service::EncryptedIntroSet other) : introset(std::move(other))
{
ID = Key_t(introset.derivedSigningKey.as_array());
ID = Key_t(introset.derived_signing_key.as_array());
}
StatusObject ExtractStatus() const
@ -56,7 +56,7 @@ namespace llarp::dht
bool operator<(const ISNode& other) const
{
return introset.signedAt < other.introset.signedAt;
return introset.signed_at < other.introset.signed_at;
}
};
} // namespace llarp::dht

View File

@ -648,7 +648,7 @@ namespace llarp::handlers
ip_range = networkConfig.if_addr;
if (!ip_range.addr.h)
{
const auto maybe = router->net().FindFreeRange();
const auto maybe = router->net().find_free_range();
if (not maybe.has_value())
throw std::runtime_error("cannot find free interface range");
ip_range = *maybe;

View File

@ -5,7 +5,6 @@
namespace llarp::handlers
{
RemoteHandler::RemoteHandler(std::string name, Router& r)
: path::PathHandler{r, NUM_ONS_LOOKUP_PATHS, path::DEFAULT_LEN}, _name{std::move(name)}
{}
@ -120,7 +119,8 @@ namespace llarp::handlers
}
*/
_dns_conf = dnsConfig;
_dns_config = dnsConfig;
_net_config = networkConfig;
// TODO: this should be in router
// if (networkConfig.endpoint_type == "null")
@ -128,32 +128,41 @@ namespace llarp::handlers
// should_init_tun = false;
// }
_ip_range = networkConfig.if_addr;
_ip_range = _net_config._if_addr;
if (!_ip_range.addr.h)
if (!_ip_range.address().is_addressable())
{
const auto maybe = _router.net().FindFreeRange();
const auto maybe = _router.net().find_free_range();
if (not maybe.has_value())
throw std::runtime_error("cannot find free interface range");
_ip_range = *maybe;
}
_next_addr = _if_addr = _ip_range.addr;
_next_addr = _if_addr = _ip_range;
_use_v6 = not _ip_range.IsV4();
_use_v6 = not _ip_range.is_ipv4();
_if_name = networkConfig._if_name;
_if_name = _net_config._if_name;
if (_if_name.empty())
{
const auto maybe = _router.net().FindFreeTun();
if (not maybe.has_value())
throw std::runtime_error("cannot find free interface name");
_if_name = *maybe;
}
log::info(logcat, "{} set ifname to {}", name(), _if_name);
for (const auto& addr : _net_config._addr_map)
{
(void)addr;
// TODO: here is where we should map remote services and exits, but first we need
// to unfuck the config
}
// if (auto* quic = GetQUICTunnel())
// {
// quic->listen([ifaddr = net::TruncateV6(if_addr)](std::string_view, uint16_t port) {
@ -165,7 +174,7 @@ namespace llarp::handlers
void RemoteHandler::map_remote(
std::string /* name */,
std::string /* token */,
std::vector<IP_range_deprecated> /* ranges */,
std::vector<IPRange> /* ranges */,
std::function<void(bool, std::string)> /* result_handler */)
{
// if (ranges.empty())

View File

@ -2,6 +2,7 @@
#include "common.hpp"
#include <llarp/address/ip_range.hpp>
#include <llarp/auth/auth.hpp>
#include <llarp/endpoint_base.hpp>
#include <llarp/handlers/remote.hpp>
@ -27,11 +28,12 @@ namespace llarp
std::string _name;
net::IPRangeMap<service::Address> _ip_map;
DnsConfig _dns_conf;
IP_range_deprecated _ip_range;
DnsConfig _dns_config;
NetworkConfig _net_config;
huint128_t _if_addr;
huint128_t _next_addr;
IPRange _ip_range;
IPRange _if_addr;
IPRange _next_addr;
std::string _if_name;
@ -53,7 +55,7 @@ namespace llarp
return _use_v6;
}
huint128_t if_addr() const
IPRange if_addr() const
{
return _if_addr;
}
@ -85,14 +87,14 @@ namespace llarp
void map_remote(
std::string name,
std::string token,
std::vector<IP_range_deprecated> ranges,
std::vector<IPRange> ranges,
std::function<void(bool, std::string)> result);
void map_range(IP_range_deprecated range, service::Address exit);
void map_range(IPRange range, service::Address exit);
void unmap_range(IP_range_deprecated range);
void unmap_range(IPRange range);
void unmap_range_by_remote(IP_range_deprecated range, std::string exit);
void unmap_range_by_remote(IPRange range, std::string exit);
};
} // namespace handlers
} // namespace llarp

View File

@ -289,9 +289,9 @@ namespace llarp::handlers
_dns_config = dnsConf;
_traffic_policy = conf.traffic_policy;
_owned_ranges = conf.owned_ranges;
_owned_ranges = conf._owned_ranges;
_base_address_v6 = conf.base_ipv6_range;
_base_address_v6 = conf._base_ipv6_range;
if (conf.path_alignment_timeout)
{
@ -307,70 +307,88 @@ namespace llarp::handlers
}
_if_name = conf._if_name;
if (_if_name.empty())
{
const auto maybe = router().net().FindFreeTun();
if (not maybe.has_value())
throw std::runtime_error("cannot find free interface name");
_if_name = *maybe;
}
_local_range = conf.if_addr;
if (!_local_range.addr.h)
_local_range = conf._if_addr;
if (!_local_range.address().is_addressable())
{
const auto maybe = router().net().FindFreeRange();
const auto maybe = router().net().find_free_range();
if (not maybe.has_value())
{
throw std::runtime_error("cannot find free address range");
}
_local_range = *maybe;
}
_local_ip = _local_range.addr;
_use_v6 = false;
_local_ip = _local_range.address();
_use_v6 = not _local_range.is_ipv4();
_persisting_addr_file = conf.addr_map_persist_file;
if (_persisting_addr_file)
{
const auto& file = *_persisting_addr_file;
if (fs::exists(file))
{
bool shouldLoadFile = true;
bool load_file = true;
{
constexpr auto LastModifiedWindow = 1min;
const auto lastmodified = fs::last_write_time(file);
const auto now = decltype(lastmodified)::clock::now();
if (now < lastmodified or now - lastmodified > LastModifiedWindow)
{
shouldLoadFile = false;
load_file = false;
}
}
std::vector<char> data;
if (auto maybe = util::OpenFileStream<fs::ifstream>(file, std::ios_base::binary);
maybe and shouldLoadFile)
if (auto maybe = util::OpenFileStream<fs::ifstream>(file, std::ios_base::binary); maybe and load_file)
{
LogInfo(name(), " loading address map file from ", file);
log::info(logcat, "{} loading persisting address map file from path:{}", name(), file);
maybe->seekg(0, std::ios_base::end);
const size_t len = maybe->tellg();
maybe->seekg(0, std::ios_base::beg);
data.resize(len);
LogInfo(name(), " reading ", len, " bytes");
log::debug(logcat, "{} reading {}B", name(), len);
maybe->read(data.data(), data.size());
}
else
{
if (shouldLoadFile)
auto err = "{} could not load persisting address map file from path:{} --"_format(name(), file);
log::info(logcat, "{} {}", err, load_file ? "NOT FOUND" : "STALE");
if (load_file)
{
LogInfo(name(), " address map file ", file, " does not exist, so we won't load it");
log::info(logcat, "{} NOT FOUND", err);
}
else
LogInfo(name(), " address map file ", file, " not loaded because it's stale");
log::info(logcat, "{} STALE", err);
}
if (not data.empty())
{
std::string_view bdata{data.data(), data.size()};
LogDebug(name(), " parsing address map data: ", bdata);
log::trace(logcat, "{} parsing address map data: {}", name(), bdata);
const auto parsed = oxenc::bt_deserialize<oxenc::bt_dict>(bdata);
@ -954,7 +972,7 @@ namespace llarp::handlers
if (_base_address_v6)
{
IP_range_deprecated v6range = _local_range;
IPRange v6range = _local_range;
v6range.addr = (*_base_address_v6) | _local_range.addr;
LogInfo(name(), " using v6 range: ", v6range);
info.addrs.emplace_back(v6range, AF_INET6);

View File

@ -136,7 +136,7 @@ namespace llarp::handlers
return _traffic_policy;
}
std::set<IP_range_deprecated> GetOwnedRanges() const /* override */
std::set<IPRange> get_owned_ranges() const /* override */
{
return _owned_ranges;
}
@ -231,26 +231,28 @@ namespace llarp::handlers
DnsConfig _dns_config;
// TODO: change the IP's to the variant IP type in address/ip_range.hpp
/// maps ip address to timestamp last active
std::unordered_map<huint128_t, llarp_time_t> _ip_activity;
/// our ip address (host byte order)
huint128_t _local_ip;
oxen::quic::Address _local_ip;
/// our network interface's ipv6 address
huint128_t _local_ipv6;
IPRange _local_ipv6;
/// next ip address to allocate (host byte order)
huint128_t _next_ip;
IPRange _next_ip;
/// highest ip address to allocate (host byte order)
huint128_t _max_ip;
IPRange _max_ip;
/// our ip range we are using
llarp::IP_range_deprecated _local_range;
IPRange _local_range;
/// list of strict connect addresses for hooks
// std::vector<IpAddress> _strict_connect_addrs;
/// use v6?
bool _use_v6;
std::string _if_name;
std::optional<huint128_t> _base_address_v6;
std::optional<IPRange> _base_address_v6;
std::shared_ptr<vpn::NetworkInterface> _net_if;
@ -258,7 +260,7 @@ namespace llarp::handlers
std::optional<net::TrafficPolicy> _traffic_policy;
/// ranges we advetise as reachable
std::set<IP_range_deprecated> _owned_ranges;
std::set<IPRange> _owned_ranges;
/// how long to wait for path alignment
llarp_time_t _path_alignment_timeout;

View File

@ -759,16 +759,17 @@ namespace llarp
auto& registered = node_db->registered_routers();
if (auto itr = registered.find(rid); itr != registered.end())
{
_router.loop()->call_soon([this, remote_rc = *remote]() {
if (node_db->verify_store_gossip_rc(remote_rc))
{
log::critical(
logcat,
"Bootstrap node confirmed RID:{} is registered; approving fetch request "
"and "
"saving RC!",
rid);
_router.loop()->call_soon(
[this, remote_rc = *remote]() { node_db->verify_gossip_bfetch_rc(remote_rc); });
"Bootstrap node confirmed RID:{} is registered; approving fetch request and saving RC!",
remote_rc.router_id());
gossip_rc(_router.local_rid(), remote_rc);
}
});
}
}
}

View File

@ -1,4 +1,5 @@
#pragma once
#include "ip_range.hpp"
namespace llarp

View File

@ -7,6 +7,7 @@
#include "net_int.hpp"
#include "uint128.hpp"
#include <llarp/address/ip_range.hpp>
#include <llarp/util/bits.hpp>
#include <llarp/util/mem.hpp>
@ -117,7 +118,7 @@ namespace llarp
// addresses; the returned Address (if set) will have its port set to the given value.
virtual std::optional<oxen::quic::Address> get_best_public_address(bool ipv4, uint16_t port) const = 0;
virtual std::optional<IP_range_deprecated> FindFreeRange() const = 0;
virtual std::optional<IPRange> find_free_range() const = 0;
virtual std::optional<std::string> FindFreeTun() const = 0;

View File

@ -71,19 +71,22 @@ namespace llarp::net
return found;
}
std::optional<IP_range_deprecated> FindFreeRange() const override
std::optional<IPRange> find_free_range() const override
{
std::list<IP_range_deprecated> currentRanges;
iter_all([&currentRanges](auto i) {
std::list<IPRange> current_ranges;
iter_all([&current_ranges](auto i) {
if (i and i->ifa_addr and i->ifa_addr->sa_family == AF_INET)
{
ipv4addr_t addr{reinterpret_cast<sockaddr_in*>(i->ifa_addr)->sin_addr.s_addr};
ipv4addr_t mask{reinterpret_cast<sockaddr_in*>(i->ifa_netmask)->sin_addr.s_addr};
currentRanges.emplace_back(IP_range_deprecated::FromIPv4(addr, mask));
oxen::quic::Address addr{i->ifa_addr};
uint8_t m = reinterpret_cast<sockaddr_in*>(i->ifa_netmask)->sin_addr.s_addr;
// ipv4addr_t addr{reinterpret_cast<sockaddr_in*>(i->ifa_addr)->sin_addr.s_addr};
// ipv4addr_t mask{reinterpret_cast<sockaddr_in*>(i->ifa_netmask)->sin_addr.s_addr};
current_ranges.emplace_back(std::move(addr), std::move(m));
}
});
return IP_range_deprecated::FindPrivateRange(currentRanges);
// TODO:
return IPRange::find_private_range(current_ranges);
}
std::optional<int> GetInterfaceIndex(ipaddr_t) const override

View File

@ -950,18 +950,6 @@ namespace llarp
return false;
}
void NodeDB::verify_gossip_bfetch_rc(const RemoteRC& rc)
{
if (auto maybe = get_rc(rc.router_id()))
{
if (not maybe->other_is_newer(rc))
return;
}
if (put_rc(rc))
_router.link_manager().gossip_rc(_router.local_rid(), rc);
}
bool NodeDB::put_rc_if_newer(RemoteRC rc)
{
if (auto maybe = get_rc(rc.router_id()))

View File

@ -523,8 +523,6 @@ namespace llarp
/// returns true if the rc was inserted
bool put_rc_if_newer(RemoteRC rc);
void verify_gossip_bfetch_rc(const RemoteRC& rc);
bool verify_store_gossip_rc(const RemoteRC& rc);
};
} // namespace llarp

View File

@ -6,10 +6,7 @@
namespace llarp::path
{
static constexpr auto DefaultPathBuildLimit = 500ms;
PathContext::PathContext(Router* router)
: _router(router), m_AllowTransit(false), path_limits(DefaultPathBuildLimit)
PathContext::PathContext(Router* router) : _router(router), m_AllowTransit(false)
{}
void PathContext::allow_transit()
@ -22,20 +19,6 @@ namespace llarp::path
return m_AllowTransit;
}
bool PathContext::check_path_limit_hit_by_ip(const Ip_address_deprecated& ip)
{
#ifdef TESTNET
return false;
#else
Ip_address_deprecated remote = ip;
// null out the port -- we don't care about it for path limiting purposes
remote.setPort(0);
// try inserting remote address by ip into decaying hash set
// if it cannot insert it has hit a limit
return not path_limits.Insert(remote);
#endif
}
const std::shared_ptr<EventLoop>& PathContext::loop()
{
return _router->loop();
@ -153,9 +136,6 @@ namespace llarp::path
void PathContext::ExpirePaths(llarp_time_t now)
{
// decay limits
path_limits.Decay(now);
{
auto itr = transit_hops.begin();
while (itr != transit_hops.end())

View File

@ -62,7 +62,7 @@ namespace llarp::path
void reject_transit();
bool check_path_limit_hit_by_ip(const Ip_address_deprecated& ip);
// bool check_path_limit_hit_by_ip(const Ip_address_deprecated& ip);
bool is_transit_allowed() const;
@ -107,6 +107,5 @@ namespace llarp::path
std::unordered_map<TransitHopID, std::shared_ptr<TransitHop>> transit_hops;
std::unordered_map<HopID, std::shared_ptr<Path>> own_paths;
bool m_AllowTransit;
util::DecayingHashSet<Ip_address_deprecated> path_limits;
};
} // namespace llarp::path

View File

@ -336,7 +336,7 @@ namespace llarp
info.ifname = network_config._if_name;
info.addrs.emplace_back(network_config.if_addr);
info.addrs.emplace_back(network_config._if_addr);
auto if_net = vpn_platform()->CreateInterface(std::move(info), this);

View File

@ -2,8 +2,8 @@
#include "rpc_request_decorators.hpp"
#include <llarp/address/ip_range.hpp>
#include <llarp/config/config.hpp>
#include <llarp/net/ip_range.hpp>
#include <llarp/router/route_poker.hpp>
#include <llarp/service/address.hpp>
#include <llarp/service/endpoint.hpp>
@ -175,9 +175,9 @@ namespace llarp::rpc
MapExit()
{
if constexpr (platform::supports_ipv6)
request.ip_range.emplace_back("::/0");
request.ip_range.emplace_back("::"s, 0);
else
request.ip_range.emplace_back("0.0.0.0/0");
request.ip_range.emplace_back("0.0.0.0"s, 0);
}
static constexpr auto name = "map_exit"sv;
@ -185,7 +185,7 @@ namespace llarp::rpc
struct request_parameters
{
std::string address;
std::vector<IP_range_deprecated> ip_range;
std::vector<IPRange> ip_range;
std::string token;
} request;
};
@ -217,16 +217,16 @@ namespace llarp::rpc
UnmapExit()
{
if constexpr (platform::supports_ipv6)
request.ip_range.emplace_back("::/0");
request.ip_range.emplace_back("::", 0);
else
request.ip_range.emplace_back("0.0.0.0/0");
request.ip_range.emplace_back("0.0.0.0", 0);
}
static constexpr auto name = "unmap_exit"sv;
struct request_parameters
{
std::vector<IP_range_deprecated> ip_range;
std::vector<IPRange> ip_range;
} request;
};

View File

@ -52,14 +52,15 @@ namespace llarp::service
// SetAuthInfoForEndpoint(exit, auth);
// }
conf.ons_range_map.ForEachEntry([&](const IP_range_deprecated& range, const std::string& name) {
std::optional<auth::AuthInfo> auth;
const auto itr = conf.ons_exit_auths.find(name);
if (itr != conf.ons_exit_auths.end())
auth = itr->second;
(void)range;
// TODO: move this to remote exit handler
// conf.ons_range_map.ForEachEntry([&](const IP_range_deprecated& range, const std::string& name) {
// std::optional<auth::AuthInfo> auth;
// const auto itr = conf.ons_exit_auths.find(name);
// if (itr != conf.ons_exit_auths.end())
// auth = itr->second;
// (void)range;
// _startup_ons_mappings[name] = std::make_pair(range, auth);
});
// });
// return _state->Configure(conf);
return true;

View File

@ -108,13 +108,6 @@ namespace llarp::service
return std::nullopt;
};
/// get the ip ranges we claim to own
/// override me
virtual std::set<IP_range_deprecated> GetOwnedRanges() const
{
return {};
};
void reset_path_state() override;
/// loop (via router)

View File

@ -164,7 +164,7 @@ namespace llarp::service
// set timestamp
// TODO: round to nearest 1000 ms
i.time_signed = now;
encrypted.signedAt = now;
encrypted.signed_at = now;
// set service info
i.address_keys = pub;
// set public encryption key
@ -175,7 +175,7 @@ namespace llarp::service
const SharedSecret k{i.address_keys.Addr()};
crypto::xchacha20(reinterpret_cast<uint8_t*>(bte.data()), bte.size(), k, encrypted.nonce);
std::memcpy(encrypted.introsetPayload.data(), bte.data(), bte.size());
std::memcpy(encrypted.introset_payload.data(), bte.data(), bte.size());
if (not encrypted.Sign(derivedSignKey))
return std::nullopt;

View File

@ -12,11 +12,11 @@ namespace llarp::service
std::string enc_payload,
std::string nonce,
std::string s)
: signedAt{signed_at},
introsetPayload{reinterpret_cast<uint8_t*>(enc_payload.data()), enc_payload.size()},
: signed_at{signed_at},
introset_payload{reinterpret_cast<uint8_t*>(enc_payload.data()), enc_payload.size()},
nonce{reinterpret_cast<uint8_t*>(nonce.data())}
{
derivedSigningKey = PubKey::make_from_hex(signing_key);
derived_signing_key = PubKey::make_from_hex(signing_key);
sig.from_string(std::move(s));
}
@ -26,10 +26,10 @@ namespace llarp::service
{
oxenc::bt_dict_consumer btdc{bt_payload};
derivedSigningKey = PubKey::make_from_hex(btdc.require<std::string>("d"));
derived_signing_key = PubKey::make_from_hex(btdc.require<std::string>("d"));
nonce.from_string(btdc.require<std::string>("n"));
signedAt = std::chrono::milliseconds{btdc.require<uint64_t>("s")};
introsetPayload = btdc.require<ustring>("x");
signed_at = std::chrono::milliseconds{btdc.require<uint64_t>("s")};
introset_payload = btdc.require<ustring>("x");
sig.from_string(btdc.require<std::string>("z"));
}
catch (...)
@ -40,8 +40,8 @@ namespace llarp::service
StatusObject EncryptedIntroSet::ExtractStatus() const
{
const auto sz = introsetPayload.size();
return {{"location", derivedSigningKey.to_string()}, {"signedAt", to_json(signedAt)}, {"size", sz}};
const auto sz = introset_payload.size();
return {{"location", derived_signing_key.to_string()}, {"signedAt", to_json(signed_at)}, {"size", sz}};
}
std::string EncryptedIntroSet::bt_encode() const
@ -50,11 +50,11 @@ namespace llarp::service
try
{
btdp.append("d", derivedSigningKey.ToView());
btdp.append("d", derived_signing_key.ToView());
btdp.append("n", nonce.ToView());
btdp.append("s", signedAt.count());
btdp.append("s", signed_at.count());
btdp.append(
"x", std::string_view{reinterpret_cast<const char*>(introsetPayload.data()), introsetPayload.size()});
"x", std::string_view{reinterpret_cast<const char*>(introset_payload.data()), introset_payload.size()});
btdp.append("z", sig.ToView());
}
catch (...)
@ -75,17 +75,17 @@ namespace llarp::service
return false;
if (strbuf.sz > MAX_INTROSET_SIZE)
return false;
introsetPayload.resize(strbuf.sz);
std::copy_n(strbuf.base, strbuf.sz, introsetPayload.data());
introset_payload.resize(strbuf.sz);
std::copy_n(strbuf.base, strbuf.sz, introset_payload.data());
return true;
}
if (not BEncodeMaybeReadDictEntry("d", derivedSigningKey, read, key, buf))
if (not BEncodeMaybeReadDictEntry("d", derived_signing_key, read, key, buf))
return false;
if (not BEncodeMaybeReadDictEntry("n", nonce, read, key, buf))
return false;
if (not BEncodeMaybeReadDictInt("s", signedAt, read, key, buf))
if (not BEncodeMaybeReadDictInt("s", signed_at, read, key, buf))
return false;
if (not BEncodeMaybeReadDictEntry("z", sig, read, key, buf))
@ -95,24 +95,24 @@ namespace llarp::service
bool EncryptedIntroSet::OtherIsNewer(const EncryptedIntroSet& other) const
{
return signedAt < other.signedAt;
return signed_at < other.signed_at;
}
std::string EncryptedIntroSet::to_string() const
{
return fmt::format(
"[EncIntroSet d={} n={} s={} x=[{} bytes] z={}]",
derivedSigningKey,
derived_signing_key,
nonce,
signedAt.count(),
introsetPayload.size(),
signed_at.count(),
introset_payload.size(),
sig);
}
IntroSet EncryptedIntroSet::decrypt(const PubKey& root) const
{
SharedSecret k(root);
std::string payload{reinterpret_cast<const char*>(introsetPayload.data()), introsetPayload.size()};
std::string payload{reinterpret_cast<const char*>(introset_payload.data()), introset_payload.size()};
crypto::xchacha20(reinterpret_cast<uint8_t*>(payload.data()), payload.size(), k, nonce);
@ -121,13 +121,13 @@ namespace llarp::service
bool EncryptedIntroSet::IsExpired(llarp_time_t now) const
{
return now >= signedAt + path::DEFAULT_LIFETIME;
return now >= signed_at + path::DEFAULT_LIFETIME;
}
bool EncryptedIntroSet::Sign(const PrivateKey& k)
{
signedAt = llarp::time_now_ms();
if (not k.to_pubkey(derivedSigningKey))
signed_at = llarp::time_now_ms();
if (not k.to_pubkey(derived_signing_key))
return false;
sig.Zero();
auto bte = bt_encode();
@ -147,7 +147,7 @@ namespace llarp::service
copy.sig.Zero();
auto bte = copy.bt_encode();
return crypto::verify(derivedSigningKey, reinterpret_cast<uint8_t*>(bte.data()), bte.size(), sig);
return crypto::verify(derived_signing_key, reinterpret_cast<uint8_t*>(bte.data()), bte.size(), sig);
}
bool EncryptedIntroSet::verify(uint8_t* introset, size_t introset_size, uint8_t* key, uint8_t* sig)

View File

@ -4,9 +4,9 @@
#include "intro.hpp"
#include "types.hpp"
#include <llarp/address/ip_range.hpp>
#include <llarp/crypto/types.hpp>
#include <llarp/dns/srv_data.hpp>
#include <llarp/net/ip_range.hpp>
#include <llarp/net/traffic_policy.hpp>
#include <llarp/util/bencode.hpp>
#include <llarp/util/time.hpp>
@ -40,7 +40,7 @@ namespace llarp::service
std::vector<ProtocolType> supported_protocols;
/// aonnuce that these ranges are reachable via our endpoint
/// only set when we support exit traffic ethertype is supported
std::set<IP_range_deprecated> owned_ranges;
std::set<IPRange> owned_ranges;
/// policies about traffic that we are willing to carry
/// a protocol/range whitelist or blacklist
@ -103,9 +103,9 @@ namespace llarp::service
/// public version of the introset that is encrypted
struct EncryptedIntroSet
{
PubKey derivedSigningKey;
llarp_time_t signedAt = 0s;
ustring introsetPayload;
PubKey derived_signing_key;
llarp_time_t signed_at = 0s;
ustring introset_payload;
SymmNonce nonce;
Signature sig;
@ -151,13 +151,13 @@ namespace llarp::service
inline bool operator<(const EncryptedIntroSet& lhs, const EncryptedIntroSet& rhs)
{
return lhs.derivedSigningKey < rhs.derivedSigningKey;
return lhs.derived_signing_key < rhs.derived_signing_key;
}
inline bool operator==(const EncryptedIntroSet& lhs, const EncryptedIntroSet& rhs)
{
return std::tie(lhs.signedAt, lhs.derivedSigningKey, lhs.nonce, lhs.sig)
== std::tie(rhs.signedAt, rhs.derivedSigningKey, rhs.nonce, rhs.sig);
return std::tie(lhs.signed_at, lhs.derived_signing_key, lhs.nonce, lhs.sig)
== std::tie(rhs.signed_at, rhs.derived_signing_key, rhs.nonce, rhs.sig);
}
inline bool operator!=(const EncryptedIntroSet& lhs, const EncryptedIntroSet& rhs)

View File

@ -33,75 +33,86 @@ namespace llarp::vpn
class LinuxInterface : public NetworkInterface
{
const int m_fd;
const int _fd;
public:
LinuxInterface(InterfaceInfo info) : NetworkInterface{std::move(info)}, m_fd{::open("/dev/net/tun", O_RDWR)}
LinuxInterface(InterfaceInfo info) : NetworkInterface{std::move(info)}, _fd{::open("/dev/net/tun", O_RDWR)}
{
if (m_fd == -1)
if (_fd == -1)
throw std::runtime_error("cannot open /dev/net/tun " + std::string{strerror(errno)});
ifreq ifr{};
in6_ifreq ifr6{};
ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
std::copy_n(m_Info.ifname.c_str(), std::min(m_Info.ifname.size(), sizeof(ifr.ifr_name)), ifr.ifr_name);
if (::ioctl(m_fd, TUNSETIFF, &ifr) == -1)
std::copy_n(_info.ifname.c_str(), std::min(_info.ifname.size(), sizeof(ifr.ifr_name)), ifr.ifr_name);
if (::ioctl(_fd, TUNSETIFF, &ifr) == -1)
throw std::runtime_error("cannot set interface name: " + std::string{strerror(errno)});
IOCTL control{AF_INET};
control.ioctl(SIOCGIFFLAGS, &ifr);
const int flags = ifr.ifr_flags;
control.ioctl(SIOCGIFINDEX, &ifr);
m_Info.index = ifr.ifr_ifindex;
for (const auto& ifaddr : m_Info.addrs)
control.ioctl(SIOCGIFINDEX, &ifr);
_info.index = ifr.ifr_ifindex;
for (const auto& ifaddr : _info.addrs)
{
auto& range = ifaddr.range;
if (ifaddr.fam == AF_INET)
{
ifr.ifr_addr.sa_family = AF_INET;
const nuint32_t addr = ToNet(net::TruncateV6(ifaddr.range.addr));
((sockaddr_in*)&ifr.ifr_addr)->sin_addr.s_addr = addr.n;
auto in4 = range.address().in4();
std::memcpy(
&((sockaddr_in*)&ifr.ifr_addr)->sin_addr.s_addr, &in4.sin_addr.s_addr, sizeof(sockaddr));
control.ioctl(SIOCSIFADDR, &ifr);
const nuint32_t mask = ToNet(net::TruncateV6(ifaddr.range.netmask_bits));
((sockaddr_in*)&ifr.ifr_netmask)->sin_addr.s_addr = mask.n;
((sockaddr_in*)&ifr.ifr_netmask)->sin_addr.s_addr =
oxenc::load_host_to_big<unsigned int>(&range.mask());
control.ioctl(SIOCSIFNETMASK, &ifr);
}
if (ifaddr.fam == AF_INET6)
{
ifr6.addr = net::HUIntToIn6(ifaddr.range.addr);
ifr6.prefixlen = llarp::bits::count_bits(ifaddr.range.netmask_bits);
ifr6.ifindex = m_Info.index;
auto in6 = range.address().in6();
std::memcpy(&ifr6.addr, &in6.sin6_addr, sizeof(in6.sin6_addr));
ifr6.prefixlen = llarp::bits::count_bits(range.mask());
ifr6.ifindex = _info.index;
try
{
IOCTL{AF_INET6}.ioctl(SIOCSIFADDR, &ifr6);
}
catch (std::exception& ex)
catch (const std::exception& e)
{
LogError("we are not allowed to use IPv6 on this system: ", ex.what());
log::error(logcat, "IPv6 not allowed on this system: {}", e.what());
}
}
}
ifr.ifr_flags = static_cast<short>(flags | IFF_UP | IFF_NO_PI);
control.ioctl(SIOCSIFFLAGS, &ifr);
}
virtual ~LinuxInterface()
~LinuxInterface() override
{
::close(m_fd);
::close(_fd);
}
int PollFD() const override
{
return m_fd;
return _fd;
}
net::IP_packet_deprecated ReadNextPacket() override
{
std::vector<uint8_t> pkt;
pkt.resize(net::IP_packet_deprecated::MaxSize);
const auto sz = read(m_fd, pkt.data(), pkt.capacity());
const auto sz = read(_fd, pkt.data(), pkt.capacity());
if (sz < 0)
{
if (errno == EAGAIN or errno == EWOULDBLOCK)
@ -117,7 +128,7 @@ namespace llarp::vpn
bool WritePacket(net::IP_packet_deprecated pkt) override
{
const auto sz = write(m_fd, pkt.data(), pkt.size());
const auto sz = write(_fd, pkt.data(), pkt.size());
if (sz <= 0)
return false;
return sz == static_cast<ssize_t>(pkt.size());
@ -170,7 +181,7 @@ namespace llarp::vpn
unsigned char bitlen;
unsigned char data[sizeof(struct in6_addr)];
_inet_addr(oxen::quic::Address& addr)
_inet_addr(oxen::quic::Address addr)
{
const auto& v4 = addr.is_ipv4();
@ -303,10 +314,10 @@ namespace llarp::vpn
}
}
void route_via_interface(int cmd, int flags, NetworkInterface& vpn, IP_range_deprecated range)
void route_via_interface(int cmd, int flags, NetworkInterface& vpn, IPRange range)
{
const auto& info = vpn.Info();
if (range.IsV4())
if (range.is_ipv4())
{
const auto maybe = Net().GetInterfaceAddr(info.ifname);
if (not maybe)
@ -314,18 +325,20 @@ namespace llarp::vpn
const auto gateway = var::visit([](auto&& ip) { return _inet_addr{ip}; }, maybe->getIP());
const _inet_addr addr{
ToNet(net::TruncateV6(range.addr)), bits::count_bits(net::TruncateV6(range.netmask_bits))};
const _inet_addr addr{range.address()};
make_route(cmd, flags, addr, gateway, GatewayMode::eUpperDefault, info.index);
}
else
{
const auto maybe = Net().GetInterfaceIPv6Address(info.ifname);
if (not maybe)
throw std::runtime_error{"we dont have our own network interface?"};
const _inet_addr gateway{ToNet(*maybe), 128};
const _inet_addr addr{ToNet(range.addr), bits::count_bits(range.netmask_bits)};
const _inet_addr addr{range.address()};
make_route(cmd, flags, addr, gateway, GatewayMode::eUpperDefault, info.index);
}
}
@ -367,12 +380,12 @@ namespace llarp::vpn
default_route_via_interface(vpn, RTM_DELROUTE, 0);
}
void add_route_via_interface(NetworkInterface& vpn, IP_range_deprecated range) override
void add_route_via_interface(NetworkInterface& vpn, IPRange range) override
{
route_via_interface(RTM_NEWROUTE, NLM_F_CREATE | NLM_F_EXCL, vpn, range);
}
void delete_route_via_interface(NetworkInterface& vpn, IP_range_deprecated range) override
void delete_route_via_interface(NetworkInterface& vpn, IPRange range) override
{
route_via_interface(RTM_DELROUTE, 0, vpn, range);
}

View File

@ -2,8 +2,8 @@
#include "i_packet_io.hpp"
#include <llarp/address/ip_range.hpp>
#include <llarp/net/ip_packet.hpp>
#include <llarp/net/ip_range.hpp>
#include <oxen/quic.hpp>
#include <oxenc/variant.h>
@ -20,10 +20,11 @@ namespace llarp::vpn
{
struct InterfaceAddress
{
constexpr InterfaceAddress(IP_range_deprecated r, int f = AF_INET) : range{std::move(r)}, fam{f}
InterfaceAddress(IPRange r) : range{std::move(r)}, fam{range.is_ipv4() ? AF_INET : AF_INET6}
{}
IP_range_deprecated range;
IPRange range;
int fam;
bool operator<(const InterfaceAddress& other) const
{
return std::tie(range, fam) < std::tie(other.range, other.fam);
@ -34,16 +35,12 @@ namespace llarp::vpn
{
std::string ifname;
unsigned int index;
huint32_t dnsaddr;
std::vector<InterfaceAddress> addrs;
/// get address number N
inline net::ipaddr_t operator[](size_t idx) const
inline oxen::quic::Address operator[](size_t idx) const
{
const auto& range = addrs[idx].range;
if (range.IsV4())
return ToNet(net::TruncateV6(range.addr));
return ToNet(range.addr);
return addrs[idx].range.address();
}
};
@ -51,17 +48,17 @@ namespace llarp::vpn
class NetworkInterface : public I_Packet_IO
{
protected:
InterfaceInfo m_Info;
InterfaceInfo _info;
public:
NetworkInterface(InterfaceInfo info) : m_Info{std::move(info)}
NetworkInterface(InterfaceInfo info) : _info{std::move(info)}
{}
NetworkInterface(const NetworkInterface&) = delete;
NetworkInterface(NetworkInterface&&) = delete;
const InterfaceInfo& Info() const
{
return m_Info;
return _info;
}
/// idempotently wake up the upper layers as needed (platform dependant)
@ -91,9 +88,9 @@ namespace llarp::vpn
virtual void delete_default_route_via_interface(NetworkInterface& vpn) = 0;
virtual void add_route_via_interface(NetworkInterface& vpn, IP_range_deprecated range) = 0;
virtual void add_route_via_interface(NetworkInterface& vpn, IPRange range) = 0;
virtual void delete_route_via_interface(NetworkInterface& vpn, IP_range_deprecated range) = 0;
virtual void delete_route_via_interface(NetworkInterface& vpn, IPRange range) = 0;
virtual std::vector<oxen::quic::Address> get_non_interface_gateways(NetworkInterface& vpn) = 0;