diff --git a/README.md b/README.md index 8c601e8..6333c75 100644 --- a/README.md +++ b/README.md @@ -30,5 +30,55 @@ We've designed a background tap service that pairs the ZeroTier protocol with sw **Direct Call** - Directly call the `zt_` API specified in [SDK.h](src/SDK.h). For this to work, just use one of the provided headers that specify the interface for your system/architecture and then either dynamically-load our library into your app or compile it right in. + +*** +## Important Build Flags + +- `SDK_IPV4=1` - Enable IPv4 support +- `SDK_IPV6=1` - Enable IPv6 support + +- `SDK_DEBUG=1` - Enables SDK debugging + +- `SDK_PICOTCP=1` - Enable the use of `picoTCP` (recommended) +- `SDK_PICO_DEBUG=1` - Enables debug output for the `picoTCP` network stack + +- `SDK_LWIP=1` - Enable the use of `lwIP` (deprecated) +- `SDK_LWIP_DEBUG=1` - Enables debug output for the `lwIP` library. + +*** + +### Apple + - For everything: `make apple` + +##### iOS + - [Embedding within an app](apple/example_app/iOS) `make ios_app_framework` -> `build/ios_app_framework/*` + - Unity3D plugin `make ios_unity3d_bundle` -> `build/ios_unity3d_bundle/*` + +##### OSX + - [Linking into an app at compiletime](../docs/osx_zt_sdk.md) `make osx_shared_lib` -> `build/libztosx.so` + - [Embedding within an app with Xcode](apple/example_app/OSX) `make osx_app_framework` -> `build/osx_app_framework/*` + - [Dynamic-linking into an app/service at runtime](../docs/osx_zt_sdk.md) `make osx_service_and_intercept` -> { `build/zerotier-sdk-service` + `build/libztintercept.so` } + - [Intercept library](../docs/osx_zt_sdk.md) `make osx_sdk_service` -> `build/zerotier-sdk-service` + - [SDK Service](../docs/osx_zt_sdk.md) `make osx_intercept` -> `build/libztintercept.so` + - [Unity3D plugin](apple/ZeroTierSDK_Apple) `make osx_unity3d_bundle` + +*** +### Linux + - For everything: `make linux` + - [Dynamic-linking into an app/service at runtime](../docs/linux_zt_sdk.md) `make linux_shared_lib` + - Service and Intercept `make linux_service_and_intercept` -> { `build/zerotier-sdk-service` + `build/libztintercept.so` } + - [Using the SDK with Docker](docker) + +### Android + - For everything: `make android` + + - [Embedding within an app](android) `make android_jni_lib` -> `build/android_jni_lib/YOUR_ARCH/libZeroTierOneJNI.so` + - [Unity 3D plugin](../docs/android_unity3d_zt_sdk.md) `make android_unity3d_plugin` -> `build/android_unity3d_plugin/*` + +*** +### Windows + - Not yet. + + *** ![Image](docs/img/api_diagram.png) diff --git a/build/README.md b/build/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/android_zt_sdk.md b/docs/android_zt_sdk.md index b615abe..229e587 100644 --- a/docs/android_zt_sdk.md +++ b/docs/android_zt_sdk.md @@ -12,7 +12,7 @@ If you want to skip the following steps and just take a look at the project, go *** **Step 1: App Code Modifications** - - In your project, create a new package called `ZeroTier` and class file within called `ZTSDK.java` and copy contents from `src/SDK_JavaWrapper.java` + - In your project, create a new package called `ZeroTier` and class file within called `ZTSDK.java` and copy contents from `src/wrappers/java/JavaWrapper.java` - Start the service diff --git a/docs/api_discussion.md b/docs/api_discussion.md index 3e91ee0..c9d0d61 100644 --- a/docs/api_discussion.md +++ b/docs/api_discussion.md @@ -19,6 +19,6 @@ ZTSDK API Options The following APIs are available for this integration: -- `Direct Call`: Consult [src/SDK_Apple-Bridging-Header.h](../../../../src/SDK_Apple-Bridging-Header.h). +- `Direct Call`: Consult [src/wrappers/swift/Apple-Bridging-Header.h](../../../../src/wrappers/swift/Apple-Bridging-Header.h). - `Hook of BSD-like sockets`: Use BSD-like sockets as you normally would. - `Proxy of NSStream`: Create NSStream. Configure stream for SOCKS5 Proxy (127.0.0.1:PORT). Start Proxy. Use stream. An example of how to use the proxy can be found in the example iOS/OSX projects. \ No newline at end of file diff --git a/docs/integrations.md b/docs/integrations.md index db50c12..0e4d3bf 100644 --- a/docs/integrations.md +++ b/docs/integrations.md @@ -12,20 +12,20 @@ Below are the specific instructions for each integration requiring *little to no For more support on these integrations, or if you'd like help creating a new integration, stop by our [community section](https://www.zerotier.com/community/)! *** -## Important Build flags +## Important Build Flags -- `SDK_IPV4=1` - Enable IPv4 support in whatever stack you have selected -- `SDK_IPV6=1` - Enable IPv6 support in whatever stack you have selected +- `SDK_IPV4=1` - Enable IPv4 support +- `SDK_IPV6=1` - Enable IPv6 support -- `SDK_LWIP=1` - Enable the use of `lwIP` -- `SDK_PICOTCP=1` - Enable the use of `picoTCP` +- `SDK_DEBUG=1` - Enables SDK debugging -- `SDK_DEBUG=1` - Turns on SDK activity/warning/error output. Levels of verbosity can be adjusted in `src/SDK_Debug.h` -- `SDK_LWIP_DEBUG=1` - Turns on debug output for the `lwIP` library. -- `SDK_BUNDLED=1` - Builds the SDK as a single bundled target including a the RPC mechanism, the `lwIP` library, and the ZeroTier service. +- `SDK_PICOTCP=1` - Enable the use of `picoTCP` (recommended) +- `SDK_PICO_DEBUG=1` - Enables debug output for the `picoTCP` network stack + +- `SDK_LWIP=1` - Enable the use of `lwIP` (deprecated) +- `SDK_LWIP_DEBUG=1` - Enables debug output for the `lwIP` library. *** -## Current Integrations ### Apple - For everything: `make apple` @@ -40,11 +40,13 @@ For more support on these integrations, or if you'd like help creating a new int - [Dynamic-linking into an app/service at runtime](../docs/osx_zt_sdk.md) `make osx_service_and_intercept` -> { `build/zerotier-sdk-service` + `build/libztintercept.so` } - [Intercept library](../docs/osx_zt_sdk.md) `make osx_sdk_service` -> `build/zerotier-sdk-service` - [SDK Service](../docs/osx_zt_sdk.md) `make osx_intercept` -> `build/libztintercept.so` - - [Unity3D plugin](apple/ZeroTierSDK_Apple) `make osx_unity3d_bundle` -> + - [Unity3D plugin](apple/ZeroTierSDK_Apple) `make osx_unity3d_bundle` *** ### Linux + - For everything: `make linux` - [Dynamic-linking into an app/service at runtime](../docs/linux_zt_sdk.md) `make linux_shared_lib` + - Service and Intercept `make linux_service_and_intercept` -> { `build/zerotier-sdk-service` + `build/libztintercept.so` } - [Using the SDK with Docker](docker) ### Android diff --git a/docs/ios_zt_sdk.md b/docs/ios_zt_sdk.md index 4fc1dad..968008f 100644 --- a/docs/ios_zt_sdk.md +++ b/docs/ios_zt_sdk.md @@ -19,8 +19,8 @@ This short tutorial will show you how to enable ZeroTier functionality for your - Add `src` directory to *Build Settings -> Header Search Paths* - Add `build/ios_app_framework/Release-iphoneos/` to *Build Settings -> Framework Search Paths* - Add `ZeroTierSDK.frameworkiOS` to *General->Embedded Binaries* -- Add `src/ZTSDK.swift`, `src/SDK_XcodeWrapper.cpp` and `src/SDK_XcodeWrapper.hpp` to your project: -- Set `src/SDK_Apple-Bridging-Header.h` as your bridging-header in *Build Settings -> Objective-C Bridging-header* +- Add `src/wrappers/swift/ZTSDK.swift`, `src/wrappers/swift/XcodeWrapper.cpp` and `src/wrappers/swift/XcodeWrapper.hpp` to your project: +- Set `src/wrappers/swift/Apple-Bridging-Header.h` as your bridging-header in *Build Settings -> Objective-C Bridging-header* **Step 3: Start the ZeroTier service** diff --git a/docs/osx_zt_sdk.md b/docs/osx_zt_sdk.md index 2524f1e..0aecfbc 100644 --- a/docs/osx_zt_sdk.md +++ b/docs/osx_zt_sdk.md @@ -36,6 +36,11 @@ Run application ./app +## Via `DYLD_LIBRARY_PATH` (Injecting code dynamically at runtime) + +As of the release of El Capitan, Apple requires one to turn off System Integrity Protection for code injection from external libraries. This method of intercepting network calls is now deprecated and we are investigating new methods for future releases of the SDK. If you still wish to use this method just `export DYLD_LIBRARY_PATH=./path/to/libztintercept.so:$DYLD_LIBRARY_PATH`. Also set `ZT_NC_NETWORK` appropriately. + + ## Via App Framework in XCode *** @@ -50,8 +55,8 @@ Run application - Add `src` directory to *Build Settings -> Header Search Paths* - Add `build/osx_app_framework/Release/` to *Build Settings -> Framework Search Paths* - Add `ZeroTierSDK.frameworkOSX` to *General->Embedded Binaries* -- Add `src/ZTSDK.swift`, `src/SDK_XcodeWrapper.cpp`, and `src/SDK_XcodeWrapper.hpp` to your project: -- Set `src/SDK_Apple-Bridging-Header.h` as your bridging-header in *Build Settings -> Objective-C Bridging-header* +- Add `src/wrappers/swift/ZTSDK.swift`, `src/wrappers/swift/XcodeWrapper.cpp`, and `src/wrappers/swift/XcodeWrapper.hpp` to your project: +- Set `src/wrappers/swift/Apple-Bridging-Header.h` as your bridging-header in *Build Settings -> Objective-C Bridging-header* **Step 3: Start the ZeroTier service** diff --git a/docs/zt_sdk_intro.md b/docs/zt_sdk_intro.md index 8c601e8..6333c75 100644 --- a/docs/zt_sdk_intro.md +++ b/docs/zt_sdk_intro.md @@ -30,5 +30,55 @@ We've designed a background tap service that pairs the ZeroTier protocol with sw **Direct Call** - Directly call the `zt_` API specified in [SDK.h](src/SDK.h). For this to work, just use one of the provided headers that specify the interface for your system/architecture and then either dynamically-load our library into your app or compile it right in. + +*** +## Important Build Flags + +- `SDK_IPV4=1` - Enable IPv4 support +- `SDK_IPV6=1` - Enable IPv6 support + +- `SDK_DEBUG=1` - Enables SDK debugging + +- `SDK_PICOTCP=1` - Enable the use of `picoTCP` (recommended) +- `SDK_PICO_DEBUG=1` - Enables debug output for the `picoTCP` network stack + +- `SDK_LWIP=1` - Enable the use of `lwIP` (deprecated) +- `SDK_LWIP_DEBUG=1` - Enables debug output for the `lwIP` library. + +*** + +### Apple + - For everything: `make apple` + +##### iOS + - [Embedding within an app](apple/example_app/iOS) `make ios_app_framework` -> `build/ios_app_framework/*` + - Unity3D plugin `make ios_unity3d_bundle` -> `build/ios_unity3d_bundle/*` + +##### OSX + - [Linking into an app at compiletime](../docs/osx_zt_sdk.md) `make osx_shared_lib` -> `build/libztosx.so` + - [Embedding within an app with Xcode](apple/example_app/OSX) `make osx_app_framework` -> `build/osx_app_framework/*` + - [Dynamic-linking into an app/service at runtime](../docs/osx_zt_sdk.md) `make osx_service_and_intercept` -> { `build/zerotier-sdk-service` + `build/libztintercept.so` } + - [Intercept library](../docs/osx_zt_sdk.md) `make osx_sdk_service` -> `build/zerotier-sdk-service` + - [SDK Service](../docs/osx_zt_sdk.md) `make osx_intercept` -> `build/libztintercept.so` + - [Unity3D plugin](apple/ZeroTierSDK_Apple) `make osx_unity3d_bundle` + +*** +### Linux + - For everything: `make linux` + - [Dynamic-linking into an app/service at runtime](../docs/linux_zt_sdk.md) `make linux_shared_lib` + - Service and Intercept `make linux_service_and_intercept` -> { `build/zerotier-sdk-service` + `build/libztintercept.so` } + - [Using the SDK with Docker](docker) + +### Android + - For everything: `make android` + + - [Embedding within an app](android) `make android_jni_lib` -> `build/android_jni_lib/YOUR_ARCH/libZeroTierOneJNI.so` + - [Unity 3D plugin](../docs/android_unity3d_zt_sdk.md) `make android_unity3d_plugin` -> `build/android_unity3d_plugin/*` + +*** +### Windows + - Not yet. + + *** ![Image](docs/img/api_diagram.png) diff --git a/docs/zt_sdk_primer.md b/docs/zt_sdk_primer.md index 2b6de85..0fa1700 100644 --- a/docs/zt_sdk_primer.md +++ b/docs/zt_sdk_primer.md @@ -51,7 +51,7 @@ From your application's perspective nothing out of the ordinary has happened. It - **What would happen if you performed a `getsockopt()` for the family/domain of an `AF_INET` socket you requested?** - You'd expect this should return `AF_LOCAL` since we repurposed the unix-domain socket, right? Nope. We've got a special implementation of `getsockopt()` which will detect whether that socket is handled under the ZeroTier tap service and if it is, it'll lie to you about the socket domain/family and report `AF_INET`. -We've got a [special implementation](../src/SDK_Sockets.c) for most of the socket API functions: `zt_setsockopt(), zt_getsockopt(),zt_socket(),zt_connect(),zt_bind(),zt_accept4(),zt_accept(),zt_listen(),zt_close(), +We've got a [special implementation](../src/sockets.c) for most of the socket API functions: `zt_setsockopt(), zt_getsockopt(),zt_socket(),zt_connect(),zt_bind(),zt_accept4(),zt_accept(),zt_listen(),zt_close(), zt_getsockname()`. Each type of API is implemented in terms of this set of core functions and has the ability to determine whether the call should be directed to the system or the ZeroTier tap service. ## Embedded Applications / IoT diff --git a/ext/lwip/src/core/ipv4/ip4.c b/ext/lwip/src/core/ipv4/ip4.c index 1bdc30f..ed2cf20 100644 --- a/ext/lwip/src/core/ipv4/ip4.c +++ b/ext/lwip/src/core/ipv4/ip4.c @@ -1031,40 +1031,42 @@ ip4_output_hinted(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, void ip4_debug_print(struct pbuf *p) { - struct ip_hdr *iphdr = (struct ip_hdr *)p->payload; + #if defined(LWIP_DEBUG) + struct ip_hdr *iphdr = (struct ip_hdr *)p->payload; - LWIP_DEBUGF(IP_DEBUG, ("IP header:\n")); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" | 0x%02"X16_F" | %5"U16_F" | (v, hl, tos, len)\n", - (u16_t)IPH_V(iphdr), - (u16_t)IPH_HL(iphdr), - (u16_t)IPH_TOS(iphdr), - ntohs(IPH_LEN(iphdr)))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n", - ntohs(IPH_ID(iphdr)), - (u16_t)(ntohs(IPH_OFFSET(iphdr)) >> 15 & 1), - (u16_t)(ntohs(IPH_OFFSET(iphdr)) >> 14 & 1), - (u16_t)(ntohs(IPH_OFFSET(iphdr)) >> 13 & 1), - (u16_t)(ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n", - (u16_t)IPH_TTL(iphdr), - (u16_t)IPH_PROTO(iphdr), - ntohs(IPH_CHKSUM(iphdr)))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n", - ip4_addr1_16(&iphdr->src), - ip4_addr2_16(&iphdr->src), - ip4_addr3_16(&iphdr->src), - ip4_addr4_16(&iphdr->src))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (dest)\n", - ip4_addr1_16(&iphdr->dest), - ip4_addr2_16(&iphdr->dest), - ip4_addr3_16(&iphdr->dest), - ip4_addr4_16(&iphdr->dest))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("IP header:\n")); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" | 0x%02"X16_F" | %5"U16_F" | (v, hl, tos, len)\n", + (u16_t)IPH_V(iphdr), + (u16_t)IPH_HL(iphdr), + (u16_t)IPH_TOS(iphdr), + ntohs(IPH_LEN(iphdr)))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n", + ntohs(IPH_ID(iphdr)), + (u16_t)(ntohs(IPH_OFFSET(iphdr)) >> 15 & 1), + (u16_t)(ntohs(IPH_OFFSET(iphdr)) >> 14 & 1), + (u16_t)(ntohs(IPH_OFFSET(iphdr)) >> 13 & 1), + (u16_t)(ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n", + (u16_t)IPH_TTL(iphdr), + (u16_t)IPH_PROTO(iphdr), + ntohs(IPH_CHKSUM(iphdr)))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n", + ip4_addr1_16(&iphdr->src), + ip4_addr2_16(&iphdr->src), + ip4_addr3_16(&iphdr->src), + ip4_addr4_16(&iphdr->src))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (dest)\n", + ip4_addr1_16(&iphdr->dest), + ip4_addr2_16(&iphdr->dest), + ip4_addr3_16(&iphdr->dest), + ip4_addr4_16(&iphdr->dest))); + LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); + #endif } #endif /* IP_DEBUG */ diff --git a/integrations/README.md b/integrations/README.md index db50c12..0e4d3bf 100644 --- a/integrations/README.md +++ b/integrations/README.md @@ -12,20 +12,20 @@ Below are the specific instructions for each integration requiring *little to no For more support on these integrations, or if you'd like help creating a new integration, stop by our [community section](https://www.zerotier.com/community/)! *** -## Important Build flags +## Important Build Flags -- `SDK_IPV4=1` - Enable IPv4 support in whatever stack you have selected -- `SDK_IPV6=1` - Enable IPv6 support in whatever stack you have selected +- `SDK_IPV4=1` - Enable IPv4 support +- `SDK_IPV6=1` - Enable IPv6 support -- `SDK_LWIP=1` - Enable the use of `lwIP` -- `SDK_PICOTCP=1` - Enable the use of `picoTCP` +- `SDK_DEBUG=1` - Enables SDK debugging -- `SDK_DEBUG=1` - Turns on SDK activity/warning/error output. Levels of verbosity can be adjusted in `src/SDK_Debug.h` -- `SDK_LWIP_DEBUG=1` - Turns on debug output for the `lwIP` library. -- `SDK_BUNDLED=1` - Builds the SDK as a single bundled target including a the RPC mechanism, the `lwIP` library, and the ZeroTier service. +- `SDK_PICOTCP=1` - Enable the use of `picoTCP` (recommended) +- `SDK_PICO_DEBUG=1` - Enables debug output for the `picoTCP` network stack + +- `SDK_LWIP=1` - Enable the use of `lwIP` (deprecated) +- `SDK_LWIP_DEBUG=1` - Enables debug output for the `lwIP` library. *** -## Current Integrations ### Apple - For everything: `make apple` @@ -40,11 +40,13 @@ For more support on these integrations, or if you'd like help creating a new int - [Dynamic-linking into an app/service at runtime](../docs/osx_zt_sdk.md) `make osx_service_and_intercept` -> { `build/zerotier-sdk-service` + `build/libztintercept.so` } - [Intercept library](../docs/osx_zt_sdk.md) `make osx_sdk_service` -> `build/zerotier-sdk-service` - [SDK Service](../docs/osx_zt_sdk.md) `make osx_intercept` -> `build/libztintercept.so` - - [Unity3D plugin](apple/ZeroTierSDK_Apple) `make osx_unity3d_bundle` -> + - [Unity3D plugin](apple/ZeroTierSDK_Apple) `make osx_unity3d_bundle` *** ### Linux + - For everything: `make linux` - [Dynamic-linking into an app/service at runtime](../docs/linux_zt_sdk.md) `make linux_shared_lib` + - Service and Intercept `make linux_service_and_intercept` -> { `build/zerotier-sdk-service` + `build/libztintercept.so` } - [Using the SDK with Docker](docker) ### Android diff --git a/integrations/android/README.md b/integrations/android/README.md index b615abe..229e587 100644 --- a/integrations/android/README.md +++ b/integrations/android/README.md @@ -12,7 +12,7 @@ If you want to skip the following steps and just take a look at the project, go *** **Step 1: App Code Modifications** - - In your project, create a new package called `ZeroTier` and class file within called `ZTSDK.java` and copy contents from `src/SDK_JavaWrapper.java` + - In your project, create a new package called `ZeroTier` and class file within called `ZTSDK.java` and copy contents from `src/wrappers/java/JavaWrapper.java` - Start the service diff --git a/integrations/apple/example_app/OSX/README.md b/integrations/apple/example_app/OSX/README.md index 2524f1e..0aecfbc 100644 --- a/integrations/apple/example_app/OSX/README.md +++ b/integrations/apple/example_app/OSX/README.md @@ -36,6 +36,11 @@ Run application ./app +## Via `DYLD_LIBRARY_PATH` (Injecting code dynamically at runtime) + +As of the release of El Capitan, Apple requires one to turn off System Integrity Protection for code injection from external libraries. This method of intercepting network calls is now deprecated and we are investigating new methods for future releases of the SDK. If you still wish to use this method just `export DYLD_LIBRARY_PATH=./path/to/libztintercept.so:$DYLD_LIBRARY_PATH`. Also set `ZT_NC_NETWORK` appropriately. + + ## Via App Framework in XCode *** @@ -50,8 +55,8 @@ Run application - Add `src` directory to *Build Settings -> Header Search Paths* - Add `build/osx_app_framework/Release/` to *Build Settings -> Framework Search Paths* - Add `ZeroTierSDK.frameworkOSX` to *General->Embedded Binaries* -- Add `src/ZTSDK.swift`, `src/SDK_XcodeWrapper.cpp`, and `src/SDK_XcodeWrapper.hpp` to your project: -- Set `src/SDK_Apple-Bridging-Header.h` as your bridging-header in *Build Settings -> Objective-C Bridging-header* +- Add `src/wrappers/swift/ZTSDK.swift`, `src/wrappers/swift/XcodeWrapper.cpp`, and `src/wrappers/swift/XcodeWrapper.hpp` to your project: +- Set `src/wrappers/swift/Apple-Bridging-Header.h` as your bridging-header in *Build Settings -> Objective-C Bridging-header* **Step 3: Start the ZeroTier service** diff --git a/integrations/apple/example_app/iOS/README.md b/integrations/apple/example_app/iOS/README.md index 4fc1dad..968008f 100644 --- a/integrations/apple/example_app/iOS/README.md +++ b/integrations/apple/example_app/iOS/README.md @@ -19,8 +19,8 @@ This short tutorial will show you how to enable ZeroTier functionality for your - Add `src` directory to *Build Settings -> Header Search Paths* - Add `build/ios_app_framework/Release-iphoneos/` to *Build Settings -> Framework Search Paths* - Add `ZeroTierSDK.frameworkiOS` to *General->Embedded Binaries* -- Add `src/ZTSDK.swift`, `src/SDK_XcodeWrapper.cpp` and `src/SDK_XcodeWrapper.hpp` to your project: -- Set `src/SDK_Apple-Bridging-Header.h` as your bridging-header in *Build Settings -> Objective-C Bridging-header* +- Add `src/wrappers/swift/ZTSDK.swift`, `src/wrappers/swift/XcodeWrapper.cpp` and `src/wrappers/swift/XcodeWrapper.hpp` to your project: +- Set `src/wrappers/swift/Apple-Bridging-Header.h` as your bridging-header in *Build Settings -> Objective-C Bridging-header* **Step 3: Start the ZeroTier service** diff --git a/make-mac.mk b/make-mac.mk index f45e50f..1e9feeb 100644 --- a/make-mac.mk +++ b/make-mac.mk @@ -78,7 +78,7 @@ else endif # Debug output for the SDK -# Specific levels can be controlled in src/SDK_Debug.h +# Specific levels can be controlled in src/debug.h ifeq ($(SDK_DEBUG),1) DEFS+=-DSDK_DEBUG -g endif @@ -164,6 +164,7 @@ jip: # Build all Apple targets apple: one osx ios + # Build vanilla ZeroTier One binary one: $(OBJS) $(ZT1)/service/OneService.o $(ZT1)/one.o $(ZT1)/osdep/OSXEthernetTap.o mkdir -p $(BUILD) @@ -174,9 +175,11 @@ one: $(OBJS) $(ZT1)/service/OneService.o $(ZT1)/one.o $(ZT1)/osdep/OSXEthernetTa # Build all iOS targets ios: ios_app_framework ios_unity3d_bundle + # Build all OSX targets osx: osx_app_framework osx_unity3d_bundle osx_shared_lib osx_sdk_service osx_intercept + # TODO: CHECK if XCODE TOOLS are installed # Build frameworks for application development osx_app_framework: @@ -188,6 +191,7 @@ ios_app_framework: cd $(INT)/apple/ZeroTierSDK_Apple; xcodebuild -configuration Debug -scheme ZeroTierSDK_iOS build SYMROOT="../../../$(BUILD)/ios_app_framework" cp docs/ios_zt_sdk.md $(BUILD)/ios_app_framework/README.md + # Build bundles for Unity integrations osx_unity3d_bundle: cd $(INT)/apple/ZeroTierSDK_Apple; xcodebuild -configuration Release -scheme ZeroTierSDK_Unity3D_OSX build SYMROOT="../../../$(BUILD)/osx_unity3d_bundle" @@ -196,10 +200,12 @@ osx_unity3d_bundle: chmod 755 $(BUILD)/osx_unity3d_bundle/Debug/ZeroTierSDK_Unity3D_OSX.bundle cp -p -R $(BUILD)/osx_unity3d_bundle/Debug/ZeroTierSDK_Unity3D_OSX.bundle $(INT)/Unity3D/Assets/Plugins + ios_unity3d_bundle: cd $(INT)/apple/ZeroTierSDK_Apple; xcodebuild -configuration Release -scheme ZeroTierSDK_Unity3D_iOS build SYMROOT="../../../$(BUILD)/ios_unity3d_bundle" cd $(INT)/apple/ZeroTierSDK_Apple; xcodebuild -configuration Debug -scheme ZeroTierSDK_Unity3D_iOS build SYMROOT="../../../$(BUILD)/ios_unity3d_bundle" cp docs/ios_unity3d_zt_sdk.md $(BUILD)/ios_unity3d_bundle/README.md + # simple_app: tests osx_service_and_intercept mkdir -p build/simple_app @@ -207,17 +213,25 @@ simple_app: tests osx_service_and_intercept $(CXX) -Isrc $(SHARED_LIB) integrations/simple_app/app.cpp -o $(BUILD)/simple_app/app cp $(LWIP_LIB) $(BUILD)/tests/zerotier/$(LWIP_LIB_NAME) + remove_only_intermediates: -find . -type f \( -name '*.o' -o -name '*.so' \) -delete + # Builds a single shared library which contains everything -osx_shared_lib: $(OBJS) - $(CXX) $(CXXFLAGS) $(LDFLAGS) -DSDK -DZT_ONE_NO_ROOT_CHECK $(INCLUDES) -shared -o $(SHARED_LIB) $(OBJS) zerotierone/service/OneService.cpp src/SDK_Service.cpp src/SDK_EthernetTap.cpp src/SDK_Proxy.cpp zerotierone/one.cpp -x c src/SDK_Sockets.c src/SDK_Intercept.c src/SDK_RPC.c $(LDLIBS) -ldl +ifeq ($(SDK_LWIP),1) +osx_shared_lib: lwip $(OBJS) + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(STACK_FLAGS) -DSDK -DZT_ONE_NO_ROOT_CHECK $(INCLUDES) -DSDK_INTERCEPT -shared -o $(SHARED_LIB) $(OBJS) $(LWIP_DRIVER_FILES) $(SDK_SERVICE_CPP_FILES) $(SDK_SERVICE_C_FILES) $(LDLIBS) -ldl +else +osx_shared_lib: pico $(OBJS) + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(STACK_FLAGS) -DSDK -DZT_ONE_NO_ROOT_CHECK $(INCLUDES) -shared -o $(SHARED_LIB) $(OBJS) $(PICO_DRIVER_FILES) $(SDK_SERVICE_CPP_FILES) $(SDK_SERVICE_C_FILES) $(LDLIBS) -ldl +endif osx_intercept: # Use gcc not clang to build standalone intercept library since gcc is typically used for libc and we want to ensure maximal ABI compatibility cd src ; gcc $(DEFS) $(INCLUDES) -g -O2 -Wall -std=c99 -fPIC -DVERBOSE -D_GNU_SOURCE -DSDK_INTERCEPT -nostdlib -nostdlib -shared -o ../$(INTERCEPT) $(SDK_INTERCEPT_C_FILES) -ldl + # Build only the SDK service ifeq ($(SDK_LWIP),1) osx_sdk_service: lwip $(OBJS) @@ -229,6 +243,7 @@ endif ln -sf $(SDK_SERVICE_NAME) $(BUILD)/zerotier-cli ln -sf $(SDK_SERVICE_NAME) $(BUILD)/zerotier-idtool + # Build both intercept library and SDK service (separate) osx_service_and_intercept: osx_intercept osx_sdk_service @@ -328,8 +343,8 @@ prep: # Copy and rename source files into example projects to follow local ordinances update_examples: - cp src/SDK_DotNetWrapper.cs integrations/Unity3D/Assets/ZTSDK.cs - cp src/SDK_JavaWrapper.java integrations/android/example_app/app/src/main/java/ZeroTier/ZTSDK.java + cp src/wrappers/dotnet/DotNetWrapper.cs integrations/Unity3D/Assets/ZTSDK.cs + cp src/wrappers/java/JavaWrapper.java integrations/android/example_app/app/src/main/java/ZeroTier/ZTSDK.java # For authors # Copies documentation to all of the relevant directories to make viewing in the repo a little easier diff --git a/src/intercept.c b/src/intercept.c index d570b25..1e6aead 100644 --- a/src/intercept.c +++ b/src/intercept.c @@ -59,7 +59,6 @@ #include "rpc.h" pthread_key_t thr_id_key; -//char *api_netpath; // externs common between SDK_Intercept and SDK_Socket from SDK.h #if defined(__linux__) @@ -321,10 +320,12 @@ pthread_key_t thr_id_key; return realconnect(fd, addr, addrlen); // Check that this is a valid fd + /* if(fcntl(fd, F_GETFD) < 0) { errno = EBADF; return -1; } + */ // Check that it is a socket int sock_type; socklen_t sock_type_len = sizeof(sock_type); @@ -402,10 +403,12 @@ pthread_key_t thr_id_key; return realbind(fd, addr, addrlen); // Check that this is a valid fd + /* if(fcntl(fd, F_GETFD) < 0) { errno = EBADF; return -1; } + */ // Check that it is a socket int opt = -1; socklen_t opt_len; @@ -445,20 +448,19 @@ pthread_key_t thr_id_key; DEBUG_ERROR("EBADF"); return -1; } - // Check that it is a socket + /* int opt; socklen_t opt_len; if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *) &opt, &opt_len) < 0) { errno = ENOTSOCK; - DEBUG_ERROR("ENOTSOCK"); return -1; } // Check that this socket supports accept() - if(!(opt && (SOCK_STREAM | SOCK_SEQPACKET))) { + if((opt != SOCK_STREAM) && (opt != SOCK_SEQPACKET)) { errno = EOPNOTSUPP; - DEBUG_ERROR("EOPNOTSUPP"); return -1; } + */ // Check that we haven't hit the soft-limit file descriptors allowed struct rlimit rl; getrlimit(RLIMIT_NOFILE, &rl); @@ -490,33 +492,11 @@ pthread_key_t thr_id_key; int listen(LISTEN_SIG) { DEBUG_ATTN("fd=%d", fd); - if (!check_intercept_enabled()) + if (!check_intercept_enabled() || !connected_to_service(fd)) return reallisten(fd, backlog); - - int sock_type; - socklen_t sock_type_len = sizeof(sock_type); - // Check that this is a valid fd - if(fcntl(fd, F_GETFD) < 0) { - errno = EBADF; - return -1; - } - // Check that it is a socket - if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &sock_type_len) < 0) { - errno = ENOTSOCK; - return -1; - } - // Check that this socket supports accept() - if(!(sock_type && (SOCK_STREAM | SOCK_SEQPACKET))) { - errno = EOPNOTSUPP; - return -1; - } // make sure we don't touch any standard outputs if(fd == 0 || fd == 1 || fd == 2) return reallisten(fd, backlog); - - if(!connected_to_service(fd)) { - return reallisten(fd, backlog); - } return zts_listen(fd, backlog); } @@ -526,10 +506,9 @@ pthread_key_t thr_id_key; // int fd int close(CLOSE_SIG) { - DEBUG_INFO("fd=%d", fd); - if(!check_intercept_enabled()) { + DEBUG_EXTRA("fd=%d", fd); + if(!check_intercept_enabled()) return realclose(fd); - } return zts_close(fd); } diff --git a/src/proxy.cpp b/src/proxy.cpp index b2ec026..31793bf 100644 --- a/src/proxy.cpp +++ b/src/proxy.cpp @@ -106,7 +106,7 @@ namespace ZeroTier struct sockaddr_in *in4 = (struct sockaddr_in *)&addr; proxyListenPhySocket = _phy.tcpListen((const struct sockaddr*)&in4,(void *)this); sockstate = SOCKS_OPEN; - DEBUG_INFO("SOCKS5 proxy server address for <%.16llx> is: <%s> (sock=%p)", nwid, inet_ntoa(in4->sin_addr), /*ntohs(in4->sin_port), */(void*)&proxyListenPhySocket); + // DEBUG_INFO("SOCKS5 proxy server address for <%.16llx> is: <%s> (sock=%p)", nwid, inet_ntoa(in4->sin_addr), /*ntohs(in4->sin_port), */(void*)&proxyListenPhySocket); return 0; } else { @@ -126,7 +126,7 @@ namespace ZeroTier unsigned int randp = 0; Utils::getSecureRandom(&randp,sizeof(randp)); portno = 1000 + (randp % 1000); - DEBUG_INFO("no port specified in networks.d/%.16llx.port, randomly picking port", nwid); + // DEBUG_INFO("no port specified in networks.d/%.16llx.port, randomly picking port", nwid); std::stringstream ss; ss << portno; portStr = ss.str(); diff --git a/src/sockets.c b/src/sockets.c index b121162..09c9aed 100644 --- a/src/sockets.c +++ b/src/sockets.c @@ -286,7 +286,8 @@ int (*realclose)(CLOSE_SIG); // DEBUG_EXTRA("zt_recvfrom(%d, ...)\n", fd); if(read(fd, buf, ZT_MAX_MTU) > 0) { // TODO: case for address size mismatch? - memcpy(addr, buf, addrlen); + memcpy(addr, buf, *addrlen); + DEBUG_ERROR("addrlen = %d", *addrlen); memcpy(&tmpsz, buf + sizeof(struct sockaddr_storage), sizeof(tmpsz)); } else { @@ -608,8 +609,8 @@ int (*realclose)(CLOSE_SIG); if ((flags & SOCK_NONBLOCK)) fcntl(fd, F_SETFL, O_NONBLOCK); #endif - int len = !addr ? 0 : addrlen; - return accept(fd, addr, len); + addrlen = !addr ? 0 : addrlen; + return accept(fd, addr, addrlen); } #endif @@ -763,7 +764,7 @@ int (*realclose)(CLOSE_SIG); } struct sockaddr_storage sock_storage; memcpy(&sock_storage, addrbuf, sizeof(struct sockaddr)); - addrlen = sizeof(struct sockaddr_in); + *addrlen = sizeof(struct sockaddr_in); memcpy(addr, &sock_storage, sizeof(struct sockaddr)); addr->sa_family = AF_INET; return 0; @@ -826,7 +827,7 @@ int (*realclose)(CLOSE_SIG); } struct sockaddr_storage sock_storage; memcpy(&sock_storage, addrbuf, sizeof(struct sockaddr)); - addrlen = sizeof(struct sockaddr_in); + *addrlen = sizeof(struct sockaddr_in); memcpy(addr, &sock_storage, sizeof(struct sockaddr)); addr->sa_family = AF_INET; return 0; diff --git a/src/stack_drivers/picotcp/picotcp.cpp b/src/stack_drivers/picotcp/picotcp.cpp index bf4e4ad..d471cf4 100644 --- a/src/stack_drivers/picotcp/picotcp.cpp +++ b/src/stack_drivers/picotcp/picotcp.cpp @@ -37,6 +37,20 @@ #include "pico_protocol.h" #include "pico_socket.h" +/* +static inline uint32_t long_be2(uint32_t le) +{ + uint8_t *b = (uint8_t *)≤ + uint32_t be = 0; + uint32_t b0, b1, b2; + b0 = b[0]; + b1 = b[1]; + b2 = b[2]; + be = b[3] + (b2 << 8) + (b1 << 16) + (b0 << 24); + return be; +} +*/ + namespace ZeroTier { // Reference to the tap interface @@ -118,27 +132,42 @@ namespace ZeroTier { } // RX packets from network onto internal buffer - // Also notifies the tap service that data can be read, buffer will be emptied by pico_handleRead() + // Also notifies the tap service that data can be read + // ----------------------------------------- + // | TAP <-> MEM BUFFER <-> STACK <-> APP | + // | | + // | APP <-> I/O BUFFER <-> STACK <-> TAP | + // | |<-----------------| | RX + // ----------------------------------------- + // After this step, buffer will be emptied periodically by pico_handleRead() void pico_cb_tcp_read(NetconEthernetTap *tap, struct pico_socket *s) { // TODO: Verify DEBUG_INFO(); Connection *conn = tap->getConnection(s); if(conn) { - int r; + int r; + uint16_t port = 0; + union { + struct pico_ip4 ip4; + struct pico_ip6 ip6; + } peer; + do { - //int avail = DEFAULT_TCP_RX_BUF_SZ - conn->rxsz; - //if(avail) { - r = tap->picostack->__pico_socket_read(s, conn->rxbuf + (conn->rxsz), ZT_MAX_MTU); + int avail = DEFAULT_TCP_RX_BUF_SZ - conn->rxsz; + if(avail) { + // r = tap->picostack->__pico_socket_read(s, conn->rxbuf + (conn->rxsz), ZT_MAX_MTU); + r = tap->picostack->__pico_socket_recvfrom(s, conn->rxbuf + (conn->rxsz), ZT_MAX_MTU, (void *)&peer.ip4.addr, &port); + // DEBUG_ATTN("received packet (%d byte) from %08X:%u", r, long_be2(peer.ip4.addr), short_be(port)); tap->_phy.setNotifyWritable(conn->sock, true); DEBUG_INFO("read=%d", r); - if (r > 0) { + if (r > 0) conn->rxsz += r; - } - //} - if (r < 0) { - exit(5); - } + else + DEBUG_ERROR("error while reading from pico_socket(%p)", s); + } + else + DEBUG_ERROR("not enough space left on I/O RX buffer for pico_socket(%p)", s); } while(r > 0); return; @@ -193,7 +222,7 @@ namespace ZeroTier { uint16_t port; struct pico_socket *client = picotap->picostack->__pico_socket_accept(s, &peer, &port); if(!client) { - DEBUG_ERROR("there was an error accepting the connection, sock=%p", (void*)(conn->picosock)); + DEBUG_EXTRA("unable to accept conn. (event might not be incoming, not necessarily an error), sock=%p", (void*)(conn->picosock)); } ZT_PHY_SOCKFD_TYPE fds[2]; @@ -250,8 +279,14 @@ namespace ZeroTier { } */ - // Sends data to the tap device (in our case, the ZeroTier service) - int pico_eth_send(struct pico_device *dev, void *buf, int len) + // Called from the stack, sends data to the tap device (in our case, the ZeroTier service) + // ----------------------------------------- + // | TAP <-> MEM BUFFER <-> STACK <-> APP | + // | |<-------------------------| | TX + // | APP <-> I/O BUFFER <-> STACK <-> TAP | + // | | + // ----------------------------------------- + int pico_eth_send(struct pico_device *dev, void *buf, int len) { DEBUG_INFO("len=%d", len); struct eth_hdr *ethhdr; @@ -268,6 +303,13 @@ namespace ZeroTier { } // Receives data from the tap device and encapsulates it into a ZeroTier ethernet frame and places it in a locked memory buffer + // ----------------------------------------- + // | TAP <-> MEM BUFFER <-> STACK <-> APP | + // | |--------------->| | RX + // | APP <-> I/O BUFFER <-> STACK <-> TAP | + // | | + // ----------------------------------------- + // It will then periodically be transfered into the network stack via pico_eth_poll() void pico_rx(NetconEthernetTap *tap, const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) { // DEBUG_INFO(); @@ -298,8 +340,14 @@ namespace ZeroTier { DEBUG_INFO("len=%d", len); } - // Is called periodically by the stack, this removes data from the locked memory buffer and feeds it into the stack. + // Called periodically by the stack, this removes data from the locked memory buffer and feeds it into the stack. // A maximum of 'loop_score' frames can be processed in each call + // ----------------------------------------- + // | TAP <-> MEM BUFFER <-> STACK <-> APP | + // | |----------------->| | RX + // | APP <-> I/O BUFFER <-> STACK <-> TAP | + // | | + // ----------------------------------------- int pico_eth_poll(struct pico_device *dev, int loop_score) { // DEBUG_EXTRA(); @@ -352,6 +400,12 @@ namespace ZeroTier { } // Writes data from the I/O buffer to the network stack + // ----------------------------------------- + // | TAP <-> MEM BUFFER <-> STACK <-> APP | + // | | + // | APP <-> I/O BUFFER <-> STACK <-> TAP | + // | |----------------->| | TX + // ----------------------------------------- void pico_handleWrite(Connection *conn) { DEBUG_INFO(); @@ -359,11 +413,13 @@ namespace ZeroTier { DEBUG_ERROR(" invalid connection"); return; } + int r, max_write_len = conn->txsz < ZT_MAX_MTU ? conn->txsz : ZT_MAX_MTU; if((r = picotap->picostack->__pico_socket_write(conn->picosock, &conn->txbuf, max_write_len)) < 0) { - DEBUG_ERROR("unable to write to pico_socket(%p)", (void*)&(conn->picosock)); + DEBUG_ERROR("unable to write to pico_socket(%p), r=%d", (void*)&(conn->picosock), r); return; } + /* if(pico_err == PICO_ERR_EINVAL) DEBUG_ERROR("PICO_ERR_EINVAL - invalid argument"); @@ -418,6 +474,8 @@ namespace ZeroTier { ret = picotap->picostack->__pico_socket_connect(conn->picosock, &zaddr, addr->sin_port); #endif + memcpy(&(conn->peer_addr), &connect_rpc->addr, sizeof(struct sockaddr_storage)); + if(ret == PICO_ERR_EPROTONOSUPPORT) { DEBUG_ERROR("PICO_ERR_EPROTONOSUPPORT"); } @@ -502,7 +560,13 @@ namespace ZeroTier { picotap->sendReturnValue(picotap->_phy.getDescriptor(rpcSock), ERR_OK, ERR_OK); // success } - // Feeds data into the client socket from the I/O buffer associated with the connection + // Feeds data into the local app socket from the I/O buffer associated with the "connection" + // ----------------------------------------- + // | TAP <-> MEM BUFFER <-> STACK <-> APP | + // | | + // | APP <-> I/O BUFFER <-> STACK <-> TAP | + // | |<---------------| | RX + // ----------------------------------------- void pico_handleRead(PhySocket *sock,void **uptr,bool lwip_invoked) { // DEBUG_INFO(); diff --git a/src/stack_drivers/picotcp/picotcp.hpp b/src/stack_drivers/picotcp/picotcp.hpp index 56225bd..9c7aad1 100644 --- a/src/stack_drivers/picotcp/picotcp.hpp +++ b/src/stack_drivers/picotcp/picotcp.hpp @@ -67,6 +67,7 @@ #define PICO_SOCKET_SEND_SIG struct pico_socket *s, const void *buf, int len #define PICO_SOCKET_SENDTO_SIG struct pico_socket *s, const void *buf, int len, void *dst, uint16_t remote_port #define PICO_SOCKET_RECV_SIG struct pico_socket *s, void *buf, int len +#define PICO_SOCKET_RECVFROM_SIG struct pico_socket *s, void *buf, int len, void *orig, uint16_t *remote_port #define PICO_SOCKET_OPEN_SIG uint16_t net, uint16_t proto, void (*wakeup)(uint16_t ev, struct pico_socket *s) #define PICO_SOCKET_BIND_SIG struct pico_socket *s, void *local_addr, uint16_t *port #define PICO_SOCKET_CONNECT_SIG struct pico_socket *s, const void *srv_addr, uint16_t remote_port @@ -77,6 +78,8 @@ #define PICO_SOCKET_SHUTDOWN_SIG struct pico_socket *s, int mode #define PICO_SOCKET_ACCEPT_SIG struct pico_socket *s, void *orig, uint16_t *port #define PICO_IPV6_LINK_ADD_SIG struct pico_device *dev, struct pico_ip6 address, struct pico_ip6 netmask +//#define PICO_IPV6_SOURCE_FIND_SIG strut pico_ip6 *dst + namespace ZeroTier { @@ -90,7 +93,14 @@ namespace ZeroTier { void pico_loop(NetconEthernetTap *tap); void pico_cb_tcp_read(NetconEthernetTap *tap, struct pico_socket *s); void pico_cb_tcp_write(NetconEthernetTap *tap, struct pico_socket *s); - void pico_cb_tcp(uint16_t ev, struct pico_socket *s); + void pico_cb_socket_activity(uint16_t ev, struct pico_socket *s); + + /* + void pico_cb_udp(uint16_t ev, struct pico_socket *s); + void pico_cb_udp_write(NetconEthernetTap *tap, struct pico_socket *s); + void pico_cb_udp_read(NetconEthernetTap *tap, struct pico_socket *s); + */ + int pico_eth_send(struct pico_device *dev, void *buf, int len); void pico_rx(NetconEthernetTap *tap, const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len); int pico_eth_poll(struct pico_device *dev, int loop_score); @@ -124,8 +134,6 @@ namespace ZeroTier { #endif } - // SIP- - void (*_pico_stack_init)(void); void (*_pico_stack_tick)(void); int (*_pico_string_to_ipv4)(PICO_STRING_TO_IPV4_SIG); @@ -139,7 +147,9 @@ namespace ZeroTier { int (*_pico_socket_setoption)(PICO_SOCKET_SETOPTION_SIG); uint32_t (*_pico_timer_add)(PICO_TIMER_ADD_SIG); int (*_pico_socket_send)(PICO_SOCKET_SEND_SIG); + int (*_pico_socket_sendto)(PICO_SOCKET_SENDTO_SIG); int (*_pico_socket_recv)(PICO_SOCKET_RECV_SIG); + int (*_pico_socket_recvfrom)(PICO_SOCKET_RECVFROM_SIG); struct pico_socket * (*_pico_socket_open)(PICO_SOCKET_OPEN_SIG); int (*_pico_socket_bind)(PICO_SOCKET_BIND_SIG); int (*_pico_socket_connect)(PICO_SOCKET_CONNECT_SIG); @@ -150,7 +160,7 @@ namespace ZeroTier { int (*_pico_socket_shutdown)(PICO_SOCKET_SHUTDOWN_SIG); struct pico_socket *(*_pico_socket_accept)(PICO_SOCKET_ACCEPT_SIG); int (*_pico_ipv6_link_add)(PICO_IPV6_LINK_ADD_SIG); - //pico_err_t (*_get_pico_err)(void); + //struct pico_ip6 *(*pico_ipv6_source_find)(PICO_IPV6_SOURCE_FIND_SIG); Mutex _lock; Mutex _lock_mem; @@ -182,7 +192,6 @@ namespace ZeroTier { #ifdef __STATIC_LWIP__ // Set static references (for use in iOS) - // SIP- _pico_stack_init = (void(*)(void))&pico_stack_init; _pico_stack_tick = (void(*)(void))&pico_stack_tick; _pico_tap_create = (struct pico_device*(*)(PICO_TAP_CREATE_SIG))&pico_tap_create; @@ -196,7 +205,9 @@ namespace ZeroTier { _pico_socket_setoption = (int(*)(PICO_SOCKET_SETOPTION_SIG))&pico_socket_setoption; _pico_timer_add = (uint32_t(*)(PICO_TIMER_ADD_SIG))&pico_timer_add; _pico_socket_send = (int(*)(PICO_SOCKET_SEND_SIG))&pico_socket_send; + _pico_socket_sendto = (int(*)(PICO_SOCKET_SENDTO_SIG))&pico_socket_sendto; _pico_socket_recv = (int(*)(PICO_SOCKET_RECV_SIG))&pico_socket_recv; + _pico_socket_recvfrom = (int32_t(*)(PICO_SOCKET_RECVFROM_SIG))&pico_socket_recvfrom; _pico_socket_open = (struct pico_socket*(*)(PICO_SOCKET_OPEN_SIG))&pico_socket_open; _pico_socket_bind = (int(*)(PICO_SOCKET_BIND_SIG))&pico_socket_bind; _pico_socket_connect = (int(*)(PICO_SOCKET_CONNECT_SIG))&pico_socket_connect; @@ -207,7 +218,7 @@ namespace ZeroTier { _pico_socket_shutdown = (int(*)(PICO_SOCKET_SHUTDOWN_SIG))&pico_socket_shutdown; _pico_socket_accept = (struct pico_socket*(*)(PICO_SOCKET_ACCEPT_SIG))&pico_socket_accept; _pico_ipv6_link_add = (int(*)(PICO_IPV6_LINK_ADD_SIG))&pico_ipv6_link_add; - //_get_pico_err = (pico_err_t(*)())&get_pico_err; + //_pico_ipv6_source_find = (struct pico_ip6 *(*))(PICO_IPV6_SOURCE_FIND_SIG))&pico_ipv6_source_find; #endif @@ -216,7 +227,6 @@ namespace ZeroTier { if(_libref == NULL) DEBUG_ERROR("dlerror(): %s", dlerror()); - // SIP- _pico_stack_init = (void(*)(void))dlsym(_libref, "pico_stack_init"); _pico_stack_tick = (void(*)(void))dlsym(_libref, "pico_stack_tick"); _pico_tap_create = (struct pico_device*(*)(PICO_TAP_CREATE_SIG))dlsym(_libref, "pico_tap_create"); @@ -230,7 +240,9 @@ namespace ZeroTier { _pico_socket_setoption = (int(*)(PICO_SOCKET_SETOPTION_SIG))dlsym(_libref, "pico_socket_setoption"); _pico_timer_add = (uint32_t(*)(PICO_TIMER_ADD_SIG))dlsym(_libref, "pico_timer_add"); _pico_socket_send = (int(*)(PICO_SOCKET_SEND_SIG))dlsym(_libref, "pico_socket_send"); + _pico_socket_sendto = (int(*)(PICO_SOCKET_SENDTO_SIG))dlsym(_libref, "pico_socket_sendto"); _pico_socket_recv = (int(*)(PICO_SOCKET_RECV_SIG))dlsym(_libref, "pico_socket_recv"); + _pico_socket_recvfrom = (int32_t(*)(PICO_SOCKET_RECVFROM_SIG))dlsym(_libref, "pico_socket_recvfrom"); _pico_socket_open = (struct pico_socket*(*)(PICO_SOCKET_OPEN_SIG))dlsym(_libref, "pico_socket_open"); _pico_socket_bind = (int(*)(PICO_SOCKET_BIND_SIG))dlsym(_libref, "pico_socket_bind"); _pico_socket_connect = (int(*)(PICO_SOCKET_CONNECT_SIG))dlsym(_libref, "pico_socket_connect"); @@ -241,8 +253,7 @@ namespace ZeroTier { _pico_socket_shutdown = (int(*)(PICO_SOCKET_SHUTDOWN_SIG))dlsym(_libref, "pico_socket_shutdown"); _pico_socket_accept = (struct pico_socket*(*)(PICO_SOCKET_ACCEPT_SIG))dlsym(_libref, "pico_socket_accept"); _pico_ipv6_link_add = (int(*)(PICO_IPV6_LINK_ADD_SIG))dlsym(_libref, "pico_ipv6_link_add"); - - //_get_pico_err = (pico_err_t(*)())dlsym(_libref, "get_pico_err"); + //_pico_ipv6_source_find = (struct pico_ip6 *(*))(PICO_IPV6_SOURCE_FIND_SIG))dlsym(_libref, "pico_ipv6_source_find"); #endif } @@ -253,7 +264,6 @@ namespace ZeroTier { dlclose(_libref); } - // SIP- inline void __pico_stack_init(void) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); _pico_stack_init(); } inline void __pico_stack_tick(void) throw() { /*DEBUG_STACK();*/ Mutex::Lock _l(_lock); _pico_stack_tick(); } inline struct pico_device * __pico_tap_create(PICO_TAP_CREATE_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_tap_create(name); } @@ -267,7 +277,9 @@ namespace ZeroTier { inline int __pico_socket_setoption(PICO_SOCKET_SETOPTION_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_socket_setoption(s, option, value); } inline uint32_t __pico_timer_add(PICO_TIMER_ADD_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_timer_add(expire, timer, arg); } inline int __pico_socket_send(PICO_SOCKET_SEND_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_socket_send(s, buf, len); } + inline int __pico_socket_sendto(PICO_SOCKET_SENDTO_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_socket_sendto(s, buf, len, dst, remote_port); } inline int __pico_socket_recv(PICO_SOCKET_RECV_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_socket_recv(s, buf, len); } + inline int __pico_socket_recvfrom(PICO_SOCKET_RECVFROM_SIG) throw() { DEBUG_STACK(); /*Mutex::Lock _l(_lock);*/ return _pico_socket_recvfrom(s, buf, len, orig, remote_port); } inline struct pico_socket * __pico_socket_open(PICO_SOCKET_OPEN_SIG) throw() { DEBUG_STACK(); return _pico_socket_open(net, proto, wakeup); } inline int __pico_socket_bind(PICO_SOCKET_BIND_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_socket_bind(s, local_addr, port); } inline int __pico_socket_connect(PICO_SOCKET_CONNECT_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_socket_connect(s, srv_addr, remote_port); } @@ -278,7 +290,7 @@ namespace ZeroTier { inline int __pico_socket_shutdown(PICO_SOCKET_SHUTDOWN_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_socket_shutdown(s, mode); } inline struct pico_socket * __pico_socket_accept(PICO_SOCKET_ACCEPT_SIG) throw() { DEBUG_STACK(); /*Mutex::Lock _l(_lock);*/ return _pico_socket_accept(s, orig, port); } inline int __pico_ipv6_link_add(PICO_IPV6_LINK_ADD_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _pico_ipv6_link_add(dev, address, netmask); } - //inline pico_err_t __get_pico_err(void) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock); return _get_pico_err(); } + //inline struct pico_ipv6 * __pico_ipv6_source_find(PICO_IPV6_SOURCE_FIND_SIG) throw() { DEBUG_STACK(); Mutex::Lock _l(_lock)l return _pico_ipv6_source_find(dst); } }; } // namespace ZeroTier diff --git a/src/tap.cpp b/src/tap.cpp index 4619254..e166f1c 100644 --- a/src/tap.cpp +++ b/src/tap.cpp @@ -126,7 +126,8 @@ NetconEthernetTap::NetconEthernetTap( } lwipstack->__lwip_init(); DEBUG_EXTRA("network stack initialized (%p)", lwipstack); - #elif defined(SDK_PICOTCP) + #elif defined(SDK_PICOTCP) + pico_frame_rxbuf_tot = 0; Utils::snprintf(stackPath,sizeof(stackPath),"%s%slibpicotcp.so",homePath,ZT_PATH_SEPARATOR_S); picostack = new picoTCP_stack(stackPath); if(!picostack) { diff --git a/src/tap.hpp b/src/tap.hpp index 79345d9..79583b7 100644 --- a/src/tap.hpp +++ b/src/tap.hpp @@ -70,12 +70,12 @@ struct accept_st; namespace ZeroTier { - extern struct pico_device picodev; - extern NetconEthernetTap *picotap; - class NetconEthernetTap; class LWIPStack; + extern struct pico_device picodev; + extern NetconEthernetTap *picotap; + /* * TCP connection */ @@ -146,9 +146,16 @@ namespace ZeroTier { void threadMain() throw(); + std::string _homePath; + MAC _mac; + unsigned int _mtu; uint64_t _nwid; void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int); void *_arg; + Phy _phy; + PhySocket *_unixListenSocket; + volatile bool _enabled; + volatile bool _run; // --- Proxy struct sockaddr_storage proxyServerAddress; @@ -162,7 +169,6 @@ namespace ZeroTier { void phyOnFileDescriptorActivity(PhySocket *sock,void **uptr,bool readable,bool writable); // --- end Proxy - std::string _homePath; // lwIP #if defined(SDK_LWIP) @@ -175,7 +181,7 @@ namespace ZeroTier { // picoTCP #if defined(SDK_PICOTCP) unsigned char pico_frame_rxbuf[MAX_PICO_FRAME_RX_BUF_SZ]; - int pico_frame_rxbuf_tot = 0; + int pico_frame_rxbuf_tot; Mutex _pico_frame_rxbuf_m; picoTCP_stack *picostack; #endif @@ -359,9 +365,6 @@ namespace ZeroTier { */ void closeConnection(PhySocket *sock); - Phy _phy; - PhySocket *_unixListenSocket; - std::vector _Connections; std::map > jobmap; @@ -370,7 +373,6 @@ namespace ZeroTier { netif interface; netif interface6; - MAC _mac; Thread _thread; std::string _dev; // path to Unix domain socket @@ -378,10 +380,6 @@ namespace ZeroTier { Mutex _multicastGroups_m; Mutex _ips_m, _tcpconns_m, _rx_buf_m, _close_m; - - unsigned int _mtu; - volatile bool _enabled; - volatile bool _run; }; } // namespace ZeroTier diff --git a/src/wrappers/swift/Apple-Bridging-Header.h b/src/wrappers/swift/Apple-Bridging-Header.h index 94eb03d..5dff716 100644 --- a/src/wrappers/swift/Apple-Bridging-Header.h +++ b/src/wrappers/swift/Apple-Bridging-Header.h @@ -1,5 +1,5 @@ // -// Implementations located in src/SDK_XcodeWrapper.cpp +// Implementations located in src/wrappers/swift/XcodeWrapper.cpp // #ifndef Example_OSX_IOS_Bridging_Header_h diff --git a/tests/api_test/tcpclient4.c b/tests/api_test/tcpclient4.c index c8ec00c..d105d89 100644 --- a/tests/api_test/tcpclient4.c +++ b/tests/api_test/tcpclient4.c @@ -4,10 +4,13 @@ #include #include #include +#include int atoi(const char *str); int close(int filedes); +#define MSG_SZ 128 + int main(int argc , char *argv[]) { if(argc < 3) { @@ -17,7 +20,7 @@ int main(int argc , char *argv[]) int sock, port = atoi(argv[2]); struct sockaddr_in server; - char message[1000] , server_reply[2000]; + char message[MSG_SZ] , server_reply[MSG_SZ]; sock = socket(AF_INET , SOCK_STREAM , 0); if (sock == -1) { @@ -35,14 +38,25 @@ int main(int argc , char *argv[]) printf("connected\n"); char *msg = "welcome to the machine!"; - // TX - if(send(sock, msg, strlen(msg), 0) < 0) { - printf("send failed"); - return 1; - } - else { - printf("sent message: %s\n", msg); - printf("len = %ld\n", strlen(msg)); + + while(1) + { + sleep(1); + // TX + if(send(sock, msg, strlen(msg), 0) < 0) { + printf("send failed"); + return 1; + } + else { + printf("TX: %s\n", msg); + printf("len = %ld\n", strlen(msg)); + + int bytes_read = read(sock, server_reply, MSG_SZ); + if(bytes_read < 0) + printf("\tRX: Nothing\n"); + else + printf("\tRX = (%d bytes): %s\n", bytes_read, server_reply); + } } close(sock); return 0;