summaryrefslogtreecommitdiff
path: root/src/ZeroTierSDK.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ZeroTierSDK.cpp')
-rw-r--r--src/ZeroTierSDK.cpp227
1 files changed, 202 insertions, 25 deletions
diff --git a/src/ZeroTierSDK.cpp b/src/ZeroTierSDK.cpp
index 3cf7ab5..18c341a 100644
--- a/src/ZeroTierSDK.cpp
+++ b/src/ZeroTierSDK.cpp
@@ -98,7 +98,7 @@ void zts_stop() {
}
}
-void zts_join_network(const char * nwid) {
+void zts_join(const char * nwid) {
if(zt1Service) {
std::string confFile = zt1Service->givenHomePath() + "/networks.d/" + nwid + ".conf";
if(!ZeroTier::OSUtils::mkdir(ZeroTier::netDir))
@@ -109,7 +109,7 @@ void zts_join_network(const char * nwid) {
}
}
-void zts_join_network_soft(const char * filepath, const char * nwid) {
+void zts_join_soft(const char * filepath, const char * nwid) {
std::string net_dir = std::string(filepath) + "/networks.d/";
std::string confFile = net_dir + std::string(nwid) + ".conf";
if(!ZeroTier::OSUtils::mkdir(net_dir)) {
@@ -122,12 +122,12 @@ void zts_join_network_soft(const char * filepath, const char * nwid) {
}
}
-void zts_leave_network(const char * nwid) {
+void zts_leave(const char * nwid) {
if(zt1Service)
zt1Service->leave(nwid);
}
-void zts_leave_network_soft(const char * filepath, const char * nwid) {
+void zts_leave_soft(const char * filepath, const char * nwid) {
std::string net_dir = std::string(filepath) + "/networks.d/";
ZeroTier::OSUtils::rm((net_dir + nwid + ".conf").c_str());
}
@@ -171,7 +171,7 @@ int zts_get_device_id(char *devID) {
return -1;
}
-int zts_service_running() {
+int zts_running() {
return !zt1Service ? false : zt1Service->isRunning();
}
@@ -322,10 +322,11 @@ int zts_socket(ZT_SOCKET_SIG) {
DEBUG_INFO();
ZeroTier::_multiplexer_lock.lock();
ZeroTier::Connection *conn = new ZeroTier::Connection();
- int err, protocol_version;
+ int err = 0, protocol_version = 0;
// set up pico_socket
struct pico_socket * psock;
+ // TODO: check ifdef logic here
#if defined(SDK_IPV4)
protocol_version = PICO_PROTO_IPV4;
#endif
@@ -842,48 +843,68 @@ int zts_write(ZT_WRITE_SIG) {
/* JNI naming convention: Java_PACKAGENAME_CLASSNAME_METHODNAME */
/****************************************************************************/
-#if defined(__ANDROID__) || defined(__JNI_LIB__)
+
+#if defined(SDK_JNI)
+
+namespace ZeroTier {
+
+ #include <jni.h>
+
+ JNIEXPORT int JNICALL Java_zerotier_ZeroTier_ztjni_1start(JNIEnv *env, jobject thisObj, jstring path) {
+ if(path) {
+ homeDir = env->GetStringUTFChars(path, NULL);
+ zts_start(homeDir.c_str());
+ }
+ }
+ // Shuts down ZeroTier service and SOCKS5 Proxy server
+ JNIEXPORT void JNICALL Java_zerotier_ZeroTier_ztjni_1stop(JNIEnv *env, jobject thisObj) {
+ if(zt1Service)
+ zts_stop();
+ }
+
// Returns whether the ZeroTier service is running
- JNIEXPORT jboolean JNICALL Java_zerotier_ZeroTier_zt_1service_1is_1running(
+ JNIEXPORT jboolean JNICALL Java_zerotier_ZeroTier_ztjni_1running(
JNIEnv *env, jobject thisObj)
{
- return zts_service_is_running();
+ return zts_running();
}
// Returns path for ZT config/data files
- JNIEXPORT jstring JNICALL Java_zerotier_ZeroTier_zt_1get_1homepath(
+ JNIEXPORT jstring JNICALL Java_zerotier_ZeroTier_ztjni_1homepath(
JNIEnv *env, jobject thisObj)
{
- return (*env).NewStringUTF(zts_get_homepath());
+ // TODO: fix, should copy into given arg
+ // return (*env).NewStringUTF(zts_get_homepath());
+ return (*env).NewStringUTF("");
}
// Join a network
- JNIEXPORT void JNICALL Java_zerotier_ZeroTier_zt_1join_1network(
+ JNIEXPORT void JNICALL Java_zerotier_ZeroTier_ztjni_1join(
JNIEnv *env, jobject thisObj, jstring nwid)
{
const char *nwidstr;
if(nwid) {
nwidstr = env->GetStringUTFChars(nwid, NULL);
- zts_join_network(nwidstr);
+ zts_join(nwidstr);
}
}
// Leave a network
- JNIEXPORT void JNICALL Java_zerotier_ZeroTier_zt_1leave_1network(
+ JNIEXPORT void JNICALL Java_zerotier_ZeroTier_ztjni_1leave(
JNIEnv *env, jobject thisObj, jstring nwid)
{
const char *nwidstr;
if(nwid) {
nwidstr = env->GetStringUTFChars(nwid, NULL);
- zts_leave_network(nwidstr);
+ zts_leave(nwidstr);
}
}
// FIXME: Re-implemented to make it play nicer with the C-linkage required for Xcode integrations
// Now only returns first assigned address per network. Shouldn't normally be a problem
- JNIEXPORT jobject JNICALL Java_zerotier_ZeroTier_zt_1get_1ipv4_1address(
+ JNIEXPORT jobject JNICALL Java_zerotier_ZeroTier_ztjni_1get_1ipv4_1address(
JNIEnv *env, jobject thisObj, jstring nwid)
{
const char *nwid_str = env->GetStringUTFChars(nwid, NULL);
char address_string[32];
memset(address_string, 0, 32);
- zts_get_ipv4_address(nwid_str, address_string);
+ zts_get_ipv4_address(nwid_str, address_string, ZT_MAX_IPADDR_LEN);
jclass clazz = (*env).FindClass("java/util/ArrayList");
jobject addresses = (*env).NewObject(clazz, (*env).GetMethodID(clazz, "<init>", "()V"));
jstring _str = (*env).NewStringUTF(address_string);
@@ -891,13 +912,13 @@ int zts_write(ZT_WRITE_SIG) {
return addresses;
}
- JNIEXPORT jobject JNICALL Java_zerotier_ZeroTier_zt_1get_1ipv6_1address(
+ JNIEXPORT jobject JNICALL Java_zerotier_ZeroTier_ztjni_1get_1ipv6_1address(
JNIEnv *env, jobject thisObj, jstring nwid)
{
const char *nwid_str = env->GetStringUTFChars(nwid, NULL);
char address_string[32];
memset(address_string, 0, 32);
- zts_get_ipv6_address(nwid_str, address_string);
+ zts_get_ipv6_address(nwid_str, address_string, ZT_MAX_IPADDR_LEN);
jclass clazz = (*env).FindClass("java/util/ArrayList");
jobject addresses = (*env).NewObject(clazz, (*env).GetMethodID(clazz, "<init>", "()V"));
jstring _str = (*env).NewStringUTF(address_string);
@@ -906,17 +927,173 @@ int zts_write(ZT_WRITE_SIG) {
}
// Returns the device is in integer form
- JNIEXPORT jint Java_zerotier_ZeroTier_zt_1get_1device_1id()
+ JNIEXPORT jint Java_zerotier_ZeroTier_ztjni_1get_1device_1id()
{
return zts_get_device_id(NULL); // TODO
}
- // Returns whether the path to an endpoint is currently relayed by a root server
- JNIEXPORT jboolean JNICALL Java_zerotier_ZeroTier_zt_1is_1relayed()
+
+ JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1send(JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len, int flags)
{
- return 0;
- // TODO
- // zts_is_relayed();
+ jbyte *body = (*env).GetByteArrayElements((_jbyteArray *)buf, 0);
+ char * bufp = (char *)malloc(sizeof(char)*len);
+ memcpy(bufp, body, len);
+ (*env).ReleaseByteArrayElements((_jbyteArray *)buf, body, 0);
+ int written_bytes = zts_write(fd, body, len);
+ return written_bytes;
}
+
+ JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1sendto(
+ JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len, jint flags, jobject ztaddr)
+ {
+ struct sockaddr_in addr;
+ jclass cls = (*env).GetObjectClass( ztaddr);
+ jfieldID f = (*env).GetFieldID( cls, "port", "I");
+ addr.sin_port = htons((*env).GetIntField( ztaddr, f));
+ f = (*env).GetFieldID( cls, "_rawAddr", "J");
+ addr.sin_addr.s_addr = (*env).GetLongField( ztaddr, f);
+ addr.sin_family = AF_INET;
+ //LOGV("zt_sendto(): fd = %d\naddr = %s\nport=%d", fd, inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
+ // TODO: Optimize this
+ jbyte *body = (*env).GetByteArrayElements((_jbyteArray *)buf, 0);
+ char * bufp = (char *)malloc(sizeof(char)*len);
+ memcpy(bufp, body, len);
+ (*env).ReleaseByteArrayElements((_jbyteArray *)buf, body, 0);
+ // "connect" and send buffer contents
+ int sent_bytes = zts_sendto(fd, body, len, flags, (struct sockaddr *)&addr, sizeof(addr));
+ return sent_bytes;
+ }
+
+ JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1recvfrom(
+ JNIEnv *env, jobject thisObj, jint fd, jbyteArray buf, jint len, jint flags, jobject ztaddr)
+ {
+ struct sockaddr_in addr;
+ jbyte *body = (*env).GetByteArrayElements( buf, 0);
+ unsigned char buffer[ZT_SDK_MTU];
+ int payload_offset = sizeof(int) + sizeof(struct sockaddr_storage);
+ int rxbytes = zts_recvfrom(fd, &buffer, len, flags, (struct sockaddr *)&addr, (socklen_t *)sizeof(struct sockaddr_storage));
+ if(rxbytes > 0)
+ memcpy(body, (jbyte*)buffer + payload_offset, rxbytes);
+ (*env).ReleaseByteArrayElements( buf, body, 0);
+ // Update fields of Java ZTAddress object
+ jfieldID fid;
+ jclass cls = (*env).GetObjectClass( ztaddr);
+ fid = (*env).GetFieldID( cls, "port", "I");
+ (*env).SetIntField( ztaddr, fid, addr.sin_port);
+ fid = (*env).GetFieldID( cls,"_rawAddr", "J");
+ (*env).SetLongField( ztaddr, fid,addr.sin_addr.s_addr);
+ return rxbytes;
+ }
+
+ JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1write(JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len)
+ {
+ jbyte *body = (*env).GetByteArrayElements((_jbyteArray *)buf, 0);
+ char * bufp = (char *)malloc(sizeof(char)*len);
+ memcpy(bufp, body, len);
+ (*env).ReleaseByteArrayElements((_jbyteArray *)buf, body, 0);
+ int written_bytes = zts_write(fd, body, len);
+ return written_bytes;
+ }
+
+ JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1read(JNIEnv *env, jobject thisObj, jint fd, jarray buf, jint len)
+ {
+ jbyte *body = (*env).GetByteArrayElements((_jbyteArray *)buf, 0);
+ int read_bytes = read(fd, body, len);
+ (*env).ReleaseByteArrayElements((_jbyteArray *)buf, body, 0);
+ return read_bytes;
+ }
+
+ JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1setsockopt(
+ JNIEnv *env, jobject thisObj, jint fd, jint level, jint optname, jint optval, jint optlen) {
+ return zts_setsockopt(fd, level, optname, (const void*)optval, optlen);
+ }
+
+ JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1getsockopt(JNIEnv *env, jobject thisObj, jint fd, jint level, jint optname, jint optval, jint optlen) {
+ return zts_getsockopt(fd, level, optname, (void*)optval, (socklen_t *)optlen);
+ }
+
+ JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1socket(JNIEnv *env, jobject thisObj, jint family, jint type, jint protocol) {
+ return zts_socket(family, type, protocol);
+ }
+
+ JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1connect(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port) {
+ struct sockaddr_in addr;
+ const char *str = (*env).GetStringUTFChars( addrstr, 0);
+ addr.sin_addr.s_addr = inet_addr(str);
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons( port );
+ (*env).ReleaseStringUTFChars( addrstr, str);
+ return zts_connect(fd, (struct sockaddr *)&addr, sizeof(addr));
+ }
+
+ JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1bind(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port) {
+ struct sockaddr_in addr;
+ const char *str = (*env).GetStringUTFChars( addrstr, 0);
+ DEBUG_INFO("fd=%d, addr=%s, port=%d", fd, str, port);
+ addr.sin_addr.s_addr = inet_addr(str);
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons( port );
+ (*env).ReleaseStringUTFChars( addrstr, str);
+ return zts_bind(fd, (struct sockaddr *)&addr, sizeof(addr));
+ }
+
+#if defined(__linux__)
+ JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1accept4(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port, jint flags) {
+ struct sockaddr_in addr;
+ char *str;
+ // = env->GetStringUTFChars(addrstr, NULL);
+ (*env).ReleaseStringUTFChars( addrstr, str);
+ addr.sin_addr.s_addr = inet_addr(str);
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons( port );
+ return zts_accept4(fd, (struct sockaddr *)&addr, sizeof(addr), flags);
+ }
+#endif
+
+ JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1accept(JNIEnv *env, jobject thisObj, jint fd, jstring addrstr, jint port) {
+ struct sockaddr_in addr;
+ // TODO: Send addr info back to Javaland
+ addr.sin_addr.s_addr = inet_addr("");
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons( port );
+ return zts_accept(fd, (struct sockaddr *)&addr, (socklen_t *)sizeof(addr));
+ }
+
+ JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1listen(JNIEnv *env, jobject thisObj, jint fd, int backlog) {
+ return zts_listen(fd, backlog);
+ }
+
+ JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1close(JNIEnv *env, jobject thisObj, jint fd) {
+ return zts_close(fd);
+ }
+
+ JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1getsockname(JNIEnv *env, jobject thisObj, jint fd, jobject ztaddr) {
+ struct sockaddr_in addr;
+ int err = zts_getsockname(fd, (struct sockaddr *)&addr, (socklen_t *)sizeof(struct sockaddr));
+ jfieldID fid;
+ jclass cls = (*env).GetObjectClass(ztaddr);
+ fid = (*env).GetFieldID( cls, "port", "I");
+ (*env).SetIntField( ztaddr, fid, addr.sin_port);
+ fid = (*env).GetFieldID( cls,"_rawAddr", "J");
+ (*env).SetLongField( ztaddr, fid,addr.sin_addr.s_addr);
+ return err;
+ }
+
+ JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1getpeername(JNIEnv *env, jobject thisObj, jint fd, jobject ztaddr) {
+ struct sockaddr_in addr;
+ int err = zts_getpeername(fd, (struct sockaddr *)&addr, (socklen_t *)sizeof(struct sockaddr));
+ jfieldID fid;
+ jclass cls = (*env).GetObjectClass( ztaddr);
+ fid = (*env).GetFieldID( cls, "port", "I");
+ (*env).SetIntField( ztaddr, fid, addr.sin_port);
+ fid = (*env).GetFieldID( cls,"_rawAddr", "J");
+ (*env).SetLongField( ztaddr, fid,addr.sin_addr.s_addr);
+ return err;
+ }
+
+ JNIEXPORT jint JNICALL Java_zerotier_ZeroTier_ztjni_1fcntl(JNIEnv *env, jobject thisObj, jint fd, jint cmd, jint flags) {
+ return zts_fcntl(fd,cmd,flags);
+ }
+}
#endif
/****************************************************************************/