Minor updates to Java ExampleApp and added select() to JNI layer

This commit is contained in:
Joseph Henry
2018-09-06 11:08:06 -07:00
parent 6e06cb36ff
commit 84fcfd3baf
5 changed files with 109 additions and 24 deletions

View File

@@ -39,7 +39,6 @@
#include "libzt.h" #include "libzt.h"
// function pointers which will have values assigned once the dynamic library is loaded // function pointers which will have values assigned once the dynamic library is loaded
int (*_zts_set_service_port)(int portno); int (*_zts_set_service_port)(int portno);
@@ -96,8 +95,8 @@ void load_library_symbols(char *library_path)
{ {
void *libHandle = dlopen(library_path, RTLD_LAZY); void *libHandle = dlopen(library_path, RTLD_LAZY);
if (libHandle == NULL) { if (libHandle == NULL) {
DEBUG_ERROR("unable to load dynamic lib"); DEBUG_ERROR("unable to load dynamic libs: %s", dlerror());
exit(0); exit(-1);
} }
// Load symbols from library (call these directly) // Load symbols from library (call these directly)
@@ -160,6 +159,15 @@ int main(int argc, char **argv)
printf("client [config_file_path] [nwid] [remote_addr] [remote_port]\n"); printf("client [config_file_path] [nwid] [remote_addr] [remote_port]\n");
exit(0); exit(0);
} }
#ifdef __linux__
char *library_path = (char*)"./libzt.so";
#endif
#ifdef __APPLE__
char *library_path = (char*)"./libzt.dylib";
#endif
load_library_symbols(library_path);
std::string path = argv[1]; std::string path = argv[1];
std::string nwidstr = argv[2]; std::string nwidstr = argv[2];
std::string remote_addr = argv[3]; std::string remote_addr = argv[3];
@@ -173,7 +181,7 @@ int main(int argc, char **argv)
in4.sin_addr.s_addr = inet_addr(remote_addr.c_str()); in4.sin_addr.s_addr = inet_addr(remote_addr.c_str());
in4.sin_family = AF_INET; in4.sin_family = AF_INET;
// --- BEGIN EXAMPLE CODE //
printf("Waiting for libzt to come online...\n"); printf("Waiting for libzt to come online...\n");
uint64_t nwid = strtoull(nwidstr.c_str(),NULL,16); uint64_t nwid = strtoull(nwidstr.c_str(),NULL,16);

View File

