Add RouteManager; make exit on/off work

pull/1688/head
Jason Rhinelander 3 years ago committed by Jeff Becker
parent c74dcba463
commit e84390748d
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -15,7 +15,7 @@ find_library(COREFOUNDATION CoreFoundation REQUIRED)
target_sources(lokinet-util PRIVATE apple_logger.cpp)
target_link_libraries(lokinet-util PUBLIC ${FOUNDATION})
target_sources(lokinet-platform PRIVATE vpn_interface.cpp context_wrapper.cpp)
target_sources(lokinet-platform PRIVATE vpn_interface.cpp route_manager.cpp context_wrapper.cpp)
add_executable(lokinet-extension MACOSX_BUNDLE
PacketTunnelProvider.m

@ -7,6 +7,8 @@ NSString* error_domain = @"com.loki-project.lokinet";
@interface LLARPPacketTunnel : NEPacketTunnelProvider
{
void* lokinet;
@public NEPacketTunnelNetworkSettings* settings;
@public NEIPv4Route* tun_route4;
}
- (void)startTunnelWithOptions:(NSDictionary<NSString*, NSObject*>*)options
@ -20,6 +22,8 @@ NSString* error_domain = @"com.loki-project.lokinet";
- (void)readPackets;
- (void)updateNetworkSettings;
@end
void nslogger(const char* msg) { NSLog(@"%s", msg); }
@ -42,6 +46,97 @@ void start_packet_reader(void* ctx) {
[t readPackets];
}
void add_ipv4_route(const char* addr, const char* netmask, void* ctx) {
NEIPv4Route* route = [[NEIPv4Route alloc]
initWithDestinationAddress: [NSString stringWithUTF8String:addr]
subnetMask: [NSString stringWithUTF8String:netmask]];
LLARPPacketTunnel* t = (__bridge LLARPPacketTunnel*) ctx;
for (NEIPv4Route* r in t->settings.IPv4Settings.includedRoutes)
if ([r.destinationAddress isEqualToString:route.destinationAddress] &&
[r.destinationSubnetMask isEqualToString:route.destinationSubnetMask])
return; // Already in the settings, nothing to add.
t->settings.IPv4Settings.includedRoutes =
[t->settings.IPv4Settings.includedRoutes arrayByAddingObject:route];
[t updateNetworkSettings];
}
void del_ipv4_route(const char* addr, const char* netmask, void* ctx) {
NEIPv4Route* route = [[NEIPv4Route alloc]
initWithDestinationAddress: [NSString stringWithUTF8String:addr]
subnetMask: [NSString stringWithUTF8String:netmask]];
LLARPPacketTunnel* t = (__bridge LLARPPacketTunnel*) ctx;
NSMutableArray<NEIPv4Route*>* routes = [NSMutableArray arrayWithArray:t->settings.IPv4Settings.includedRoutes];
for (int i = 0; i < routes.count; i++) {
if ([routes[i].destinationAddress isEqualToString:route.destinationAddress] &&
[routes[i].destinationSubnetMask isEqualToString:route.destinationSubnetMask]) {
[routes removeObjectAtIndex:i];
i--;
}
}
if (routes.count != t->settings.IPv4Settings.includedRoutes.count) {
t->settings.IPv4Settings.includedRoutes = routes;
[t updateNetworkSettings];
}
}
void add_ipv6_route(const char* addr, int prefix, void* ctx) {
NEIPv6Route* route = [[NEIPv6Route alloc]
initWithDestinationAddress: [NSString stringWithUTF8String:addr]
networkPrefixLength: [NSNumber numberWithInt:prefix]];
LLARPPacketTunnel* t = (__bridge LLARPPacketTunnel*) ctx;
for (NEIPv6Route* r in t->settings.IPv6Settings.includedRoutes)
if ([r.destinationAddress isEqualToString:route.destinationAddress] &&
[r.destinationNetworkPrefixLength isEqualToNumber:route.destinationNetworkPrefixLength])
return; // Already in the settings, nothing to add.
t->settings.IPv6Settings.includedRoutes =
[t->settings.IPv6Settings.includedRoutes arrayByAddingObject:route];
[t updateNetworkSettings];
}
void del_ipv6_route(const char* addr, int prefix, void* ctx) {
NEIPv6Route* route = [[NEIPv6Route alloc]
initWithDestinationAddress: [NSString stringWithUTF8String:addr]
networkPrefixLength: [NSNumber numberWithInt:prefix]];
LLARPPacketTunnel* t = (__bridge LLARPPacketTunnel*) ctx;
NSMutableArray<NEIPv6Route*>* routes = [NSMutableArray arrayWithArray:t->settings.IPv6Settings.includedRoutes];
for (int i = 0; i < routes.count; i++) {
if ([routes[i].destinationAddress isEqualToString:route.destinationAddress] &&
[routes[i].destinationNetworkPrefixLength isEqualToNumber:route.destinationNetworkPrefixLength]) {
[routes removeObjectAtIndex:i];
i--;
}
}
if (routes.count != t->settings.IPv6Settings.includedRoutes.count) {
t->settings.IPv6Settings.includedRoutes = routes;
[t updateNetworkSettings];
}
}
void add_default_route(void* ctx) {
LLARPPacketTunnel* t = (__bridge LLARPPacketTunnel*) ctx;
t->settings.IPv4Settings.includedRoutes = @[NEIPv4Route.defaultRoute];
t->settings.IPv6Settings.includedRoutes = @[NEIPv6Route.defaultRoute];
[t updateNetworkSettings];
}
void del_default_route(void* ctx) {
LLARPPacketTunnel* t = (__bridge LLARPPacketTunnel*) ctx;
t->settings.IPv4Settings.includedRoutes = @[t->tun_route4];
t->settings.IPv4Settings.includedRoutes = @[]; // No tun_route6 yet.
[t updateNetworkSettings];
}
@implementation LLARPPacketTunnel
- (void)readPackets
@ -63,21 +158,39 @@ void start_packet_reader(void* ctx) {
char mask_buf[16];
char dns_buf[16];
NSString* default_bootstrap = [[NSBundle mainBundle] pathForResource:@"bootstrap" ofType:@"signed"];
NSString* default_bootstrap = [NSBundle.mainBundle pathForResource:@"bootstrap" ofType:@"signed"];
NSString* home = NSHomeDirectory();
lokinet = llarp_apple_init(nslogger, NSHomeDirectory().UTF8String, default_bootstrap.UTF8String, ip_buf, mask_buf, dns_buf);
llarp_apple_config conf = {
.config_dir = home.UTF8String,
.default_bootstrap = default_bootstrap.UTF8String,
.ns_logger = nslogger,
.packet_writer = packet_writer,
.start_reading = start_packet_reader,
.route_callbacks = {
.add_ipv4_route = add_ipv4_route,
.del_ipv4_route = del_ipv4_route,
.add_ipv6_route = add_ipv6_route,
.del_ipv6_route = del_ipv6_route,
.add_default_route = add_default_route,
.del_default_route = del_default_route
},
};
lokinet = llarp_apple_init(&conf);
if (!lokinet) {
NSError *init_failure = [NSError errorWithDomain:error_domain code:500 userInfo:@{@"Error": @"Failed to initialize lokinet"}];
NSLog(@"%@", [init_failure localizedDescription]);
return completionHandler(init_failure);
}
NSString* ip = [[NSString alloc] initWithUTF8String:ip_buf];
NSString* mask = [[NSString alloc] initWithUTF8String:mask_buf];
NSString* dnsaddr = [[NSString alloc] initWithUTF8String:dns_buf];
NEPacketTunnelNetworkSettings* settings =
[[NEPacketTunnelNetworkSettings alloc] initWithTunnelRemoteAddress:@"127.0.0.1"];
NSString* ip = [NSString stringWithUTF8String:conf.tunnel_ipv4_ip];
NSString* mask = [NSString stringWithUTF8String:conf.tunnel_ipv4_netmask];
NSString* dnsaddr = [NSString stringWithUTF8String:conf.tunnel_dns];
// We don't have a fixed address so just stick some bogus value here:
settings = [[NEPacketTunnelNetworkSettings alloc] initWithTunnelRemoteAddress:@"127.3.2.1"];
NEDNSSettings* dns = [[NEDNSSettings alloc] initWithServers:@[dnsaddr]];
dns.domainName = @"localhost.loki";
// In theory, matchDomains is supposed to be set to DNS suffixes that we resolve. This seems
@ -96,16 +209,21 @@ void start_packet_reader(void* ctx) {
dns.searchDomains = @[];
NEIPv4Settings* ipv4 = [[NEIPv4Settings alloc] initWithAddresses:@[ip]
subnetMasks:@[mask]];
ipv4.includedRoutes = @[[[NEIPv4Route alloc] initWithDestinationAddress:ip subnetMask: mask]];
tun_route4 = [[NEIPv4Route alloc] initWithDestinationAddress:ip subnetMask: mask];
ipv4.includedRoutes = @[tun_route4];
settings.IPv4Settings = ipv4;
settings.DNSSettings = dns;
__weak LLARPPacketTunnel* weakSelf = self;
[self setTunnelNetworkSettings:settings completionHandler:^(NSError* err) {
if (err) {
NSLog(@"Failed to configure lokinet tunnel: %@", err);
return completionHandler(err);
}
int start_ret = llarp_apple_start(lokinet, packet_writer, start_packet_reader, (__bridge void*) self);
LLARPPacketTunnel* strongSelf = weakSelf;
if (!strongSelf)
return completionHandler(nil);
int start_ret = llarp_apple_start(strongSelf->lokinet, (__bridge void*) strongSelf);
if (start_ret != 0) {
NSError *start_failure = [NSError errorWithDomain:error_domain code:start_ret userInfo:@{@"Error": @"Failed to start lokinet"}];
NSLog(@"%@", start_failure);
@ -132,4 +250,34 @@ void start_packet_reader(void* ctx) {
NSData* response = [NSData dataWithBytesNoCopy:"ok" length:3 freeWhenDone:NO];
completionHandler(response);
}
- (void)updateNetworkSettings
{
self.reasserting = YES;
__weak LLARPPacketTunnel* weakSelf = self;
// Apple documentation says that setting network settings to nil isn't required before setting it
// to a new value. Apple lies: both end up with a routing table that looks exactly the same (from
// both `netstat -rn` and from everything that happens in `route -n monitor`), but if we don't
// call with nil first then everything fails to route to either lokinet *and* clearnet through the
// exit, so there is apparently some special magic internal Apple state that actually *does*
// require the tunnel settings being reset with nil first.
//
// Thanks for the accurate documentation, Apple.
//
[self setTunnelNetworkSettings:nil completionHandler:^(NSError* err) {
if (err)
NSLog(@"Failed to clear lokinet tunnel settings: %@", err);
LLARPPacketTunnel* strongSelf = weakSelf;
if (strongSelf) {
[weakSelf setTunnelNetworkSettings:strongSelf->settings completionHandler:^(NSError* err) {
LLARPPacketTunnel* strongSelf = weakSelf;
if (strongSelf)
strongSelf.reasserting = NO;
if (err)
NSLog(@"Failed to reconfigure lokinet tunnel settings: %@", err);
}];
}
}];
}
@end

@ -2,6 +2,7 @@
#include <llarp.hpp>
#include "vpn_platform.hpp"
#include "route_manager.hpp"
namespace llarp::apple
{
@ -10,7 +11,7 @@ namespace llarp::apple
std::shared_ptr<vpn::Platform>
makeVPNPlatform() override
{
return std::make_shared<VPNPlatform>(*this, m_PacketWriter, m_OnReadable);
return std::make_shared<VPNPlatform>(*this, m_PacketWriter, m_OnReadable, route_callbacks, callback_context);
}
// Callbacks that must be set for packet handling *before* calling Setup/Configure/Run; the main
@ -18,6 +19,8 @@ namespace llarp::apple
// after construction.
VPNInterface::packet_write_callback m_PacketWriter;
VPNInterface::on_readable_callback m_OnReadable;
llarp_route_callbacks route_callbacks{};
void* callback_context = nullptr;
};
} // namespace llarp::apple

@ -19,6 +19,8 @@ namespace
{
llarp::apple::Context context;
std::thread runner;
packet_writer_callback packet_writer;
start_reading_callback start_reading;
std::weak_ptr<llarp::apple::VPNInterface> iface;
};
@ -26,19 +28,13 @@ namespace
} // namespace
void*
llarp_apple_init(
ns_logger_callback ns_logger,
const char* config_dir_,
const char* default_bootstrap,
char* ip,
char* netmask,
char* dns)
llarp_apple_init(llarp_apple_config* appleconf)
{
llarp::LogContext::Instance().logStream = std::make_unique<llarp::apple::NSLogStream>(ns_logger);
llarp::LogContext::Instance().logStream = std::make_unique<llarp::apple::NSLogStream>(appleconf->ns_logger);
try
{
auto config_dir = fs::u8path(config_dir_);
auto config_dir = fs::u8path(appleconf->config_dir);
auto config = std::make_shared<llarp::Config>(config_dir);
fs::path config_path = config_dir / "lokinet.ini";
if (!fs::exists(config_path))
@ -59,10 +55,10 @@ llarp_apple_init(
auto mask = llarp::net::TruncateV6(range.netmask_bits).ToString();
if (addr.size() > 15 || mask.size() > 15)
throw std::runtime_error{"Unexpected non-IPv4 tunnel range configured"};
std::strcpy(ip, addr.c_str());
std::strcpy(netmask, mask.c_str());
std::strcpy(appleconf->tunnel_ipv4_ip, addr.c_str());
std::strcpy(appleconf->tunnel_ipv4_netmask, mask.c_str());
// XXX possibly DNS needs to be the .0 instead of the .1 because mac reasons?
std::strcpy(dns, addr.c_str());
std::strcpy(appleconf->tunnel_dns, addr.c_str());
// The default DNS bind setting just isn't something we can use as a non-root network extension
// so remap the default value to a high port unless explicitly set to something else.
@ -71,10 +67,16 @@ llarp_apple_init(
// If no explicit bootstrap then set the system default one included with the app bundle
if (config->bootstrap.files.empty())
config->bootstrap.files.push_back(fs::u8path(default_bootstrap));
config->bootstrap.files.push_back(fs::u8path(appleconf->default_bootstrap));
auto inst = std::make_unique<instance_data>();
inst->context.Configure(std::move(config));
inst->context.route_callbacks = appleconf->route_callbacks;
inst->packet_writer = appleconf->packet_writer;
inst->start_reading = appleconf->start_reading;
return inst.release();
}
catch (const std::exception& e)
@ -87,21 +89,22 @@ llarp_apple_init(
int
llarp_apple_start(
void* lokinet,
packet_writer_callback packet_writer,
start_reading_callback start_reading,
void* callback_context)
{
auto* inst = static_cast<instance_data*>(lokinet);
inst->context.m_PacketWriter = [inst, packet_writer, callback_context](
int af_family, void* data, size_t size) {
packet_writer(af_family, data, size, callback_context);
return true;
inst->context.callback_context = callback_context;
inst->context.m_PacketWriter = [inst, callback_context](
int af_family, void* data, size_t size) {
inst->packet_writer(af_family, data, size, callback_context);
return true;
};
inst->context.m_OnReadable =
[inst, start_reading, callback_context](llarp::apple::VPNInterface& iface) {
[inst, callback_context](llarp::apple::VPNInterface& iface) {
inst->iface = iface.weak_from_this();
start_reading(callback_context);
inst->start_reading(callback_context);
};
std::promise<void> result;

@ -12,70 +12,112 @@ extern "C"
#include <sys/socket.h>
/// C callback function for us to invoke when we need to write a packet
typedef void(packet_writer_callback)(int af, const void* data, size_t size, void* ctx);
typedef void(*packet_writer_callback)(int af, const void* data, size_t size, void* ctx);
/// C callback function to invoke once we are ready to start receiving packets
typedef void(start_reading_callback)(void* ctx);
typedef void(*start_reading_callback)(void* ctx);
/// C callback that bridges things into NSLog
typedef void(ns_logger_callback)(const char* msg);
typedef void(*ns_logger_callback)(const char* msg);
/// C callbacks to add/remove specific and default routes to the tunnel
typedef void(*llarp_route_ipv4_callback)(const char* addr, const char* netmask, void* ctx);
typedef void(*llarp_route_ipv6_callback)(const char* addr, int prefix, void* ctx);
typedef void(*llarp_default_route_callback)(void* ctx);
typedef struct llarp_route_callbacks {
/// Callback invoked to set up an IPv4 range that should be routed through the tunnel
/// interface. Called with the address and netmask.
llarp_route_ipv4_callback add_ipv4_route;
/// Callback invoked to set the tunnel as the default IPv4 route.
llarp_default_route_callback add_ipv4_default_route;
/// Callback invoked to remove a specific range from the tunnel IPv4 routes. Called with the
/// address and netmask.
llarp_route_ipv4_callback del_ipv4_route;
/// Callback invoked to set up an IPv6 range that should be routed through the tunnel
/// interface. Called with the address and netmask.
llarp_route_ipv6_callback add_ipv6_route;
/// Callback invoked to remove a specific range from the tunnel IPv6 routes. Called with the
/// address and netmask.
llarp_route_ipv6_callback del_ipv6_route;
/// Callback invoked to set the tunnel as the default IPv4/IPv6 route.
llarp_default_route_callback add_default_route;
/// Callback invoked to remove the tunnel as the default IPv4/IPv6 route.
llarp_default_route_callback del_default_route;
} llarp_route_callbacks;
/// Pack of crap to be passed into llarp_apple_init to initialize
typedef struct llarp_apple_config
{
/// lokinet configuration directory, expected to be the application-specific "home" directory,
/// which is where state files are stored and the lokinet.ini will be loaded (or created if it
/// doesn't exist).
const char* config_dir;
/// path to the default bootstrap.signed file included in installation, which will be used by
/// default when no specific bootstrap is in the config file.
const char* default_bootstrap;
/// llarp_apple_init writes the IP address for the primary tunnel IP address here,
/// null-terminated.
char tunnel_ipv4_ip[16];
/// llarp_apple_init writes the netmask of the tunnel address here, null-terminated.
char tunnel_ipv4_netmask[16];
/// The DNS server IPv4 address the OS should use. Null-terminated.
char tunnel_dns[16];
/// \defgroup callbacks Callbacks
/// Callbacks we invoke for various operations that require glue into the Apple network
/// extension APIs. All of these except for ns_logger are passed the pointer provided to
/// llarp_apple_start when invoked.
/// @{
/// simple wrapper around NSLog for lokinet message logging
ns_logger_callback ns_logger;
/// C function callback that will be called when we need to write a packet to the packet
/// tunnel. Will be passed AF_INET or AF_INET6, a void pointer to the data, and the size of
/// the data in bytes.
packet_writer_callback packet_writer;
/// C function callback that will be called when lokinet is setup and ready to start receiving
/// packets from the packet tunnel. This should set up the read handler to deliver packets
/// via llarp_apple_incoming.
start_reading_callback start_reading;
/// Callbacks invoked to add/remove routes to the tunnel.
llarp_route_callbacks route_callbacks;
/// @}
} llarp_apple_config;
/// Initializes a lokinet instance by initializing various objects and loading the configuration
/// (if {config_dir}/lokinet.ini exists). Does not actually start lokinet (call llarp_apple_start
/// (if <config_dir>/lokinet.ini exists). Does not actually start lokinet (call llarp_apple_start
/// for that).
///
/// Returns NULL if there was a problem initializing/loading the configuration, otherwise returns
/// an opaque void pointer that should be passed into the other llarp_apple_* functions.
///
/// \param logger a logger callback that we pass log messages to to relay them (i.e. via NSLog).
///
/// \param config_dir the lokinet configuration directory where lokinet.ini can be and the various
/// other lokinet state files go.
///
/// \param default_bootstrap the path to the default bootstrap.signed included in installation,
/// which will be used if no explicit bootstrap is set in the config file.
///
/// \param ip - char buffer where we will write the primary tunnel IP address as a string such as
/// "172.16.0.0". Will write up to 16 characters (including the null terminator). This will be
/// the tunnel IP from the lokinet.ini, if it exists and specifies a range, otherwise we'll
/// configure lokinet to use a currently-unused range and return that.
///
/// \param netmask the tunnel netmask as a string such as "255.255.0.0". Will write up to 16
/// characters (including the null terminator).
///
/// \param dns the DNS address that should be configured to query lokinet, as a string such as
/// "172.16.0.1". Will write up to 16 characters (including the null terminator).
/// \param config pointer to a llarp_apple_config where we get the various settings needed
/// and return the ip/mask/dns fields needed for the tunnel.
void*
llarp_apple_init(
ns_logger_callback ns_logger,
const char* config_dir,
const char* default_bootstrap,
char* ip,
char* netmask,
char* dns);
llarp_apple_init(llarp_apple_config* config);
/// Starts the lokinet instance in a new thread.
///
/// \param packet_writer C function callback that will be called when we need to write a packet to
/// the packet tunnel. Will be passed AF_INET or AF_INET6, a void pointer to the data, the size
/// of the data in bytes, and the opaque callback_context pointer.
///
/// \param start_reading C function callback that will be called when lokinet is setup and ready
/// to start receiving packets from the packet tunnel. This should set up the read handler to
/// deliver packets via llarp_apple_incoming. This is called with a single argument of the opaque
/// callback_context pointer.
/// \param lokinet the void pointer returned by llarp_apple_init
///
/// \param callback_context Opaque pointer that is passed into the packet_writer and start_reading
/// callback, intended to allow context to be passed through to the callbacks. This code does
/// nothing with this pointer aside from passing it through to callbacks.
/// \param callback_context Opaque pointer that is passed into the various callbacks provided to
/// llarp_apple_init. This code does nothing with this pointer aside from passing it through to
/// callbacks.
///
/// \returns 0 on succesful startup, -1 on failure.
int
llarp_apple_start(
void* lokinet,
packet_writer_callback packet_writer,
start_reading_callback start_reading,
void* callback_context);
llarp_apple_start(void* lokinet, void* callback_context);
/// Called to deliver an incoming packet from the apple layer into lokinet; returns 0 on success,
/// -1 if the packet could not be parsed, -2 if there is no current active VPNInterface associated

@ -0,0 +1,61 @@
#include "route_manager.hpp"
namespace llarp::apple {
void RouteManager::AddDefaultRouteViaInterface(std::string)
{
LogWarn("AddDefaultRouteViaInterface with cbctx=", (bool) callback_context, ", adr=", (bool) route_callbacks.add_default_route);
if (callback_context and route_callbacks.add_default_route)
route_callbacks.add_default_route(callback_context);
}
void RouteManager::DelDefaultRouteViaInterface(std::string)
{
LogWarn("DelDefaultRouteViaInterface with cbctx=", (bool) callback_context, ", ddr=", (bool) route_callbacks.del_default_route);
if (callback_context and route_callbacks.del_default_route)
route_callbacks.del_default_route(callback_context);
}
void
RouteManager::AddRouteViaInterface(vpn::NetworkInterface&, IPRange range)
{
LogWarn("AddRoute with cbctx=", (bool) callback_context, ", a4r=", (bool) route_callbacks.add_ipv4_route,
"a6r", (bool) route_callbacks.add_ipv6_route);
if (callback_context)
{
if (range.IsV4()) {
if (route_callbacks.add_ipv4_route)
route_callbacks.add_ipv4_route(
range.BaseAddressString().c_str(),
net::TruncateV6(range.netmask_bits).ToString().c_str(),
callback_context);
} else {
if (route_callbacks.add_ipv6_route)
route_callbacks.add_ipv6_route(range.BaseAddressString().c_str(), range.HostmaskBits(), callback_context);
}
}
}
void
RouteManager::DelRouteViaInterface(vpn::NetworkInterface&, IPRange range)
{
LogWarn("DelRoute with cbctx=", (bool) callback_context, ", a4r=", (bool) route_callbacks.del_ipv4_route,
"a6r", (bool) route_callbacks.del_ipv6_route);
if (callback_context)
{
if (range.IsV4()) {
if (route_callbacks.del_ipv4_route)
route_callbacks.del_ipv4_route(
range.BaseAddressString().c_str(),
net::TruncateV6(range.netmask_bits).ToString().c_str(),
callback_context);
} else {
if (route_callbacks.del_ipv6_route)
route_callbacks.del_ipv6_route(range.BaseAddressString().c_str(), range.HostmaskBits(), callback_context);
}
}
}
}

@ -0,0 +1,46 @@
#pragma once
#include <llarp/ev/vpn.hpp>
#include "context_wrapper.h"
namespace llarp::apple {
class RouteManager final : public llarp::vpn::IRouteManager {
public:
RouteManager(llarp_route_callbacks rcs, void* callback_context)
: route_callbacks{std::move(rcs)}, callback_context{callback_context} {}
/// These are called for poking route holes, but we don't have to do that at all on macos
/// because the appex isn't subject to its own rules.
void
AddRoute(IPVariant_t ip, IPVariant_t gateway) override {}
void
DelRoute(IPVariant_t ip, IPVariant_t gateway) override {}
void
AddDefaultRouteViaInterface(std::string ifname) override;
void
DelDefaultRouteViaInterface(std::string ifname) override;
void
AddRouteViaInterface(vpn::NetworkInterface& vpn, IPRange range) override;
void
DelRouteViaInterface(vpn::NetworkInterface& vpn, IPRange range) override;
virtual std::vector<IPVariant_t>
GetGatewaysNotOnInterface(std::string ifname) override {
// We can't get this on mac from our sandbox, but we don't actually need it because we
// ignore the gateway for AddRoute/DelRoute anyway, so just return a zero IP.
std::vector<IPVariant_t> ret;
ret.push_back(huint32_t{0});
return ret;
}
void* callback_context = nullptr;
llarp_route_callbacks route_callbacks;
};
}

@ -2,6 +2,7 @@
#include <llarp/ev/vpn.hpp>
#include "vpn_interface.hpp"
#include "route_manager.hpp"
namespace llarp::apple
{
@ -11,8 +12,11 @@ namespace llarp::apple
explicit VPNPlatform(
Context& ctx,
VPNInterface::packet_write_callback packet_writer,
VPNInterface::on_readable_callback on_readable)
VPNInterface::on_readable_callback on_readable,
llarp_route_callbacks route_callbacks,
void* callback_context)
: m_Context{ctx}
, m_RouteManager{std::move(route_callbacks), callback_context}
, m_PacketWriter{std::move(packet_writer)}
, m_OnReadable{std::move(on_readable)}
{}
@ -22,8 +26,11 @@ namespace llarp::apple
return std::make_shared<VPNInterface>(m_Context, m_PacketWriter, m_OnReadable);
}
vpn::IRouteManager& RouteManager() override { return m_RouteManager; }
private:
Context& m_Context;
apple::RouteManager m_RouteManager;
VPNInterface::packet_write_callback m_PacketWriter;
VPNInterface::on_readable_callback m_OnReadable;
};

Loading…
Cancel
Save