API usability update, normalized zt_ naming convention

This commit is contained in:
Joseph Henry
2016-07-20 14:20:45 -07:00
parent d894077b81
commit 27c26b61b2
23 changed files with 476 additions and 378 deletions

BIN
docs/img/api_diagram.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 KiB

View File

@@ -34,4 +34,7 @@ We've built a special background service that pairs the ZeroTier protocol with a
- Provides an integrated SOCKS5 server alongside the ZeroTier service to proxy connections from an application to resources on a ZeroTier network. For instance, a developer which has built an iOS app using the NSStreams API could add ZeroTier to their application and simply use the SOCKS5 support build into NSStreams to reach resources on their network. An Android developer could do the same using the SOCKS5 support provided in the `Socket` API.
**Direct Call**
- Directly call the `zt_/zts_` 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.
- 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.
***
![Image](docs/img/api_diagram.png)

View File

@@ -7,10 +7,10 @@ APP_PLATFORM := android-14
# Architectures
# APP_ABI := all
APP_ABI += arm64-v8a
#APP_ABI += arm64-v8a
#APP_ABI += armeabi
APP_ABI += armeabi-v7a
#APP_ABI += mips
#APP_ABI += mips64
APP_ABI += x86
APP_ABI += x86_64
#APP_ABI += x86
#APP_ABI += x86_64

View File

@@ -1,3 +1,29 @@
/*
* ZeroTier One - Network Virtualization Everywhere
* Copyright (C) 2011-2015 ZeroTier, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* --
*
* ZeroTier may be used and distributed under the terms of the GPLv3, which
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
*
* If you would like to embed ZeroTier into a commercial application or
* redistribute it in a modified binary form, please contact ZeroTier Networks
* LLC. Start here: http://www.zerotier.com/
*/
package ZeroTier;
import java.net.SocketAddress;
@@ -16,21 +42,21 @@ public class SDK {
static { System.loadLibrary("ZeroTierOneJNI"); }
// ZeroTier service controls
public native void startOneService(String homeDir);
public native void joinNetwork(String nwid);
public native void leaveNetwork(String nwid);
public native boolean isRunning();
public native void zt_start_service(String homeDir);
public native void zt_join_network(String nwid);
public native void zt_leave_network(String nwid);
public native boolean zt_running();
// Direct-call API
// --- These calls skip the intercept and interface directly via the RPC mechanism ---
public native int ztjniSocket(int family, int type, int protocol);
public native int ztjniConnect(int fd, String addr, int port);
public native int ztjniBind(int fd, String addr, int port);
public native int ztjniAccept4(int fd, String addr, int port);
public native int ztjniAccept(int fd, String addr, int port, int flags);
public native int ztjniListen(int fd, int backlog);
//public native int ztjniGetsockopt(int fd, int type, int protocol);
//public native int ztjniSetsockopt(int fd, int type, int protocol);
//public native int ztjniGetsockname(int fd, int type, int protocol);
public native int ztjniClose(int fd);
// --- These calls skip the intercept and interface directly via the RPC mechanism
public native int zt_socket(int family, int type, int protocol);
public native int zt_connect(int fd, String addr, int port);
public native int zt_bind(int fd, String addr, int port);
public native int zt_accept4(int fd, String addr, int port);
public native int zt_accept(int fd, String addr, int port, int flags);
public native int zt_listen(int fd, int backlog);
//public native int zt_getsockopt(int fd, int type, int protocol);
//public native int zt_setsockopt(int fd, int type, int protocol);
//public native int zt_getsockname(int fd, int type, int protocol);
public native int zt_close(int fd);
}

View File