@@ -95,8 +95,8 @@ void load_library_symbols(char *library_path)
{ {
void *libHandle = dlopen(library_path, RTLD_LAZY); void *libHandle = dlopen(library_path, RTLD_LAZY);
if (libHandle == NULL) { if (libHandle == NULL) {
DEBUG_ERROR("unable to load dynamic lib"); DEBUG_ERROR("unable to load dynamic libs: %s", dlerror());
exit(0); exit(-1);
} }
// Load symbols from library (call these directly) // Load symbols from library (call these directly)
@@ -150,7 +150,6 @@ void load_library_symbols(char *library_path)
_zts_add_dns_nameserver = (int(*)(struct sockaddr *addr))dlsym(libHandle, "zts_add_dns_nameserver"); _zts_add_dns_nameserver = (int(*)(struct sockaddr *addr))dlsym(libHandle, "zts_add_dns_nameserver");
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if (argc != 4) { if (argc != 4) {
@@ -158,6 +157,15 @@ int main(int argc, char **argv)
printf("server [config_file_path] [nwid] [bind_port]\n"); printf("server [config_file_path] [nwid] [bind_port]\n");
exit(0); exit(0);
} }
#ifdef __linux__
char *library_path = (char*)"./libzt.so";
#endif
#ifdef __APPLE__
char *library_path = (char*)"./libzt.dylib";
#endif
load_library_symbols(library_path);
std::string path = argv[1]; std::string path = argv[1];
std::string nwidstr = argv[2]; std::string nwidstr = argv[2];
int bind_port = atoi(argv[3]); int bind_port = atoi(argv[3]);
@@ -170,10 +178,7 @@ int main(int argc, char **argv)
in4.sin_addr.s_addr = INADDR_ANY; in4.sin_addr.s_addr = INADDR_ANY;
in4.sin_family = AF_INET; in4.sin_family = AF_INET;
// --- BEGIN EXAMPLE CODE //
char *library_path = (char*)"bin/lib/libzt.dylib";
load_library_symbols(library_path);
printf("Waiting for libzt to come online...\n"); printf("Waiting for libzt to come online...\n");
uint64_t nwid = strtoull(nwidstr.c_str(),NULL,16); uint64_t nwid = strtoull(nwidstr.c_str(),NULL,16);

View File

@@ -30,13 +30,9 @@ import com.zerotier.libzt.ZeroTier;
import com.zerotier.libzt.ZTSocketAddress; import com.zerotier.libzt.ZTSocketAddress;
import com.zerotier.libzt.ZTFDSet; import com.zerotier.libzt.ZTFDSet;
//import java.net.*;
import java.lang.Thread; import java.lang.Thread;
public class ExampleApp { public class ExampleApp {
public native int loadsymbols();
public native void startOneService();
static { System.loadLibrary("zt"); } // load libzt.dylib or libzt.so static { System.loadLibrary("zt"); } // load libzt.dylib or libzt.so
@@ -143,11 +139,11 @@ public class ExampleApp {
return; return;
} }
String echo_msg = "echo!"; String echo_msg = "echo!";
w = zt.write(fd, echo_msg.getBytes(), echo_msg.length()); w = zt.write(fd, echo_msg.getBytes());
rxBuffer = new byte[100]; rxBuffer = new byte[100];
lengthToRead = 100; lengthToRead = 100;
System.out.println("reading bytes..."); System.out.println("reading bytes...");
r = zt.read(fd, rxBuffer, lengthToRead); r = zt.read(fd, rxBuffer);
System.out.println("r="+r); System.out.println("r="+r);
System.out.println("string="+new String(rxBuffer)); System.out.println("string="+new String(rxBuffer));
} }
@@ -174,12 +170,12 @@ public class ExampleApp {
rxBuffer = new byte[100]; rxBuffer = new byte[100];
lengthToRead = 100; lengthToRead = 100;
System.out.println("reading bytes..."); System.out.println("reading bytes...");
r = zt.read(client_fd, rxBuffer, lengthToRead); r = zt.read(client_fd, rxBuffer);
System.out.println("r="+r); System.out.println("r="+r);
System.out.println("string="+new String(rxBuffer)); System.out.println("string="+new String(rxBuffer));
System.out.println("writing bytes..."); System.out.println("writing bytes...");
String echo_msg = "echo!"; String echo_msg = "echo!";
w = zt.write(client_fd, echo_msg.getBytes(), echo_msg.length()); w = zt.write(client_fd, echo_msg.getBytes());
System.out.println("wrote (" + w + ") bytes"); System.out.println("wrote (" + w + ") bytes");
} }
} }
@@ -204,14 +200,14 @@ public class ExampleApp {
if (loop) { if (loop) {
while (true) { while (true) {
sleep(500); sleep(500);
if ((w = zt.sendto(fd, txBuffer, txBuffer.length, flags, remoteAddr)) < 0) { if ((w = zt.sendto(fd, txBuffer, flags, remoteAddr)) < 0) {
System.out.println("error sending bytes"); System.out.println("error sending bytes");
} else { } else {
System.out.println("sendto()=" + w); System.out.println("sendto()=" + w);
} }
} }
} else { } else {
if ((w = zt.sendto(fd, txBuffer, txBuffer.length, flags, remoteAddr)) < 0) { if ((w = zt.sendto(fd, txBuffer, flags, remoteAddr)) < 0) {
System.out.println("error sending bytes"); System.out.println("error sending bytes");
} else { } else {
System.out.println("sendto()=" + w); System.out.println("sendto()=" + w);
@@ -252,7 +248,7 @@ public class ExampleApp {
if (master_set.ISSET(i)) if (master_set.ISSET(i))
{ {
System.out.println("attempting to read from: " + i); System.out.println("attempting to read from: " + i);
r = zt.recvfrom(fd, rxBuffer, rxBuffer.length, flags, remoteAddr); r = zt.recvfrom(fd, rxBuffer, flags, remoteAddr);
System.out.println("read (" + r + ") bytes from " + remoteAddr.toString() + ", buffer = " + new String(rxBuffer)); System.out.println("read (" + r + ") bytes from " + remoteAddr.toString() + ", buffer = " + new String(rxBuffer));
} }
} }
@@ -263,7 +259,7 @@ public class ExampleApp {
{ {
while(true) { while(true) {
addr = new ZTSocketAddress(); addr = new ZTSocketAddress();
r = zt.recvfrom(fd, rxBuffer, rxBuffer.length, flags, remoteAddr); r = zt.recvfrom(fd, rxBuffer, flags, remoteAddr);
System.out.println("read (" + r + ") bytes from " + remoteAddr.toString() + ", buffer = " + new String(rxBuffer)); System.out.println("read (" + r + ") bytes from " + remoteAddr.toString() + ", buffer = " + new String(rxBuffer));
} }
} }

View File

@@ -18,7 +18,7 @@ find . -type f \( -name '*.DS_Store' -o -name 'thumbs.db' \) -delete
# Emit a README file # Emit a README file
echo $'* libzt version: '${LIBZT_VERSION}$'r'${LIBZT_REVISION}$'\n* Core ZeroTier version: '${ZT_CORE_VERSION}$'\n* Date: '$(date)$'\n\nZeroTier Manual: https://www.zerotier.com/manual.shtml\n echo $'* libzt version: '${LIBZT_VERSION}$'r'${LIBZT_REVISION}$'\n* Core ZeroTier version: '${ZT_CORE_VERSION}$'\n* Date: '$(date)$'\n\nZeroTier Manual: https://www.zerotier.com/manual.shtml\n
Other Downloads: https://www.zerotier.com/download.shtml Other Downloads: https://www.zerotier.com/download.shtml
\nlibzt Repo: https://github.com/zerotier/libzt' > ${STAGING_DIR}/README.md \nlibzt Repo: https://github.com/zerotier/libzt\n\nFor more assistance, visit https://my.zerotier.com and ask your question in our Community section' > ${STAGING_DIR}/README.md
cp ${STAGING_DIR}/README.md ${STAGING_DIR}/debug/README.md cp ${STAGING_DIR}/README.md ${STAGING_DIR}/debug/README.md
cp ${STAGING_DIR}/README.md ${STAGING_DIR}/release/README.md cp ${STAGING_DIR}/README.md ${STAGING_DIR}/release/README.md

View File

@@ -54,6 +54,8 @@ namespace ZeroTier {
void ss2zta(JNIEnv *env, struct sockaddr_storage *ss, jobject addr); void ss2zta(JNIEnv *env, struct sockaddr_storage *ss, jobject addr);
void zta2ss(JNIEnv *env, struct sockaddr_storage *ss, jobject addr); void zta2ss(JNIEnv *env, struct sockaddr_storage *ss, jobject addr);
void ztfdset2fdset(JNIEnv *env, int nfds, jobject src_ztfd_set, fd_set *dest_fd_set);
void fdset2ztfdset(JNIEnv *env, int nfds, fd_set *src_fd_set, jobject dest_ztfd_set);
/****************************************************************************/ /****************************************************************************/
/* ZeroTier service controls */ /* ZeroTier service controls */
@@ -352,6 +354,80 @@ namespace ZeroTier {
{ {
return zts_shutdown(fd, how); return zts_shutdown(fd, how);
} }
JNIEXPORT jint JNICALL Java_com_zerotier_libzt_ZeroTier_select(JNIEnv *env, jobject thisObj,
jint nfds, jobject readfds, jobject writefds, jobject exceptfds, jint timeout_sec, jint timeout_usec)
{
struct timeval _timeout;
_timeout.tv_sec = timeout_sec;
_timeout.tv_usec = timeout_usec;
fd_set _readfds, _writefds, _exceptfds;
fd_set *r = NULL;
fd_set *w = NULL;
fd_set *e = NULL;
if (readfds) {
r = &_readfds;
ztfdset2fdset(env, nfds, readfds, &_readfds);
}
if (writefds) {
w = &_writefds;
ztfdset2fdset(env, nfds, writefds, &_writefds);
}
if (exceptfds) {
e = &_exceptfds;
ztfdset2fdset(env, nfds, exceptfds, &_exceptfds);
}
int err = zts_select(nfds, r, w, e, &_timeout);
if (readfds) {
fdset2ztfdset(env, nfds, &_readfds, readfds);
}
if (writefds) {
fdset2ztfdset(env, nfds, &_writefds, writefds);
}
if (exceptfds) {
fdset2ztfdset(env, nfds, &_exceptfds, exceptfds);
}
return err;
}
}
void ztfdset2fdset(JNIEnv *env, int nfds, jobject src_ztfd_set, fd_set *dest_fd_set)
{
jclass c = (*env).GetObjectClass(src_ztfd_set);
if (!c) {
return;
}
FD_ZERO(dest_fd_set);
jfieldID fid = env->GetFieldID(c, "fds_bits", "[B");
jobject fdData = (*env).GetObjectField (src_ztfd_set, fid);
jbyteArray * arr = reinterpret_cast<jbyteArray*>(&fdData);
char *data = (char*)(*env).GetByteArrayElements(*arr, NULL);
for (int i=0; i<nfds; i++) {
if (data[i] == 0x01) {
FD_SET(i, dest_fd_set);
}
}
(*env).ReleaseByteArrayElements(*arr, (jbyte*)data, 0);
return;
}
void fdset2ztfdset(JNIEnv *env, int nfds, fd_set *src_fd_set, jobject dest_ztfd_set)
{
jclass c = (*env).GetObjectClass(dest_ztfd_set);
if (!c) {
return;
}
jfieldID fid = env->GetFieldID(c, "fds_bits", "[B");
jobject fdData = (*env).GetObjectField (dest_ztfd_set, fid);
jbyteArray * arr = reinterpret_cast<jbyteArray*>(&fdData);
char *data = (char*)(*env).GetByteArrayElements(*arr, NULL);
for (int i=0; i<nfds; i++) {
if (FD_ISSET(i, src_fd_set)) {
data[i] = 0x01;
}
}
(*env).ReleaseByteArrayElements(*arr, (jbyte*)data, 0);
return;
} }
/****************************************************************************/ /****************************************************************************/