removed all contents
This commit is contained in:
@@ -1,65 +0,0 @@
|
||||
Android + ZeroTier SDK
|
||||
====
|
||||
|
||||
Welcome!
|
||||
|
||||
Imagine a flat, encrypted, no-configuration LAN for all of the instances of your Android app. This short tutorial will show you how to enable ZeroTier functionality for your Android app with little to no code modification. Check out our [ZeroTier SDK](https://www.zerotier.com/blog) page for more info on how the integration works. In this example we aim to set up a minimal [Android Studio](https://developer.android.com/studio/index.html) project which contains all of the components necessary to enable ZeroTier for your app.
|
||||
|
||||
*NOTE: For Android JNI libraries to build you'll need to install [Android Studio](https://developer.android.com/studio/index.html) the [Android NDK](https://developer.android.com/ndk/index.html). Currently only Android NDK r10e is supported and can be found [here for OSX](http://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip) and [here for Linux](http://dl.google.com/android/repository/android-ndk-r10e-linux-x86_64.zip). You'll need to tell our project where you put it by putting the path in [this file](android_jni_lib/proj/local.properties), you'll need to install the Android Build-Tools (this can typically be done through the editor the first time you start it up), and finally you should probably upgrade your Gradle plugin if it asks you to. If you don't have these things installed and configured we will detect that and just skip those builds automatically.*
|
||||
|
||||
If you want to skip the following steps and just take a look at the project, go [here](example_app).
|
||||
|
||||
***
|
||||
|
||||
**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/wrappers/java/JavaWrapper.java`
|
||||
|
||||
- Start the service
|
||||
|
||||
```
|
||||
String nwid = "8056c2e21c000001";
|
||||
// Set up service
|
||||
final ZTSDK zt = new ZTSDK();
|
||||
final String homeDir = getApplicationContext().getFilesDir() + "/zerotier";
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
// Calls to JNI code
|
||||
zt.start_service(homeDir);
|
||||
}
|
||||
}).start();
|
||||
while(!zt.running()) { }
|
||||
```
|
||||
|
||||
- Join network and start doing network stuff!
|
||||
|
||||
```
|
||||
zt.join_network(nwid);
|
||||
int sock = zt.socket(zt.AF_INET, zt.SOCK_STREAM, 0);
|
||||
int err = zt.connect(sock, "10.9.9.203", 8080, nwid);
|
||||
// zt.recvfrom(), zt.write(), etc...
|
||||
```
|
||||
|
||||
**Step 2: App permissions**
|
||||
|
||||
- In order for your application to write the auth keys and network files to the internal storage you'll need to set a few permissions in your `AndroidManifest.xml` file at the same scope level as `<application>`:
|
||||
|
||||
```
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
```
|
||||
|
||||
**Step 3: Set NDK/SDK paths**
|
||||
- Specify your SDK/NDK path in `android_jni_lib/proj/local.properties`. For example:
|
||||
|
||||
```
|
||||
sdk.dir=/Users/Name/Library/Android/sdk
|
||||
ndk.dir=/Users/Name/Library/Android/ndk-r10e
|
||||
```
|
||||
|
||||
**Step 4: Select build targets**
|
||||
- Specify the target architectures you want to build in [Application.mk](android_jni_lib/java/jni/Application.mk). By default it will build `arm64-v8a`, `armeabi`, `armeabi-v7a`, `mips`, `mips64`, `x86`, and `x86_64`. For each architecture you wish to support a different shared library will need to be built. This is all taken care of automatically by the build script.
|
||||
|
||||
**Step 4: Build Shared Library**
|
||||
- `make android_jni_lib`
|
||||
- The resultant `build/android_jni_lib/ARCH/libZeroTierOneJNI.so` is what you want to import into your own project to provide our API implementation to your app. Select your architecture and copy the shared library `libZeroTierOneJNI.so` into your project's JNI directory, possibly `/src/main/jniLibs/ARCH/libZeroTierOneJNI.so`.
|
||||
- Selecting only the architectures you need will *significantly* reduce overall build time.
|
||||
@@ -1,94 +0,0 @@
|
||||
Docker + ZeroTier SDK
|
||||
====
|
||||
|
||||
Welcome!
|
||||
|
||||
Imagine a flat, encrypted, no-configuration LAN for all of your Docker containers.
|
||||
|
||||
This short tutorial will show you how to enable ZeroTier functionality for your Docker container. In this example we aim to build a Docker container with ZeroTier’s Network Container service bundled right in so that it’s effortless to hook any number of your services in the container up to your virtual network. Alternatively, you can check out a docker project directory [here](docker_demo).
|
||||
|
||||
|
||||
**Step 1: Build ZeroTier shared library**
|
||||
|
||||
`make linux_service_and_intercept`
|
||||
- For debug output from the SDK, use `SDK_DEBUG=1`, or `ZT_DEBUG=1` to see debug output from the ZeroTier service.
|
||||
|
||||
**Step 2: Build your Docker image**
|
||||
|
||||
`docker build --tag=redis_test .`
|
||||
|
||||
The example dockerfile below incorperates a few important elements:
|
||||
|
||||
1) The ZeroTier service binaries
|
||||
2) Whatever ZeroTier identity keys you plan on using (if you don't already have keys you wish to use, fret not! A new identity will be generated automatically).
|
||||
3) The service we've chosen to use. In this case, redis.
|
||||
```
|
||||
FROM fedora:23
|
||||
# Install apps
|
||||
RUN yum -y update
|
||||
RUN yum -y install redis-3.0.4-1.fc23.x86_64
|
||||
RUN yum clean all
|
||||
# Add ZT files
|
||||
RUN mkdir -p /var/lib/zerotier-one/networks.d
|
||||
ADD sdk_identity.public /var/lib/zerotier-one/identity.public
|
||||
ADD sdk_identity.secret /var/lib/zerotier-one/identity.secret
|
||||
ADD *.conf /var/lib/zerotier-one/networks.d/
|
||||
ADD *.conf /
|
||||
ADD *.name /
|
||||
EXPOSE 9993/udp 6379/udp
|
||||
# Install LWIP library used by service
|
||||
ADD liblwip.so /var/lib/zerotier-one/liblwip.so
|
||||
# Install syscall intercept library
|
||||
ADD libztintercept.so /
|
||||
RUN cp libztintercept.so lib/libztintercept.so
|
||||
RUN ln -sf /lib/libztintercept.so /lib/libztintercept
|
||||
ADD zerotier-cli /
|
||||
Add zerotier-sdk-service /
|
||||
# Install test scripts
|
||||
ADD sdk_entrypoint.sh /sdk_entrypoint.sh
|
||||
RUN chmod -v +x /sdk_entrypoint.sh
|
||||
# Start ZeroTier-One
|
||||
CMD ["./sdk_entrypoint.sh"]
|
||||
```
|
||||
|
||||
**Step 3: Start container**
|
||||
|
||||
`docker run -d -it redis_test /bin/bash`
|
||||
|
||||
**Step 4: From container, set up environment variables**
|
||||
|
||||
Set our application pre-load with `export LD_PRELOAD=./libztintercept.so`. This dynamically loads our intercept library into your application which allows us to re-direct its network calls to our virtual network.
|
||||
|
||||
Tell the ZeroTier Network Containers service which network to connect to with `export ZT_NC_NETWORK=/var/lib/zerotier-one/nc_XXXXXXXXXXXXXXXX`.
|
||||
|
||||
**Step 5: Run your new ZeroTier-enabled service**
|
||||
|
||||
At this point, simply run your application as you normally would. It will be automatically intercepted and linked to the ZeroTier service (and hence your virtual networks!)
|
||||
|
||||
`/usr/bin/redis-server --port 6379`
|
||||
|
||||
***
|
||||
**Additional info**
|
||||
If you'd like to know the IP address your service can be reached at on this particular virtual network, use the following:
|
||||
`zerotier-cli -D/var/lib/zerotier-one/nc_XXXXXXXXXXXXXXXX listnetworks`
|
||||
|
||||
## Installing in a Docker container (or any other container engine)
|
||||
|
||||
If it's not immediately obvious, installation into a Docker container is easy. Just install `zerotier-sdk-service`, `libztintercept.so`, and `liblwip.so` into the container at an appropriate locations. We suggest putting it all in `/var/lib/zerotier-one` since this is the default ZeroTier home and will eliminate the need to supply a path to any of ZeroTier's services or utilities. Then, in your Docker container entry point script launch the service with *-d* to run it in the background, set the appropriate environment variables as described above, and launch your container's main application.
|
||||
|
||||
The only bit of complexity is configuring which virtual network to join. ZeroTier's service automatically joins networks that have `.conf` files in `ZTHOME/networks.d` even if the `.conf` file is empty. So one way of doing this very easily is to add the following commands to your Dockerfile or container entry point script:
|
||||
|
||||
mkdir -p /var/lib/zerotier-one/networks.d
|
||||
touch /var/lib/zerotier-one/networks.d/8056c2e21c000001.conf
|
||||
|
||||
Replace 8056c2e21c000001 with the network ID of the network you want your container to automatically join. It's also a good idea in your container's entry point script to add a small loop to wait until the container's instance of ZeroTier generates an identity and comes online. This could be something like:
|
||||
|
||||
/var/lib/zerotier-one/zerotier-sdk-service -d
|
||||
while [ ! -f /var/lib/zerotier-one/identity.secret ]; do
|
||||
sleep 0.1
|
||||
done
|
||||
# zerotier-sdk-service is now running and has generated an identity
|
||||
|
||||
(Be sure you don't bundle the identity into the container, otherwise every container will try to be the same device and they will "fight" over the device's address.)
|
||||
|
||||
Now each new instance of your container will automatically join the specified network on startup. Authorizing the container on a private network still requires a manual authorization step either via the ZeroTier Central web UI or the API. We're working on some ideas to automate this via bearer token auth or similar since doing this manually or with scripts for large deployments is tedious.
|
||||
89
docs/faq.md
89
docs/faq.md
@@ -1,89 +0,0 @@
|
||||
Frequently Asked Questions
|
||||
======
|
||||
|
||||
|
||||
#### Why would I integrate ZeroTier into my app?
|
||||
|
||||
The ZeroTier SDK is designed specifically for the developer that doesn't want to work with or deal with the headaches of writing a networking layer for their app. Integrating ZeroTier into your application will prevent you from having to figure out how to do the complex networking that your app might require. It will provide you with a secure, easy-to-use, P2P connectivity solution.
|
||||
|
||||
##### Use in Mobile Apps
|
||||
If you're writing a game and you'd like to give it the ability talk to other instances in a secure and fast manner, you can embed our library into your app and choose from a couple different APIs. If you're developing for iOS, you'll want to add our [iOS Framework](https://github.com/zerotier/ZeroTierSDK/tree/master/integrations/apple/example_app/iOS) to your project. If you're developing for Android, you'll need to add our [JNI library](https://github.com/zerotier/ZeroTierSDK/tree/master/integrations/android) to your project. Once your app starts up, a separate thread will start which contains the ZeroTier service and a network stack dedicated entirely to your app. Each of these integrations give your app two main options for talking over a ZeroTier network. The first is a "direct call" which is means you'll call functions such as `zt_socket(), zt_connect(), ...` which are reimplementations of the traditional [socket API](https://en.wikipedia.org/wiki/Berkeley_sockets). Alternatively we provide a SOCKS5 proxy server in a separate thread which you can turn on via `zt_start_proxy_server(...)`. And if you've already implemented your networking layer using the traditional socket API and you aren't using third-party libraries that need to make network calls, you can `zt_start_intercept()`. The intercept will essentially hijack your network calls and route them to our reimplementations. This has the advantage that you literally don't have to change a single line of your networking code to use ZeroTier. (NOTE, the intercept is *not* available on Android).
|
||||
|
||||
##### Use in Desktop Apps
|
||||
Desktop apps are a bit easier than mobile apps to integrate with ZeroTier and you'll have even more API options. The exact details vary slightly among the various [platforms/OSes we support](https://github.com/zerotier/ZeroTierSDK/tree/master/integrations), but generally you can either link the ZeroTier library into your application (same as mobile), you can use the built-in SOCKS5 proxy (same as mobile), you can use the intercept (so far tested on OSX, Linux), or you can use `LD_PRELOAD` to dynamically load just the intercept into each of your apps and all will talk to a single `zerotier-sdk-service` running on the local host. This last option is a good option if you don't have access to the source code of the application and thus cannot use the direct call or SOCKS5 proxy APIs.
|
||||
|
||||
***
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### I want technical details on how this all works under the hood.
|
||||
- Cool. Read [this](technical.md) and let us know [here](zerotier.com/community/) if you have any questions.
|
||||
|
||||
***
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### I don't have access to my an app's source but I still want to embed ZeroTier into it. Is this possible?
|
||||
- Yes! Since you can't build your app with our library you'll have to use the **Intercept** mode. This means that you will dynamically-load our library at runtime and it'll connect to the locally-running ZeroTier service and function just the same.
|
||||
|
||||
***
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### How do switch network stacks?
|
||||
|
||||
We currently provide a driver for [picoTCP](http://www.picotcp.com/) and [lwIP](http://savannah.nongnu.org/projects/lwip/), and we recommend their useage in that order. Each one has its own pros and cons, if you experience strange behavior it might be worth it to test your app on a different stack. Use `SDK_PICOTCP=1` or `SDK_LWIP=1`. For more info, see: [Network Stacks](network_stacks.md)
|
||||
|
||||
***
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### Suitable for games?
|
||||
|
||||
Yes. We think this solution is well suited for low-latency multiplayer games where reliability and ease of use are important.
|
||||
|
||||
The ZeroTier protocol is inherently P2P and only falls back to a relay in the event that your direct link is interrupted. It's in our best interest to automatically find the quickest route for your data and to *not* handle your data. This has the obvious benefits of reduced latency for your game, but also provides you better security and control of your data and reduces our costs. It seems non-sensical to do it any other way. ZeroTier is not a "cloud" that you send all of your data to.
|
||||
|
||||
We've just begun work on a native [Unity 3D](https://unity3d.com/) plugin to enable your Unity game to communicate over ZeroTier networks. You can check it out [here](../integrations/Unity3D)
|
||||
|
||||
***
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### Embedded Applications / IoT
|
||||
|
||||
We foresee the largest application of the ZeroTier SDK to be embedded devices that require lightweight, efficient and reliable networking layers that are also secure and effortless to provision. We've specifically engineered the core service and the API library to be as lightweight and portable as possible. We'd like to see people retake control of their data and security by skipping the the "cloud" without adding complexity.
|
||||
|
||||
***
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### Controlling traffic?
|
||||
|
||||
The SDK's interception of network calls is currently all or nothing. If engaged, the intercept library intercepts all network I/O calls and redirects them through the new path. A network-containerized application cannot communicate over the regular network connection of its host or container or with anything else except other hosts on its ZeroTier virtual LAN. Support for optional "fall-through" to the host IP stack for outgoing connections outside the virtual network and for gateway routes within the virtual network is planned. (It will be optional since in some cases total network isolation might be considered a nice security feature.)
|
||||
|
||||
***
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 406 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 52 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 278 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 97 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 194 KiB |
@@ -1,59 +0,0 @@
|
||||
ZeroTier Integrations
|
||||
====
|
||||
|
||||
If you want everything built at once, type `make all` and go play outside for a few minutes, we'll copy all of the targets into the `build` directory for you along with specific instructions contained in a `README.md` on how to use each binary. You can then use `make -s check` to check the build status of each binary target.
|
||||
|
||||
*NOTE for Apple platforms: In order to build iOS/OSX Frameworks and Bundles you will need XCode command line tools `xcode-select --install`*
|
||||
|
||||
*NOTE: For Android JNI libraries to build you'll need to install [Android Studio](https://developer.android.com/studio/index.html) the [Android NDK](https://developer.android.com/ndk/index.html). Currently only Android NDK r10e is supported and can be found [here for OSX](http://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip) and [here for Linux](http://dl.google.com/android/repository/android-ndk-r10e-linux-x86_64.zip). You'll need to tell our project where you put it by putting the path in [this file](android/proj/local.properties), you'll need to install the Android Build-Tools (this can typically be done through the editor the first time you start it up), and finally you should probably upgrade your Gradle plugin if it asks you to. If you don't have these things installed and configured we will detect that and just skip those builds automatically. Additionally, you can specify the target architectures you wish to build for by editing [Application.mk](android/android_jni_lib/java/jni/Application.mk). By default it will build `arm64-v8a`, `armeabi`, `armeabi-v7a`, `mips`, `mips64`, `x86`, and `x86_64`*
|
||||
|
||||
Below are the specific instructions for each integration requiring *little to no modification to your code*. Remember, with a full build we'll put a copy of the appropriate integration instructions in the resultant binary's folder for you anyway.
|
||||
|
||||
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
|
||||
|
||||
- `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 <flags>`
|
||||
|
||||
##### 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.md) `make osx_static_lib` -> `build/libzt.a`
|
||||
- [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.md) `make osx_service_and_intercept` -> { `build/zerotier-sdk-service` + `build/libztintercept.so` }
|
||||
- [Intercept library](../docs/osx.md) `make osx_sdk_service` -> `build/zerotier-sdk-service`
|
||||
- [SDK Service](../docs/osx.md) `make osx_intercept` -> `build/libztintercept.so`
|
||||
- [Unity3D plugin](apple/ZeroTierSDK_Apple) `make osx_unity3d_bundle`
|
||||
|
||||
***
|
||||
### Linux
|
||||
- For everything: `make linux <flags>`
|
||||
- [Dynamic-linking into an app/service at runtime](../docs/linux.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`
|
||||
|
||||
***
|
||||
### Windows
|
||||
- Not yet.
|
||||
105
docs/intro.md
105
docs/intro.md
@@ -1,105 +0,0 @@
|
||||
ZeroTier SDK
|
||||
======
|
||||
|
||||
ZeroTier-enabled apps, devices, and services.
|
||||
|
||||
Secure virtual network access embedded directly into applications, games, and devices. Imagine starting an instance of your application or game and having it automatically be a member of your virtual network without having to rewrite your networking layer. Check out our [Integrations](integrations/) to learn how to integrate this into your application, device, or ecosystem.
|
||||
|
||||
The general idea is this:
|
||||
|
||||
- Your application starts.
|
||||
- The API and ZeroTier service initializes inside a separate thread of your app.
|
||||
- Your app can now reach anything on your flat virtual network via normal network calls.
|
||||
|
||||
It's as simple as that!
|
||||
|
||||
To build everything for your platform, you can start with:
|
||||
|
||||
- On Linux: `make linux SDK_PICOTCP=1 SDK_IPV4=1 SDK_DEBUG=1; make -s check; ls -lG build`
|
||||
- On macOS: `make apple SDK_PICOTCP=1 SDK_IPV4=1 SDK_DEBUG=1; make -s check; ls -lG build`
|
||||
|
||||
***
|
||||
|
||||
The SDK couples the ZeroTier core Ethernet virtualization engine with a user-space TCP/IP stack and a carefully-crafted API which intercepts and re-directs network API calls to our service. This allows servers and applications to be used without modification or recompilation. It can be used to run services on virtual networks without elevated privileges, special configuration of the physical host, kernel support, or any other application specific configuration. It's ideal for [containerized applications](integrations/docker/), [games](integrations/Unity3D/), and [desktop/mobile apps](integrations/).
|
||||
|
||||
Combine this functionality with the network/device management capabilities of [ZeroTier Central](https://my.zerotier.com) and its associated [API](https://my.zerotier.com/help/api) and we've hopefully created a simple and reliable way for you to flatten and reduce the complexity of your app's networking layer.
|
||||
|
||||
The ZeroTier SDK now works on both *x64* and *ARM* architectures. We've tested a beta version for *iOS*, *Android*, *Linux*, and *macOS*.
|
||||
|
||||
## How do I use it?
|
||||
|
||||
There are generally two ways one might want to use the service.
|
||||
|
||||
- The first approach is a *compile-time static linking* of our service library directly into your application. With this option you can bundle our entire functionality right into your app with no need to communicate with a service externally, it'll all be handled automatically. This is most typical for mobile applications, games, etc.
|
||||
|
||||
- The second is a service-oriented approach where our smaller intercept library is *dynamically-linked* into your app upon startup and will communicate to a single ZeroTier service on the host which will relay traffic to and from the ZeroTier virtual network. This can be useful if you don't have access to the app's source code and can't perform a static linking.
|
||||
|
||||

|
||||
|
||||
## How does it work?
|
||||
|
||||
We've designed a background tap service that pairs the ZeroTier protocol with swappable user-space network stacks. We've provided drivers for [Lightweight IP (lwIP)](http://savannah.nongnu.org/projects/lwip/) and [picoTCP](http://www.picotcp.com/). The aim is to give you a new way to bring your applications onto your virtual network. For a more in-depth explanation of how it works take a look at our [Technical discussion](docs/technical.md)
|
||||
|
||||
## APIs
|
||||
|
||||
**Hook/Intercept**
|
||||
- Uses dynamic loading of our library to allow function interposition or "hooking" to re-implement traditional socket API functions like `socket()`, `connect()`, `bind()`, etc.
|
||||
|
||||
**Direct Call**
|
||||
- Directly call the `zts_*` API specified in [src/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 statically-link it at compile-time.
|
||||
|
||||
|
||||
***
|
||||
## 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_PICOTCP_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 <flags>`
|
||||
|
||||
##### iOS
|
||||
- [Embedding within an app](integrations/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_static_lib` -> `build/libzt.a`
|
||||
- [Embedding within an app with Xcode](integrations/apple/example_app/OSX) `make osx_app_framework` -> `build/osx_app_framework/*`
|
||||
- [Dynamic-linking into an app/service at runtime](docs/osx.md) `make osx_service_and_intercept` -> { `build/zerotier-sdk-service` + `build/libztintercept.so` }
|
||||
- [Intercept library](docs/osx.md) `make osx_sdk_service` -> `build/zerotier-sdk-service`
|
||||
- [SDK Service](docs/osx.md) `make osx_intercept` -> `build/libztintercept.so`
|
||||
- [Unity3D plugin](integrations/apple/ZeroTierSDK_Apple) `make osx_unity3d_bundle`
|
||||
|
||||
***
|
||||
### Linux
|
||||
- For everything: `make linux <flags>`
|
||||
- [Dynamic-linking into an app/service at runtime](docs/linux.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](integrations/docker)
|
||||
|
||||
### Android
|
||||
- For everything: `make android`
|
||||
|
||||
- [Embedding within an app](integrations/android) `make android_jni_lib` -> `build/android_jni_lib/YOUR_ARCH/libZeroTierOneJNI.so`
|
||||
|
||||
***
|
||||
### Windows
|
||||
- Not yet.
|
||||
|
||||
|
||||
***
|
||||

|
||||
|
||||
|
||||
More discussion can be found in our [original blog announcement](https://www.zerotier.com/blog/?p=490) and [the SDK product page](https://www.zerotier.com/product-netcon.shtml).
|
||||
If you have any feature or support requests, be sure to let us know [here](https://www.zerotier.com/community/)!
|
||||
54
docs/ios.md
54
docs/ios.md
@@ -1,54 +0,0 @@
|
||||
iOS + ZeroTier SDK
|
||||
====
|
||||
|
||||
Welcome!
|
||||
|
||||
Imagine a flat, encrypted, no-configuration LAN for all of the instances of your iOS app.
|
||||
|
||||
This short tutorial will show you how to enable ZeroTier functionality for your iOS app with little to no code modification. Check out our [ZeroTier SDK](https://www.zerotier.com/blog) page for more info on how the integration works.
|
||||
|
||||
***
|
||||
**Step 1: Build iOS framework**
|
||||
|
||||
- `make ios_app_framework`
|
||||
- This will output to `build/ios_app_framework/Release-iphoneos/ZeroTierSDK_iOS.framework`
|
||||
|
||||
**Step 2: Integrate SDK into project**
|
||||
|
||||
- Add the resultant framework package to your project
|
||||
- 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/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**
|
||||
|
||||
Start the service:
|
||||
|
||||
```
|
||||
zt.start_service(nil);
|
||||
zt.join_network(nwid);
|
||||
```
|
||||
|
||||
Listen for incoming connections:
|
||||
|
||||
```
|
||||
let sock: Int32 = zt.socket(AF_INET, SOCK_STREAM, 0)
|
||||
let ztaddr: ZTAddress = ZTAddress(AF_INET, serverAddr, Int16(serverPort))
|
||||
let bind_err = zt.bind(sock, ztaddr)
|
||||
zt_listen(sock, 1);
|
||||
let accepted_sock: Int32 = zt.accept(sock, ztaddr)
|
||||
```
|
||||
|
||||
Or, establish a connection:
|
||||
|
||||
```
|
||||
let sock: Int32 = zt.socket(AF_INET, SOCK_STREAM, 0)
|
||||
let ztaddr: ZTAddress = ZTAddress(AF_INET, serverAddr, Int16(serverPort))
|
||||
let connect_err: Int32 = zt.connect(sock, ztaddr)
|
||||
```
|
||||
|
||||
**Alternative APIs**
|
||||
|
||||
CLick [here](../../../../docs/api_discussion.md) to learn more about alternative APIs such as the Intercept and SOCKS5 Proxy.
|
||||
@@ -1,98 +0,0 @@
|
||||
Unity3D iOS + ZeroTier SDK
|
||||
====
|
||||
|
||||
Welcome!
|
||||
|
||||
We want your Unity apps to talk *directly* over a flat, secure, no-config virtual network without sending everything into the "cloud". Thus, we introduce the ZeroTier-Unity3D integration!
|
||||
|
||||
Our implementation currently intends to be the bare minimum required to get your Unity application to talk over ZeroTier virtual networks. As a result, we've created an API that is very similar to the classic BSD-style sockets API. With this basic API it is possible to construct more abstracted network layers much like Unity's LLAPI and HLAPI.
|
||||
|
||||
*NOTE: Although the API and Unity project structure is identical for iOS/OSX, if you're targeting iOS you'll need to generate an iOS unity project and integrate it with your Xcode project, instructions can be found [here](https://unity3d.com/learn/tutorials/topics/mobile-touch/building-your-unity-game-ios-device-testing).*
|
||||
|
||||
***
|
||||
## API
|
||||
|
||||
- `Join(nwid)`: Joins a ZeroTier virtual network
|
||||
- `Leave(nwid)`: Leaves a ZeroTier virtual network
|
||||
- `Socket(family, type, protocol)`: Creates a ZeroTier-administered socket (returns an `fd`)
|
||||
- `Bind(fd, addr, port)`: Binds to that socket on the address and port given
|
||||
- `Listen(fd, backlog)`: Puts a socket into a listening state
|
||||
- `Accept(fd)`: Accepts an incoming connection
|
||||
- `Connect(fd, addr, port)`: Connects to an endpoint associated with the given `fd`
|
||||
- `Write(fd, buf, len)`: Sends data to the endpoint associated with the given `fd`
|
||||
- `Read(fd, buf, len)`: Receives data from an endpoint associated with the given `fd`
|
||||
- `SendTo(fd, buf, len, flags, addr, port)`: Sends data to a given address
|
||||
- `RecvFrom(fd, ref buf, len, flags, addr, port)`: Receives data
|
||||
- `Close(fd)`: Closes a connection to an endpoint
|
||||
|
||||
***
|
||||
## Adding ZeroTier to your Unity app
|
||||
|
||||
**Step 1: Create virtual ZeroTier [virtual network](https://my.zerotier.com/)**
|
||||
|
||||
**Step 2: Add plugin to Unity project**
|
||||
- Create folder `Assets/Plugins`
|
||||
- Place `ZeroTierSDK_Unity3D_iOS.bundle` in folder
|
||||
|
||||
**Step 3: Include wrapper class source**
|
||||
- Drag `ZTSDK.cs` into your `Assets` folder.
|
||||
|
||||
**Step 4: Create and use a `ZTSDK` object**
|
||||
- See examples below for how to use it!
|
||||
|
||||
***
|
||||
|
||||
## Listening for a connection
|
||||
```
|
||||
public class Example
|
||||
{
|
||||
public ZTSDK zt;
|
||||
|
||||
public void example_server()
|
||||
{
|
||||
Thread connectThread = new Thread(() => {
|
||||
// Create ZeroTier-administered socket
|
||||
int sock = zt.Socket ((int)AddressFamily.InterNetwork, (int)SocketType.Stream, (int)ProtocolType.Unspecified);
|
||||
zt.Bind(sock, "0.0.0.0", 8000);
|
||||
zt.Listen(sock, 1);
|
||||
|
||||
// Accept() client connection
|
||||
int accept_sock = -1;
|
||||
while(accept_res < 0) {
|
||||
accept_sock = zt.Accept(sock);
|
||||
}
|
||||
|
||||
// Read data from client
|
||||
char[] msg = new char[1024];
|
||||
int bytes_read = 0;
|
||||
while(bytes_read >= 0) {
|
||||
bytes_read = zt.Read(accept_sock, ref msg, 80);
|
||||
string msgstr = new string(msg);
|
||||
Debug.Log("MSG (" + bytes_read + "):" + msgstr);
|
||||
}
|
||||
});
|
||||
connectThread.IsBackground = true;
|
||||
connectThread.Start();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Establishing a connection
|
||||
```
|
||||
public class Example
|
||||
{
|
||||
public ZTSDK zt;
|
||||
|
||||
public void example_client()
|
||||
{
|
||||
Thread connectThread = new Thread(() => {
|
||||
// Create ZeroTier-administered socket
|
||||
int sock = zt.Socket ((int)AddressFamily.InterNetwork, (int)SocketType.Stream, (int)ProtocolType.Unspecified);
|
||||
zt.Connect (sock, "0.0.0.0",8000);
|
||||
zt.Write(sock, "Welcome to the machine!", 24);
|
||||
});
|
||||
connectThread.IsBackground = true;
|
||||
connectThread.Start();
|
||||
}
|
||||
}
|
||||
```
|
||||
164
docs/linux.md
164
docs/linux.md
@@ -1,164 +0,0 @@
|
||||
Linux + ZeroTier SDK
|
||||
====
|
||||
|
||||
Welcome!
|
||||
|
||||
Imagine a flat, encrypted, no-configuration LAN for all of your Linux applications.
|
||||
|
||||
This short tutorial will show you how to inject ZeroTier functionality into your application by dynamic linking via `LD_PRELOAD`.
|
||||
|
||||
## Use with Docker
|
||||
|
||||
See [doc/docker_linux_zt_sdk.md](doc/docker_linux_zt_sdk.md)
|
||||
|
||||
## Short and sweet example
|
||||
|
||||
**Step 1: Make library and copy key files**
|
||||
|
||||
```
|
||||
make linux_shared_lib
|
||||
mkdir /tmp/sdk-test-home
|
||||
cp -f build/lwip/liblwip.so /tmp/sdk-test-home
|
||||
```
|
||||
|
||||
**Step 2: Start service and join network**
|
||||
|
||||
```
|
||||
./build/zerotier-sdk-service -d -p8000 /tmp/sdk-test-home
|
||||
./build/zerotier-cli -D/tmp/sdk-test-home join 8056c2e21c000001
|
||||
```
|
||||
|
||||
**Step 3: Get new IP address assigned to app**
|
||||
|
||||
```
|
||||
./build/zerotier-cli -D/tmp/sdk-test-home listnetworks
|
||||
```
|
||||
|
||||
**Step 4: Set environment variables**
|
||||
|
||||
```
|
||||
export LD_PRELOAD=`pwd`/build/linux_shared_lib/libztintercept.so
|
||||
export ZT_NC_NETWORK=/tmp/sdk-test-home/nc_8056c2e21c000001
|
||||
```
|
||||
|
||||
**Step 5: Start application**
|
||||
|
||||
```
|
||||
node tests/httpserver.js
|
||||
```
|
||||
**Step 6: Test it!**
|
||||
|
||||
From another system on the same virtual network `curl http://APP.SPECIFIC.IP.ADDR/`
|
||||
|
||||
*For a more in-depth explanation of what's happening here, see the section below:*
|
||||
|
||||
|
||||
## Dynamic Linking
|
||||
|
||||
Build the library:
|
||||
|
||||
`make linux_shared_lib`
|
||||
|
||||
This will build a binary called `zerotier-sdk-service` and a library called `libztintercept.so`. It will also build the IP stack as `build/lwip/liblwip.so`.
|
||||
|
||||
The `zerotier-sdk-service` binary is almost the same as a regular ZeroTier One build except instead of creating virtual network ports using Linux's `/dev/net/tun` interface, it creates instances of a user-space TCP/IP stack for each virtual network and provides RPC access to this stack via a Unix domain socket. The latter is a library that can be loaded with the Linux `LD_PRELOAD` environment variable or by placement into `/etc/ld.so.preload` on a Linux system or container. Additional magic involving nameless Unix domain socket pairs and interprocess socket handoff is used to emulate TCP sockets with extremely low overhead and in a way that's compatible with select, poll, epoll, and other I/O event mechanisms.
|
||||
|
||||
The intercept library does nothing unless the `ZT_NC_NETWORK` environment variable is set. If on program launch (or fork) it detects the presence of this environment variable, it will attempt to connect to a running `zerotier-sdk-service` at the specified Unix domain socket path.
|
||||
|
||||
Unlike `zerotier-one`, `zerotier-sdk-service` does not need to be run with root privileges and will not modify the host's network configuration in any way. It can be run alongside `zerotier-one` on the same host with no ill effect, though this can be confusing since you'll have to remember the difference between "real" host interfaces (tun/tap) and network containerized endpoints. The latter are completely unknown to the kernel and will not show up in `ifconfig`.
|
||||
|
||||
|
||||
#### Starting the SDK Service
|
||||
|
||||
A simple test can be performed in user space (no root) in your own home directory.
|
||||
|
||||
First, build the SDK service and intercept library as described above. Then create a directory to act as a temporary ZeroTier home for your test SDK service instance. You'll need to move the `liblwip.so` binary that was built with `make linux_shared_lib` into there, since the service must be able to find it there and load it.
|
||||
|
||||
mkdir /tmp/sdk-test-home
|
||||
cp -f build/lwip/liblwip.so /tmp/sdk-test-home
|
||||
|
||||
Now you can run the service (no sudo needed, and `-d` tells it to run in the background):
|
||||
|
||||
./build/zerotier-sdk-service -d -p8000 /tmp/sdk-test-home
|
||||
|
||||
As with ZeroTier One in its normal incarnation, you'll need to join a network for anything interesting to happen:
|
||||
|
||||
./build/zerotier-cli -D/tmp/sdk-test-home join 8056c2e21c000001
|
||||
|
||||
If you don't want to use [Earth](https://www.zerotier.com/public.shtml) for this test, replace 8056c2e21c000001 with a different network ID. The `-D` option tells `zerotier-cli` not to look in `/var/lib/zerotier-one` for information about a running instance of the ZeroTier system service but instead to look in `/tmp/sdk-test-home`.
|
||||
|
||||
Now type:
|
||||
|
||||
./build/zerotier-cli -D/tmp/sdk-test-home listnetworks
|
||||
|
||||
Try it a few times until you see that you've successfully joined the network and have an IP address. Instead of a *zt#* device, a path to a Unix domain socket will be listed for the network's port.
|
||||
|
||||
Now you will want to have ZeroTier One (the normal `zerotier-one` build, not the SDK) running somewhere else, such as on another Linux system or VM. Technically you could run it on the *same* Linux system and it wouldn't matter at all, but many people find this intensely confusing until they grasp just what exactly is happening here.
|
||||
|
||||
On the other Linux system, join the same network if you haven't already (8056c2e21c000001 if you're using Earth) and wait until you have an IP address. Then try pinging the IP address your SDK service instance received. You should see ping replies.
|
||||
|
||||
Back on the host that's running `zerotier-sdk-service`, type `ip addr list` or `ifconfig` (ifconfig is technically deprecated so some Linux systems might not have it). Notice that the IP address of the network containers endpoint is not listed and no network device is listed for it either. That's because as far as the Linux kernel is concerned it doesn't exist.
|
||||
|
||||
What are you pinging? What is happening here?
|
||||
|
||||
The `zerotier-sdk-service` binary has joined a *virtual* network and is running a *virtual* TCP/IP stack entirely in user space. As far as your system is concerned it's just another program exchanging UDP packets with a few other hosts on the Internet and nothing out of the ordinary is happening at all. That's why you never had to type *sudo*. It didn't change anything on the host.
|
||||
|
||||
Now you can run an application .
|
||||
|
||||
export LD_PRELOAD=`pwd`/build/linux_shared_lib/libztintercept.so
|
||||
export ZT_NC_NETWORK=/tmp/sdk-test-home/nc_8056c2e21c000001
|
||||
node tests/httpserver.js
|
||||
|
||||
Also note that the "pwd" in `LD_PRELOAD` assumes you are in the ZeroTier source root and have built the SDK there. If not, substitute the full path to `libztintercept.so`. If you want to remove those environment variables later, use `unset LD_PRELOAD` and `unset ZT_NC_NETWORK`.
|
||||
|
||||
If you don't have node.js installed, an alternative test using python would be:
|
||||
|
||||
python -m SimpleHTTPServer 80
|
||||
|
||||
If you are running Python 3, use `-m http.server`.
|
||||
|
||||
If all went well a small static HTTP server is now serving up the current directory, but only inside the network container. Going to port 80 on your machine won't work. To reach it, go to the other system where you joined the same network with a conventional ZeroTier instance and try:
|
||||
|
||||
curl http://APP.SPECIFIC.IP.ADDR/
|
||||
|
||||
Replace `APP.SPECIFIC.IP.ADDR` with the IP address that `zerotier-sdk-service` was assigned on the virtual network. (This is the same IP you pinged in your first test.) If everything works, you should get back a copy of ZeroTier One's main README.md file.
|
||||
|
||||
|
||||
***
|
||||
#### Dynamic linking compatibility test results
|
||||
|
||||
The following applications have been tested and confirmed to work for the beta release:
|
||||
|
||||
Fedora 23:
|
||||
|
||||
httpstub.c
|
||||
nginx 1.8.0
|
||||
http 2.4.16, 2.4.17
|
||||
darkhttpd 1.11
|
||||
python 2.7.10 (python -m SimpleHTTPServer)
|
||||
python 3.4.3 (python -m http.server)
|
||||
redis 3.0.4
|
||||
node 6.0.0-pre
|
||||
sshd
|
||||
|
||||
CentOS 7:
|
||||
|
||||
httpstub.c
|
||||
nginx 1.6.3
|
||||
httpd 2.4.6 (debug mode -X)
|
||||
darkhttpd 1.11
|
||||
node 4.2.2
|
||||
redis 2.8.19
|
||||
sshd
|
||||
|
||||
Ubuntu 14.04.3:
|
||||
|
||||
httpstub.c
|
||||
nginx 1.4.6
|
||||
python 2.7.6 (python -m SimpleHTTPServer)
|
||||
python 3.4.0 (python -m http.server)
|
||||
node 5.2.0
|
||||
redis 2.8.4
|
||||
sshd
|
||||
|
||||
It is *likely* to work with other things but there are no guarantees.
|
||||
@@ -1,25 +0,0 @@
|
||||
Hot-Swappable Network Stacks!
|
||||
====
|
||||
|
||||
We've now enabled the ability for users to build the ZeroTier SDK with different network stacks with the mere flip of a compiler flag as well as running different stacks concurrently! This is perfect for embedded developers which may need a smaller code footprint and would like to use their own smaller or more specialized network stacks.
|
||||
|
||||
`SDK_LWIP=1` and `SDK_PICOTCP=1` will enable the lwIP and picoTCP network stacks respectively.
|
||||
|
||||
Currently our *lwIP* stack driver supports IPV4 and limited IPV6, whereas our *picoTCP* stack driver supports both IPV4 and IPV6 with no known issues.
|
||||
|
||||
To enable specific protocol versions use `SDK_IPV4=1` and `SDK_IPV6=1` in conjunction with the above stack selection flags.
|
||||
|
||||
Also, to enable debug for the SDK use `SDK_DEBUG=1`, to enable debug for the *lwIP* stack use `SDK_LWIP_DEBUG=1`.
|
||||
|
||||
## Integrating Your Own Custom Stack
|
||||
|
||||
If you don't know why this section exists, then I suggest turning back now. This is not for you. Otherwise, let's get on with things, here's how you can integrate your own custom network stack if for some reason lwIP or picoTCP aren't cutting it for you:
|
||||
|
||||
Investigate the structure of `src/tap.cpp`, this file contains calls to functions implemented in the stack driver code (located in `src/stack_drivers`).
|
||||
|
||||
Each stack is different but generally you'll need to provide:
|
||||
- An initialization function to configure and bring up the stack's `interface` (or similar).
|
||||
- An I/O polling loop section where you'll execute your timer calls, and check for inbound and outbound frames.
|
||||
- A low-level input and output function to handle feeding ethernet frames into and out of the stack in its own unique way.
|
||||
- Calls to your stack's API which roughly correspond with `handleRead()`, `handleWrite()`, `handleSocket()`, `handleConnect()`, etc
|
||||
- In those calls you'll need to handle the creation, management, and destruction of your stack's "connection" objects, whatever that may be.
|
||||
78
docs/osx.md
78
docs/osx.md
@@ -1,78 +0,0 @@
|
||||
OSX + ZeroTier SDK
|
||||
====
|
||||
|
||||
Welcome!
|
||||
|
||||
Imagine a flat, encrypted, no-configuration LAN for all of the instances of your OSX app.
|
||||
|
||||
***
|
||||
|
||||
## Via Traditional Linking (Service and Intercept)
|
||||
|
||||
- This will allow the interception of traditional socket API calls such as `socket()`, `connect()`, `bind()`, etc.
|
||||
|
||||
Build against our library:
|
||||
|
||||
gcc app.c -o app libztintercept.so
|
||||
export ZT_NC_NETWORK=/tmp/sdk-test-home/nc_8056c2e21c000001
|
||||
|
||||
Start service
|
||||
|
||||
./zerotier-sdk-service -d -p8000 /tmp/sdk-test-home &
|
||||
|
||||
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
|
||||
|
||||
***
|
||||
**Step 1: Build OSX framework**
|
||||
|
||||
- `make osx_app_framework`
|
||||
- This will output to `build/osx_app_framework/Release/ZeroTierSDK_OSX.framework`
|
||||
|
||||
**Step 2: Integrate SDK into project**
|
||||
|
||||
- Add the resultant framework package to your project
|
||||
- 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/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**
|
||||
|
||||
Start the service:
|
||||
|
||||
```
|
||||
zt.start_service("."); // Where the ZeroTier config files for this app will be stored
|
||||
zt.join_network(nwid);
|
||||
```
|
||||
|
||||
Listen for incoming connections:
|
||||
|
||||
```
|
||||
let sock: Int32 = zt.socket(AF_INET, SOCK_STREAM, 0)
|
||||
let ztaddr: ZTAddress = ZTAddress(AF_INET, serverAddr, Int16(serverPort))
|
||||
let bind_err: Int32 = zt.bind(sock, ztaddr)
|
||||
zt_listen(sock, 1);
|
||||
let accepted_sock: Int32 = zt.accept(sock, ztaddr)
|
||||
```
|
||||
|
||||
Or, establish a connection:
|
||||
|
||||
```
|
||||
let sock: Int32 = zt.socket(AF_INET, SOCK_STREAM, 0)
|
||||
let ztaddr: ZTAddress = ZTAddress(AF_INET, serverAddr, Int16(serverPort))
|
||||
let connect_err: Int32 = zt.connect(sock, ztaddr)
|
||||
```
|
||||
|
||||
**Alternative APIs**
|
||||
|
||||
Click [here](../../../../docs/api_discussion.md) to learn more about alternative APIs such as the Intercept and SOCKS5 Proxy.
|
||||
@@ -1,103 +0,0 @@
|
||||
Unity3D OSX + ZeroTier SDK
|
||||
====
|
||||
|
||||
Welcome!
|
||||
|
||||
We want your Unity apps to talk *directly* over a flat, secure, no-config virtual network without sending everything into the "cloud". Thus, we introduce the ZeroTier-Unity3D integration!
|
||||
|
||||
Our implementation currently intends to be the bare minimum required to get your Unity application to talk over ZeroTier virtual networks. As a result, we've created an API that is very similar to the classic BSD-style sockets API. With this basic API it is possible to construct more abstracted network layers much like Unity's LLAPI and HLAPI.
|
||||
|
||||
***
|
||||
## API
|
||||
|
||||
- `Join(nwid)`: Joins a ZeroTier virtual network
|
||||
- `Leave(nwid)`: Leaves a ZeroTier virtual network
|
||||
- `Socket(family, type, protocol)`: Creates a ZeroTier-administered socket (returns an `fd`)
|
||||
- `Bind(fd, addr, port)`: Binds to that socket on the address and port given
|
||||
- `Listen(fd, backlog)`: Puts a socket into a listening state
|
||||
- `Accept(fd)`: Accepts an incoming connection
|
||||
- `Connect(fd, addr, port)`: Connects to an endpoint associated with the given `fd`
|
||||
- `Write(fd, buf, len)`: Sends data to the endpoint associated with the given `fd`
|
||||
- `Read(fd, buf, len)`: Receives data from an endpoint associated with the given `fd`
|
||||
- `SendTo(fd, buf, len, flags, addr, port)`: Sends data to a given address
|
||||
- `RecvFrom(fd, ref buf, len, flags, addr, port)`: Receives data
|
||||
- `Close(fd)`: Closes a connection to an endpoint
|
||||
|
||||
***
|
||||
## Adding ZeroTier to your Unity app
|
||||
|
||||
**Step 1: Create virtual ZeroTier [virtual network](https://my.zerotier.com/)**
|
||||
|
||||
**Step 2: Add plugin to Unity project**
|
||||
- Create folder `Assets/Plugins`
|
||||
- Place `ZeroTierSDK_Unity3D_OSX.bundle` in folder
|
||||
|
||||
**Step 3: Include wrapper class source**
|
||||
- Drag `ZTSDK.cs` into your `Assets` folder.
|
||||
- Add a file `Assets/smcs.rsp` containing the flag `-unsafe`. This is needed to execute the native library.
|
||||
|
||||
**Step 4: Create and use a `ZTSDK` object**
|
||||
- See examples below for how to use it!
|
||||
|
||||
***
|
||||
|
||||
## Listening for a connection
|
||||
```
|
||||
public class Example
|
||||
{
|
||||
public ZTSDK zt;
|
||||
|
||||
public void example_server()
|
||||
{
|
||||
zt = new ZTSDK (); // Start interface
|
||||
zt.Join("8056c2e21c000001"); // Join your network
|
||||
|
||||
Thread connectThread = new Thread(() => {
|
||||
// Create ZeroTier-administered socket
|
||||
int sock = zt.Socket ((int)AddressFamily.InterNetwork, (int)SocketType.Stream, (int)ProtocolType.Unspecified);
|
||||
zt.Bind(sock, "0.0.0.0", 8000);
|
||||
zt.Listen(sock, 1);
|
||||
|
||||
// Accept client connection
|
||||
int accept_sock = -1;
|
||||
while(accept_res < 0) {
|
||||
accept_sock = zt.Accept(sock);
|
||||
}
|
||||
|
||||
// Read data from client
|
||||
char[] msg = new char[1024];
|
||||
int bytes_read = 0;
|
||||
while(bytes_read >= 0) {
|
||||
bytes_read = zt.Read(accept_sock, ref msg, 80);
|
||||
string msgstr = new string(msg);
|
||||
Debug.Log("MSG (" + bytes_read + "):" + msgstr);
|
||||
}
|
||||
});
|
||||
connectThread.IsBackground = true;
|
||||
connectThread.Start();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Establishing a connection
|
||||
```
|
||||
public class Example
|
||||
{
|
||||
public ZTSDK zt;
|
||||
|
||||
public void example_client()
|
||||
{
|
||||
zt = new ZTSDK ();
|
||||
zt.Join("8056c2e21c000001");
|
||||
|
||||
Thread connectThread = new Thread(() => {
|
||||
// Create ZeroTier-administered socket
|
||||
int sock = zt.Socket ((int)AddressFamily.InterNetwork, (int)SocketType.Stream, (int)ProtocolType.Unspecified);
|
||||
zt.Connect (sock, "0.0.0.0",8000);
|
||||
zt.Write(sock, "Welcome to the machine!", 24);
|
||||
});
|
||||
connectThread.IsBackground = true;
|
||||
connectThread.Start();
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -1,169 +0,0 @@
|
||||
Technical Discussion
|
||||
======
|
||||
|
||||
*Note: It is not necessary for you to understand anything in this document, this is merely for those curious about the inner workings of the intercept, tap service, stack driver, and network stack.*
|
||||
|
||||
In this document we will walk you through what happens when your ZeroTier-enabled app does things like accepting a connection, receiving data, etc. But before we get into specific cases it's worth understanding the three major components which work together to produce this magic:
|
||||
|
||||
- **Intercept Library**: Mates to your app and allows us to re-implement classic network calls such as `socket()`, `bind()`, etc
|
||||
- **Tap Service / Stack Driver**: Mediates communication between the Intercept Library and the Network Stack.
|
||||
- **Network Stack**: Handles incoming ethernet frames and generates outgoing frames.
|
||||
|
||||
So now that we've clarified what these components do, here's the general idea:
|
||||
|
||||
You make a network call, the intercept routes that to our tap service which uses the user-space network stack to generate ethernet frames which is then sent out onto your ZeroTier virtual network.
|
||||
|
||||
***
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Creating a socket
|
||||
|
||||
Your app requests a socket:
|
||||
|
||||
```
|
||||
socket()
|
||||
```
|
||||
|
||||
Our library's implementation of `socket()` is executed instead of the kernel's. We automatically establish an `AF_UNIX` socket connection with the **tap service**. This is how your app will communicate with ZeroTier. An `RPC_SOCKET` message is sent to the **tap service**. The **tap service** receives the `RPC_SOCKET` message and requests the allocation of a new `Connection` object from the **stack driver** which represents the new socket. The **tap service** then repurposes the socket used for the RPC message and returns its file descriptor to your app for it to use as the new socket.
|
||||
|
||||
From your app's perspective nothing out of the ordinary has happened. It called `socket()`, and got a file descriptor back.
|
||||
***
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Establishing a connection
|
||||
|
||||
You app connects to a remote host:
|
||||
|
||||
```
|
||||
connect()
|
||||
```
|
||||
|
||||
An `RPC_CONNECT` call is sent to the **tap service**, it is unpacked by the **stack driver** in `pico_handleConnect()`. A `pico_socket_connect()` call is made to the **network stack**. Once it establishes a connection (or fails), it sends a return value back to the app.
|
||||
|
||||
```
|
||||
phyOnUnixData()
|
||||
pico_handleConnect()
|
||||
pico_socket_connect()
|
||||
```
|
||||
***
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Accepting a connection
|
||||
|
||||
Your app places a socket into a listen state:
|
||||
|
||||
```
|
||||
listen()
|
||||
```
|
||||
An `RPC_LISTEN` call is sent to the **tap service** and **stack driver**
|
||||
|
||||
You app accepts a connection:
|
||||
|
||||
```
|
||||
accept()
|
||||
```
|
||||
|
||||
The **network stack** raises a `PICO_SOCK_EV_CONN` event which calls `pico_cb_socket_activity()`. From here we request a new `pico_socket` be created to represent the new connection. This is done via `pico_socket_accept()`. Once we have a valid `pico_socket`, we create an `AF_UNIX` socket pair. We associate one end with the newly-created `pico_socket` via a `Connection` object. And we send the other end of the socket pair to the app.
|
||||
|
||||
Our library's implementation of `accept()` will read and return the new file descriptor representing one end of the socket pair. From your app's prespective this is a normal file descriptor.
|
||||
***
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Receiving data
|
||||
|
||||
The **tap service** monitors incoming packets, when one destined for us is detected it notifies the **stack driver** via `put()`. Then `pico_rx()` is called, its job is to re-encapsulate the ethernet frame and copy it onto the guarded `pico_frame_rxbuf`. This buffer is guarded because it is accessed via the **tap service** thread and the **network stack** thread.
|
||||
|
||||
```
|
||||
wire
|
||||
put()
|
||||
pico_rx() ---> <pico_frame_rxbuf>
|
||||
```
|
||||
|
||||
Periodically the **network stack** thread will call `pico_eth_poll()`, this is responsible for reading the frames from the aformentioned `pico_frame_rxbuf` and feeding it into the stack via `pico_stack_recv()`.
|
||||
|
||||
```
|
||||
pico_eth_poll()
|
||||
<pico_frame_rxbuf> ---> pico_stack_recv()
|
||||
```
|
||||
|
||||
After some time has passed and the **network stack** has processed the incoming frames a `PICO_SOCK_EV_RD` event will be triggered which calls `pico_cb_socket_activity()`, and ultimately `pico_cb_tcp_read()`. This is where we copy the incoming data from the `pico_socket` to the `Connection`'s `rxbuf` (different from `pico_frame_rxbuf`). We then notify the **tap service** that the `PhySocket` (a wrapped file descriptor with one end visible to the application) associated with this `Connection` has data in its `rxbuf` that needs to be written so the app can read it.
|
||||
|
||||
```
|
||||
pico_cb_socket_activity()
|
||||
pico_cb_tcp_read() ---> <rxbuf>
|
||||
setNotifyWritable(TRUE)
|
||||
```
|
||||
|
||||
After some (more) time, the **tap service** thread will call `pico_handleRead()`, this will copy the data from the `rxbuf` to the `AF_UNIX` socket which links the service and your application.
|
||||
|
||||
```
|
||||
pico_handleRead()
|
||||
streamSend(): <rxbuf> ---> PhySock
|
||||
```
|
||||
|
||||
After this point it's up to your application to read the data via a conventional `read()`, `recv()`, or `recvfrom()` call.
|
||||
|
||||
```
|
||||
read()
|
||||
```
|
||||
***
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### Sending data
|
||||
|
||||
Your app performs a `write()`, `send()`, or `sendto()` call.
|
||||
|
||||
```
|
||||
write()
|
||||
```
|
||||
|
||||
The other end of the `AF_UNIX` socket which was written to is monitored by the **tap service** thread. Once data is read from the socket, it will call `phyOnUnixData()` which will copy the buffer contents onto the `Connection`'s `txbuf`. Then `pico_handleWrite()` will be called. The **stack driver** will determine how much of the buffer can safely be sent to the **network stack** (up to `ZT_MAX_MTU` which is currently set at 2800 bytes). A call is made to `pico_socket_write()` which copies the data from the `txbuf` to the `pico_socket`.
|
||||
|
||||
```
|
||||
phyOnUnixData()
|
||||
handleWrite()
|
||||
pico_socket_write(): <txbuf> ---> picosock
|
||||
```
|
||||
|
||||
Periodically a `PICO_SOCK_EV_WR` event will be raised by the **network stack**, this will call `pico_cb_socket_activity()` and ultimately `pico_cb_tcp_write()` where a `pico_socket_write()` call will be made to copy any remaining `txbuf` contents into the stack.
|
||||
|
||||
```
|
||||
pico_cb_tcp_write()
|
||||
```
|
||||
|
||||
After some time, the **network stack** will emit an ethernet frame via `pico_eth_send()`, we then copy the frame into the **tap service** where it will then be sent onto the network.
|
||||
|
||||
```
|
||||
pico_eth_send()
|
||||
tap->_handler()
|
||||
```
|
||||
***
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
Testing
|
||||
======
|
||||
|
||||
|
||||
|
||||
|
||||
### Unit Tests
|
||||
|
||||
To build the API unit tests:
|
||||
- `make tests`
|
||||
|
||||
All necessary binaries and scripts will be built and copied into `build/tests`.
|
||||
|
||||
Running `build/tests/test.sh` will execute the automatic API unit tests.
|
||||
|
||||
***
|
||||
|
||||
|
||||
|
||||
|
||||
### Docker Unit Tests
|
||||
|
||||
**Running all docker tests**
|
||||
|
||||
- Build the docker images: `make docker_images`
|
||||
|
||||
- Run the docker tests from the docker containers: `make docker_test`
|
||||
|
||||
- Check the results of the completed tests: `make docker_test_check`
|
||||
|
||||
Each unit test will temporarily copy all required ZeroTier binaries into its local directory, then build the `sdk_dockerfile` and `monitor_dockerfile`. Once built, each container will be run and perform tests and monitoring specified in `sdk_entrypoint.sh` and `monitor_entrypoint.sh`
|
||||
|
||||
Results will be written to the `tests/docker/_results/` directory which is a common shared volume between all containers involved in the test and will be a combination of raw and formatted dumps to files whose names reflect the test performed. In the event of failure, `FAIL.` will be prepended to the result file's name (e.g. `FAIL.my_application_1.0.2.x86_64`), likewise in the event of success, `OK.` will be prepended.
|
||||
|
||||
To run unit tests:
|
||||
|
||||
1) Disable SELinux. This is so the containers can use a shared volume to exchange MD5 sums and address information.
|
||||
|
||||
2) Set up your own network at [https://my.zerotier.com/](https://my.zerotier.com/). For our example we'll just use the Earth network (8056c2e21c000001). Use its network id as follows:
|
||||
|
||||
3) Generate two pairs of identity keys. Each public/private pair will be used by the *sdk* and *monitor* containers:
|
||||
|
||||
mkdir -p /tmp/sdk_first
|
||||
cp -f ./sdk/liblwip.so /tmp/sdk_first
|
||||
./zerotier-sdk-service -d -p8100 /tmp/sdk_first
|
||||
while [ ! -f /tmp/sdk_first/identity.secret ]; do
|
||||
sleep 0.1
|
||||
done
|
||||
./zerotier-cli -D/tmp/sdk_first join 8056c2e21c000001
|
||||
kill `cat /tmp/sdk_first/zerotier-one.pid`
|
||||
|
||||
mkdir -p /tmp/sdk_second
|
||||
cp -f ./sdk/liblwip.so /tmp/sdk_second
|
||||
./zerotier-sdk-service -d -p8101 /tmp/sdk_second
|
||||
while [ ! -f /tmp/sdk_second/identity.secret ]; do
|
||||
sleep 0.1
|
||||
done
|
||||
./zerotier-cli -D/tmp/sdk_second join 8056c2e21c000001
|
||||
kill `cat /tmp/sdk_second/zerotier-one.pid`
|
||||
|
||||
4) Copy the identity files to *tests/docker*. Names will be altered during copy step so the dockerfiles know which identities to use for each image/container:
|
||||
|
||||
cp /tmp/sdk_first/identity.public ./sdk/tests/docker/sdk_identity.public
|
||||
cp /tmp/sdk_first/identity.secret ./sdk/tests/docker/sdk_identity.secret
|
||||
|
||||
cp /tmp/sdk_second/identity.public ./sdk/tests/docker/monitor_identity.public
|
||||
cp /tmp/sdk_second/identity.secret ./sdk/tests/docker/monitor_identity.secret
|
||||
|
||||
|
||||
5) Place a blank network config file in the `tests/docker` directory (e.g. "8056c2e21c000001.conf")
|
||||
- This will be used to inform test-specific scripts what network to use for testing
|
||||
|
||||
After you've created your network and placed its blank config file in `tests/docker` run the following to perform unit tests for httpd:
|
||||
|
||||
./build.sh httpd
|
||||
./test.sh httpd
|
||||
|
||||
It's useful to note that the keyword *httpd* in this example is merely a substring for a test name, this means that if we replaced it with *x86_64*, *fc23*, or *nginx*, it would run all unit tests for *x86_64*, *Fedora 23*, or *nginx* respectively.
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
Walkthrough
|
||||
======
|
||||
|
||||
In this document we'll run through a simple example which should demonstrate the concept of the ZeroTier SDK. For this tutorial you'll need two devices (or at least the ability to run a VM or something like [Docker](https://www.docker.com/)). We will demonstrate a simple TCP server application intercepted on linux. This is only one of *many* ways the SDK can be used, but it'll at least convey the core concept how how the intercept works.
|
||||
|
||||
#### On your first device:
|
||||
- Download ZeroTier at [zerotier.com](https://www.zerotier.com/product-one.shtml)
|
||||
- Install it on a device/computer
|
||||
- Create an account and new virtual network at [my.zerotier.com](https://my.zerotier.com/)
|
||||
- Join your device to the network and assign it an address `zerotier-cli join <nwid>`
|
||||
- Use `zerotier-cli listnetworks` to verify that you've joined the network.
|
||||
***
|
||||
|
||||
|
||||
|
||||
#### On your second device:
|
||||
|
||||
##### Build the SDK
|
||||
```
|
||||
make linux SDK_PICOTCP=1 SDK_IPV4=1 SDK_DEBUG=1; make -s check; ls -lG build
|
||||
```
|
||||
|
||||
##### Build test apps
|
||||
|
||||
```
|
||||
make tests
|
||||
```
|
||||
|
||||
##### Start the SDK service in the background
|
||||
```
|
||||
./zerotier-cli -U -p8000 /netpath &
|
||||
```
|
||||
|
||||
##### Set environment variables
|
||||
```
|
||||
export ZT_NC_NETWORK=/netpath/nc_XXXXXXXXXXXXXXXX
|
||||
export LD_PRELOAD=./libztintercept.so
|
||||
```
|
||||
|
||||
Where `netpath` can be any path you'd like the client's keys and configuration to be stored and `XXXXXXXXXXXXXXXX` is the 16-digit network ID.
|
||||
|
||||
##### Start your app
|
||||
```
|
||||
./build/tests/linux.tcpserver4.out 8001
|
||||
```
|
||||
|
||||
Now, on your first device, `./build/tests/linux.tcpclient4.out <ip> 8001` where `<ip>` is the ip address that you assigned to your first device.
|
||||
|
||||
Now, you'll note that your new TCP server is automatically intercepted and available at on port 8001. The `tcpclient4` sample app running on the device with a normal instance of ZeroTier running will be able to connect directly to your intercepted `tcpserver4` app on the second machine running the SDK.
|
||||
***
|
||||
|
||||
|
||||
You've just uplifted your app onto your private ZeroTier network.
|
||||
|
||||
Reference in New Issue
Block a user