@@ -25,15 +25,15 @@ public class MainActivity extends AppCompatActivity {
new Thread(new Runnable() {
public void run() {
// Calls to JNI code
zt.startOneService(homeDir);
zt.zt_start_service(homeDir);
}
}).start();
while(!zt.isRunning()) { }
zt.joinNetwork("XXXXXXXXXXXXXXXX");
while(!zt.zt_running()) { }
zt.zt_join_network("XXXXXXXXXXXXXXXX");
// Create ZeroTier socket
int sock = zt.ztjniSocket(zt.AF_INET, zt.SOCK_STREAM, 0);
int sock = zt.zt_socket(zt.AF_INET, zt.SOCK_STREAM, 0);
try {
Thread.sleep(10000);
@@ -41,8 +41,8 @@ public class MainActivity extends AppCompatActivity {
catch(java.lang.InterruptedException e) { }
// Connect to remote host
Log.d("","ztjniConnect()\n");
int err = zt.ztjniConnect(sock, "10.9.9.203", 8080);
Log.d("","zt_connect()\n");
int err = zt.zt_connect(sock, "10.9.9.203", 8080);
// Set up example proxy connection to SDK proxy server
/*

View File

@@ -3,14 +3,13 @@ Android + ZeroTier SDK
Welcome!
Imagine a flat, encrypted, no-configuration LAN for all of the instances of your Android app.
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.
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 and [Shim Techniques](https://www.zerotier.com/blog) for a discussion of shims available for your app/technology.
*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.*
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. If you'd rather skip all of these steps and grab the code, look in the [sdk/android](https://github.com/zerotier/ZeroTierOne/tree/dev/sdk/integrations/android/example_app) folder in the source tree. Otherwise, let's get started!
*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.*
If you want to skip these steps and just take a look at the project, go [here](example_app).
***
**Step 1: Select build targets**
- Specify the target architectures you want to build in [Application.mk](android/java/jni/Application.mk). By default it will build `arm64-v8a`, `armeabi`, `armeabi-v7a`, `mips`, `mips64`, `x86`, and `x86_64`.
@@ -18,7 +17,16 @@ In this example we aim to set up a minimal [Android Studio](https://developer.an
- `make android_jni_lib`
- The resultant `build/android_jni_lib_YOUR_ARCH/libZeroTierOneJNI.so` is what you want to import into your own project to provide the API to your app. Select your architecture and copy the shared library into your project's JNI directory, possibly `/src/main/jniLibs/YOUR_ARCH/`. Selecting only the architectures you need will *significantly* reduce overall build time.
**Step 3: App Code Modifications**
**Step 3: 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 4: App Code Modifications**
- Create new package called `ZeroTierSDK` in your project and add a new file called `ZeroTierSDK.java` containing:
```
@@ -32,36 +40,33 @@ public class ZeroTierSDK {
}
```
- And now, start the service in your app with:
- Start the service
```
final SDK zt = new SDK();
final String homeDir = getApplicationContext().getFilesDir() + "/zerotier";
new Thread(new Runnable() {
public void run() {
ZeroTierSDK wrapper = new ZeroTierSDK();
wrapper.startOneService(); // Calls to JNI code
}
public void run() {
// Calls to JNI code
zt.startOneService(homeDir);
}
}).start();
```
**Step 4: 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>`:
- Join network and perform network call
```
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
while(!zt.isRunning()) { }
zt.joinNetwork("XXXXXXXXXXXXXXXX");
// Create ZeroTier socket
int sock = zt.ztjniSocket(zt.AF_INET, zt.SOCK_STREAM, 0);
// Connect to remote host
int err = zt.ztjniConnect(sock, "10.9.9.203", 8080);
```
**Step 5: Pick an API**
- If functional interposition isn't available for the API or library you've chosen to use, ZeroTier offers a SOCKS5 proxy server which can allow connectivity to your virtual network as long as your client API supports the SOCKS5 protocol. This proxy service will run alongside the tap service and can be turned on by compiling with the `-DUSE_SOCKS_PROXY` flag. By default, the proxy service is available at `0.0.0.0:1337`.
**Step 6: Join a network!**
- Simply call `wrapper.joinNetwork("XXXXXXXXXXXXXXXX")`
***
*Note for the curious on JNI naming conventions: In order to reference a symbol in the JNI library you need to structure the package and class in your Android Studio project in a very particular way. For example, in the ZeroTierSDK we define a function called `Java_ZeroTier_SDK_startOneService`, the name can be broken down as follows: `Java_PACKAGENAME_CLASSNAME_startOneService`, so as we've defined it, you must create a package called `ZeroTier` and add a class called `SDK`.*

View File

@@ -46,7 +46,9 @@
startingColumnNumber = "9223372036854775807"
endingColumnNumber = "9223372036854775807"
startingLineNumber = "50"
endingLineNumber = "50">
endingLineNumber = "50"
landmarkName = "zt_join_network(const char * nwid)"
landmarkType = "7">
</BreakpointContent>
</BreakpointProxy>
<BreakpointProxy

View File

@@ -78,7 +78,7 @@ class ViewController: NSViewController {
// TCP
if(selectedProtocol == SOCK_STREAM)
{
sock = zts_socket(AF_INET, SOCK_STREAM, 0)
sock = zt_socket(AF_INET, SOCK_STREAM, 0)
var addr = sockaddr_in(sin_len: UInt8(sizeof(sockaddr_in)),
sin_family: UInt8(AF_INET),
sin_port: UInt16(serverPort).bigEndian,
@@ -87,7 +87,7 @@ class ViewController: NSViewController {
inet_pton(AF_INET, serverAddr, &(addr.sin_addr));
let connect_err = zts_connect(sock, UnsafePointer<sockaddr>([addr]), UInt32(addr.sin_len))
let connect_err = zt_connect(sock, UnsafePointer<sockaddr>([addr]), UInt32(addr.sin_len))
print("connect_err = \(connect_err),\(errno)")
if connect_err < 0 {
@@ -119,7 +119,7 @@ class ViewController: NSViewController {
// TCP
if(selectedProtocol == SOCK_STREAM)
{
sock = zts_socket(AF_INET, SOCK_STREAM, 0)
sock = zt_socket(AF_INET, SOCK_STREAM, 0)
var addr = sockaddr_in(sin_len: UInt8(sizeof(sockaddr_in)),
sin_family: UInt8(AF_INET),
sin_port: UInt16(serverPort).bigEndian,
@@ -128,7 +128,7 @@ class ViewController: NSViewController {
inet_pton(AF_INET, serverAddr, &(addr.sin_addr));
let bind_err = zts_bind(sock, UnsafePointer<sockaddr>([addr]), UInt32(addr.sin_len))
let bind_err = zt_bind(sock, UnsafePointer<sockaddr>([addr]), UInt32(addr.sin_len))
print("bind_err = \(bind_err),\(errno)")
@@ -139,13 +139,13 @@ class ViewController: NSViewController {
}
// Put socket into listening state
zts_listen(sock, 1);
zt_listen(sock, 1);
// Accept connection
var len:socklen_t = 0;
var legIntPtr = withUnsafeMutablePointer(&len, { $0 })
while(accepted_sock < 0) {
accepted_sock = zts_accept(sock, UnsafeMutablePointer<sockaddr>([addr]), legIntPtr)
accepted_sock = zt_accept(sock, UnsafeMutablePointer<sockaddr>([addr]), legIntPtr)
}
print("accepted connection")
}

View File

@@ -94,7 +94,7 @@ class ViewController: UIViewController {
// TCP
if(selectedProtocol == SOCK_STREAM)
{
sock = zts_socket(AF_INET, SOCK_STREAM, 0)
sock = zt_socket(AF_INET, SOCK_STREAM, 0)
var addr = sockaddr_in(sin_len: UInt8(sizeof(sockaddr_in)),
sin_family: UInt8(AF_INET),
sin_port: UInt16(serverPort).bigEndian,
@@ -103,7 +103,7 @@ class ViewController: UIViewController {
inet_pton(AF_INET, serverAddr, &(addr.sin_addr));
let connect_err = zts_connect(sock, UnsafePointer<sockaddr>([addr]), UInt32(addr.sin_len))
let connect_err = zt_connect(sock, UnsafePointer<sockaddr>([addr]), UInt32(addr.sin_len))
print("connect_err = \(connect_err),\(errno)")
if connect_err < 0 {
@@ -135,7 +135,7 @@ class ViewController: UIViewController {
// TCP
if(selectedProtocol == SOCK_STREAM)
{
sock = zts_socket(AF_INET, SOCK_STREAM, 0)
sock = zt_socket(AF_INET, SOCK_STREAM, 0)
var addr = sockaddr_in(sin_len: UInt8(sizeof(sockaddr_in)),
sin_family: UInt8(AF_INET),
sin_port: UInt16(serverPort).bigEndian,
@@ -144,7 +144,7 @@ class ViewController: UIViewController {
inet_pton(AF_INET, serverAddr, &(addr.sin_addr));
let bind_err = zts_bind(sock, UnsafePointer<sockaddr>([addr]), UInt32(addr.sin_len))
let bind_err = zt_bind(sock, UnsafePointer<sockaddr>([addr]), UInt32(addr.sin_len))
print("bind_err = \(bind_err),\(errno)")
@@ -155,13 +155,13 @@ class ViewController: UIViewController {
}
// Put socket into listening state
zts_listen(sock, 1);
zt_listen(sock, 1);
// Accept connection
var len:socklen_t = 0;
var legIntPtr = withUnsafeMutablePointer(&len, { $0 })
while(accepted_sock < 0) {
accepted_sock = zts_accept(sock, UnsafeMutablePointer<sockaddr>([addr]), legIntPtr)
accepted_sock = zt_accept(sock, UnsafeMutablePointer<sockaddr>([addr]), legIntPtr)
}
print("accepted connection")
}

View File

@@ -163,6 +163,9 @@ clean:
# example android app project
-cd $(INT)/android/example_app; ./gradlew clean
clean_for_production:
-find . -type f \( -name '*.identity'\) -delete
# For authors
# Copies documentation to all of the relevant directories to make viewing in the repo a little easier

View File

@@ -32,8 +32,8 @@
#include <stdbool.h>
#include "SDK_Signatures.h"
// For defining the Android direct-call API
#if defined(__ANDROID__)
// For defining the Android direct-call API
#include <jni.h>
#endif
@@ -49,6 +49,9 @@ extern void zt_init_rpc(const char *path, const char *nwid);
extern char *api_netpath;
extern char *debug_logfile;
// Function pointers to original system calls
// - These are used when we detect that either the intercept is not
// available or that ZeroTier hasn't administered the given socket
#if defined(__linux__)
extern int (*realaccept4)(ACCEPT4_SIG);
#if !defined(__ANDROID__)
@@ -73,46 +76,55 @@ extern char *debug_logfile;
extern int (*realclose)(CLOSE_SIG);
extern int (*realgetsockname)(GETSOCKNAME_SIG);
ssize_t zt_sendto(SENDTO_SIG);
ssize_t zt_sendmsg(SENDMSG_SIG);
ssize_t zt_recvfrom(RECVFROM_SIG);
ssize_t zt_recvmsg(RECVMSG_SIG);
// Direct call
// - Skips intercept
// - Uses RPC
// - Depending on the target, the API will be exposed as zt_* in
// the specific way needed for that platform, but will be implemented
// in terms of zts_*
int zts_socket(SOCKET_SIG);
int zts_connect(CONNECT_SIG);
int zts_bind(BIND_SIG);
#if defined(__linux__)
int zts_accept4(ACCEPT4_SIG);
#endif
int zts_accept(ACCEPT_SIG);
int zts_listen(LISTEN_SIG);
int zts_setsockopt(SETSOCKOPT_SIG);
int zts_getsockopt(GETSOCKOPT_SIG);
int zts_getsockname(GETSOCKNAME_SIG);
int zts_close(CLOSE_SIG);
ssize_t zts_sendto(SENDTO_SIG);
ssize_t zts_sendmsg(SENDMSG_SIG);
ssize_t zts_recvfrom(RECVFROM_SIG);
ssize_t zts_recvmsg(RECVMSG_SIG);
#if defined(__UNITY_3D__)
ssize_t zt_recv(int fd, void *buf, int len);
ssize_t zt_send(int fd, void *buf, int len);
int zt_set_nonblock(int fd);
ssize_t zts_recv(int fd, void *buf, int len);
ssize_t zts_send(int fd, void *buf, int len);
int zts_set_nonblock(int fd);
#endif
// Android JNI Direct-call API
// - Implemented in terms of zt_* direct calls
#if defined(__ANDROID__)
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_ztjniSocket(JNIEnv *env, jobject thisObj, jint family, jint type, jint protocol);
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_ztjniConnect(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port);
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_ztjniBind(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port);
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_ztjniAccept(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port);
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_ztjniAccept4(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port, jint flags);
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_ztjniListen(JNIEnv *env, jobject thisObj, jint fd, int backlog);
//JNIEXPORT void JNICALL Java_ZeroTier_SDK_ztjniSetsockopt(JNIEnv *env, jobject thisObj);
//JNIEXPORT void JNICALL Java_ZeroTier_SDK_ztjniGetsockopt(JNIEnv *env, jobject thisObj);
//JNIEXPORT void JNICALL Java_ZeroTier_SDK_ztjniGetsockname(JNIEnv *env, jobject thisObj);
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_ztjniClose(JNIEnv *env, jobject thisObj, jint fd);
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1socket(JNIEnv *env, jobject thisObj, jint family, jint type, jint protocol);
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1connect(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port);
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1bind(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port);
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1accept(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port);
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1accept4(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port, jint flags);
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1listen(JNIEnv *env, jobject thisObj, jint fd, int backlog);
//JNIEXPORT void JNICALL Java_ZeroTier_SDK_zt_1setsockopt(JNIEnv *env, jobject thisObj);
//JNIEXPORT void JNICALL Java_ZeroTier_SDK_zt_1getsockopt(JNIEnv *env, jobject thisObj);
//JNIEXPORT void JNICALL Java_ZeroTier_SDK_zt_1getsockname(JNIEnv *env, jobject thisObj);
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1close(JNIEnv *env, jobject thisObj, jint fd);
#endif
int zt_socket(SOCKET_SIG);
int zt_connect(CONNECT_SIG);
int zt_bind(BIND_SIG);
#if defined(__linux__)
int zt_accept4(ACCEPT4_SIG);
#endif
int zt_accept(ACCEPT_SIG);
int zt_listen(LISTEN_SIG);
int zt_setsockopt(SETSOCKOPT_SIG);
int zt_getsockopt(GETSOCKOPT_SIG);
int zt_getsockname(GETSOCKNAME_SIG);
int zt_close(CLOSE_SIG);
// Prototypes for redefinition of syscalls
// - Implemented in SDK_Intercept.c
#if defined(SDK_INTERCEPT)
int socket(SOCKET_SIG);
int connect(CONNECT_SIG);

View File

@@ -20,16 +20,16 @@ void zt_leave_network(const char *nwid);
// Direct Call ZT API
// These functions will provide direct access to ZT-enabled sockets with no hassle
int zts_init_rpc(const char *path, const char *nwid);
int zts_connect(CONNECT_SIG);
int zts_bind(BIND_SIG);
int zts_accept(ACCEPT_SIG);
int zts_listen(LISTEN_SIG);
int zts_socket(SOCKET_SIG);
int zts_setsockopt(SETSOCKOPT_SIG);
int zts_getsockopt(GETSOCKOPT_SIG);
int zts_close(CLOSE_SIG);
int zts_getsockname(GETSOCKNAME_SIG);
int zt_init_rpc(const char *path, const char *nwid);
int zt_connect(CONNECT_SIG);
int zt_bind(BIND_SIG);
int zt_accept(ACCEPT_SIG);
int zt_listen(LISTEN_SIG);
int zt_socket(SOCKET_SIG);
int zt_setsockopt(SETSOCKOPT_SIG);
int zt_getsockopt(GETSOCKOPT_SIG);
int zt_close(CLOSE_SIG);
int zt_getsockname(GETSOCKNAME_SIG);
#endif /* Example_OSX_Bridging_Header_h */

View File

@@ -173,7 +173,7 @@ char *api_netpath;
dwr(MSG_DEBUG, "sendto(%d, %d)\n", sockfd, len);
//if (!check_intercept_enabled())
return realsendto(sockfd, buf, len, flags, addr, addr_len);
return zt_sendto(sockfd, buf, len, flags, addr, addr_len);
return zts_sendto(sockfd, buf, len, flags, addr, addr_len);
}
#endif
@@ -188,7 +188,7 @@ char *api_netpath;
dwr(MSG_DEBUG, "sendmsg()\n");
//if(!check_intercept_enabled())
return realsendmsg(socket, message, flags);
zt_sendmsg(socket, message, flags);
zts_sendmsg(socket, message, flags);
}
#endif
@@ -204,7 +204,7 @@ char *api_netpath;
dwr(MSG_DEBUG, "recvfrom(%d)\n", socket);
if(!check_intercept_enabled())
return realrecvfrom(socket, buffer, length, flags, address, address_len);
return zt_recvfrom(socket, buffer, length, flags, address, address_len);
return zts_recvfrom(socket, buffer, length, flags, address, address_len);
}
#endif
@@ -219,7 +219,7 @@ char *api_netpath;
dwr(MSG_DEBUG, "recvmsg(%d)\n", socket);
//if(!check_intercept_enabled())
return realrecvmsg(socket, message, flags);
return zt_recvmsg(socket, message, flags);
return zts_recvmsg(socket, message, flags);
}
#endif
@@ -244,7 +244,7 @@ char *api_netpath;
return 0;
if(realsetsockopt(socket, level, option_name, option_value, option_len) < 0)
perror("setsockopt():\n");
return zt_setsockopt(socket, level, option_name, option_value, option_len);
return zts_setsockopt(socket, level, option_name, option_value, option_len);
}
// ------------------------------------------------------------------------------
@@ -258,7 +258,7 @@ char *api_netpath;
dwr(MSG_DEBUG, "getsockopt(%d)\n", sockfd);
if (!check_intercept_enabled() || !connected_to_service(sockfd))
return realgetsockopt(sockfd, level, optname, optval, optlen);
return zt_getsockopt(sockfd, level, optname, optval, optlen);
return zts_getsockopt(sockfd, level, optname, optval, optlen);
}
// ------------------------------------------------------------------------------
@@ -289,7 +289,7 @@ char *api_netpath;
dwr(MSG_DEBUG,"realsocket() = %d\n", err);
return err;
}
return zt_socket(socket_family, socket_type, protocol);
return zts_socket(socket_family, socket_type, protocol);
}
// ------------------------------------------------------------------------------
@@ -352,7 +352,7 @@ char *api_netpath;
|| connaddr->sin_family == AF_UNIX)) {
return realconnect(__fd, __addr, __len);
}
return zt_connect(__fd, __addr, __len);
return zts_connect(__fd, __addr, __len);
}
// ------------------------------------------------------------------------------
@@ -410,7 +410,7 @@ char *api_netpath;
errno = ENOTSOCK;
return -1;
}
return zt_bind(sockfd, addr, addrlen);
return zts_bind(sockfd, addr, addrlen);
}
// ------------------------------------------------------------------------------
@@ -421,7 +421,7 @@ char *api_netpath;
#if defined(__linux__)
int accept4(ACCEPT4_SIG) {
dwr(MSG_DEBUG,"accept4(%d):\n", sockfd);
return zt_accept4(sockfd, addr, addrlen, flags);
return zts_accept4(sockfd, addr, addrlen, flags);
}
#endif
@@ -476,7 +476,7 @@ char *api_netpath;
return(realaccept(sockfd, addr, addrlen));
}
return zt_accept(sockfd, addr, addrlen);
return zts_accept(sockfd, addr, addrlen);
}
// ------------------------------------------------------------------------------
@@ -514,7 +514,7 @@ char *api_netpath;
if(!connected_to_service(sockfd)) {
return reallisten(sockfd, backlog);
}
return zt_listen(sockfd, backlog);
return zts_listen(sockfd, backlog);
}
// ------------------------------------------------------------------------------
@@ -527,7 +527,7 @@ char *api_netpath;
if(!check_intercept_enabled()) {
return realclose(fd);
}
return zt_close(fd);
return zts_close(fd);
}
// ------------------------------------------------------------------------------
@@ -547,7 +547,7 @@ char *api_netpath;
dwr(MSG_DEBUG,"getsockname(): not used by service\n");
return realgetsockname(sockfd, addr, addrlen);
}
return zt_getsockname(sockfd, addr, addrlen);
return zts_getsockname(sockfd, addr, addrlen);
}
// ------------------------------------------------------------------------------
@@ -598,5 +598,5 @@ char *api_netpath;
#endif
#endif
#endif // ZT_SDK_INTERCEPT
#endif // zts_SDK_INTERCEPT

