diff --git a/README.md b/README.md index 8ffa88f..71e4f99 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,7 @@ Requires an Apple Developer account for the App Groups and Network Extension entitlements. -You will need to provision an app group and update bundle IDs throughout the Xcode project as appropriate. You can find them all by asking `git`: - -``` -git grep "eu.neilalexander.yggdrasil" -``` +You will need to provision an app group and update bundle IDs throughout the Xcode project as appropriate. To build, install Go 1.13 or later, and then install `gomobile`: diff --git a/Yggdrasil Network Cross-Platform/ConfigurationProxy.swift b/Yggdrasil Network Cross-Platform/ConfigurationProxy.swift deleted file mode 100644 index 6c02443..0000000 --- a/Yggdrasil Network Cross-Platform/ConfigurationProxy.swift +++ /dev/null @@ -1,220 +0,0 @@ -// -// ConfigurationProxy.swift -// YggdrasilNetwork -// -// Created by Neil Alexander on 07/01/2019. -// - -#if canImport(UIKit) -import UIKit -#elseif canImport(AppKit) -import AppKit -#endif -import Yggdrasil -import NetworkExtension - -#if os(iOS) -class PlatformItemSource: NSObject, UIActivityItemSource { - func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any { - return "yggdrasil.conf" - } - - func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? { - return nil - } -} -#elseif os(OSX) -class PlatformItemSource: NSObject {} -#endif - -class ConfigurationProxy: PlatformItemSource { - - private var json: Data? = nil - private var dict: [String: Any]? = nil - - override init() { - super.init() - self.json = MobileGenerateConfigJSON() - do { - try self.convertToDict() - } catch { - NSLog("ConfigurationProxy: Error deserialising JSON (\(error))") - } - #if os(iOS) - self.set("name", inSection: "NodeInfo", to: UIDevice.current.name) - #elseif os(OSX) - self.set("name", inSection: "NodeInfo", to: Host.current().localizedName ?? "") - #endif - self.set("MulticastInterfaces", to: ["en*"] as [String]) - self.set("AllowFromDirect", inSection: "SessionFirewall", to: true) - self.set("AllowFromRemote", inSection: "SessionFirewall", to: false) - self.set("AlwaysAllowOutbound", inSection: "SessionFirewall", to: true) - self.set("Enable", inSection: "SessionFirewall", to: true) - } - - init(json: Data) throws { - super.init() - self.json = json - try self.convertToDict() - } - - private func fix() { - self.set("Listen", to: [] as [String]) - self.set("AdminListen", to: "none") - self.set("IfName", to: "dummy") - self.set("Enable", inSection: "SessionFirewall", to: true) - self.set("MaxTotalQueueSize", inSection: "SwitchOptions", to: 1048576) - - if self.get("AutoStart") == nil { - self.set("AutoStart", to: ["WiFi": false, "Mobile": false] as [String: Bool]) - } - let interfaces = self.get("MulticastInterfaces") as? [String] ?? [] - if interfaces.contains(where: { $0 == "lo0" }) { - self.add("lo0", in: "MulticastInterfaces") - } - } - - func get(_ key: String) -> Any? { - if let dict = self.dict { - if dict.keys.contains(key) { - return dict[key] - } - } - return nil - } - - func get(_ key: String, inSection section: String) -> Any? { - if let dict = self.get(section) as? [String: Any] { - if dict.keys.contains(key) { - return dict[key] - } - } - return nil - } - - func add(_ value: Any, in key: String) { - if self.dict != nil { - if self.dict![key] as? [Any] != nil { - var temp = self.dict![key] as? [Any] ?? [] - temp.append(value) - self.dict!.updateValue(temp, forKey: key) - } - } - } - - func remove(_ value: String, from key: String) { - if self.dict != nil { - if self.dict![key] as? [String] != nil { - var temp = self.dict![key] as? [String] ?? [] - if let index = temp.firstIndex(of: value) { - temp.remove(at: index) - } - self.dict!.updateValue(temp, forKey: key) - } - } - } - - func remove(index: Int, from key: String) { - if self.dict != nil { - if self.dict![key] as? [Any] != nil { - var temp = self.dict![key] as? [Any] ?? [] - temp.remove(at: index) - self.dict!.updateValue(temp, forKey: key) - } - } - } - - func set(_ key: String, to value: Any) { - if self.dict != nil { - self.dict![key] = value - } - } - - func set(_ key: String, inSection section: String, to value: Any?) { - if self.dict != nil { - if self.dict!.keys.contains(section), let value = value { - var temp = self.dict![section] as? [String: Any] ?? [:] - temp.updateValue(value, forKey: key) - self.dict!.updateValue(temp, forKey: section) - } - } - } - - func data() -> Data? { - do { - try self.convertToJson() - return self.json - } catch { - return nil - } - } - - func save(to manager: inout NETunnelProviderManager) throws { - self.fix() - if let data = self.data() { - let providerProtocol = NETunnelProviderProtocol() - #if os(iOS) - providerProtocol.providerBundleIdentifier = "eu.neilalexander.yggdrasil.extension" - #elseif os(OSX) - providerProtocol.providerBundleIdentifier = "eu.neilalexander.yggdrasilmac.extension" - #endif - providerProtocol.providerConfiguration = [ "json": data ] - providerProtocol.serverAddress = "yggdrasil" - providerProtocol.username = self.get("EncryptionPublicKey") as? String ?? "(unknown public key)" - - let disconnectrule = NEOnDemandRuleDisconnect() - var rules: [NEOnDemandRule] = [disconnectrule] - if self.get("WiFi", inSection: "AutoStart") as? Bool ?? false { - let wifirule = NEOnDemandRuleConnect() - wifirule.interfaceTypeMatch = .wiFi - rules.insert(wifirule, at: 0) - } - #if canImport(UIKit) - if self.get("Mobile", inSection: "AutoStart") as? Bool ?? false { - let mobilerule = NEOnDemandRuleConnect() - mobilerule.interfaceTypeMatch = .cellular - rules.insert(mobilerule, at: 0) - } - #endif - manager.onDemandRules = rules - manager.isOnDemandEnabled = rules.count > 1 - providerProtocol.disconnectOnSleep = rules.count > 1 - - manager.protocolConfiguration = providerProtocol - - manager.saveToPreferences(completionHandler: { (error:Error?) in - if let error = error { - print(error) - } else { - print("Save successfully") - NotificationCenter.default.post(name: NSNotification.Name.YggdrasilSettingsUpdated, object: self) - } - }) - } - } - - private func convertToDict() throws { - self.dict = try JSONSerialization.jsonObject(with: self.json!, options: []) as? [String: Any] - } - - private func convertToJson() throws { - self.json = try JSONSerialization.data(withJSONObject: self.dict as Any, options: .prettyPrinted) - } - - #if canImport(UIKit) - override func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any { - return "yggdrasil.conf" - } - - override func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? { - return self.data() - } - - func activityViewController(_ activityViewController: UIActivityViewController, subjectForActivityType activityType: UIActivity.ActivityType?) -> String { - if let pubkey = self.get("EncryptionPublicKey") as? String, pubkey.count > 56 { - return "yggdrasil-\(pubkey.dropFirst(56)).conf.json" - } - return "yggdrasil.conf.json" - } - #endif -} diff --git a/Yggdrasil Network Cross-Platform/CrossPlatformAppDelegate.swift b/Yggdrasil Network Cross-Platform/CrossPlatformAppDelegate.swift deleted file mode 100644 index 249bd47..0000000 --- a/Yggdrasil Network Cross-Platform/CrossPlatformAppDelegate.swift +++ /dev/null @@ -1,151 +0,0 @@ -// -// AppDelegateExtension.swift -// Yggdrasil Network -// -// Created by Neil Alexander on 11/01/2019. -// - -import Foundation -import NetworkExtension -import Yggdrasil -import UIKit - -class CrossPlatformAppDelegate: PlatformAppDelegate { - var vpnManager: NETunnelProviderManager = NETunnelProviderManager() - - #if os(iOS) - let yggdrasilComponent = "eu.neilalexander.yggdrasil.extension" - #elseif os(OSX) - let yggdrasilComponent = "eu.neilalexander.yggdrasilmac.extension" - #endif - - var yggdrasilConfig: ConfigurationProxy? = nil - - var yggdrasilAdminTimer: DispatchSourceTimer? - - var yggdrasilSelfIP: String = "N/A" - var yggdrasilSelfSubnet: String = "N/A" - var yggdrasilSelfCoords: String = "[]" - - var yggdrasilPeers: [[String: Any]] = [[:]] - var yggdrasilSwitchPeers: [[String: Any]] = [[:]] - var yggdrasilNodeInfo: [String: Any] = [:] - - func applicationDidBecomeActive(_ application: UIApplication) { - if self.yggdrasilAdminTimer == nil { - self.yggdrasilAdminTimer = DispatchSource.makeTimerSource(flags: .strict, queue: DispatchQueue(label: "Admin Queue")) - self.yggdrasilAdminTimer!.schedule(deadline: DispatchTime.now(), repeating: DispatchTimeInterval.seconds(2), leeway: DispatchTimeInterval.seconds(1)) - self.yggdrasilAdminTimer!.setEventHandler { - self.makeIPCRequests() - } - } - if self.yggdrasilAdminTimer != nil { - self.yggdrasilAdminTimer!.resume() - } - - NotificationCenter.default.addObserver(forName: .NEVPNStatusDidChange, object: nil, queue: nil, using: { notification in - if let conn = notification.object as? NEVPNConnection { - self.updateStatus(conn: conn) - } - }) - - self.updateStatus(conn: self.vpnManager.connection) - } - - func updateStatus(conn: NEVPNConnection) { - if conn.status == .connected { - self.makeIPCRequests() - } else if conn.status == .disconnecting || conn.status == .disconnected { - self.clearStatus() - } - } - - func applicationWillResignActive(_ application: UIApplication) { - if self.yggdrasilAdminTimer != nil { - self.yggdrasilAdminTimer!.suspend() - } - } - - func vpnTunnelProviderManagerInit() { - 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.yggdrasilComponent { - print("Found saved VPN Manager") - self.vpnManager = manager - } - } - } - - self.vpnManager.loadFromPreferences(completionHandler: { (error: Error?) in - if let error = error { - print(error) - } - - if let vpnConfig = self.vpnManager.protocolConfiguration as? NETunnelProviderProtocol, - let confJson = vpnConfig.providerConfiguration!["json"] as? Data { - print("Found existing protocol configuration") - self.yggdrasilConfig = try? ConfigurationProxy(json: confJson) - } else { - print("Generating new protocol configuration") - self.yggdrasilConfig = ConfigurationProxy() - } - - self.vpnManager.localizedDescription = "Yggdrasil" - self.vpnManager.isEnabled = true - - - if let config = self.yggdrasilConfig { - try? config.save(to: &self.vpnManager) - } - }) - } - } - - func makeIPCRequests() { - if self.vpnManager.connection.status != .connected { - return - } - if let session = self.vpnManager.connection as? NETunnelProviderSession { - try? session.sendProviderMessage("address".data(using: .utf8)!) { (address) in - self.yggdrasilSelfIP = String(data: address!, encoding: .utf8)! - NotificationCenter.default.post(name: .YggdrasilSelfUpdated, object: nil) - } - try? session.sendProviderMessage("subnet".data(using: .utf8)!) { (subnet) in - self.yggdrasilSelfSubnet = String(data: subnet!, encoding: .utf8)! - NotificationCenter.default.post(name: .YggdrasilSelfUpdated, object: nil) - } - try? session.sendProviderMessage("coords".data(using: .utf8)!) { (coords) in - self.yggdrasilSelfCoords = String(data: coords!, encoding: .utf8)! - NotificationCenter.default.post(name: .YggdrasilSelfUpdated, object: nil) - } - try? session.sendProviderMessage("peers".data(using: .utf8)!) { (peers) in - if let jsonResponse = try? JSONSerialization.jsonObject(with: peers!, options: []) as? [[String: Any]] { - self.yggdrasilPeers = jsonResponse - NotificationCenter.default.post(name: .YggdrasilPeersUpdated, object: nil) - } - } - try? session.sendProviderMessage("switchpeers".data(using: .utf8)!) { (switchpeers) in - if let jsonResponse = try? JSONSerialization.jsonObject(with: switchpeers!, options: []) as? [[String: Any]] { - self.yggdrasilSwitchPeers = jsonResponse - NotificationCenter.default.post(name: .YggdrasilSwitchPeersUpdated, object: nil) - } - } - } - } - - func clearStatus() { - self.yggdrasilSelfIP = "N/A" - self.yggdrasilSelfSubnet = "N/A" - self.yggdrasilSelfCoords = "[]" - self.yggdrasilPeers = [] - self.yggdrasilSwitchPeers = [] - NotificationCenter.default.post(name: .YggdrasilSelfUpdated, object: nil) - NotificationCenter.default.post(name: .YggdrasilPeersUpdated, object: nil) - NotificationCenter.default.post(name: .YggdrasilSwitchPeersUpdated, object: nil) - } -} diff --git a/Yggdrasil Network Extension/PacketTunnelProvider.swift b/Yggdrasil Network Extension/PacketTunnelProvider.swift index 22cb47e..a444de0 100644 --- a/Yggdrasil Network Extension/PacketTunnelProvider.swift +++ b/Yggdrasil Network Extension/PacketTunnelProvider.swift @@ -5,9 +5,12 @@ import Yggdrasil class PacketTunnelProvider: NEPacketTunnelProvider { var yggdrasil: MobileYggdrasil = MobileYggdrasil() - var conduit: DummyConduitEndpoint? = nil var yggdrasilConfig: ConfigurationProxy? + private var readThread: Thread? + private var writeThread: Thread? + private var writeBuffer = Data(count: 65535) + @objc func readPacketsFromTun() { autoreleasepool { self.packetFlow.readPackets { (packets: [Data], protocols: [NSNumber]) in @@ -28,7 +31,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider { } } } - + func startYggdrasil() -> Error? { var err: Error? = nil @@ -47,7 +50,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider { NSLog("Configuration loaded") do { - self.conduit = try self.yggdrasil.startJSON(config.data()) + try self.yggdrasil.startJSON(config.data()) } catch { NSLog("Starting Yggdrasil process produced an error: " + error.localizedDescription) return @@ -62,6 +65,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider { let tunnelNetworkSettings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: address) tunnelNetworkSettings.ipv6Settings = NEIPv6Settings(addresses: [address], networkPrefixLengths: [7]) tunnelNetworkSettings.ipv6Settings?.includedRoutes = [NEIPv6Route(destinationAddress: "0200::", networkPrefixLength: 7)] + tunnelNetworkSettings.mtu = NSNumber(integerLiteral: self.yggdrasil.getMTU()) NSLog("Setting tunnel network settings...") @@ -73,16 +77,19 @@ class PacketTunnelProvider: NEPacketTunnelProvider { } else { NSLog("Yggdrasil tunnel settings set successfully") - let readthread: Thread = Thread(target: self, selector: #selector(self.readPacketsFromTun), object: nil) - readthread.name = "TUN Packet Reader" - readthread.qualityOfService = .utility + self.readThread = Thread(target: self, selector: #selector(self.readPacketsFromTun), object: nil) + if let readThread = self.readThread { + readThread.name = "TUN Packet Reader" + readThread.qualityOfService = .utility + readThread.start() + } - let writethread: Thread = Thread(target: self, selector: #selector(self.writePacketsToTun), object: nil) - writethread.name = "TUN Packet Writer" - writethread.qualityOfService = .utility - - readthread.start() - writethread.start() + self.writeThread = Thread(target: self, selector: #selector(self.writePacketsToTun), object: nil) + if let writeThread = self.writeThread { + writeThread.name = "TUN Packet Writer" + writeThread.qualityOfService = .utility + writeThread.start() + } } } } @@ -110,6 +117,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider { } override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) { + self.readThread?.cancel() + self.writeThread?.cancel() try? self.yggdrasil.stop() super.stopTunnel(with: reason, completionHandler: completionHandler) } @@ -125,8 +134,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider { completionHandler?(self.yggdrasil.getCoordsString().data(using: .utf8)) case "peers": completionHandler?(self.yggdrasil.getPeersJSON().data(using: .utf8)) - case "switchpeers": - completionHandler?(self.yggdrasil.getSwitchPeersJSON().data(using: .utf8)) + case "dht": + completionHandler?(self.yggdrasil.getDHTJSON().data(using: .utf8)) default: completionHandler?(nil) } diff --git a/Yggdrasil Network iOS/Application/NSNotification.swift b/Yggdrasil Network iOS/Application/NSNotification.swift index 537668c..b0e6fd5 100644 --- a/Yggdrasil Network iOS/Application/NSNotification.swift +++ b/Yggdrasil Network iOS/Application/NSNotification.swift @@ -14,6 +14,6 @@ import AppKit extension Notification.Name { static let YggdrasilSelfUpdated = Notification.Name("YggdrasilSelfUpdated") static let YggdrasilPeersUpdated = Notification.Name("YggdrasilPeersUpdated") - static let YggdrasilSwitchPeersUpdated = Notification.Name("YggdrasilSwitchPeersUpdated") static let YggdrasilSettingsUpdated = Notification.Name("YggdrasilSettingsUpdated") + static let YggdrasilDHTUpdated = Notification.Name("YggdrasilPeersUpdated") } diff --git a/Yggdrasil Network iOS/Assets.xcassets/YggdrasilNetwork.imageset/Contents.json b/Yggdrasil Network iOS/Assets.xcassets/YggdrasilNetwork.imageset/Contents.json index b556306..4e7019e 100644 --- a/Yggdrasil Network iOS/Assets.xcassets/YggdrasilNetwork.imageset/Contents.json +++ b/Yggdrasil Network iOS/Assets.xcassets/YggdrasilNetwork.imageset/Contents.json @@ -1,23 +1,56 @@ { "images" : [ { - "idiom" : "universal", "filename" : "img1.png", + "idiom" : "universal", "scale" : "1x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "img1w.png", "idiom" : "universal", + "scale" : "1x" + }, + { "filename" : "img2.png", + "idiom" : "universal", "scale" : "2x" }, { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "img2w.png", "idiom" : "universal", + "scale" : "2x" + }, + { "filename" : "img3.png", + "idiom" : "universal", + "scale" : "3x" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "img3w.png", + "idiom" : "universal", "scale" : "3x" } ], "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/Yggdrasil Network iOS/Assets.xcassets/YggdrasilNetwork.imageset/img1w.png b/Yggdrasil Network iOS/Assets.xcassets/YggdrasilNetwork.imageset/img1w.png new file mode 100644 index 0000000..f4cd7df Binary files /dev/null and b/Yggdrasil Network iOS/Assets.xcassets/YggdrasilNetwork.imageset/img1w.png differ diff --git a/Yggdrasil Network iOS/Assets.xcassets/YggdrasilNetwork.imageset/img2w.png b/Yggdrasil Network iOS/Assets.xcassets/YggdrasilNetwork.imageset/img2w.png new file mode 100644 index 0000000..a8bd987 Binary files /dev/null and b/Yggdrasil Network iOS/Assets.xcassets/YggdrasilNetwork.imageset/img2w.png differ diff --git a/Yggdrasil Network iOS/Assets.xcassets/YggdrasilNetwork.imageset/img3w.png b/Yggdrasil Network iOS/Assets.xcassets/YggdrasilNetwork.imageset/img3w.png new file mode 100644 index 0000000..902eefd Binary files /dev/null and b/Yggdrasil Network iOS/Assets.xcassets/YggdrasilNetwork.imageset/img3w.png differ diff --git a/Yggdrasil Network iOS/Storyboards/Base.lproj/LaunchScreen.storyboard b/Yggdrasil Network iOS/Storyboards/Base.lproj/LaunchScreen.storyboard index 16aafe8..f584721 100644 --- a/Yggdrasil Network iOS/Storyboards/Base.lproj/LaunchScreen.storyboard +++ b/Yggdrasil Network iOS/Storyboards/Base.lproj/LaunchScreen.storyboard @@ -1,12 +1,11 @@ - - - - + + - + + @@ -19,20 +18,21 @@ - + + - + + @@ -41,7 +41,6 @@ - @@ -50,6 +49,12 @@ - + + + + + + + diff --git a/Yggdrasil Network iOS/Storyboards/Base.lproj/Main.storyboard b/Yggdrasil Network iOS/Storyboards/Base.lproj/Main.storyboard index 2544e02..69f6769 100644 --- a/Yggdrasil Network iOS/Storyboards/Base.lproj/Main.storyboard +++ b/Yggdrasil Network iOS/Storyboards/Base.lproj/Main.storyboard @@ -1,9 +1,11 @@ - - + + - + + + @@ -11,20 +13,19 @@ - - + + - - + - + - + - + - - + - + - + - + - + @@ -135,7 +136,7 @@ - + @@ -150,22 +151,21 @@ - - + + - - + - + - + @@ -199,17 +199,17 @@ - + - + - + - + - + - - The above options allow you to control whether your device is reachable from other devices on the network. "All outgoing traffic" allows connections only to devices that you initiate first. This does not affect peerings. + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - + - @@ -351,17 +261,17 @@ - Configuration will be exported to the Files app. Your configuration contains your private keys which are extremely sensitive. You must not share it with others. + Configuration will be exported to the Files app. Your configuration contains your private key which is extremely sensitive. You must not share it with others. - + - + - + - + @@ -440,7 +346,7 @@ - + @@ -455,28 +361,27 @@ - - + + - - + - + - + - + @@ -492,14 +397,14 @@ - + - + - + - + + + + + + + + + + + + + @@ -660,6 +589,7 @@ + @@ -669,15 +599,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + @@ -691,9 +651,10 @@ - + + @@ -701,4 +662,13 @@ + + + + + + + + + diff --git a/Yggdrasil Network iOS/View Controllers/PeersViewController.swift b/Yggdrasil Network iOS/View Controllers/PeersViewController.swift index 0105ad4..c7bca2c 100644 --- a/Yggdrasil Network iOS/View Controllers/PeersViewController.swift +++ b/Yggdrasil Network iOS/View Controllers/PeersViewController.swift @@ -49,7 +49,7 @@ class PeersViewController: UITableViewController { override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { switch section { - case 0: return app.yggdrasilSwitchPeers.count + case 0: return app.yggdrasilPeers.count case 1: if let config = self.app.yggdrasilConfig { if let peers = config.get("Peers") as? [String] { @@ -58,9 +58,6 @@ class PeersViewController: UITableViewController { } return 0 case 2: - if UIDevice.current.hasCellularCapabilites { - return 3 - } return 2 default: return 0 } @@ -70,20 +67,18 @@ class PeersViewController: UITableViewController { switch indexPath.section { case 0: let cell = tableView.dequeueReusableCell(withIdentifier: "discoveredPeerPrototype", for: indexPath) - let peers = app.yggdrasilSwitchPeers.sorted { (a, b) -> Bool in + let peers = app.yggdrasilPeers.sorted { (a, b) -> Bool in return (a["Port"] as! Int) < (b["Port"] as! Int) } if indexPath.row < peers.count { let value = peers[indexPath.row] let proto = value["Protocol"] as? String ?? "tcp" - let sent = value["BytesSent"] as? Double ?? 0 - let recvd = value["BytesRecvd"] as? Double ?? 0 - let rx = self.format(bytes: sent) - let tx = self.format(bytes: recvd) + let remote = value["Remote"] as? String ?? "unknown" + let prio = value["Priority"] as? Int ?? 0 - cell.textLabel?.text = "\(value["Endpoint"] ?? "unknown")" - cell.detailTextLabel?.text = "\(proto.uppercased()) peer on port \(value["Port"] ?? "unknown"), sent \(tx), received \(rx)" + cell.textLabel?.text = "\(value["IP"] ?? "(unknown)")" + cell.detailTextLabel?.text = "\(proto.uppercased()): \(remote)" } return cell case 1: @@ -101,33 +96,24 @@ class PeersViewController: UITableViewController { case 0: let cell = tableView.dequeueReusableCell(withIdentifier: "togglePrototype", for: indexPath) as! ToggleTableViewCell cell.isUserInteractionEnabled = true - cell.label?.text = "Search for multicast peers" + cell.label?.text = "Discoverable over multicast" cell.label?.isEnabled = true - cell.toggle?.addTarget(self, action: #selector(toggledMulticast), for: .valueChanged) + cell.toggle?.addTarget(self, action: #selector(toggledMulticastBeacons), for: .valueChanged) cell.toggle?.isEnabled = true if let config = self.app.yggdrasilConfig { - let interfaces = config.get("MulticastInterfaces") as? [String] ?? [] - cell.toggle?.isOn = interfaces.contains("en*") + cell.toggle?.isOn = config.multicastBeacons } return cell case 1: let cell = tableView.dequeueReusableCell(withIdentifier: "togglePrototype", for: indexPath) as! ToggleTableViewCell - cell.isUserInteractionEnabled = false - cell.label?.text = "Search for nearby iOS peers" - cell.label?.isEnabled = false - cell.toggle?.addTarget(self, action: #selector(toggledAWDL), for: .valueChanged) - cell.toggle?.setOn(false, animated: false) - cell.toggle?.isEnabled = false - /*if let config = self.app.yggdrasilConfig { - let interfaces = config.get("MulticastInterfaces") as? [String] ?? [] - cell.toggle?.isOn = interfaces.contains("awdl0") - }*/ - return cell - case 2: - let cell = tableView.dequeueReusableCell(withIdentifier: "menuPrototype", for: indexPath) cell.isUserInteractionEnabled = true - cell.textLabel?.text = "Device settings" - cell.textLabel?.isEnabled = true + cell.label?.text = "Search for multicast peers" + cell.label?.isEnabled = true + cell.toggle?.addTarget(self, action: #selector(toggledMulticastListen), for: .valueChanged) + cell.toggle?.isEnabled = true + if let config = self.app.yggdrasilConfig { + cell.toggle?.isOn = config.multicastListen + } return cell default: let cell = tableView.dequeueReusableCell(withIdentifier: "menuPrototype", for: indexPath) @@ -163,28 +149,16 @@ class PeersViewController: UITableViewController { return "\(numberString) \(suffix)" } - @objc func toggledMulticast(_ sender: UISwitch) { + @objc func toggledMulticastBeacons(_ sender: UISwitch) { if let config = self.app.yggdrasilConfig { - var interfaces = config.get("MulticastInterfaces") as! [String] - if sender.isOn { - interfaces.append("en*") - } else { - interfaces.removeAll(where: { $0 == "en*" }) - } - config.set("MulticastInterfaces", to: interfaces as [String]) + config.multicastBeacons = sender.isOn try? config.save(to: &app.vpnManager) } } - @objc func toggledAWDL(_ sender: UISwitch) { + @objc func toggledMulticastListen(_ sender: UISwitch) { if let config = self.app.yggdrasilConfig { - var interfaces = config.get("MulticastInterfaces") as! [String] - if sender.isOn { - interfaces.append("awdl0") - } else { - interfaces.removeAll(where: { $0 == "awdl0" }) - } - config.set("MulticastInterfaces", to: interfaces as [String]) + config.multicastListen = sender.isOn try? config.save(to: &app.vpnManager) } } @@ -214,7 +188,7 @@ class PeersViewController: UITableViewController { override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? { switch section { case 1: - return "Yggdrasil will automatically attempt to connect to configured peers when started." + return "Yggdrasil will automatically attempt to connect to configured peers when started. If you configure more than one peer, your device may carry traffic on behalf of other network nodes. Avoid this by configuring only a single peer." case 2: var str = "Multicast peers will be discovered on the same Wi-Fi network or via USB." if UIDevice.current.hasCellularCapabilites { diff --git a/Yggdrasil Network iOS/View Controllers/SettingsViewController.swift b/Yggdrasil Network iOS/View Controllers/SettingsViewController.swift index 9637a46..073d853 100644 --- a/Yggdrasil Network iOS/View Controllers/SettingsViewController.swift +++ b/Yggdrasil Network iOS/View Controllers/SettingsViewController.swift @@ -13,28 +13,18 @@ class SettingsViewController: UITableViewController, UIDocumentBrowserViewContro @IBOutlet weak var deviceNameField: UITextField! - @IBOutlet weak var encryptionPublicKeyLabel: UILabel! @IBOutlet weak var signingPublicKeyLabel: UILabel! @IBOutlet weak var autoStartWiFiCell: UITableViewCell! @IBOutlet weak var autoStartMobileCell: UITableViewCell! - @IBOutlet weak var sessionFirewallPeeredCell: UITableViewCell! - @IBOutlet weak var sessionFirewallOtherCell: UITableViewCell! - @IBOutlet weak var sessionFirewallOutboundCell: UITableViewCell! - override func viewDidLoad() { super.viewDidLoad() if let config = self.app.yggdrasilConfig { deviceNameField.text = config.get("name", inSection: "NodeInfo") as? String ?? "" - encryptionPublicKeyLabel.text = config.get("EncryptionPublicKey") as? String ?? "Unknown" - signingPublicKeyLabel.text = config.get("SigningPublicKey") as? String ?? "Unknown" - - sessionFirewallPeeredCell.accessoryType = config.get("AllowFromDirect", inSection: "SessionFirewall") as? Bool ?? true ? .checkmark : .none - sessionFirewallOtherCell.accessoryType = config.get("AllowFromRemote", inSection: "SessionFirewall") as? Bool ?? true ? .checkmark : .none - sessionFirewallOutboundCell.accessoryType = config.get("AlwaysAllowOutbound", inSection: "SessionFirewall") as? Bool ?? true ? .checkmark : .none - + signingPublicKeyLabel.text = config.get("PublicKey") as? String ?? config.get("SigningPublicKey") as? String ?? "Unknown" + autoStartWiFiCell.accessoryType = config.get("WiFi", inSection: "AutoStart") as? Bool ?? false ? .checkmark : .none autoStartMobileCell.accessoryType = config.get("Mobile", inSection: "AutoStart") as? Bool ?? false ? .checkmark : .none } @@ -61,20 +51,7 @@ class SettingsViewController: UITableViewController, UIDocumentBrowserViewContro try? config.save(to: &app.vpnManager) } } - case 2: - let settings = [ - "AllowFromDirect", - "AllowFromRemote", - "AlwaysAllowOutbound" - ] - if let cell = tableView.cellForRow(at: indexPath) { - cell.accessoryType = cell.accessoryType == .checkmark ? .none : .checkmark - if let config = self.app.yggdrasilConfig { - config.set(settings[indexPath.last!], inSection: "SessionFirewall", to: cell.accessoryType == .checkmark) - try? config.save(to: &app.vpnManager) - } - } - case 4: + case 3: switch indexPath.last { case 0: // import if #available(iOS 11.0, *) { @@ -113,7 +90,7 @@ class SettingsViewController: UITableViewController, UIDocumentBrowserViewContro default: break } - case 5: + case 4: let alert = UIAlertController(title: "Warning", message: "This operation will reset your configuration and generate new keys. This is not reversible unless your configuration has been exported. Changes will not take effect until the next time Yggdrasil is restarted.", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "Reset", style: .destructive, handler: { action in self.app.yggdrasilConfig = ConfigurationProxy() @@ -133,7 +110,6 @@ class SettingsViewController: UITableViewController, UIDocumentBrowserViewContro self.dismiss(animated: true, completion: nil) } - @available(iOS 11.0, *) func documentBrowser(_ controller: UIDocumentBrowserViewController, didPickDocumentsAt documentURLs: [URL]) { do { if let url = documentURLs.first { diff --git a/Yggdrasil Network iOS/View Controllers/SplitViewController.swift b/Yggdrasil Network iOS/View Controllers/SplitViewController.swift index c4e580d..4149fd3 100644 --- a/Yggdrasil Network iOS/View Controllers/SplitViewController.swift +++ b/Yggdrasil Network iOS/View Controllers/SplitViewController.swift @@ -14,5 +14,14 @@ class SplitViewController: UISplitViewController, UISplitViewControllerDelegate self.delegate = self self.preferredDisplayMode = .allVisible } - + + func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool { + return true + } + + @available(iOS 14.0,*) + func splitViewController(_ svc: UISplitViewController, topColumnForCollapsingToProposedTopColumn proposedTopColumn: UISplitViewController.Column) -> UISplitViewController.Column { + return .primary + } + } diff --git a/Yggdrasil Network iOS/View Controllers/TableViewController.swift b/Yggdrasil Network iOS/View Controllers/TableViewController.swift index 7261e85..58870a9 100644 --- a/Yggdrasil Network iOS/View Controllers/TableViewController.swift +++ b/Yggdrasil Network iOS/View Controllers/TableViewController.swift @@ -20,10 +20,12 @@ class TableViewController: UITableViewController { @IBOutlet var statsSelfCoords: UILabel! @IBOutlet var statsSelfPeers: UILabel! + @IBOutlet var statsVersion: UILabel! + override func viewDidLoad() { NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilSelfUpdated), name: NSNotification.Name.YggdrasilSelfUpdated, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilPeersUpdated), name: NSNotification.Name.YggdrasilPeersUpdated, object: nil) - NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilSwitchPeersUpdated), name: NSNotification.Name.YggdrasilSwitchPeersUpdated, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilDHTUpdated), name: NSNotification.Name.YggdrasilDHTUpdated, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(self.onYggdrasilSettingsUpdated), name: NSNotification.Name.YggdrasilSettingsUpdated, object: nil) } @@ -39,6 +41,8 @@ class TableViewController: UITableViewController { if let row = self.tableView.indexPathForSelectedRow { self.tableView.deselectRow(at: row, animated: true) } + + self.statsVersion.text = Yggdrasil.MobileGetVersion() } override func viewWillDisappear(_ animated: Bool) { @@ -65,18 +69,18 @@ class TableViewController: UITableViewController { if let footer = toggleTableView.footerView(forSection: 0) { if let label = footer.textLabel { - label.text = app.vpnManager.isOnDemandEnabled ? "Yggdrasil will automatically stop and start based on settings." : "You must restart Yggdrasil to make configuration changes effective." + label.text = app.vpnManager.isOnDemandEnabled ? "Yggdrasil is configured to automatically start and stop based on available connectivity." : "Yggdrasil is configured to start and stop manually." } } } func updateConnectedStatus() { if self.app.vpnManager.connection.status == .connected { - if app.yggdrasilSwitchPeers.count > 0 { - connectedStatusLabel.text = "Connected" + if app.yggdrasilDHT.count > 0 { + connectedStatusLabel.text = "Enabled" connectedStatusLabel.textColor = UIColor(red: 0.37, green: 0.79, blue: 0.35, alpha: 1.0) } else { - connectedStatusLabel.text = "No active connections" + connectedStatusLabel.text = "No connectivity" connectedStatusLabel.textColor = UIColor.red } } else { @@ -104,12 +108,12 @@ class TableViewController: UITableViewController { self.updateConnectedStatus() } - @objc func onYggdrasilSwitchPeersUpdated(notification: NSNotification) { + @objc func onYggdrasilDHTUpdated(notification: NSNotification) { self.updateConnectedStatus() } @objc func onYggdrasilPeersUpdated(notification: NSNotification) { - let peercount = app.yggdrasilSwitchPeers.count + let peercount = app.yggdrasilPeers.count if peercount <= 0 { statsSelfPeers.text = "No peers" } else if peercount == 1 { diff --git a/Yggdrasil Network.xcodeproj/project.pbxproj b/Yggdrasil Network.xcodeproj/project.pbxproj index 7d645ca..5062c55 100644 --- a/Yggdrasil Network.xcodeproj/project.pbxproj +++ b/Yggdrasil Network.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -11,13 +11,11 @@ 3939196B21E35A7C009320F3 /* PeersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3939196A21E35A7C009320F3 /* PeersViewController.swift */; }; 3939196D21E39313009320F3 /* UIDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3939196C21E39313009320F3 /* UIDevice.swift */; }; 3939197321E39815009320F3 /* ToggleTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3939197221E39815009320F3 /* ToggleTableViewCell.swift */; }; - 3939197521E3AADB009320F3 /* ConfigurationProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3939197421E3AADB009320F3 /* ConfigurationProxy.swift */; }; - 3940354623F4C0C100E81A29 /* Yggdrasil.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3944B66321DAAEA500AF102D /* Yggdrasil.framework */; }; 394A1EB321DEA46400D9F553 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 394A1EB221DEA46400D9F553 /* SettingsViewController.swift */; }; 39682A392225AD15004FB670 /* CopyableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39682A382225AD15004FB670 /* CopyableLabel.swift */; }; - 397346D521E8E422009B17F6 /* CrossPlatformAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 397346D421E8E422009B17F6 /* CrossPlatformAppDelegate.swift */; }; + 3996AF38270328080070947D /* Yggdrasil.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3996AF37270328080070947D /* Yggdrasil.xcframework */; }; + 3996AF39270328080070947D /* Yggdrasil.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3996AF37270328080070947D /* Yggdrasil.xcframework */; }; 39AE88392319C93F0010FFF6 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 39AE88382319C93F0010FFF6 /* NetworkExtension.framework */; }; - 39AE883A2319CA750010FFF6 /* ConfigurationProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3939197421E3AADB009320F3 /* ConfigurationProxy.swift */; }; 39CC924C221DEDCE004960DC /* NSNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CC924B221DEDCE004960DC /* NSNotification.swift */; }; 39CC924D221DEDD3004960DC /* NSNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CC924B221DEDCE004960DC /* NSNotification.swift */; }; E593CE6F1DF8FC3C00D7265D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E593CE6E1DF8FC3C00D7265D /* AppDelegate.swift */; }; @@ -60,12 +58,9 @@ 3939196A21E35A7C009320F3 /* PeersViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PeersViewController.swift; sourceTree = ""; }; 3939196C21E39313009320F3 /* UIDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIDevice.swift; sourceTree = ""; }; 3939197221E39815009320F3 /* ToggleTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleTableViewCell.swift; sourceTree = ""; }; - 3939197421E3AADB009320F3 /* ConfigurationProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurationProxy.swift; sourceTree = ""; }; - 3944B66321DAAEA500AF102D /* Yggdrasil.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Yggdrasil.framework; sourceTree = ""; }; 394A1EB221DEA46400D9F553 /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; }; 39682A382225AD15004FB670 /* CopyableLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CopyableLabel.swift; sourceTree = ""; }; - 397346D021E8BB5F009B17F6 /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/NetworkExtension.framework; sourceTree = DEVELOPER_DIR; }; - 397346D421E8E422009B17F6 /* CrossPlatformAppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrossPlatformAppDelegate.swift; sourceTree = ""; }; + 3996AF37270328080070947D /* Yggdrasil.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; path = Yggdrasil.xcframework; sourceTree = ""; }; 39AE88382319C93F0010FFF6 /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; }; 39CC924B221DEDCE004960DC /* NSNotification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSNotification.swift; sourceTree = ""; }; E593CE6B1DF8FC3C00D7265D /* YggdrasilNetwork.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = YggdrasilNetwork.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -85,6 +80,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 3996AF38270328080070947D /* Yggdrasil.xcframework in Frameworks */, 39AE88392319C93F0010FFF6 /* NetworkExtension.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -93,7 +89,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 3940354623F4C0C100E81A29 /* Yggdrasil.framework in Frameworks */, + 3996AF39270328080070947D /* Yggdrasil.xcframework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -149,29 +145,18 @@ 399D032221DA775D0016354F /* Frameworks */ = { isa = PBXGroup; children = ( + 3996AF37270328080070947D /* Yggdrasil.xcframework */, 39AE88382319C93F0010FFF6 /* NetworkExtension.framework */, - 397346D021E8BB5F009B17F6 /* NetworkExtension.framework */, - 3944B66321DAAEA500AF102D /* Yggdrasil.framework */, ); name = Frameworks; sourceTree = ""; }; - 39AE88372319C8840010FFF6 /* Yggdrasil Network Cross-Platform */ = { - isa = PBXGroup; - children = ( - 397346D421E8E422009B17F6 /* CrossPlatformAppDelegate.swift */, - 3939197421E3AADB009320F3 /* ConfigurationProxy.swift */, - ); - path = "Yggdrasil Network Cross-Platform"; - sourceTree = ""; - }; E593CE621DF8FC3C00D7265D = { isa = PBXGroup; children = ( 3913E99E21DB9B41001E0EC7 /* YggdrasilNetwork.entitlements */, 3913E99C21DB9B1C001E0EC7 /* YggdrasilNetworkExtension.entitlements */, E593CE981DF905AF00D7265D /* Yggdrasil Network Extension */, - 39AE88372319C8840010FFF6 /* Yggdrasil Network Cross-Platform */, E593CE6D1DF8FC3C00D7265D /* Yggdrasil Network iOS */, E593CE6C1DF8FC3C00D7265D /* Products */, 399D032221DA775D0016354F /* Frameworks */, @@ -256,14 +241,12 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 1010; - LastUpgradeCheck = 1030; + LastUpgradeCheck = 1250; ORGANIZATIONNAME = ""; TargetAttributes = { E593CE6A1DF8FC3C00D7265D = { CreatedOnToolsVersion = 8.1; - DevelopmentTeam = R9AV23TXF2; LastSwiftMigration = 1030; - ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.ApplicationGroups.iOS = { enabled = 1; @@ -281,9 +264,7 @@ }; E593CE961DF905AF00D7265D = { CreatedOnToolsVersion = 8.1; - DevelopmentTeam = R9AV23TXF2; LastSwiftMigration = 1030; - ProvisioningStyle = Automatic; SystemCapabilities = { com.apple.ApplicationGroups.iOS = { enabled = 1; @@ -348,9 +329,7 @@ 394A1EB321DEA46400D9F553 /* SettingsViewController.swift in Sources */, E593CE711DF8FC3C00D7265D /* TableViewController.swift in Sources */, 39682A392225AD15004FB670 /* CopyableLabel.swift in Sources */, - 3939197521E3AADB009320F3 /* ConfigurationProxy.swift in Sources */, E593CE6F1DF8FC3C00D7265D /* AppDelegate.swift in Sources */, - 397346D521E8E422009B17F6 /* CrossPlatformAppDelegate.swift in Sources */, 3913E9C021DD3A51001E0EC7 /* SplitViewController.swift in Sources */, 39CC924C221DEDCE004960DC /* NSNotification.swift in Sources */, ); @@ -362,7 +341,6 @@ files = ( 39CC924D221DEDD3004960DC /* NSNotification.swift in Sources */, E593CE9C1DF905AF00D7265D /* PacketTunnelProvider.swift in Sources */, - 39AE883A2319CA750010FFF6 /* ConfigurationProxy.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -421,6 +399,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -446,7 +425,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.1; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; @@ -484,6 +463,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -503,7 +483,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 10.1; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; MACOSX_DEPLOYMENT_TARGET = 10.12; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; @@ -522,9 +502,9 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = YggdrasilNetwork.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 21; + CURRENT_PROJECT_VERSION = 32; DEVELOPMENT_TEAM = R9AV23TXF2; ENABLE_BITCODE = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -532,14 +512,17 @@ "$(PROJECT_DIR)", ); INFOPLIST_FILE = "$(SRCROOT)/Yggdrasil Network iOS/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = eu.neilalexander.yggdrasil; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; STRIP_INSTALLED_PRODUCT = NO; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -553,9 +536,9 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = YggdrasilNetwork.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 21; + CURRENT_PROJECT_VERSION = 32; DEVELOPMENT_TEAM = R9AV23TXF2; ENABLE_BITCODE = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -563,13 +546,16 @@ "$(PROJECT_DIR)", ); INFOPLIST_FILE = "$(SRCROOT)/Yggdrasil Network iOS/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = eu.neilalexander.yggdrasil; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -580,9 +566,9 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_ENTITLEMENTS = YggdrasilNetworkExtension.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 21; + CURRENT_PROJECT_VERSION = 32; DEVELOPMENT_TEAM = R9AV23TXF2; ENABLE_BITCODE = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -590,7 +576,8 @@ "$(PROJECT_DIR)", ); INFOPLIST_FILE = "$(SRCROOT)/Yggdrasil Network Extension/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + "IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.2; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -600,8 +587,11 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; STRIP_INSTALLED_PRODUCT = NO; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,6"; }; name = Debug; }; @@ -609,9 +599,9 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_ENTITLEMENTS = YggdrasilNetworkExtension.entitlements; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 21; + CURRENT_PROJECT_VERSION = 32; DEVELOPMENT_TEAM = R9AV23TXF2; ENABLE_BITCODE = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -619,7 +609,8 @@ "$(PROJECT_DIR)", ); INFOPLIST_FILE = "$(SRCROOT)/Yggdrasil Network Extension/Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 10.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + "IPHONEOS_DEPLOYMENT_TARGET[sdk=macosx*]" = 14.2; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -629,8 +620,11 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = "8ce353d5-fd5f-4d5e-b664-8ad294091125"; PROVISIONING_PROFILE_SPECIFIER = ""; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; SWIFT_OBJC_BRIDGING_HEADER = ""; SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,6"; }; name = Release; }; diff --git a/Yggdrasil Network.xcodeproj/xcshareddata/xcschemes/YggdrasilNetwork.xcscheme b/Yggdrasil Network.xcodeproj/xcshareddata/xcschemes/YggdrasilNetwork.xcscheme index 759e8a3..433fa74 100644 --- a/Yggdrasil Network.xcodeproj/xcshareddata/xcschemes/YggdrasilNetwork.xcscheme +++ b/Yggdrasil Network.xcodeproj/xcshareddata/xcschemes/YggdrasilNetwork.xcscheme @@ -1,6 +1,6 @@ allow-vpn + com.apple.security.app-sandbox + com.apple.security.application-groups group.eu.neilalexander.yggdrasil + com.apple.security.network.client + diff --git a/YggdrasilNetworkExtension.entitlements b/YggdrasilNetworkExtension.entitlements index e1e1350..9069017 100644 --- a/YggdrasilNetworkExtension.entitlements +++ b/YggdrasilNetworkExtension.entitlements @@ -2,6 +2,8 @@ + com.apple.developer.networking.multicast + com.apple.developer.networking.networkextension packet-tunnel-provider @@ -10,9 +12,13 @@ allow-vpn + com.apple.security.app-sandbox + com.apple.security.application-groups group.eu.neilalexander.yggdrasil + com.apple.security.network.client +