From c52782ab32e0f0f46cad66c9c4a52ae30c5b3ec3 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Fri, 3 Sep 2021 15:35:09 -0300 Subject: [PATCH] Add IPv6 addr/routing for macos --- llarp/apple/PacketTunnelProvider.m | 15 +++++++++++++-- llarp/apple/context_wrapper.cpp | 12 ++++++++++-- llarp/apple/context_wrapper.h | 11 ++++++++--- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/llarp/apple/PacketTunnelProvider.m b/llarp/apple/PacketTunnelProvider.m index 38dae4a74..b340e56cb 100644 --- a/llarp/apple/PacketTunnelProvider.m +++ b/llarp/apple/PacketTunnelProvider.m @@ -8,6 +8,7 @@ void* lokinet; @public NEPacketTunnelNetworkSettings* settings; @public NEIPv4Route* tun_route4; + @public NEIPv6Route* tun_route6; LLARPDNSTrampoline* dns_tramp; } @@ -135,7 +136,7 @@ static void del_default_route(void* ctx) { LLARPPacketTunnel* t = (__bridge LLARPPacketTunnel*) ctx; t->settings.IPv4Settings.includedRoutes = @[t->tun_route4]; - t->settings.IPv6Settings.includedRoutes = @[]; // No tun_route6 yet. + t->settings.IPv6Settings.includedRoutes = @[t->tun_route6]; [t updateNetworkSettings]; } @@ -206,6 +207,7 @@ static void del_default_route(void* ctx) { dns.matchDomains = @[@""]; dns.matchDomainsNoSearch = true; dns.searchDomains = @[]; + settings.DNSSettings = dns; NWHostEndpoint* upstreamdns_ep; if (strlen(conf.upstream_dns)) @@ -216,7 +218,16 @@ static void del_default_route(void* ctx) { tun_route4 = [[NEIPv4Route alloc] initWithDestinationAddress:ip subnetMask: mask]; ipv4.includedRoutes = @[tun_route4]; settings.IPv4Settings = ipv4; - settings.DNSSettings = dns; + + NSString* ip6 = [NSString stringWithUTF8String:conf.tunnel_ipv6_ip]; + NSNumber* ip6_prefix = [NSNumber numberWithUnsignedInt:conf.tunnel_ipv6_prefix]; + NEIPv6Settings* ipv6 = [[NEIPv6Settings alloc] initWithAddresses:@[ip6] + networkPrefixLengths:@[ip6_prefix]]; + tun_route6 = [[NEIPv6Route alloc] initWithDestinationAddress:ip6 + networkPrefixLength:ip6_prefix]; + ipv6.includedRoutes = @[tun_route6]; + settings.IPv6Settings = ipv6; + __weak LLARPPacketTunnel* weakSelf = self; [self setTunnelNetworkSettings:settings completionHandler:^(NSError* err) { if (err) { diff --git a/llarp/apple/context_wrapper.cpp b/llarp/apple/context_wrapper.cpp index ce9354540..f2a655778 100644 --- a/llarp/apple/context_wrapper.cpp +++ b/llarp/apple/context_wrapper.cpp @@ -60,8 +60,16 @@ llarp_apple_init(llarp_apple_config* appleconf) 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(appleconf->tunnel_ipv4_ip, addr.c_str()); - std::strcpy(appleconf->tunnel_ipv4_netmask, mask.c_str()); + std::strncpy(appleconf->tunnel_ipv4_ip, addr.c_str(), sizeof(appleconf->tunnel_ipv4_ip)); + std::strncpy(appleconf->tunnel_ipv4_netmask, mask.c_str(), sizeof(appleconf->tunnel_ipv4_netmask)); + + // TODO: in the future we want to do this properly with our pubkey (see issue #1705), but that's + // going to take a bit more work because we currently can't *get* the (usually) ephemeral pubkey + // at this stage of lokinet configuration. So for now we just stick our IPv4 address into it + // until #1705 gets implemented. + llarp::huint128_t ipv6{llarp::uint128_t{0xfd2e'6c6f'6b69'0000, llarp::net::TruncateV6(range.addr).h}}; + std::strncpy(appleconf->tunnel_ipv6_ip, ipv6.ToString().c_str(), sizeof(appleconf->tunnel_ipv6_ip)); + appleconf->tunnel_ipv6_prefix = 48; appleconf->upstream_dns[0] = '\0'; for (auto& upstream : config->dns.m_upstreamDNS) diff --git a/llarp/apple/context_wrapper.h b/llarp/apple/context_wrapper.h index 914446741..37c8a5c7b 100644 --- a/llarp/apple/context_wrapper.h +++ b/llarp/apple/context_wrapper.h @@ -69,12 +69,17 @@ extern "C" 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]; + char tunnel_ipv4_ip[INET_ADDRSTRLEN]; /// llarp_apple_init writes the netmask of the tunnel address here, null-terminated. - char tunnel_ipv4_netmask[16]; + char tunnel_ipv4_netmask[INET_ADDRSTRLEN]; + /// Writes the IPv6 address for the tunnel here, null-terminated. + char tunnel_ipv6_ip[INET6_ADDRSTRLEN]; + /// IPv6 address prefix. + uint16_t tunnel_ipv6_prefix; + /// The first upstream DNS server's IPv4 address the OS should use when in exit mode. /// (Currently on mac in exit mode we only support querying the first such configured server). - char upstream_dns[16]; + char upstream_dns[INET_ADDRSTRLEN]; uint16_t upstream_dns_port; /// \defgroup callbacks Callbacks