View File

@@ -24,29 +24,39 @@
* redistribute it in a modified binary form, please contact ZeroTier Networks
* LLC. Start here: http://www.zerotier.com/
*/
package ZeroTier;
import java.net.SocketAddress;
public class SDK {
// Loads JNI code
// Socket families
public int AF_UNIX = 1;
public int AF_INET = 2;
// Socket types
public int SOCK_STREAM = 1;
public int SOCK_DGRAM = 2;
// Loads JNI code
static { System.loadLibrary("ZeroTierOneJNI"); }
// ZeroTier service controls
public native void startOneService(String homeDir);
public native void joinNetwork(String nwid);
public native void leaveNetwork(String nwid);
public native boolean isRunning();
// ZeroTier service controls
public native void zt_start_service(String homeDir);
public native void zt_join_network(String nwid);
public native void zt_leave_network(String nwid);
public native boolean zt_running();
// Direct-call API
// --- These calls skip the intercept and interface directly via the RPC mechanism ---
public native int ztjniSocket(int family, int type, int protocol);
public native int ztjniConnect(int fd, SocketAddress addr, int addrlen);
public native int ztjniBind(int fd, SocketAddress addr, int addrlen);
public native int ztjniAccept4(int fd, SocketAddress addr, int addrlen);
public native int ztjniAccept(int fd, SocketAddress addr, int addrlen, int flags);
public native int ztjniListen(int fd, int backlog);
//public native int ztjniGetsockopt(int fd, int type, int protocol);
//public native int ztjniSetsockopt(int fd, int type, int protocol);
//public native int ztjniGetsockname(int fd, int type, int protocol);
public native int ztjniClose(int fd);
// --- These calls skip the intercept and interface directly via the RPC mechanism
public native int zt_socket(int family, int type, int protocol);
public native int zt_connect(int fd, String addr, int port);
public native int zt_bind(int fd, String addr, int port);
public native int zt_accept4(int fd, String addr, int port);
public native int zt_accept(int fd, String addr, int port, int flags);
public native int zt_listen(int fd, int backlog);
//public native int zt_getsockopt(int fd, int type, int protocol);
//public native int zt_setsockopt(int fd, int type, int protocol);
//public native int zt_getsockname(int fd, int type, int protocol);
public native int zt_close(int fd);
}

