diff --git a/integrations/apple/ZeroTierSDK_Apple/ZeroTierSDK_Apple.xcodeproj/project.pbxproj b/integrations/apple/ZeroTierSDK_Apple/ZeroTierSDK_Apple.xcodeproj/project.pbxproj index 28086b2..0443195 100644 --- a/integrations/apple/ZeroTierSDK_Apple/ZeroTierSDK_Apple.xcodeproj/project.pbxproj +++ b/integrations/apple/ZeroTierSDK_Apple/ZeroTierSDK_Apple.xcodeproj/project.pbxproj @@ -1424,6 +1424,7 @@ "-D__IOS__", "-DLWIP_DEBUG", "-DSDK_BUNDLED", + "-DUSING_BRIDGING_HEADER", ); PRODUCT_BUNDLE_IDENTIFIER = "zerotier.ZeroTierSDK-iOS"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1457,6 +1458,7 @@ "-DSDK", "-D__IOS__", "-DSDK_BUNDLED", + "-DUSING_BRIDGING_HEADER", ); PRODUCT_BUNDLE_IDENTIFIER = "zerotier.ZeroTierSDK-iOS"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1492,6 +1494,7 @@ "-DSDK_DEBUG", "-D__XCODE__", "-DLWIP_DEBUG", + "-DUSING_BRIDGING_HEADER", ); PRODUCT_BUNDLE_IDENTIFIER = "zerotier.ZeroTierSDK-OSX"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1522,6 +1525,7 @@ "-DSDK_SERVICE", "-DSDK_BUNDLED", "-D__XCODE__", + "-DUSING_BRIDGING_HEADER", ); PRODUCT_BUNDLE_IDENTIFIER = "zerotier.ZeroTierSDK-OSX"; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/integrations/apple/example_app/iOS/Example_iOS_App.xcodeproj/project.pbxproj b/integrations/apple/example_app/iOS/Example_iOS_App.xcodeproj/project.pbxproj index cea1dff..7abf7ec 100644 --- a/integrations/apple/example_app/iOS/Example_iOS_App.xcodeproj/project.pbxproj +++ b/integrations/apple/example_app/iOS/Example_iOS_App.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 7C1345841D80CDD700AF7FD1 /* ZTSDK.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C1345831D80CDD700AF7FD1 /* ZTSDK.swift */; }; 7C8BC03C1D3348A6001E1B6F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C8BC03B1D3348A6001E1B6F /* AppDelegate.swift */; }; 7C8BC03E1D3348A6001E1B6F /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C8BC03D1D3348A6001E1B6F /* ViewController.swift */; }; 7C8BC0411D3348A6001E1B6F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7C8BC03F1D3348A6001E1B6F /* Main.storyboard */; }; @@ -32,6 +33,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 7C1345831D80CDD700AF7FD1 /* ZTSDK.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ZTSDK.swift; path = ../../../../../src/ZTSDK.swift; sourceTree = ""; }; 7C8BC0381D3348A6001E1B6F /* Example_iOS_App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example_iOS_App.app; sourceTree = BUILT_PRODUCTS_DIR; }; 7C8BC03B1D3348A6001E1B6F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7C8BC03D1D3348A6001E1B6F /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; @@ -76,6 +78,7 @@ 7C8BC03A1D3348A6001E1B6F /* Example_iOS_App */ = { isa = PBXGroup; children = ( + 7C1345831D80CDD700AF7FD1 /* ZTSDK.swift */, 7CE8BFA91D3C553400350023 /* SDK_XcodeWrapper.cpp */, 7CE8BFAA1D3C553400350023 /* SDK_XcodeWrapper.hpp */, 7C8BC03B1D3348A6001E1B6F /* AppDelegate.swift */, @@ -163,6 +166,7 @@ files = ( 7C8BC03E1D3348A6001E1B6F /* ViewController.swift in Sources */, 7CE8BFAB1D3C553400350023 /* SDK_XcodeWrapper.cpp in Sources */, + 7C1345841D80CDD700AF7FD1 /* ZTSDK.swift in Sources */, 7C8BC03C1D3348A6001E1B6F /* AppDelegate.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/integrations/apple/example_app/iOS/Example_iOS_App.xcodeproj/xcuserdata/Joseph.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/integrations/apple/example_app/iOS/Example_iOS_App.xcodeproj/xcuserdata/Joseph.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 3f04978..1c954db 100644 --- a/integrations/apple/example_app/iOS/Example_iOS_App.xcodeproj/xcuserdata/Joseph.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/integrations/apple/example_app/iOS/Example_iOS_App.xcodeproj/xcuserdata/Joseph.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -10,11 +10,11 @@ ignoreCount = "0" continueAfterRunningActions = "No" filePath = "Example_iOS_App/ViewController.swift" - timestampString = "492476189.334255" + timestampString = "494987032.463726" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "56" - endingLineNumber = "56" + startingLineNumber = "54" + endingLineNumber = "54" landmarkName = "UI_TX(_:)" landmarkType = "5"> @@ -26,11 +26,11 @@ ignoreCount = "0" continueAfterRunningActions = "No" filePath = "Example_iOS_App/ViewController.swift" - timestampString = "492477955.572263" + timestampString = "494987032.463726" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "249" - endingLineNumber = "249" + startingLineNumber = "230" + endingLineNumber = "230" landmarkName = "update_rx()" landmarkType = "5"> @@ -42,14 +42,78 @@ ignoreCount = "0" continueAfterRunningActions = "No" filePath = "Example_iOS_App/ViewController.swift" - timestampString = "492482204.82335" + timestampString = "494987032.463726" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "283" - endingLineNumber = "283" + startingLineNumber = "261" + endingLineNumber = "261" landmarkName = "update_rx()" landmarkType = "5"> + + + + + + + + + + + + + + + + diff --git a/integrations/apple/example_app/iOS/Example_iOS_App/ViewController.swift b/integrations/apple/example_app/iOS/Example_iOS_App/ViewController.swift index deea115..a586ec2 100644 --- a/integrations/apple/example_app/iOS/Example_iOS_App/ViewController.swift +++ b/integrations/apple/example_app/iOS/Example_iOS_App/ViewController.swift @@ -10,7 +10,9 @@ import UIKit class ViewController: UIViewController { - var serverPort:UInt16 = 8080 + let zt = ZTSDK(); + + var serverPort:Int16 = 8080 var serverAddr:String = "10.9.9.100" var selectedProtocol:Int32 = 0 var sock:Int32 = -1 @@ -29,18 +31,16 @@ class ViewController: UIViewController { // Use ordinary read/write calls on ZeroTier socket // TCP - if(selectedProtocol == SOCK_STREAM) - { + if(selectedProtocol == SOCK_STREAM) { var buffer = [UInt8](count: 100, repeatedValue: 0) read(accepted_sock, &buffer, 100); print(buffer) } // UDP - if(selectedProtocol == SOCK_DGRAM) - { + if(selectedProtocol == SOCK_DGRAM) { var buffer = [UInt8](count: 100, repeatedValue: 0) - read(sock, &buffer, 100); + read(Int32(sock), &buffer, 100); print(buffer) } } @@ -48,16 +48,13 @@ class ViewController: UIViewController { @IBAction func UI_TX(sender: AnyObject) { // Use ordinary read/write calls on ZeroTier socket - // TCP - if(selectedProtocol == SOCK_STREAM) - { - write(sock, txtTX.description, txtTX.description.characters.count); + if(selectedProtocol == SOCK_STREAM) { + write(Int32(sock), txtTX.description, txtTX.description.characters.count); } // UDP - if(selectedProtocol == SOCK_DGRAM) - { - sendto(sock, txtTX.description, txtTX.description.characters.count, 0, UnsafePointer([udp_addr]), UInt32(udp_addr.sin_len)) + if(selectedProtocol == SOCK_DGRAM) { + sendto(Int32(sock), txtTX.description, txtTX.description.characters.count, 0, UnsafePointer([udp_addr]), UInt32(udp_addr.sin_len)) } } @@ -66,12 +63,12 @@ class ViewController: UIViewController { @IBOutlet weak var btnJoinNetwork: UIButton! @IBAction func UI_JoinNetwork(sender: AnyObject) { - zt_join_network(txtNWID.text!) + zt.join_network(txtNWID.text!) } @IBOutlet weak var btnLeaveNetwork: UIButton! @IBAction func UI_LeaveNetwork(sender: AnyObject) { - zt_leave_network(txtNWID.text!) + zt.leave_network(txtNWID.text!) } @IBOutlet weak var segmentProtocol: UISegmentedControl! @@ -95,16 +92,10 @@ class ViewController: UIViewController { // TCP if(selectedProtocol == SOCK_STREAM) { - sock = zt_socket(AF_INET, SOCK_STREAM, 0) - var addr = sockaddr_in(sin_len: UInt8(sizeof(sockaddr_in)), - sin_family: UInt8(AF_INET), - sin_port: UInt16(serverPort).bigEndian, - sin_addr: in_addr(s_addr: 0), - sin_zero: (0,0,0,0,0,0,0,0)) + sock = zt.socket(AF_INET, socket_type: SOCK_STREAM, socket_protocol: 0) + let ztaddr: ZTAddress = ZTAddress(family: AF_INET, addr: serverAddr, port: serverPort) + let connect_err = zt.connect(sock, addr: ztaddr) - inet_pton(AF_INET, serverAddr, &(addr.sin_addr)); - - let connect_err = zt_connect(sock, UnsafePointer([addr]), UInt32(addr.sin_len)) print("connect_err = \(connect_err),\(errno)") if connect_err < 0 { @@ -138,16 +129,9 @@ class ViewController: UIViewController { // TCP if(selectedProtocol == SOCK_STREAM) { - sock = zt_socket(AF_INET, SOCK_STREAM, 0) - var addr = sockaddr_in(sin_len: UInt8(sizeof(sockaddr_in)), - sin_family: UInt8(AF_INET), - sin_port: UInt16(serverPort).bigEndian, - sin_addr: in_addr(s_addr: 0), - sin_zero: (0,0,0,0,0,0,0,0)) - - inet_pton(AF_INET, serverAddr, &(addr.sin_addr)); - - let bind_err = zt_bind(sock, UnsafePointer([addr]), UInt32(addr.sin_len)) + sock = Int16(zt_socket(AF_INET, SOCK_STREAM, 0)) + let ztaddr: ZTAddress = ZTAddress(family: AF_INET, addr: serverAddr, port: serverPort) + let bind_err = zt.bind(sock, addr: ztaddr) print("bind_err = \(bind_err),\(errno)") @@ -158,13 +142,13 @@ class ViewController: UIViewController { } // Put socket into listening state - zt_listen(sock, 1); + zt_listen(Int32(sock), 1); // Accept connection var len:socklen_t = 0; var legIntPtr = withUnsafeMutablePointer(&len, { $0 }) while(accepted_sock < 0) { - accepted_sock = zt_accept(sock, UnsafeMutablePointer([addr]), legIntPtr) + accepted_sock = zt.accept(sock, addr: ztaddr) } print("accepted connection") } @@ -172,18 +156,13 @@ class ViewController: UIViewController { // UDP if(selectedProtocol == SOCK_DGRAM) { - var addr = sockaddr_in(sin_len: UInt8(sizeof(sockaddr_in)), - sin_family: UInt8(AF_INET), - sin_port: UInt16(serverPort).bigEndian, - sin_addr: in_addr(s_addr: 0), - sin_zero: (0,0,0,0,0,0,0,0)) + let ztaddr: ZTAddress = ZTAddress(family: AF_INET, addr: serverAddr, port: serverPort) - - sock = zt_socket(AF_INET, SOCK_DGRAM, 0) - err = zt_bind(sock, UnsafePointer([addr]), UInt32(addr.sin_len)) + sock = Int16(zt_socket(AF_INET, SOCK_DGRAM, 0)) + err = zt.bind(sock, addr: ztaddr) print("bind_err = ", err) - err = zt_listen(sock, 0) + err = zt.listen(sock, backlog: 0) print("listen_err = ", err) } } @@ -208,13 +187,15 @@ class ViewController: UIViewController { while(true) { sleep(1) + dispatch_async(dispatch_get_main_queue()) { var str_buf = [Int8](count: 16, repeatedValue: 0) - zt_get_addresses(self.txtNWID.text!, &str_buf); + print(self.zt.get_address(self.txtNWID.text!)) //, &str_buf); self.lblAddress.text = String.fromCString(str_buf) // print("IPV4 = ", String.fromCString(str_buf)) } + // TCP if(selectedProtocol == SOCK_STREAM) { @@ -233,23 +214,22 @@ class ViewController: UIViewController { } } // UDP + /* if(selectedProtocol == SOCK_DGRAM) { let len = 32 var buffer = [UInt8](count: len, repeatedValue: 0) - /* - udp_addr = sockaddr_in(sin_len: UInt8(sizeof(sockaddr_in)), - sin_family: UInt8(AF_INET), - sin_port: UInt16(0).bigEndian, - sin_addr: in_addr(s_addr: 0), - sin_zero: (0,0,0,0,0,0,0,0)) - - var addrlen:socklen_t = 0; - var legIntPtr = withUnsafeMutablePointer(&addrlen, { $0 }) - let n = recvfrom(sock, &buffer, len, 0, UnsafeMutablePointer([udp_addr]), legIntPtr) - */ + //udp_addr = sockaddr_in(sin_len: UInt8(sizeof(sockaddr_in)), + // sin_family: UInt8(AF_INET), + // sin_port: UInt16(0).bigEndian, + // sin_addr: in_addr(s_addr: 0), + // sin_zero: (0,0,0,0,0,0,0,0)) + //var addrlen:socklen_t = 0; + //var legIntPtr = withUnsafeMutablePointer(&addrlen, { $0 }) + //let n = recvfrom(sock, &buffer, len, 0, UnsafeMutablePointer([udp_addr]), legIntPtr) + var socketAddress = sockaddr_storage() var socketAddressLength = socklen_t(sizeof(sockaddr_storage.self)) @@ -269,11 +249,9 @@ class ViewController: UIViewController { print("bytesWritten = ", bytesWritten); - /* - let bytesWritten = withUnsafePointer(&socketAddress.sin) { - sendto(sock, buffer, len, 0, UnsafePointer($0), socklen_t(socketAddress.sin.sin_len)) - } -*/ + //let bytesWritten = withUnsafePointer(&socketAddress.sin) { + // sendto(sock, buffer, len, 0, UnsafePointer($0), socklen_t(socketAddress.sin.sin_len)) + //} if let str = String(data: NSData(bytes: &buffer, length: len), encoding: NSUTF8StringEncoding) { dispatch_async(dispatch_get_main_queue()) { @@ -284,15 +262,9 @@ class ViewController: UIViewController { } } } + */ } } - - // ZeroTier service thread - var service_thread : NSThread! - func ztnc_start_service() { - let path = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true) - zt_start_service_and_rpc(path[0],"8056c2e21c000001") - } override func viewDidLoad() { super.viewDidLoad() @@ -306,11 +278,13 @@ class ViewController: UIViewController { selectedProtocol = SOCK_STREAM - // ZeroTier Service thread - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), { - self.service_thread = NSThread(target:self, selector:"ztnc_start_service", object:nil) - self.service_thread.start() - }); + print("Starting ZeroTier...\n"); + zt.start_service(nil); + + print("Joining network...\n"); + zt.join_network(txtNWID.text!); + + print("Complete\n"); // UI RX update dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), { diff --git a/src/SDK_Apple-Bridging-Header.h b/src/SDK_Apple-Bridging-Header.h index e90dbf7..bcc6dd0 100644 --- a/src/SDK_Apple-Bridging-Header.h +++ b/src/SDK_Apple-Bridging-Header.h @@ -18,6 +18,7 @@ void zt_enable_intercept(); void zt_start_service(const char * path); void zt_stop_service(); void zt_start_service_and_rpc(const char * path, const char * nwid); +bool zt_service_is_running(); void zt_join_network(const char *nwid); void zt_leave_network(const char *nwid); void zt_is_running(const char *nwid); diff --git a/src/ZTSDK.swift b/src/ZTSDK.swift new file mode 100644 index 0000000..3eb0fe9 --- /dev/null +++ b/src/ZTSDK.swift @@ -0,0 +1,182 @@ +// +// ZTSDK.swift +// Example_iOS_App +// +// Created by Joseph Henry on 9/7/16. +// Copyright © 2016 ZeroTier Inc. All rights reserved. +// + +import Foundation + +// Convenience structure for getting address data to/from the native library +struct ZTAddress +{ + var family: Int32 + var addr: String + var port: Int16 + var data: sockaddr_in? + + init(family: Int32, addr: String, port: Int16) + { + self.family = family + self.addr = addr + self.port = port + } + + func to_sockaddr_in() -> UnsafePointer + { + var data = sockaddr_in(sin_len: UInt8(sizeof(sockaddr_in)), + sin_family: UInt8(AF_INET), + sin_port: UInt16(port).bigEndian, + sin_addr: in_addr(s_addr: 0), + sin_zero: (0,0,0,0,0,0,0,0)) + inet_pton(AF_INET, addr, &(data.sin_addr)); + return UnsafePointer([data]); + } + + func len() -> UInt8 + { + return UInt8(sizeof(sockaddr_in)) + } +} + + +// Convenience wrapper class for ZeroTier/SDK/Proxy controls +// Implemented in terms of SDK_XcodeWrapper.cpp +class ZTSDK : NSObject +{ + var service_thread : NSThread! + private func ztnc_start_service(path: String?) + { + if(path == nil) { + zt_start_service( + NSSearchPathForDirectoriesInDomains( + NSSearchPathDirectory.DocumentDirectory,NSSearchPathDomainMask.UserDomainMask,true)[0]) + return; + } + zt_start_service(path!) + } + + // Starts the ZeroTier background service + func start_service(path: String?) + { + + let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) + dispatch_async(queue) { + self.ztnc_start_service(path) + } + sleep(2) + while(service_is_running() == false) { /* waiting for service to start */ } + } + + // Stops the ZeroTier background service + func stop_service() + { + zt_stop_service(); + } + + // Returns whether the ZeroTier background service is running + func service_is_running() -> Bool + { + return zt_service_is_running(); + } + + // Joins a ZeroTier network + func join_network(nwid: String) + { + zt_join_network(nwid); + } + + // Leaves a ZeroTier network + func leave_network(nwid: String) + { + zt_leave_network(nwid); + } + + // Returns the address of this device on a given ZeroTier network + func get_address(nwid: String) -> (String, String) + { + // zts_get_addresses(nwid, addrstr); + return ("ipv4", "ipv6") + } + + + // PROXY SERVER CONTROLS + // + /* + func start_proxy_server(homepath: String, nwid: String, struct sockaddr_storage *addr) { + zt_start_proxy_server(homepath, nwid, addr); + } + // + func stop_proxy_server(nwid: String) { + zt_stop_proxy_server(nwid); + } + // + func proxy_is_running(const char *homepath, const char *nwid, struct sockaddr_storage *addr) { + zt_start_proxy_server(homepath, nwid, addr); + } + // + func get_proxy_server_address(const char *nwid, struct sockaddr_storage *addr) { + zt_get_proxy_server_address(nwid, addr); + } + // Explicit ZT API wrappers + #if !defined(__IOS__) + // This isn't available for iOS since function interposition isn't as reliable + func init_rpc(const char *path, const char *nwid) { + zt_init_rpc(path, nwid); + } + #endif + + */ + + // SOCKET API + func socket(socket_family: Int32, _ socket_type: Int32, _ socket_protocol: Int32) -> Int16 { + return Int16(zt_socket(socket_family, socket_type, socket_protocol)); + } + + func connect(fd: Int32, _ addr: ZTAddress) -> Int32 { + return zt_connect(Int32(fd), addr.to_sockaddr_in(), UInt32(addr.len())); + } + func bind(fd: Int32, _ addr: ZTAddress) -> Int32 { + return zt_bind(Int32(fd), addr.to_sockaddr_in(), UInt32(addr.len())); + } + + func accept(fd: Int32, _ addr: ZTAddress) -> Int32 { + return zt_accept(Int32(fd), UnsafeMutablePointer([addr.data]), UnsafeMutablePointer([addr.len])); + } + + func listen(fd: Int32, _ backlog: Int16) -> Int32 { + return zt_listen(Int32(fd), Int32(backlog)); + } + func setsockopt(fd: Int32, _ level: Int32, _ optname: Int32, _ optval: UnsafePointer, _ optlen: Int32) -> Int32 { + return zt_setsockopt(fd, level, optname, optval, UInt32(optlen)); + } + + func getsockopt(fd: Int32, _ level: Int32, _ optname: Int32, _ optval: UnsafeMutablePointer, _ optlen: UInt32) -> Int32 { + return zt_getsockopt(fd, level, optname, optval, UnsafeMutablePointer([optlen])); + } + + func close(fd: Int32) -> Int32 { + return zt_close(fd); + } + + func getsockname(fd: Int32, _ addr: ZTAddress) -> Int32 { + return zt_getsockname(fd, UnsafeMutablePointer([addr.data]), UnsafeMutablePointer([addr.len])); + } + + func getpeername(fd: Int32, _ addr: ZTAddress) -> Int32 { + return zt_getpeername(fd, UnsafeMutablePointer([addr.data]), UnsafeMutablePointer([addr.len])); + } +/* + func fcntl(fd: Int32, _ cmd: Int32, _ flags: Int32) -> Int32 { + return zt_fcntl(fd, cmd, flags); + } +*/ + func recvfrom(fd: Int32, _ buf: UnsafeMutablePointer, _ len: Int32, _ flags: Int32, _ addr: ZTAddress) -> Int32 { + return zt_recvfrom(fd, buf, Int(len), flags, UnsafeMutablePointer([addr.data]), UnsafeMutablePointer([addr.len])); + } + + func sendto(fd: Int32, _ buf: UnsafePointer, _ len: Int32, _ flags: Int32, _ addr: ZTAddress) -> Int32 { + return zt_sendto(fd, buf, Int(len), flags, addr.to_sockaddr_in(), UInt32(addr.len())); + } +}