diff --git a/.swift-version b/.swift-version new file mode 100644 index 000000000..8ae03c119 --- /dev/null +++ b/.swift-version @@ -0,0 +1 @@ +5.4.2 diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f9b1a4a0..aa6fc1290 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,7 @@ if(RELEASE_MOTTO AND CMAKE_BUILD_TYPE MATCHES "[Rr][Ee][Ll][Ee][Aa][Ss][Ee]") add_definitions(-DLLARP_RELEASE_MOTTO="${RELEASE_MOTTO}") endif() +set(LOKINET_VERSION "${lokinet_VERSION_MAJOR}.${lokinet_VERSION_MINOR}.${lokinet_VERSION_PATCH}") list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") diff --git a/contrib/format.sh b/contrib/format.sh index 26ed77d3c..5b5f5a495 100755 --- a/contrib/format.sh +++ b/contrib/format.sh @@ -18,11 +18,11 @@ fi cd "$(dirname $0)/../" if [ "$1" = "verify" ] ; then - if [ $($binary --output-replacements-xml $(find jni daemon llarp include pybind | grep -E '\.[hc](pp)?$' | grep -v '\#') | grep '' | wc -l) -ne 0 ] ; then + if [ $($binary --output-replacements-xml $(find jni daemon llarp include pybind | grep -E '\.([hc](pp)?|mm)$' | grep -v '\#') | grep '' | wc -l) -ne 0 ] ; then exit 1 fi else - $binary -i $(find jni daemon llarp include pybind | grep -E '\.[hc](pp)?$' | grep -v '\#') &> /dev/null + $binary -i $(find jni daemon llarp include pybind | grep -E '\.([hc](pp)?|mm)$' | grep -v '\#') &> /dev/null fi swift_format=$(which swiftformat 2>/dev/null) diff --git a/contrib/macos/Info.plist b/contrib/macos/Info.plist index de014151e..d39aed3a8 100644 --- a/contrib/macos/Info.plist +++ b/contrib/macos/Info.plist @@ -9,7 +9,7 @@ CFBundleExecutable MacOS/lokinet CFBundleIdentifier - org.lokinet.Daemon + com.loki-project.lokinet CFBundleInfoDictionaryVersion 6.0 CFBundleName diff --git a/contrib/macos/LokinetExtension.Info.plist b/contrib/macos/LokinetExtension.Info.plist deleted file mode 100644 index bc6b357af..000000000 --- a/contrib/macos/LokinetExtension.Info.plist +++ /dev/null @@ -1,31 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleDisplayName - Lokinet - CFBundleExecutable - lokinet-extension - CFBundleIdentifier - org.lokinet.NetworkExtension - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - Lokinet - CFBundlePackageType - XPC! - CFBundleShortVersionString - 0.1 - CFBundleVersion - 0.1 - NSExtension - - NSExtensionPointIdentifier - com.apple.networkextension.packet-tunnel - NSExtensionPrincipalClass - Lokinet.LLARPPacketTunnel - - - diff --git a/contrib/macos/LokinetExtension.Info.plist.in b/contrib/macos/LokinetExtension.Info.plist.in new file mode 100644 index 000000000..7f6ecadbb --- /dev/null +++ b/contrib/macos/LokinetExtension.Info.plist.in @@ -0,0 +1,40 @@ + + + + + CFBundleDisplayName + Lokinet + + CFBundleExecutable + lokinet-extension + + CFBundleIdentifier + com.loki-project.lokinet.network-extension + + CFBundleInfoDictionaryVersion + 6.0 + + CFBundlePackageType + XPC! + + CFBundleName + lokinet + + CFBundleVersion + ${LOKINET_VERSION} + + ITSAppUsesNonExemptEncryption + + + LSMinimumSystemVersion + 11.0 + + NSExtension + + NSExtensionPointIdentifier + com.apple.networkextension.packet-tunnel + NSExtensionPrincipalClass + LLARPPacketTunnel + + + diff --git a/contrib/macos/lokinet-extension.entitlements.plist.in b/contrib/macos/lokinet-extension.entitlements.plist.in new file mode 100644 index 000000000..6f8dfb41b --- /dev/null +++ b/contrib/macos/lokinet-extension.entitlements.plist.in @@ -0,0 +1,25 @@ + + + + + com.apple.developer.networking.networkextension + + packet-tunnel-provider + + + com.apple.security.network.client + + + diff --git a/contrib/macos/lokinet.entitlements.plist b/contrib/macos/lokinet.entitlements.plist deleted file mode 100644 index 589ce8b28..000000000 --- a/contrib/macos/lokinet.entitlements.plist +++ /dev/null @@ -1,10 +0,0 @@ - - - - - com.apple.developer.networking.networkextension - - packet-tunnel-provider - - - diff --git a/contrib/macos/lokinet.entitlements.plist.in b/contrib/macos/lokinet.entitlements.plist.in new file mode 100644 index 000000000..66bbbb80c --- /dev/null +++ b/contrib/macos/lokinet.entitlements.plist.in @@ -0,0 +1,24 @@ + + + + + com.apple.developer.networking.networkextension + + packet-tunnel-provider + + + com.apple.security.network.client + + + diff --git a/contrib/macos/sign.sh.in b/contrib/macos/sign.sh.in index fc1136d9b..c255a94e8 100755 --- a/contrib/macos/sign.sh.in +++ b/contrib/macos/sign.sh.in @@ -1,8 +1,6 @@ #!/usr/bin/env bash -set -x set -e -for file in "${SIGN_TARGET}/Contents/Frameworks/lokinet-extension.framework" "${SIGN_TARGET}/Contents/MacOS/Lokinet" "${SIGN_TARGET}" ; do - codesign -vvvv --force -s "${CODESIGN_KEY}" --entitlements "${SIGN_ENTITLEMENTS}" --deep --timestamp --options=runtime "$file" +codesign --verbose=4 --force -s "${CODESIGN_KEY}" --entitlements "${NETEXT_ENTITLEMENTS}" --deep --timestamp --options=runtime "${SIGN_TARGET}/Contents/Frameworks/lokinet-extension.framework" +for file in "${SIGN_TARGET}/Contents/MacOS/Lokinet" "${SIGN_TARGET}" ; do + codesign --verbose=4 --force -s "${CODESIGN_KEY}" --entitlements "${LOKINET_ENTITLEMENTS}" --deep --timestamp --options=runtime "$file" done - -codesign --verify "${SIGN_TARGET}" diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt index 257daebed..a03ebef2a 100644 --- a/daemon/CMakeLists.txt +++ b/daemon/CMakeLists.txt @@ -1,19 +1,17 @@ if(APPLE) - option(WITH_SWIFT "use swift" ON) - if(WITH_SWIFT) - add_executable(lokinet lokinet.swift) - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Lokinet.modulemap.in ${CMAKE_CURRENT_BINARY_DIR}/swift/LokinetExtension/module.modulemap ESCAPE_QUOTES @ONLY) - target_include_directories(lokinet PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/swift) - else() - add_executable(lokinet lokinet.mm) - endif() + set(LOKINET_SWIFT_SOURCES lokinet.swift) + add_executable(lokinet ${LOKINET_SWIFT_SOURCES}) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Lokinet.modulemap.in ${CMAKE_CURRENT_BINARY_DIR}/swift/LokinetExtension/module.modulemap ESCAPE_QUOTES @ONLY) + target_include_directories(lokinet PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/swift) target_link_libraries(lokinet PUBLIC lokinet-extension) + add_executable(lokinet-old lokinet.cpp) + enable_lto(lokinet-old) else() add_executable(lokinet lokinet.cpp) + add_executable(lokinet-vpn lokinet-vpn.cpp) + add_executable(lokinet-bootstrap lokinet-bootstrap.cpp) + enable_lto(lokinet lokinet-vpn lokinet-bootstrap) endif() -add_executable(lokinet-vpn lokinet-vpn.cpp) -add_executable(lokinet-bootstrap lokinet-bootstrap.cpp) -enable_lto(lokinet lokinet-vpn lokinet-bootstrap) if(TRACY_ROOT) target_sources(lokinet PRIVATE ${TRACY_ROOT}/TracyClient.cpp) @@ -35,16 +33,19 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux") endif() endif() -target_link_libraries(lokinet-bootstrap PUBLIC cpr::cpr) -if(NOT WIN32) - find_package(OpenSSL REQUIRED) - # because debian sid's curl doesn't link against openssl for some godawful cursed reason - target_link_libraries(lokinet-bootstrap PUBLIC OpenSSL::SSL OpenSSL::Crypto) +if(NOT APPLE) + target_link_libraries(lokinet-bootstrap PUBLIC cpr::cpr) + if(NOT WIN32) + find_package(OpenSSL REQUIRED) + # because debian sid's curl doesn't link against openssl for some godawful cursed reason + target_link_libraries(lokinet-bootstrap PUBLIC OpenSSL::SSL OpenSSL::Crypto) + endif() endif() -set(exetargets lokinet-vpn lokinet-bootstrap) -if(NOT APPLE) - set(exetargets lokinet ${exes}) +if(APPLE) + set(exetargets lokinet-old lokinet) +else() + set(exetargets lokinet lokinet-vpn lokinet-bootstrap) endif() foreach(exe ${exetargets}) @@ -55,11 +56,11 @@ foreach(exe ${exetargets}) elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") target_link_directories(${exe} PRIVATE /usr/local/lib) endif() - target_link_libraries(${exe} PRIVATE liblokinet) + target_link_libraries(${exe} PUBLIC liblokinet) if(WITH_JEMALLOC) target_link_libraries(${exe} PUBLIC jemalloc) endif() - target_include_directories(${exe} PRIVATE ${CMAKE_SOURCE_DIR}) + target_include_directories(${exe} PUBLIC "${PROJECT_SOURCE_DIR}") target_compile_definitions(${exe} PRIVATE -DVERSIONTAG=${GIT_VERSION_REAL}) add_log_tag(${exe}) if(should_install) @@ -87,18 +88,23 @@ if(APPLE) MACOSX_BUNDLE TRUE MACOSX_BUNDLE_INFO_STRING "Lokinet IP Packet Onion Router" MACOSX_BUNDLE_BUNDLE_NAME "Lokinet" - MACOSX_BUNDLE_BUNDLE_VERSION "${lokinet_VERSION_MAJOR}.${lokinet_VERSION_MINOR}.${lokinet_VERSION_PATCH}" + MACOSX_BUNDLE_BUNDLE_VERSION "${LOKINET_VERSION}" MACOSX_BUNDLE_LONG_VERSION_STRING "${lokinet_VERSION}.$lokinet_VERSION_MINOR}" MACOSX_BUNDLE_SHORT_VERSION_STRING "${lokinet_VERSION_MAJOR}.${lokinet_VERSION_MINOR}" - MACOSX_BUNDLE_GUI_IDENTIFIER "org.lokinet.lokinet" + MACOSX_BUNDLE_GUI_IDENTIFIER "com.loki-project.lokinet" MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/contrib/macos/Info.plist" MACOSX_BUNDLE_ICON_FILE "${CMAKE_CURRENT_BINARY_DIR}/lokinet.icns" MACOSX_BUNDLE_COPYRIGHT "© 2021, The Loki Project") option(CODESIGN_KEY "codesign all the shit with this key" OFF) - if (CODESIGN_KEY) + if (CODESIGN_KEY AND CODESIGN_TEAM_ID) message(STATUS "codesigning with ${CODESIGN_KEY}") - set(SIGN_TARGET "${CMAKE_CURRENT_BINARY_DIR}/Lokinet.app") - set(SIGN_ENTITLEMENTS "${CMAKE_SOURCE_DIR}/contrib/macos/lokinet.entitlements.plist") + set(SIGN_TARGET "${CMAKE_CURRENT_BINARY_DIR}/Lokinet.app") + configure_file("${CMAKE_SOURCE_DIR}/contrib/macos/lokinet.entitlements.plist.in" + "${CMAKE_BINARY_DIR}/lokinet.entitlements.plist") + configure_file("${CMAKE_SOURCE_DIR}/contrib/macos/lokinet-extension.entitlements.plist.in" + "${CMAKE_BINARY_DIR}/lokinet-extension.entitlements.plist") + set(LOKINET_ENTITLEMENTS "${CMAKE_BINARY_DIR}/lokinet.entitlements.plist") + set(NETEXT_ENTITLEMENTS "${CMAKE_BINARY_DIR}/lokinet-extension.entitlements.plist") configure_file( "${PROJECT_SOURCE_DIR}/contrib/macos/sign.sh.in" "${CMAKE_BINARY_DIR}/sign.sh") diff --git a/daemon/lokinet.cpp b/daemon/lokinet.cpp index 316d1b856..52664e897 100644 --- a/daemon/lokinet.cpp +++ b/daemon/lokinet.cpp @@ -11,6 +11,10 @@ #include #endif +#ifdef __APPLE__ +#include +#endif + #include #include @@ -396,6 +400,10 @@ lokinet_main(int argc, char* argv[]) { return result; } +#ifdef __APPLE__ + llarp::LogContext::Instance().logStream.reset(new llarp::NSLogStream{}); +#endif + llarp::RuntimeOptions opts; #ifdef _WIN32 diff --git a/daemon/lokinet.mm b/daemon/lokinet.mm deleted file mode 100644 index 1baa58379..000000000 --- a/daemon/lokinet.mm +++ /dev/null @@ -1,9 +0,0 @@ -#import -#include - - -int main (int argc, const char * argv[]) -{ - - return 0; -} diff --git a/daemon/lokinet.swift b/daemon/lokinet.swift index 28eefe06c..b80c01227 100644 --- a/daemon/lokinet.swift +++ b/daemon/lokinet.swift @@ -1,52 +1,70 @@ -// AppDelegateExtension.swift - +import AppKit import Foundation import LokinetExtension import NetworkExtension -class LokinetMain: NSObject { - var vpnManager = NETunnelProviderManager() +let app = NSApplication.shared - let lokinetComponent = "org.lokinet.NetworkExtension" +class LokinetMain: NSObject, NSApplicationDelegate { + var vpnManager = NETunnelProviderManager() + let lokinetComponent = "com.loki-project.lokinet.network-extension" var lokinetAdminTimer: DispatchSourceTimer? - func runMain() { - print("Starting up lokinet") - NETunnelProviderManager.loadAllFromPreferences { (savedManagers: [NETunnelProviderManager]?, error: Error?) in + func applicationDidFinishLaunching(_: Notification) { + setupVPNJizz() + } + + func bail() { + app.terminate(self) + } + + func setupVPNJizz() { + NSLog("Starting up lokinet") + NETunnelProviderManager.loadAllFromPreferences { [self] (savedManagers: [NETunnelProviderManager]?, error: Error?) in if let error = error { - print(error) + NSLog(error.localizedDescription) + bail() } if let savedManagers = savedManagers { for manager in savedManagers { if (manager.protocolConfiguration as? NETunnelProviderProtocol)?.providerBundleIdentifier == self.lokinetComponent { - print("Found saved VPN Manager") + NSLog("%@", manager) + NSLog("Found saved VPN Manager") self.vpnManager = manager } } } let providerProtocol = NETunnelProviderProtocol() - providerProtocol.serverAddress = "lokinet" + providerProtocol.serverAddress = "" + providerProtocol.username = "anonymous" providerProtocol.providerBundleIdentifier = self.lokinetComponent + providerProtocol.includeAllNetworks = true self.vpnManager.protocolConfiguration = providerProtocol self.vpnManager.isEnabled = true + self.vpnManager.isOnDemandEnabled = true self.vpnManager.saveToPreferences(completionHandler: { error -> Void in if error != nil { - print("Error saving to preferences") + NSLog("Error saving to preferences") + NSLog(error!.localizedDescription) + bail() } else { - print("saved...") self.vpnManager.loadFromPreferences(completionHandler: { error in if error != nil { - print("Error loading from preferences") + NSLog("Error loading from preferences") + NSLog(error!.localizedDescription) + bail() } else { do { - print("Trying to start") + NSLog("Trying to start") self.initializeConnectionObserver() try self.vpnManager.connection.startVPNTunnel() } catch let error as NSError { - print(error) + NSLog(error.localizedDescription) + bail() } catch { - print("There was a fatal error") + NSLog("There was a fatal error") + bail() } } }) @@ -57,21 +75,21 @@ class LokinetMain: NSObject { func initializeConnectionObserver() { NotificationCenter.default.addObserver(forName: NSNotification.Name.NEVPNStatusDidChange, object: vpnManager.connection, queue: OperationQueue.main) { _ -> Void in - if self.vpnManager.connection.status == .invalid { - print("VPN configuration is invalid") + NSLog("VPN configuration is invalid") } else if self.vpnManager.connection.status == .disconnected { - print("VPN is disconnected.") + NSLog("VPN is disconnected.") } else if self.vpnManager.connection.status == .connecting { - print("VPN is connecting...") + NSLog("VPN is connecting...") } else if self.vpnManager.connection.status == .reasserting { - print("VPN is reasserting...") + NSLog("VPN is reasserting...") } else if self.vpnManager.connection.status == .disconnecting { - print("VPN is disconnecting...") + NSLog("VPN is disconnecting...") } } } } -let lokinet = LokinetMain() -lokinet.runMain() +let delegate = LokinetMain() +app.delegate = delegate +app.run() diff --git a/daemon/swift/Lokinet/module.modulemap b/daemon/swift/Lokinet/module.modulemap deleted file mode 100644 index fda10e4b7..000000000 --- a/daemon/swift/Lokinet/module.modulemap +++ /dev/null @@ -1,4 +0,0 @@ - -module Lokinet { - header "lokinet-extension.hpp" -} \ No newline at end of file diff --git a/daemon/swift/LokinetMain.swift b/daemon/swift/LokinetMain.swift deleted file mode 100644 index 561df3e7f..000000000 --- a/daemon/swift/LokinetMain.swift +++ /dev/null @@ -1,43 +0,0 @@ -// AppDelegateExtension.swift -// lifed from yggdrasil network ios port -// - -import Foundation -import Lokinet -import NetworkExtension - -class LokinetMain: PlatformAppDelegate { - var vpnManager = NETunnelProviderManager() - var app = NSApplication.shared() - let lokinetComponent = "org.lokinet.NetworkExtension" - var lokinetAdminTimer: DispatchSourceTimer? - - func runMain() { - print("Starting up lokinet") - NETunnelProviderManager.loadAllFromPreferences { (savedManagers: [NETunnelProviderManager]?, error: Error?) in - if let error = error { - print(error) - } - - if let savedManagers = savedManagers { - for manager in savedManagers { - if (manager.protocolConfiguration as? NETunnelProviderProtocol)?.providerBundleIdentifier == self.lokinetComponent { - print("Found saved VPN Manager") - self.vpnManager = manager - } - } - } - - self.vpnManager.loadFromPreferences(completionHandler: { (error: Error?) in - if let error = error { - print(error) - } - self.vpnManager.localizedDescription = "Lokinet" - self.vpnManager.isEnabled = true - }) - } - app.finishLaunching() - app.run() - print("end") - } -} diff --git a/include/lokinet-extension.hpp b/include/lokinet-extension.hpp index 5bbae9946..df436ab4e 100644 --- a/include/lokinet-extension.hpp +++ b/include/lokinet-extension.hpp @@ -6,13 +6,16 @@ struct ContextWrapper; @interface LLARPPacketTunnel : NEPacketTunnelProvider { - @private struct ContextWrapper* m_Context; } + - (void)startTunnelWithOptions:(NSDictionary*)options completionHandler:(void (^)(NSError* error))completionHandler; - (void)stopTunnelWithReason:(NEProviderStopReason)reason completionHandler:(void (^)(void))completionHandler; +- (void)handleAppMessage:(NSData*)messageData + completionHandler:(void (^)(NSData* responseData))completionHandler; + @end diff --git a/llarp/CMakeLists.txt b/llarp/CMakeLists.txt index aaf388457..6730dd0a5 100644 --- a/llarp/CMakeLists.txt +++ b/llarp/CMakeLists.txt @@ -8,6 +8,7 @@ add_library(lokinet-util util/fs.cpp util/json.cpp util/logging/android_logger.cpp + util/logging/apple_logger.mm util/logging/buffer.cpp util/logging/file_logger.cpp util/logging/json_logger.cpp @@ -37,6 +38,11 @@ target_link_libraries(lokinet-util PUBLIC oxenmq::oxenmq ) +if(APPLE) + find_library(FOUNDATION Foundation REQUIRED) + target_link_libraries(lokinet-util PUBLIC ${FOUNDATION}) +endif() + if(ANDROID) target_link_libraries(lokinet-util PUBLIC log) endif() @@ -263,6 +269,7 @@ if(BUILD_LIBLOKINET) endif() if(APPLE) + # god made apple so that man may suffer find_library(NETEXT NetworkExtension REQUIRED) find_library(COREFOUNDATION CoreFoundation REQUIRED) @@ -276,15 +283,18 @@ if(APPLE) ${COREFOUNDATION} ${NETEXT}) + configure_file(${CMAKE_SOURCE_DIR}/contrib/macos/LokinetExtension.Info.plist.in + ${CMAKE_CURRENT_BINARY_DIR}/LokinetExtension.Info.plist) + set_target_properties(lokinet-extension PROPERTIES FRAMEWORK TRUE - FRAMEWORK_VERSION CXX - MACOSX_FRAMEWORK_IDENTIFIER org.lokinet.NetworkExtension - MACOSX_FRAMEWORK_INFO_PLIST ${CMAKE_SOURCE_DIR}/contrib/macos/LokinetExtension.Info.plist + FRAMEWORK_VERSION ${lokinet_VERSION} + MACOSX_FRAMEWORK_IDENTIFIER com.loki-project.lokinet.network-extension + MACOSX_FRAMEWORK_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/LokinetExtension.Info.plist # "current version" in semantic format in Mach-O binary file - VERSION 16.4.0 + VERSION ${lokinet_VERSION} # "compatibility version" in semantic format in Mach-O binary file - SOVERSION 1.0.0 + SOVERSION ${lokinet_VERSION} PUBLIC_HEADER ${CMAKE_SOURCE_DIR}/include/lokinet-extension.hpp) endif() diff --git a/llarp/framework.mm b/llarp/framework.mm index a5bd7d93f..032c2424a 100644 --- a/llarp/framework.mm +++ b/llarp/framework.mm @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -11,54 +12,51 @@ namespace llarp::apple { struct FrameworkContext : public llarp::Context { - - explicit FrameworkContext(NEPacketTunnelProvider * tunnel); + explicit FrameworkContext(NEPacketTunnelProvider* tunnel); + + ~FrameworkContext() + {} - ~FrameworkContext() {} - std::shared_ptr makeVPNPlatform() override; void Start(); - - private: - NEPacketTunnelProvider * m_Tunnel; + + private: + NEPacketTunnelProvider* const m_Tunnel; std::unique_ptr m_Runner; - }; + }; class VPNInterface final : public vpn::NetworkInterface { - NEPacketTunnelProvider * m_Tunnel; + NEPacketTunnelProvider* const m_Tunnel; static inline constexpr auto PacketQueueSize = 1024; - + thread::Queue m_ReadQueue; void - OfferReadPacket(NSData * data) + OfferReadPacket(NSData* data) { llarp::net::IPPacket pkt; - const llarp_buffer_t buf{static_cast(data.bytes), data.length}; - if(pkt.Load(buf)) + const llarp_buffer_t buf{static_cast(data.bytes), data.length}; + if (pkt.Load(buf)) m_ReadQueue.tryPushBack(std::move(pkt)); } - public: - explicit VPNInterface(NEPacketTunnelProvider * tunnel) - : m_Tunnel{tunnel}, - m_ReadQueue{PacketQueueSize} + public: + explicit VPNInterface(NEPacketTunnelProvider* tunnel) + : m_Tunnel{tunnel}, m_ReadQueue{PacketQueueSize} { - auto handler = - [this](NSArray * packets, NSArray *) + auto handler = [this](NSArray* packets, NSArray*) { + NSUInteger num = [packets count]; + for (NSUInteger idx = 0; idx < num; ++idx) { - NSUInteger num = [packets count]; - for(NSUInteger idx = 0; idx < num ; ++idx) - { - NSData * pkt = [packets objectAtIndex:idx]; - OfferReadPacket(pkt); - } - }; + NSData* pkt = [packets objectAtIndex:idx]; + OfferReadPacket(pkt); + } + }; [m_Tunnel.packetFlow readPacketsWithCompletionHandler:handler]; } @@ -73,12 +71,12 @@ namespace llarp::apple { return ""; } - + net::IPPacket ReadNextPacket() override { net::IPPacket pkt{}; - if(not m_ReadQueue.empty()) + if (not m_ReadQueue.empty()) pkt = m_ReadQueue.popFront(); return pkt; } @@ -87,61 +85,53 @@ namespace llarp::apple WritePacket(net::IPPacket pkt) override { const sa_family_t fam = pkt.IsV6() ? AF_INET6 : AF_INET; - const uint8_t * pktbuf = pkt.buf; + const uint8_t* pktbuf = pkt.buf; const size_t pktsz = pkt.sz; - NSData * datapkt = [NSData dataWithBytes:pktbuf length:pktsz]; - NEPacket * npkt = [[NEPacket alloc] initWithData:datapkt protocolFamily:fam]; - NSArray * pkts = @[npkt]; + NSData* datapkt = [NSData dataWithBytes:pktbuf length:pktsz]; + NEPacket* npkt = [[NEPacket alloc] initWithData:datapkt protocolFamily:fam]; + NSArray* pkts = @[npkt]; return [m_Tunnel.packetFlow writePacketObjects:pkts]; } - }; class VPNPlatform final : public vpn::Platform { - NEPacketTunnelProvider * m_Tunnel; - public: - explicit VPNPlatform(NEPacketTunnelProvider * tunnel) - : m_Tunnel{tunnel} - { - } - - std::shared_ptr - ObtainInterface(vpn::InterfaceInfo) override + NEPacketTunnelProvider* const m_Tunnel; + + public: + explicit VPNPlatform(NEPacketTunnelProvider* tunnel) : m_Tunnel{tunnel} + {} + + std::shared_ptr ObtainInterface(vpn::InterfaceInfo) override { return std::make_shared(m_Tunnel); } }; - - FrameworkContext::FrameworkContext(NEPacketTunnelProvider * tunnel) : - llarp::Context{}, - m_Tunnel{tunnel} - { - } + FrameworkContext::FrameworkContext(NEPacketTunnelProvider* tunnel) + : llarp::Context{}, m_Tunnel{tunnel} + {} void FrameworkContext::Start() { std::promise result; - m_Runner = std::make_unique( - [&result, this]() + m_Runner = std::make_unique([&result, this]() { + const RuntimeOptions opts{}; + try { - const RuntimeOptions opts{}; - try - { - Setup(opts); - Configure(llarp::Config::NetworkExtensionConfig()); - } - catch(std::exception & ) - { - result.set_exception(std::current_exception()); - return; - } - result.set_value(); - Run(opts); - }); + Setup(opts); + Configure(llarp::Config::NetworkExtensionConfig()); + } + catch (std::exception&) + { + result.set_exception(std::current_exception()); + return; + } + result.set_value(); + Run(opts); + }); auto ftr = result.get_future(); ftr.get(); @@ -154,13 +144,13 @@ namespace llarp::apple } } - struct ContextWrapper { - std::shared_ptr m_Context; -public: - explicit ContextWrapper(NEPacketTunnelProvider * tunnel) : - m_Context{std::make_shared(tunnel)} + std::unique_ptr m_Context; + + public: + explicit ContextWrapper(NEPacketTunnelProvider* tunnel) + : m_Context{std::make_unique(tunnel)} {} void @@ -176,20 +166,35 @@ public: m_Context->Wait(); } }; - +static std::string_view +DataAsStringView(NSData* data) +{ + return std::string_view{reinterpret_cast(data.bytes), data.length}; +} + +static NSData* +StringViewToData(std::string_view data) +{ + const char* ptr = data.data(); + const size_t sz = data.size(); + return [NSData dataWithBytes:ptr length:sz]; +} @implementation LLARPPacketTunnel -- (void)startTunnelWithOptions:(NSDictionary *)options completionHandler:(void (^)(NSError *error))completionHandler { +- (void)startTunnelWithOptions:(NSDictionary*)options + completionHandler:(void (^)(NSError*))completionHandler +{ m_Context = new ContextWrapper{self}; m_Context->Start(); - completionHandler(nullptr); + [self setTunnelNetworkSettings:nullptr completionHandler:completionHandler]; } -- (void)stopTunnelWithReason:(NEProviderStopReason)reason -completionHandler:(void (^)(void))completionHandler { - if(m_Context) +- (void)stopTunnelWithReason:(NEProviderStopReason)reason + completionHandler:(void (^)(void))completionHandler +{ + if (m_Context) { m_Context->Stop(); delete m_Context; @@ -198,5 +203,13 @@ completionHandler:(void (^)(void))completionHandler { completionHandler(); } +- (void)handleAppMessage:(NSData*)messageData + completionHandler:(void (^)(NSData* responseData))completionHandler +{ + const auto data = DataAsStringView(messageData); + LogInfo("app message: ", data); + + completionHandler(StringViewToData("ok")); +} @end diff --git a/llarp/util/logging/apple_logger.hpp b/llarp/util/logging/apple_logger.hpp new file mode 100644 index 000000000..00450b391 --- /dev/null +++ b/llarp/util/logging/apple_logger.hpp @@ -0,0 +1,32 @@ +#pragma once +#ifdef __APPLE__ +#include "logstream.hpp" + +namespace llarp +{ + struct NSLogStream : public ILogStream + { + void + PreLog( + std::stringstream& s, + LogLevel lvl, + const char* fname, + int lineno, + const std::string& nodename) const override; + + void + Print(LogLevel lvl, const char* tag, const std::string& msg) override; + + void + PostLog(std::stringstream& ss) const override; + + virtual void + ImmediateFlush() override + {} + + void Tick(llarp_time_t) override + {} + }; +} // namespace llarp + +#endif diff --git a/llarp/util/logging/apple_logger.mm b/llarp/util/logging/apple_logger.mm new file mode 100644 index 000000000..e5ca746c1 --- /dev/null +++ b/llarp/util/logging/apple_logger.mm @@ -0,0 +1,38 @@ +#ifdef __APPLE__ +#include "apple_logger.hpp" +#include "logger_internal.hpp" + +#include + +namespace llarp +{ + void + NSLogStream::PreLog( + std::stringstream& ss, + LogLevel lvl, + const char* fname, + int lineno, + const std::string& nodename) const + { + ss << "[" << LogLevelToString(lvl) << "] "; + ss << "[" << nodename << "]" + << "(" << thread_id_string() << ") " << log_timestamp() << " " << fname << ":" << lineno + << "\t"; + } + + void + NSLogStream::Print(LogLevel, const char*, const std::string& msg) + { + const char* msg_ptr = msg.c_str(); + const char* msg_fmt = "%s"; + NSString* fmt = [[NSString alloc] initWithUTF8String:msg_ptr]; + NSString* str = [[NSString alloc] initWithUTF8String:msg_fmt]; + NSLog(fmt, str); + } + + void + NSLogStream::PostLog(std::stringstream&) const + {} + +} // namespace llarp +#endif diff --git a/readme.md b/readme.md index 9122baf13..42b339e53 100644 --- a/readme.md +++ b/readme.md @@ -62,7 +62,7 @@ alternatively you can build from source, make sure you have cmake, libuv and xco $ git clone --recursive https://github.com/oxen-io/lokinet $ cd lokinet - $ ./contrib/mac.sh -DCODESIGN_KEY='insert your key identity here' + $ ./contrib/mac.sh -DCODESIGN_KEY='insert your key identity here' -DCODESIGN_TEAM_ID='team id here' ### Windows