View File

@@ -47,7 +47,6 @@
#include <dlfcn.h>
#include <stdint.h>
#include <sys/socket.h>
//#include <sys/un.h>
#include <strings.h>
#include "SDK.h"

View File

@@ -28,16 +28,7 @@
#ifndef __RPCLIB_H_
#define __RPCLIB_H_
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <strings.h>
#define CANARY_SZ sizeof(uint64_t)
#define PADDING_SZ 12

View File

@@ -60,9 +60,9 @@ std::string localHomeDir; // Local shortened path
std::string givenHomeDir; // What the user/application provides as a suggestion
std::string homeDir; // The resultant platform-specific dir we *must* use internally
std::string netDir;
std::string rpcNWID;
bool rpcEnabled;
std::string rpcNWID;
#ifdef __cplusplus
extern "C" {
@@ -92,56 +92,50 @@ void zt_init_rpc(const char * path, const char * nwid);
}
#endif
void join_network(const char * nwid)
{
std::string confFile = zt1Service->givenHomePath() + "/networks.d/" + nwid + ".conf";
LOGV("writing conf file = %s\n", confFile.c_str());
if(!ZeroTier::OSUtils::mkdir(netDir)) {
LOGV("unable to create %s\n", netDir.c_str());
}
if(!ZeroTier::OSUtils::writeFile(confFile.c_str(), "")) {
LOGV("unable to write network conf file: %s\n", confFile.c_str());
}
// This provides the API with the RPC information
zt_init_rpc(homeDir.c_str(), nwid);
}
void leave_network(const char *nwid) { zt1Service->leave(nwid); }
void zt_join_network(const char * nwid) { join_network(nwid); }
void zt_leave_network(const char * nwid) { leave_network(nwid); }
bool zt_is_running() { return zt1Service->isRunning(); }
void zt_terminate() { zt1Service->terminate(); }
// Basic ZT service controls
void zts_join_network(const char * nwid) {
std::string confFile = zt1Service->givenHomePath() + "/networks.d/" + nwid + ".conf";
LOGV("writing conf file = %s\n", confFile.c_str());
if(!ZeroTier::OSUtils::mkdir(netDir)) {
LOGV("unable to create %s\n", netDir.c_str());
}
if(!ZeroTier::OSUtils::writeFile(confFile.c_str(), "")) {
LOGV("unable to write network conf file: %s\n", confFile.c_str());
}
// Provide the API with the RPC information
zt_init_rpc(homeDir.c_str(), nwid);
}
void zts_leave_network(const char * nwid) { zt1Service->leave(nwid); }
bool zts_is_running() { return zt1Service->isRunning(); }
void zts_terminate() { zt1Service->terminate(); }
// Android JNI wrapper
// JNI naming convention: Java_PACKAGENAME_CLASSNAME_METHODNAME
#if defined(__ANDROID__)
// JNI naming convention: Java_PACKAGENAME_CLASSNAME_METHODNAME
JNIEXPORT void JNICALL Java_ZeroTier_SDK_joinNetwork(JNIEnv *env, jobject thisObj, jstring nwid) {
JNIEXPORT void JNICALL Java_ZeroTier_SDK_zt_1join_1network(JNIEnv *env, jobject thisObj, jstring nwid) {
const char *nwidstr;
if(nwid) {
nwidstr = env->GetStringUTFChars(nwid, NULL);
zt_join_network(nwidstr);
zts_join_network(nwidstr);
}
}
// JNI naming convention: Java_PACKAGENAME_CLASSNAME_METHODNAME
JNIEXPORT void JNICALL Java_ZeroTier_SDK_leaveNetwork(JNIEnv *env, jobject thisObj, jstring nwid) {
JNIEXPORT void JNICALL Java_ZeroTier_SDK_zt_1leave_1network(JNIEnv *env, jobject thisObj, jstring nwid) {
const char *nwidstr;
if(nwid) {
nwidstr = env->GetStringUTFChars(nwid, NULL);
zt_leave_network(nwidstr);
zts_leave_network(nwidstr);
}
}
// JNI naming convention: Java_PACKAGENAME_CLASSNAME_METHODNAME
JNIEXPORT jboolean JNICALL Java_ZeroTier_SDK_isRunning(JNIEnv *env, jobject thisObj) {
JNIEXPORT jboolean JNICALL Java_ZeroTier_SDK_zt_1running(JNIEnv *env, jobject thisObj) {
if(zt1Service)
return zt1Service->isRunning();
return zts_is_running();
return false;
}
// JNI naming convention: Java_PACKAGENAME_CLASSNAME_METHODNAME
JNIEXPORT void JNICALL Java_ZeroTier_SDK_terminate(JNIEnv *env, jobject thisObj) {
JNIEXPORT void JNICALL Java_ZeroTier_SDK_zt_1terminate(JNIEnv *env, jobject thisObj) {
if(zt1Service)
zt1Service->terminate();
zts_terminate();
}
#endif
@@ -156,7 +150,7 @@ void zt_init_rpc(const char * path, const char * nwid);
pthread_key_create(&thr_id_key, NULL);
intercept_thread_id = (int*)malloc(sizeof(int));
*intercept_thread_id = key;
pthread_create(&intercept_thread, NULL, startOneService, (void *)(intercept_thread_id));
pthread_create(&intercept_thread, NULL, zt_start_service, (void *)(intercept_thread_id));
}
void init_service_and_rpc(int key, const char * path, const char * nwid) {
rpcEnabled = true;
@@ -179,18 +173,15 @@ void zt_init_rpc(const char * path, const char * nwid);
* Starts a new service instance
*/
#if defined(__ANDROID__)
// JNI naming convention: Java_PACKAGENAME_CLASSNAME_METHODNAME
JNIEXPORT void JNICALL Java_ZeroTier_SDK_startOneService(JNIEnv *env, jobject thisObj, jstring path) {
if(path) {
JNIEXPORT int JNICALL Java_ZeroTier_SDK_zt_1start_1service(JNIEnv *env, jobject thisObj, jstring path) {
if(path)
homeDir = env->GetStringUTFChars(path, NULL);
}
#else
void *startOneService(void *thread_id) {
void *zt_start_service(void *thread_id) {
#endif
#if defined(SDK_BUNDLED) && !defined(__ANDROID__)
// Don't intercept network calls originating from ZeroTier service
set_intercept_status(INTERCEPT_DISABLED);
set_intercept_status(INTERCEPT_DISABLED); // Ignore network calls from ZT service
#endif
#if defined(__UNITY_3D__)
@@ -198,7 +189,7 @@ void zt_init_rpc(const char * path, const char * nwid);
char current_dir[MAX_DIR_SZ];
getcwd(current_dir, MAX_DIR_SZ);
chdir(service_path.c_str());
homeDir = current_dir; // homeDir shall be current dir
homeDir = current_dir; // homeDir shall be current_dir
#endif
#if defined(__APPLE__)
@@ -231,14 +222,8 @@ void zt_init_rpc(const char * path, const char * nwid);
zt1Service = (ZeroTier::OneService *)0;
// Construct path for network config and supporting service files
if (!homeDir.length()) {
#if defined(__ANDROID__)
return;
#else
return NULL;
#endif
} else {
LOGV("startOneService(): constructing path...\n");
if (homeDir.length()) {
LOGV("start_service(): constructing path...\n");
std::vector<std::string> hpsp(ZeroTier::Utils::split(homeDir.c_str(),ZT_PATH_SEPARATOR_S,"",""));
std::string ptmp;
if (homeDir[0] == ZT_PATH_SEPARATOR)
@@ -254,6 +239,10 @@ void zt_init_rpc(const char * path, const char * nwid);
}
}
}
else {
fprintf(stderr, "start_service(): homeDir is empty, could not construct path\n");
return NULL;
}
#if defined(__IOS__)
// Go to the app's data directory so we can shorten the sun_path we bind to
@@ -287,28 +276,26 @@ void zt_init_rpc(const char * path, const char * nwid);
case ZeroTier::OneService::ONE_NORMAL_TERMINATION:
break;
case ZeroTier::OneService::ONE_UNRECOVERABLE_ERROR:
//fprintf(stderr,"%s: fatal error: %s" ZT_EOL_S,argv[0],zt1Service->fatalErrorMessage().c_str());
//returnValue = 1;
fprintf(stderr,"start_service(): fatal error: %s",zt1Service->fatalErrorMessage().c_str());
break;
case ZeroTier::OneService::ONE_IDENTITY_COLLISION: {
delete zt1Service;
zt1Service = (ZeroTier::OneService *)0;
std::string oldid;
//OSUtils::readFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str(),oldid);
ZeroTier::OSUtils::readFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str(),oldid);
if (oldid.length()) {
//OSUtils::writeFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret.saved_after_collision").c_str(),oldid);
//OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str());
//OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.public").c_str());
ZeroTier::OSUtils::writeFile((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret.saved_after_collision").c_str(),oldid);
ZeroTier::OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.secret").c_str());
ZeroTier::OSUtils::rm((homeDir + ZT_PATH_SEPARATOR_S + "identity.public").c_str());
}
} continue; // restart!
}
break; // terminate loop -- normally we don't keep restarting
}
#if defined(__ANDROID__)
return;
#else
return NULL;
#endif
}
continue; // restart!
}
break; // terminate loop -- normally we don't keep restarting
}
delete zt1Service;
zt1Service = (ZeroTier::OneService *)0;
return NULL;
}
#ifdef __cplusplus

View File

@@ -27,7 +27,6 @@
#include <string>
#ifdef __cplusplus
extern "C" {
#endif
@@ -49,19 +48,27 @@ extern std::string homeDir;
/* If you define anything else in this file it that you wish to expose to your Android
Java application you *must* follow that convention and any corresponding Java package/classes
in your Android project must match this as well */
JNIEXPORT void JNICALL Java_ZeroTier_SDK_startOneService(JNIEnv *env, jobject thisObj, jstring path);
JNIEXPORT void JNICALL Java_ZeroTier_SDK_joinNetwork(JNIEnv *env, jobject thisObj, jstring nwid);
JNIEXPORT void JNICALL Java_ZeroTier_SDK_leaveNetwork(JNIEnv *env, jobject thisObj, jstring nwid);
JNIEXPORT jboolean JNICALL Java_ZeroTier_SDK_isRunning(JNIEnv *env, jobject thisObj);
JNIEXPORT void JNICALL Java_ZeroTier_SDK_zt_1join_1network(JNIEnv *env, jobject thisObj, jstring nwid);
JNIEXPORT void JNICALL Java_ZeroTier_SDK_zt_1leave_1network(JNIEnv *env, jobject thisObj, jstring nwid);
JNIEXPORT jboolean JNICALL Java_ZeroTier_SDK_zt_1running(JNIEnv *env, jobject thisObj);
#else
void *startOneService(void *thread_id);
void init_service(int key, const char * path);
void init_service_and_rpc(int key, const char * path, const char * nwid);
void init_intercept(int key);
#endif
#if defined (__ANDROID__)
JNIEXPORT int JNICALL Java_ZeroTier_SDK_zt_1start_1service(JNIEnv *env, jobject thisObj, jstring path);
#else
void * zt_start_service(void *thread_id);
#endif
void set_intercept_status(int mode);
void join_network(const char * nwid);
void leave_network(const char * nwid);
void zts_join_network(const char * nwid);
void zts_leave_network(const char * nwid);
bool zts_is_running();
void zts_terminate();
#endif

View File

@@ -40,7 +40,6 @@
#include <stdlib.h>
#include <dlfcn.h>
#include <strings.h>
#include <pwd.h>
#include <errno.h>
#include <stdarg.h>
#include <netdb.h>
@@ -51,8 +50,6 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/poll.h>
#include <sys/un.h>
#include <sys/resource.h>
#include <arpa/inet.h>
#include <netinet/in.h>
@@ -131,43 +128,47 @@ int (*realclose)(CLOSE_SIG);
// const struct sockaddr *addr, socklen_t addr_len
#if !defined(__ANDROID__)
ssize_t zt_sendto(SENDTO_SIG)
{
dwr(MSG_DEBUG, "zt_sendto()\n");
if(len > ZT_UDP_DEFAULT_PAYLOAD_MTU) {
errno = EMSGSIZE; // Msg is too large
return -1;
}
int socktype = 0;
socklen_t socktype_len;
getsockopt(sockfd,SOL_SOCKET, SO_TYPE, (void*)&socktype, &socktype_len);
if((socktype & SOCK_STREAM) || (socktype & SOCK_SEQPACKET)) {
if(addr == NULL || flags != 0) {
errno = EISCONN;
#ifdef DYNAMIC_LIB
ssize_t zt_sendto(SENDTO_SIG) // Exposed as API
#else
ssize_t zts_sendto(SENDTO_SIG) // Used as internal implementation
#endif
{
dwr(MSG_DEBUG, "zt_sendto()\n");
if(len > ZT_UDP_DEFAULT_PAYLOAD_MTU) {
errno = EMSGSIZE; // Msg is too large
return -1;
}
}
int socktype = 0;
socklen_t socktype_len;
getsockopt(sockfd,SOL_SOCKET, SO_TYPE, (void*)&socktype, &socktype_len);
// the socket isn't connected
//int err = rpc_send_command(api_netpath, RPC_IS_CONNECTED, -1, &fd, sizeof(struct fd));
//if(err == -1) {
// errno = ENOTCONN;
// return -1;
//}
if((socktype & SOCK_STREAM) || (socktype & SOCK_SEQPACKET)) {
if(addr == NULL || flags != 0) {
errno = EISCONN;
return -1;
}
}
// EMSGSIZE should be returned if the message is too long to be passed atomically through
// the underlying protocol, in our case MTU?
// TODO: More efficient solution
// This connect call is used to get the address info to the stack for sending the packet
int err;
if((err = connect(sockfd, addr, addr_len)) < 0) {
dwr(MSG_DEBUG, "sendto(): unknown problem passing address info to stack\n");
errno = EISCONN; // double-check this is correct
return -1;
// the socket isn't connected
//int err = rpc_send_command(api_netpath, RPC_IS_CONNECTED, -1, &fd, sizeof(struct fd));
//if(err == -1) {
// errno = ENOTCONN;
// return -1;
//}
// EMSGSIZE should be returned if the message is too long to be passed atomically through
// the underlying protocol, in our case MTU?
// TODO: More efficient solution
// This connect call is used to get the address info to the stack for sending the packet
int err;
if((err = connect(sockfd, addr, addr_len)) < 0) {
dwr(MSG_DEBUG, "sendto(): unknown problem passing address info to stack\n");
errno = EISCONN; // double-check this is correct
return -1;
}
return send(sockfd, buf, len, flags);
}
return send(sockfd, buf, len, flags);
}
#endif
// ------------------------------------------------------------------------------
@@ -176,33 +177,37 @@ int (*realclose)(CLOSE_SIG);
// int socket, const struct msghdr *message, int flags
#if !defined(__ANDROID__)
ssize_t zt_sendmsg(SENDMSG_SIG)
{
dwr(MSG_DEBUG, "zt_sendmsg()\n");
char * p, * buf;
size_t tot_len = 0;
size_t err;
struct iovec * iov = message->msg_iov;
for(int i=0; i<message->msg_iovlen; ++i)
tot_len += iov[i].iov_len;
if(tot_len > ZT_UDP_DEFAULT_PAYLOAD_MTU) {
errno = EMSGSIZE; // Message too large to send atomically via underlying protocol, don't send
return -1;
#ifdef DYNAMIC_LIB
ssize_t zt_sendmsg(SENDMSG_SIG)
#else
ssize_t zts_sendmsg(SENDMSG_SIG)
#endif
{
dwr(MSG_DEBUG, "zt_sendmsg()\n");
char * p, * buf;
size_t tot_len = 0;
size_t err;
struct iovec * iov = message->msg_iov;
for(int i=0; i<message->msg_iovlen; ++i)
tot_len += iov[i].iov_len;
if(tot_len > ZT_UDP_DEFAULT_PAYLOAD_MTU) {
errno = EMSGSIZE; // Message too large to send atomically via underlying protocol, don't send
return -1;
}
buf = malloc(tot_len);
if(tot_len != 0 && buf == NULL) {
errno = ENOMEM; // Unable to allocate space for message
return -1;
}
p = buf;
for(int i=0; i < message->msg_iovlen; ++i) {
memcpy(p, iov[i].iov_base, iov[i].iov_len);
p += iov[i].iov_len;
}
err = sendto(socket, buf, tot_len, flags, message->msg_name, message->msg_namelen);
free(buf);
return err;
}
buf = malloc(tot_len);
if(tot_len != 0 && buf == NULL) {
errno = ENOMEM; // Unable to allocate space for message
return -1;
}
p = buf;
for(int i=0; i < message->msg_iovlen; ++i) {
memcpy(p, iov[i].iov_base, iov[i].iov_len);
p += iov[i].iov_len;
}
err = sendto(socket, buf, tot_len, flags, message->msg_name, message->msg_namelen);
free(buf);
return err;
}
#endif
// ------------------------------------------------------------------------------
@@ -212,25 +217,29 @@ int (*realclose)(CLOSE_SIG);
// *restrict address, socklen_t *restrict address_len
#if !defined(__ANDROID__)
ssize_t zt_recvfrom(RECVFROM_SIG)
{
dwr(MSG_DEBUG,"zt_recvfrom(%d)\n", socket);
ssize_t err;
// Since this can be called for connection-oriented sockets,
// we need to check the type before we try to read the address info
/*
int sock_type;
socklen_t type_len;
realgetsockopt(socket, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &type_len);
*/
//if(sock_type == SOCK_DGRAM && address != NULL && address_len != NULL) {
zt_getsockname(socket, address, address_len);
//}
err = read(socket, buffer, length);
if(err < 0)
perror("read:\n");
return err;
}
#ifdef DYNAMIC_LIB
ssize_t zt_recvfrom(RECVFROM_SIG)
#else
ssize_t zts_recvfrom(RECVFROM_SIG)
#endif
{
dwr(MSG_DEBUG,"zt_recvfrom(%d)\n", socket);
ssize_t err;
// Since this can be called for connection-oriented sockets,
// we need to check the type before we try to read the address info
/*
int sock_type;
socklen_t type_len;
realgetsockopt(socket, SOL_SOCKET, SO_TYPE, (void *) &sock_type, &type_len);
*/
//if(sock_type == SOCK_DGRAM && address != NULL && address_len != NULL) {
zts_getsockname(socket, address, address_len);
//}
err = read(socket, buffer, length);
if(err < 0)
perror("read:\n");
return err;
}
#endif
// ------------------------------------------------------------------------------
@@ -239,39 +248,43 @@ int (*realclose)(CLOSE_SIG);
// int socket, struct msghdr *message, int flags
#if !defined(__ANDROID__)
ssize_t zt_recvmsg(RECVMSG_SIG)
{
dwr(MSG_DEBUG, "zt_recvmsg(%d)\n", socket);
ssize_t err, n, tot_len = 0;
char *buf, *p;
struct iovec *iov = message->msg_iov;
#ifdef DYNAMIC_LIB
ssize_t zt_recvmsg(RECVMSG_SIG)
#else
ssize_t zts_recvmsg(RECVMSG_SIG)
#endif
{
dwr(MSG_DEBUG, "zt_recvmsg(%d)\n", socket);
ssize_t err, n, tot_len = 0;
char *buf, *p;
struct iovec *iov = message->msg_iov;
for(int i = 0; i < message->msg_iovlen; ++i)
tot_len += iov[i].iov_len;
buf = malloc(tot_len);
if(tot_len != 0 && buf == NULL) {
errno = ENOMEM;
return -1;
}
n = err = recvfrom(socket, buf, tot_len, flags, message->msg_name, &message->msg_namelen);
p = buf;
for(int i = 0; i < message->msg_iovlen; ++i)
tot_len += iov[i].iov_len;
buf = malloc(tot_len);
if(tot_len != 0 && buf == NULL) {
errno = ENOMEM;
return -1;
}
n = err = recvfrom(socket, buf, tot_len, flags, message->msg_name, &message->msg_namelen);
p = buf;
// According to: http://pubs.opengroup.org/onlinepubs/009695399/functions/recvmsg.html
if(err > message->msg_controllen && !( message->msg_flags & MSG_PEEK)) {
// excess data should be disgarded
message->msg_flags |= MSG_TRUNC; // Indicate that the buffer has been truncated
}
// According to: http://pubs.opengroup.org/onlinepubs/009695399/functions/recvmsg.html
if(err > message->msg_controllen && !( message->msg_flags & MSG_PEEK)) {
// excess data should be disgarded
message->msg_flags |= MSG_TRUNC; // Indicate that the buffer has been truncated
}
while (n > 0) {
ssize_t count = n < iov->iov_len ? n : iov->iov_len;
memcpy (iov->iov_base, p, count);
p += count;
n -= count;
++iov;
while (n > 0) {
ssize_t count = n < iov->iov_len ? n : iov->iov_len;
memcpy (iov->iov_base, p, count);
p += count;
n -= count;
++iov;
}
free(buf);
return err;
}
free(buf);
return err;
}
#endif
// ------------------------------------------------------------------------------
@@ -299,7 +312,11 @@ int (*realclose)(CLOSE_SIG);
// int socket, int level, int option_name, const void *option_value,
// socklen_t option_len
#ifdef DYNAMIC_LIB
int zt_setsockopt(SETSOCKOPT_SIG)
#else
int zts_setsockopt(SETSOCKOPT_SIG)
#endif
{
dwr(MSG_DEBUG, "zt_setsockopt()\n");
return 0;
@@ -311,7 +328,12 @@ int (*realclose)(CLOSE_SIG);
// int sockfd, int level, int optname, void *optval,
// socklen_t *optlen
#ifdef DYNAMIC_LIB
int zt_getsockopt(GETSOCKOPT_SIG)
#else
int zts_getsockopt(GETSOCKOPT_SIG)
#endif
{
dwr(MSG_DEBUG,"zt_getsockopt(%d)\n", sockfd);
if(optname == SO_TYPE) {
@@ -328,12 +350,17 @@ int (*realclose)(CLOSE_SIG);
// int socket_family, int socket_type, int protocol
#if defined(__ANDROID__)
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_ztjniSocket(JNIEnv *env, jobject thisObj, jint family, jint type, jint protocol) {
return zt_socket(family, type, protocol);
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1socket(JNIEnv *env, jobject thisObj, jint family, jint type, jint protocol) {
return zts_socket(family, type, protocol);
}
#endif
int zt_socket(SOCKET_SIG) {
#ifdef DYNAMIC_LIB
int zts_socket(SOCKET_SIG)
#else
int zts_socket(SOCKET_SIG)
#endif
{
get_api_netpath();
dwr(MSG_DEBUG, "zt_socket()\n");
/* Check that type makes sense */
@@ -384,18 +411,22 @@ int (*realclose)(CLOSE_SIG);
// int __fd, const struct sockaddr * __addr, socklen_t __len
#if defined(__ANDROID__)
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_ztjniConnect(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port) {
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1connect(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port) {
struct sockaddr_in addr;
char *str;
(*env)->ReleaseStringUTFChars(env, addrstr, str);
addr.sin_addr.s_addr = inet_addr(str);
addr.sin_family = AF_INET;
addr.sin_port = htons( port );
return zt_connect(fd, (struct sockaddr *)&addr, sizeof(addr));
return zts_connect(fd, (struct sockaddr *)&addr, sizeof(addr));
}
#endif
#ifdef DYNAMIC_LIB
int zt_connect(CONNECT_SIG)
#else
int zts_connect(CONNECT_SIG)
#endif
{
get_api_netpath();
dwr(MSG_DEBUG,"zt_connect(%d)\n", __fd);
@@ -419,7 +450,7 @@ int (*realclose)(CLOSE_SIG);
// int sockfd, const struct sockaddr *addr, socklen_t addrlen
#if defined(__ANDROID__)
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_ztjniBind(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port) {
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1bind(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port) {
struct sockaddr_in addr;
char *str;
// = env->GetStringUTFChars(addrstr, NULL);
@@ -433,7 +464,11 @@ int (*realclose)(CLOSE_SIG);
#endif
#if !defined(__ANDROID__)
#ifdef DYNAMIC_LIB
int zt_bind(BIND_SIG)
#else
int zts_bind(BIND_SIG)
#endif
{
get_api_netpath();
dwr(MSG_DEBUG,"zt_bind(%d)\n", sockfd);
@@ -458,7 +493,7 @@ int (*realclose)(CLOSE_SIG);
// int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags
#if defined(__ANDROID__)
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_ztjniAccept4(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port, jint flags) {
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1accept4(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port, jint flags) {
struct sockaddr_in addr;
char *str;
// = env->GetStringUTFChars(addrstr, NULL);
@@ -466,12 +501,16 @@ int (*realclose)(CLOSE_SIG);
addr.sin_addr.s_addr = inet_addr(str);
addr.sin_family = AF_INET;
addr.sin_port = htons( port );
return zt_accept4(fd, (struct sockaddr *)&addr, sizeof(addr), flags);
return zts_accept4(fd, (struct sockaddr *)&addr, sizeof(addr), flags);
}
#endif
#if defined(__linux__)
#ifdef DYNAMIC_LIB
int zt_accept4(ACCEPT4_SIG)
#else
int zts_accept4(ACCEPT4_SIG)
#endif
{
get_api_netpath();
dwr(MSG_DEBUG,"zt_accept4(%d):\n", sockfd);
@@ -491,7 +530,7 @@ int (*realclose)(CLOSE_SIG);
// int sockfd struct sockaddr *addr, socklen_t *addrlen
#if defined(__ANDROID__)
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_ztjniAccept(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port) {
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1accept(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port) {
struct sockaddr_in addr;
char *str;
// = env->GetStringUTFChars(addrstr, NULL);
@@ -499,11 +538,15 @@ int (*realclose)(CLOSE_SIG);
addr.sin_addr.s_addr = inet_addr(str);
addr.sin_family = AF_INET;
addr.sin_port = htons( port );
return zt_accept(fd, (struct sockaddr *)&addr, sizeof(addr));
return zts_accept(fd, (struct sockaddr *)&addr, sizeof(addr));
}
#endif
#ifdef DYNAMIC_LIB
int zt_accept(ACCEPT_SIG)
#else
int zts_accept(ACCEPT_SIG)
#endif
{
get_api_netpath();
dwr(MSG_DEBUG,"zt_accept(%d):\n", sockfd);
@@ -529,12 +572,16 @@ int (*realclose)(CLOSE_SIG);
// int sockfd, int backlog
#if defined(__ANDROID__)
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_ztjniListen(JNIEnv *env, jobject thisObj, jint fd, int backlog) {
return zt_listen(fd, backlog);
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1listen(JNIEnv *env, jobject thisObj, jint fd, int backlog) {
return zts_listen(fd, backlog);
}
#endif
#ifdef DYNAMIC_LIB
int zt_listen(LISTEN_SIG)
#else
int zts_listen(LISTEN_SIG)
#endif
{
get_api_netpath();
dwr(MSG_DEBUG,"zt_listen(%d):\n", sockfd);
@@ -557,12 +604,17 @@ int (*realclose)(CLOSE_SIG);
// int fd
#if defined(__ANDROID__)
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_ztjniClose(JNIEnv *env, jobject thisObj, jint fd) {
return zt_close(fd);
JNIEXPORT jint JNICALL Java_ZeroTier_SDK_zt_1close(JNIEnv *env, jobject thisObj, jint fd) {
return zts_close(fd);
}
#endif
int zt_close(CLOSE_SIG) {
#ifdef DYNAMIC_LIB
int zt_close(CLOSE_SIG)
#else
int zts_close(CLOSE_SIG)
#endif
{
get_api_netpath();
dwr(MSG_DEBUG, "zt_close(%d)\n", fd);
return realclose(fd);
@@ -573,7 +625,11 @@ int (*realclose)(CLOSE_SIG);
// ------------------------------------------------------------------------------
// int sockfd, struct sockaddr *addr, socklen_t *addrlen
#ifdef DYNAMIC_LIB
int zt_getsockname(GETSOCKNAME_SIG)
#else
int zts_getsockname(GETSOCKNAME_SIG)
#endif
{
get_api_netpath();
dwr(MSG_DEBUG,"zt_getsockname(%d):\n", sockfd);

View File

@@ -28,7 +28,6 @@
#include "SDK.h"
#include "SDK_XcodeWrapper.hpp"
#include "SDK_Signatures.h"
#include <sys/socket.h>
#define INTERCEPT_ENABLED 111
#define INTERCEPT_DISABLED 222
@@ -49,12 +48,12 @@ extern "C" void start_service_and_rpc(const char * path, const char * nwid) {
// Joins a ZeroTier virtual network
extern "C" void zt_join_network(const char * nwid){
join_network(nwid);
zts_join_network(nwid);
}
// Leaves a ZeroTier virtual network
extern "C" void zt_leave_network(const char * nwid){
leave_network(nwid);
zts_leave_network(nwid);
}
// Explicit ZT API wrappers
@@ -65,30 +64,30 @@ extern "C" void zt_leave_network(const char * nwid){
}
#endif
extern "C" int zts_socket(SOCKET_SIG) {
return zt_socket(socket_family, socket_type, protocol);
extern "C" int zt_socket(SOCKET_SIG) {
return zts_socket(socket_family, socket_type, protocol);
}
extern "C" int zts_connect(CONNECT_SIG) {
return zt_connect(__fd, __addr, __len);
extern "C" int zt_connect(CONNECT_SIG) {
return zts_connect(__fd, __addr, __len);
}
extern "C" int zts_bind(BIND_SIG){
return zt_bind(sockfd, addr, addrlen);
extern "C" int zt_bind(BIND_SIG){
return zts_bind(sockfd, addr, addrlen);
}
extern "C" int zts_accept(ACCEPT_SIG) {
return zt_accept(sockfd, addr, addrlen);
extern "C" int zt_accept(ACCEPT_SIG) {
return zts_accept(sockfd, addr, addrlen);
}
extern "C" int zts_listen(LISTEN_SIG) {
return zt_listen(sockfd, backlog);
extern "C" int zt_listen(LISTEN_SIG) {
return zts_listen(sockfd, backlog);
}
extern "C" int zts_setsockopt(SETSOCKOPT_SIG) {
return zt_setsockopt(socket, level, option_name, option_value, option_len);
extern "C" int zt_setsockopt(SETSOCKOPT_SIG) {
return zts_setsockopt(socket, level, option_name, option_value, option_len);
}
extern "C" int zts_getsockopt(GETSOCKOPT_SIG) {
return zt_getsockopt(sockfd, level, optname, optval, optlen);
extern "C" int zt_getsockopt(GETSOCKOPT_SIG) {
return zts_getsockopt(sockfd, level, optname, optval, optlen);
}
extern "C" int zts_close(CLOSE_SIG) {
return zt_close(fd);
extern "C" int zt_close(CLOSE_SIG) {
return zts_close(fd);
}
extern "C" int zts_getsockname(GETSOCKNAME_SIG) {
return zt_getsockname(sockfd, addr, addrlen);
extern "C" int zt_getsockname(GETSOCKNAME_SIG) {
return zts_getsockname(sockfd, addr, addrlen);
}

View File

@@ -28,6 +28,4 @@
#ifndef SDK_XCODE_WRAPPER_HPP
#define SDK_XCODE_WRAPPER_HPP
#include <stdio.h>
#endif /* SDK_XCODE_WRAPPER_HPP */