From a9c8f705fb4702ed153bcc79f5d53f83a0799805 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Wed, 29 Jan 2025 20:58:12 +0800 Subject: [PATCH] Hack it to compile for now --- llarp/vpn/apple.hpp | 87 +++++++++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 30 deletions(-) diff --git llarp/vpn/apple.hpp llarp/vpn/apple.hpp index f20c50ce3..0f3bdb51d 100644 --- llarp/vpn/apple.hpp +++ llarp/vpn/apple.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include "platform.hpp" #include "common.hpp" #include @@ -34,30 +34,28 @@ { class AppleInterface : public NetworkInterface { - const int m_FD; - const InterfaceInfo m_Info; + const int m_fd; std::string m_IfName; static void Exec(std::string cmd) { - LogDebug(cmd); system(cmd.c_str()); } public: AppleInterface(InterfaceInfo info) - : m_FD{::socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL)}, m_Info{std::move(info)} + : NetworkInterface{std::move(info)}, m_fd{::socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL)} { - if (m_FD == -1) + if (m_fd == -1) throw std::invalid_argument{"cannot open control socket: " + std::string{strerror(errno)}}; ctl_info cinfo{}; const std::string apple_utun = "com.apple.net.utun_control"; std::copy_n(apple_utun.c_str(), apple_utun.size(), cinfo.ctl_name); - if (::ioctl(m_FD, CTLIOCGINFO, &cinfo) < 0) + if (::ioctl(m_fd, CTLIOCGINFO, &cinfo) < 0) { - ::close(m_FD); + ::close(m_fd); throw std::runtime_error{"ioctl CTLIOCGINFO call failed: " + std::string{strerror(errno)}}; } sockaddr_ctl addr{}; @@ -68,21 +66,28 @@ addr.ss_sysaddr = AF_SYS_CONTROL; addr.sc_unit = 0; - if (connect(m_FD, (sockaddr*)&addr, sizeof(addr)) < 0) + if (connect(m_fd, (sockaddr*)&addr, sizeof(addr)) < 0) { - ::close(m_FD); + ::close(m_fd); throw std::runtime_error{ "cannot connect to control socket address: " + std::string{strerror(errno)}}; } uint32_t namesz = IFNAMSIZ; char name[IFNAMSIZ + 1]{}; - if (getsockopt(m_FD, SYSPROTO_CONTROL, 2, name, &namesz) < 0) + if (getsockopt(m_fd, SYSPROTO_CONTROL, 2, name, &namesz) < 0) { - ::close(m_FD); + ::close(m_fd); throw std::runtime_error{ "cannot query for interface name: " + std::string{strerror(errno)}}; } m_IfName = name; + int flags = ::fcntl(m_fd, F_GETFL, 0); + if (flags == -1 || ::fcntl(m_fd, F_SETFL, flags | O_NONBLOCK) == -1) + { + ::close(m_fd); + throw std::runtime_error{ + "cannot set non-blocking on utun fd: " + std::string{strerror(errno)}}; + } for (const auto& ifaddr : m_Info.addrs) { if (ifaddr.fam == AF_INET) @@ -107,38 +112,34 @@ ~AppleInterface() { - ::close(m_FD); - } - - std::string - IfName() const override - { - return m_IfName; + ::close(m_fd); } int PollFD() const override { - return m_FD; + return m_fd; } net::IPPacket ReadNextPacket() override { constexpr int uintsize = sizeof(unsigned int); - net::IPPacket pkt{}; unsigned int pktinfo = 0; + std::vector buf(net::IPPacket::MaxSize); const struct iovec vecs[2] = { {.iov_base = &pktinfo, .iov_len = uintsize}, - {.iov_base = pkt.buf, .iov_len = sizeof(pkt.buf)}}; - int sz = readv(m_FD, vecs, 2); + {.iov_base = buf.data(), .iov_len = buf.size()} + }; + int sz = readv(m_fd, vecs, 2); if (sz >= uintsize) - pkt.sz = sz - uintsize; + sz -= sizeof(unsigned int); else if (sz >= 0 || errno == EAGAIN || errno == EWOULDBLOCK) - pkt.sz = 0; + sz = 0; else throw std::error_code{errno, std::system_category()}; - return pkt; + buf.resize(static_cast(sz)); + return net::IPPacket{std::move(buf)}; } bool @@ -149,25 +150,59 @@ const struct iovec vecs[2] = { {.iov_base = pkt.IsV6() ? &af6 : &af4, .iov_len = sizeof(unsigned int)}, - {.iov_base = pkt.buf, .iov_len = pkt.sz}}; + {.iov_base = pkt.data(), .iov_len = pkt.size()} + }; - ssize_t n = writev(m_FD, vecs, 2); - if (n >= (int)sizeof(unsigned int)) + ssize_t sz = writev(m_fd, vecs, 2); + if (sz >= (int)sizeof(unsigned int)) { - n -= sizeof(unsigned int); - return static_cast(n) == pkt.sz; + sz -= sizeof(unsigned int); + return static_cast(sz) == pkt.size(); } return false; } }; + class AppleRouteManager : public IRouteManager + { + void AddRoute(net::ipaddr_t, net::ipaddr_t) override{}; + + void DelRoute(net::ipaddr_t, net::ipaddr_t) override{}; + + void + AddDefaultRouteViaInterface(NetworkInterface&) override{}; + + void + DelDefaultRouteViaInterface(NetworkInterface&) override{}; + + void + AddRouteViaInterface(NetworkInterface&, IPRange) override{}; + + void + DelRouteViaInterface(NetworkInterface&, IPRange) override{}; + + std::vector + GetGatewaysNotOnInterface(NetworkInterface&) override + { + return std::vector{}; + }; + }; + class ApplePlatform : public Platform { + AppleRouteManager _routeManager{}; + public: std::shared_ptr - ObtainInterface(InterfaceInfo info) override + ObtainInterface(InterfaceInfo info, AbstractRouter*) override { return std::make_shared(std::move(info)); + }; + + IRouteManager& + RouteManager() override + { + return _routeManager; } }; } // namespace llarp::vpn