diff --git a/integrations/README.md b/integrations/README.md index ebff82a..5ad8b40 100644 --- a/integrations/README.md +++ b/integrations/README.md @@ -45,7 +45,7 @@ For more support on these integrations, or if you'd like help creating a new int *** ### Linux - [Dynamic-linking into an app/service at runtime](../docs/linux_zt_sdk.md) `make linux_shared_lib` - - [Using the SDK with Doc;ker](../docs/docker_linux_zt_sdk.md) `make linux_shared_lib` + - [Using the SDK with Docker](../docs/docker_linux_zt_sdk.md) `make linux_shared_lib` ### Android `make android` - [Embedding within an app](../docs/android_zt_sdk.md) `make android_jni_lib` diff --git a/integrations/android/android_jni_lib/java/jni/Application.mk b/integrations/android/android_jni_lib/java/jni/Application.mk index 8437a62..8ac5e8a 100644 --- a/integrations/android/android_jni_lib/java/jni/Application.mk +++ b/integrations/android/android_jni_lib/java/jni/Application.mk @@ -1,6 +1,7 @@ NDK_TOOLCHAIN_VERSION := clang APP_STL := c++_static -APP_CPPFLAGS := -O3 -DZT_DEBUG -DSDK_DEBUG -DLWIP_DEBUG -DUSE_SOCKS_PROXY -DSDK -fPIC -fPIE -fvectorize -Wall -fstack-protector -fexceptions -fno-strict-aliasing -Wno-deprecated-register -DZT_NO_TYPE_PUNNING=1 +APP_CPPFLAGS := -g -O3 -DSDK_BUNDLED -DZT_DEBUG -DSDK_DEBUG -DLWIP_DEBUG -DUSE_SOCKS_PROXY -DSDK -fPIC -fPIE -fvectorize -Wall -fstack-protector -fexceptions -fno-strict-aliasing -Wno-deprecated-register -DZT_NO_TYPE_PUNNING=1 +APP_CFLAGS := -g -DSDK_BUNDLED APP_PLATFORM := android-14 # Architectures diff --git a/integrations/android/example_app/app/src/main/java/ZeroTier/SDK.java b/integrations/android/example_app/app/src/main/java/ZeroTier/SDK.java index b0f7386..241cad3 100644 --- a/integrations/android/example_app/app/src/main/java/ZeroTier/SDK.java +++ b/integrations/android/example_app/app/src/main/java/ZeroTier/SDK.java @@ -1,8 +1,36 @@ package ZeroTier; + +import java.net.SocketAddress; + public class SDK { + + // 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(); - static { System.loadLibrary("ZeroTierOneJNI"); } // Loads JNI code + + // 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); } \ No newline at end of file diff --git a/integrations/android/example_app/app/src/main/java/com/example/joseph/example_app/MainActivity.java b/integrations/android/example_app/app/src/main/java/com/example/joseph/example_app/MainActivity.java index 42be80d..1a499cb 100644 --- a/integrations/android/example_app/app/src/main/java/com/example/joseph/example_app/MainActivity.java +++ b/integrations/android/example_app/app/src/main/java/com/example/joseph/example_app/MainActivity.java @@ -2,12 +2,14 @@ package com.example.joseph.example_app; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; +import android.os.Environment; import android.util.Log; - -import ZeroTier.SDK; - import java.net.InetSocketAddress; import java.net.*; +import android.content.Context; +import android.os.Handler; + +import ZeroTier.SDK; public class MainActivity extends AppCompatActivity { @@ -16,28 +18,64 @@ public class MainActivity extends AppCompatActivity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - final SDK wrapper = new SDK(); - final String homeDir = "sdcard/zerotier"; + final SDK zt = new SDK(); + final String homeDir = getApplicationContext().getFilesDir() + "/zerotier"; // Service thread new Thread(new Runnable() { public void run() { - wrapper.startOneService(homeDir); // Calls to JNI code + // Calls to JNI code + zt.startOneService(homeDir); } }).start(); - // Wait for service before joining network - Log.d("SDK-Javaland", "Waiting for service to start...\n"); - while(!wrapper.isRunning()) { - Log.d("SDK-Javaland", "Waiting...\n"); + Log.d("SDK", "Starting service...\n"); + while(!zt.isRunning()) { } + Log.d("SDK","Joining network...\n"); + zt.joinNetwork("565799d8f65063e5"); + +/* + final Handler handler = new Handler(); + handler.postDelayed(new Runnable() { + @Override + public void run() { + //Do something after 100ms + } + }, 10000); +*/ + + try + { + Thread.sleep(1000); } - Log.d("SDK-Javaland","Joining network...\n"); - wrapper.joinNetwork("565799d8f65063e5"); + catch(java.lang.InterruptedException e) + { + + } + + + // Create ZeroTier socket + Log.d("","ztjniSocket()\n"); + int sock = zt.ztjniSocket(zt.AF_INET, zt.SOCK_STREAM, 0); + Log.d("", "ztjniSocket() = " + sock + "\n"); + + + // Construct remote host address + //InetAddress addr = InetAddress.getByName("10.144.211.245"); + //int port = 8080; + //SocketAddress sockaddr = new InetSocketAddress(addr, port); + + // Connect to remote host + //Log.d("","ztjniConnect()\n"); + //int err = zt.ztjniConnect(sock, "10.144.211.245", 8080); + //Log.d("", "ztjniConnect() = " + err + "\n"); // Set up example proxy connection to SDK proxy server + /* Log.d("ZTSDK-InJavaland", "Setting up connection to SDK proxy server"); Socket s = new Socket(); SocketAddress proxyAddr = new InetSocketAddress("0.0.0.0", 1337); Proxy proxy = new Proxy(Proxy.Type.SOCKS, proxyAddr); + */ } } \ No newline at end of file diff --git a/integrations/android/example_app/gradle.properties b/integrations/android/example_app/gradle.properties index aac7c9b..57e6f04 100644 --- a/integrations/android/example_app/gradle.properties +++ b/integrations/android/example_app/gradle.properties @@ -11,6 +11,8 @@ # The setting is particularly useful for tweaking memory settings. org.gradle.jvmargs=-Xmx1536m +org.gradle.daemon=true + # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects diff --git a/make-mac.mk b/make-mac.mk index d2ff04f..49901e0 100644 --- a/make-mac.mk +++ b/make-mac.mk @@ -87,7 +87,7 @@ android_jni_lib: cd $(INT)/android/android_jni_lib/proj; ./gradlew assembleDebug # copy binary into example android project dir # mv $(INT)/android/android_jni_lib/java/libs/* build - mv $(INT)/android/android_jni_lib/java/libs/* $(INT)/android/example_app/app/src/main/jniLibs + mv -f $(INT)/android/android_jni_lib/java/libs/* $(INT)/android/example_app/app/src/main/jniLibs # cd build; for res_f in *; do mv "$res_f" "android_jni_lib_$res_f"; done # cp docs/android_zt_sdk.md $(BUILD)/README.md diff --git a/src/SDK.h b/src/SDK.h index f9d9ab7..72052f6 100644 --- a/src/SDK.h +++ b/src/SDK.h @@ -32,6 +32,11 @@ #include #include "SDK_Signatures.h" +// For defining the Android direct-call API +#if defined(__ANDROID__) + #include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -80,6 +85,20 @@ ssize_t zt_recvmsg(RECVMSG_SIG); int zt_set_nonblock(int fd); #endif +// Android JNI Direct-call API +#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); +#endif + int zt_socket(SOCKET_SIG); int zt_connect(CONNECT_SIG); int zt_bind(BIND_SIG); diff --git a/src/SDK_Debug.c b/src/SDK_Debug.c index 3701dfc..cfda981 100644 --- a/src/SDK_Debug.c +++ b/src/SDK_Debug.c @@ -54,6 +54,27 @@ #define MSG_DEBUG 4 // Information which is only useful to someone debugging #define MSG_DEBUG_EXTRA 5 // If nothing in your world makes sense +#ifdef __cplusplus +extern "C" { +#endif + #if __ANDROID__ + #include + #include + #define LOG_TAG "ZTSDK" + #define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) + #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) + #define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) + #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) + #else + #define LOGV(...) fprintf(stdout, __VA_ARGS__) + #define LOGI(...) fprintf(stdout, __VA_ARGS__) + #define LOGD(...) fprintf(stdout, __VA_ARGS__) + #define LOGE(...) fprintf(stdout, __VA_ARGS__) + #endif +#ifdef __cplusplus +} // extern "C" +#endif + //char *debug_logfile = (char*)0; void dwr(int level, const char *fmt, ... ); @@ -94,33 +115,17 @@ void dwr(int level, const char *fmt, ... ) va_start(ap, fmt); fprintf(stderr, "%s [tid=%7d] ", timestring, tid); vfprintf(stderr, fmt, ap); + +// Outputs to Android debug console +#if defined(__ANDROID__) + LOGV(fmt, ap); +#endif + fflush(stderr); errno = saveerr; va_end(ap); #endif // _SDK_DEBUG } -#ifdef __cplusplus -extern "C" { -#endif - #if __ANDROID__ - #include - #include - #define LOG_TAG "ZTSDK" - #define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) - #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)) - #define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) - #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)) - #else - #define LOGV(...) fprintf(stdout, __VA_ARGS__) - #define LOGI(...) fprintf(stdout, __VA_ARGS__) - #define LOGD(...) fprintf(stdout, __VA_ARGS__) - #define LOGE(...) fprintf(stdout, __VA_ARGS__) - #endif -#ifdef __cplusplus -} // extern "C" -#endif - -#endif - -#endif \ No newline at end of file +#endif // +#endif // \ No newline at end of file diff --git a/src/SDK_EthernetTap.cpp b/src/SDK_EthernetTap.cpp index 8909e97..a3f3ca6 100644 --- a/src/SDK_EthernetTap.cpp +++ b/src/SDK_EthernetTap.cpp @@ -148,8 +148,9 @@ NetconEthernetTap::NetconEthernetTap( _unixListenSocket = _phy.unixListen(sockPath,(void *)this); dwr(MSG_DEBUG, " NetconEthernetTap initialized on: %s\n", sockPath); - //if (!_unixListenSocket) - // throw std::runtime_error(std::string("unable to bind to ")+sockPath); + LOGV(" NetconEthernetTap initialized on: %s\n", sockPath); + if (!_unixListenSocket) + LOGV("unable to bind to: %s\n", sockPath); _thread = Thread::start(this); } diff --git a/src/SDK_JNI_Java_Wapper.java b/src/SDK_JNI_Java_Wapper.java new file mode 100644 index 0000000..faa9180 --- /dev/null +++ b/src/SDK_JNI_Java_Wapper.java @@ -0,0 +1,25 @@ +package ZeroTier; +public class SDK { + + // 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(); + + // 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); +} \ No newline at end of file diff --git a/src/SDK_RPC.c b/src/SDK_RPC.c index a0b8573..168f6f8 100644 --- a/src/SDK_RPC.c +++ b/src/SDK_RPC.c @@ -33,6 +33,11 @@ #include #endif +// For defining the Android direct-call API +#if defined(__ANDROID__) + #include +#endif + #include #include #include @@ -42,10 +47,13 @@ #include #include #include +//#include #include #include "SDK.h" #include "SDK_RPC.h" +#include "SDK_Debug.h" + // externs common between SDK_Intercept and SDK_Socket from SDK.h int (*realsocket)(SOCKET_SIG); @@ -109,7 +117,7 @@ int load_symbols_rpc() { #if defined(SDK_BUNDLED) || defined(__IOS__) || defined(__UNITY_3D__) realsocket = dlsym(RTLD_NEXT, "socket"); - realconnect = dlsym(RTLD_NEXT, "connect"); + realconnect = dlsym(RTLD_NOW, "connect"); if(!realconnect || !realsocket) return -1; #endif @@ -118,6 +126,7 @@ int load_symbols_rpc() int rpc_join(char * sockname) { + LOGV("RPC = %s\n", sockname); if(sockname == NULL) { printf("Warning, rpc netpath is NULL\n"); } @@ -129,13 +138,22 @@ int rpc_join(char * sockname) addr.sun_family = AF_UNIX; strncpy(addr.sun_path, sockname, sizeof(addr.sun_path)-1); int sock; + +#if defined(__ANDROID__) + if((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){ +#else if((sock = realsocket(AF_UNIX, SOCK_STREAM, 0)) < 0){ - fprintf(stderr, "Error while creating RPC socket\n"); +#endif + LOGV(stderr, "Error while creating RPC socket\n"); return -1; } while((conn_err != 0) && (attempts < SERVICE_CONNECT_ATTEMPTS)){ - if((conn_err = realconnect(sock, (struct sockaddr*)&addr, sizeof(addr))) != 0) { - fprintf(stderr, "Error while connecting to RPC socket. Re-attempting...\n"); + #if defined(__ANDROID__) + if((conn_err = connect(sock, (struct sockaddr*)&addr, sizeof(addr))) != 0) { + #else + if((conn_err = realconnect(sock, (struct sockaddr*)&addr, sizeof(addr))) != 0) { + #endif + LOGV("Error while connecting to RPC socket. Re-attempting...\n"); sleep(1); } else @@ -157,9 +175,7 @@ int rpc_send_command(char *path, int cmd, int forfd, void *data, int len) memcpy(CANARY+CANARY_SZ, padding, sizeof(padding)); uint64_t canary_num; // ephemeral RPC socket used only for this command - printf("calling rpc_join"); int rpc_sock = rpc_join(path); - printf("fin\n"); // Generate token int fdrand = open("/dev/urandom", O_RDONLY); if(read(fdrand, &CANARY, CANARY_SZ) < 0) { diff --git a/src/SDK_ServiceSetup.cpp b/src/SDK_ServiceSetup.cpp index 13866eb..2b19592 100644 --- a/src/SDK_ServiceSetup.cpp +++ b/src/SDK_ServiceSetup.cpp @@ -94,7 +94,8 @@ void zt_init_rpc(const char * path, const char * nwid); //zt1Service->join(nwid); LOGV("started up\n"); - //zt_init_rpc(homeDir.c_str(), nwid); // This provides the shim API with the RPC information + // This provides the shim API with the RPC information + zt_init_rpc(homeDir.c_str(), nwid); } void leave_network(const char *nwid) { zt1Service->leave(nwid); } @@ -175,7 +176,7 @@ void zt_init_rpc(const char * path, const char * nwid); void *startOneService(void *thread_id) { #endif - #if defined(SDK_BUNDLED) + #if defined(SDK_BUNDLED) && !defined(__ANDROID__) // Don't intercept network calls originating from ZeroTier service set_intercept_status(INTERCEPT_DISABLED); #endif @@ -196,11 +197,6 @@ void zt_init_rpc(const char * path, const char * nwid); homeDir = current_dir; // homeDir shall be current dir #endif - #if defined(__ANDROID__) - homeDir = "/sdcard/zerotier"; - join_network("565799d8f65063e5"); - #endif - #if defined(__APPLE__) #include "TargetConditionals.h" #if TARGET_IPHONE_SIMULATOR @@ -211,6 +207,15 @@ void zt_init_rpc(const char * path, const char * nwid); #endif } + #if defined(__ANDROID__) + /* NOTE: Since on Android devices the sdcard is formatted as fat32, we can't use this + location to set up the RPC unix domain socket. Rather we must use the application's + specific data directory given by getApplicationContext().getFilesDir() */ + //rpcDir = homeDir; // Take given homeDir as rpcDir + //homeDir = "/sdcard/zerotier"; // Use fat32-formatted sdcard for writing network conf & supporting files + //join_network("565799d8f65063e5"); + #endif + LOGV("homeDir = %s", homeDir.c_str()); // Where network .conf files will be stored netDir = homeDir + "/networks.d"; @@ -225,8 +230,7 @@ void zt_init_rpc(const char * path, const char * nwid); return NULL; #endif } else { - LOGV("constructing path...\n"); - + LOGV("startOneService(): constructing path...\n"); std::vector hpsp(ZeroTier::Utils::split(homeDir.c_str(),ZT_PATH_SEPARATOR_S,"","")); std::string ptmp; if (homeDir[0] == ZT_PATH_SEPARATOR) @@ -237,28 +241,22 @@ void zt_init_rpc(const char * path, const char * nwid); ptmp.append(*pi); if ((*pi != ".")&&(*pi != "..")) { if (!ZeroTier::OSUtils::mkdir(ptmp)) { - std::string homePathErrStr = "home path does not exist, and could not create"; - throw std::runtime_error(homePathErrStr); + LOGV("startOneService(): home path does not exist, and could not create\n"); } } } } //chdir(current_dir); // Return to previous current working directory (at the request of Unity3D) - //Debug(homeDir.c_str()); // Generate random port for new service instance unsigned int randp = 0; ZeroTier::Utils::getSecureRandom(&randp,sizeof(randp)); int servicePort = 9000 + (randp % 1000); - - LOGV("generated port\n"); - + for(;;) { zt1Service = ZeroTier::OneService::newInstance(homeDir.c_str(),servicePort); - LOGV("created new instance\n"); - switch(zt1Service->run()) { case ZeroTier::OneService::ONE_STILL_RUNNING: // shouldn't happen, run() won't return until done case ZeroTier::OneService::ONE_NORMAL_TERMINATION: diff --git a/src/SDK_Sockets.c b/src/SDK_Sockets.c index 5686fa7..d06c99d 100644 --- a/src/SDK_Sockets.c +++ b/src/SDK_Sockets.c @@ -29,6 +29,11 @@ #define _GNU_SOURCE #endif +// For defining the Android direct-call API +#if defined(__ANDROID__) + #include +#endif + #include #include #include @@ -95,11 +100,13 @@ int (*realclose)(CLOSE_SIG); if(!api_netpath) { #if defined(SDK_BUNDLED) // Get the path/nwid from the user application + // netpath = [path + "/nc_" + nwid] char *fullpath = malloc(strlen(path)+strlen(nwid)+1); if(fullpath) { strcpy(fullpath, path); strcat(fullpath, nwid); - api_netpath = fullpath; + //api_netpath = fullpath; + api_netpath = "/data/data/com.example.joseph.example_app/files/zerotier/nc_565799d8f65063e5"; } #else // Get path/nwid from environment variables @@ -316,6 +323,12 @@ 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); + } +#endif + int zt_socket(SOCKET_SIG) { get_api_netpath(); dwr(MSG_DEBUG, "zt_socket()\n"); @@ -355,7 +368,9 @@ int (*realclose)(CLOSE_SIG); #endif /* -1 is passed since we we're generating the new socket in this call */ printf("path = %s\n", api_netpath); + LOGV("path = %s\n", api_netpath); int err = rpc_send_command(api_netpath, RPC_SOCKET, -1, &rpc_st, sizeof(struct socket_st)); + LOGV("socket() = %s\n", err); dwr(MSG_DEBUG," socket() = %d\n", err); return err; } @@ -365,6 +380,19 @@ 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) { + struct sockaddr_in addr; + char *str; + // = env->GetStringUTFChars(addrstr, NULL); + (*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)); + } +#endif + int zt_connect(CONNECT_SIG) { get_api_netpath(); @@ -388,6 +416,20 @@ 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) { + struct sockaddr_in addr; + char *str; + // = env->GetStringUTFChars(addrstr, NULL); + (*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_bind(fd, (struct sockaddr *)&addr, sizeof(addr)); + return 0; + } +#endif + #if !defined(__ANDROID__) int zt_bind(BIND_SIG) { @@ -413,6 +455,19 @@ 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) { + struct sockaddr_in addr; + char *str; + // = env->GetStringUTFChars(addrstr, NULL); + (*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_accept4(fd, (struct sockaddr *)&addr, sizeof(addr), flags); + } +#endif + #if defined(__linux__) int zt_accept4(ACCEPT4_SIG) { @@ -433,6 +488,19 @@ 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) { + struct sockaddr_in addr; + char *str; + // = env->GetStringUTFChars(addrstr, NULL); + (*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_accept(fd, (struct sockaddr *)&addr, sizeof(addr)); + } +#endif + int zt_accept(ACCEPT_SIG) { get_api_netpath(); @@ -458,6 +526,12 @@ 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); + } +#endif + int zt_listen(LISTEN_SIG) { get_api_netpath(); @@ -480,6 +554,12 @@ 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); + } +#endif + int zt_close(CLOSE_SIG) { get_api_netpath(); dwr(MSG_DEBUG, "zt_close(%d)\n", fd);