partial implementation of android direct-call API -- still has path problems

This commit is contained in:
Joseph Henry
2016-07-15 14:52:02 -07:00
parent f805b0d285
commit 40f3404f9d
13 changed files with 279 additions and 66 deletions

View File

@@ -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`

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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);
*/
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -32,6 +32,11 @@
#include <stdbool.h>
#include "SDK_Signatures.h"
// For defining the Android direct-call API
#if defined(__ANDROID__)
#include <jni.h>
#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);

View File

@@ -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 <jni.h>
#include <android/log.h>
#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 <jni.h>
#include <android/log.h>
#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
#endif //
#endif //

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -33,6 +33,11 @@
#include <sys/syscall.h>
#endif
// For defining the Android direct-call API
#if defined(__ANDROID__)
#include <jni.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <sys/un.h>
@@ -42,10 +47,13 @@
#include <dlfcn.h>
#include <stdint.h>
#include <sys/socket.h>
//#include <sys/un.h>
#include <strings.h>
#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) {

View File

@@ -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<std::string> 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:

View File

@@ -29,6 +29,11 @@
#define _GNU_SOURCE
#endif
// For defining the Android direct-call API
#if defined(__ANDROID__)
#include <jni.h>
#endif
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
@@ -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);