diff --git a/examples/cpp/sharedlib/ipv4client_shared.cpp b/examples/cpp/sharedlib/ipv4client_shared.cpp index b369387..83a0782 100644 --- a/examples/cpp/sharedlib/ipv4client_shared.cpp +++ b/examples/cpp/sharedlib/ipv4client_shared.cpp @@ -39,7 +39,6 @@ #include "libzt.h" - // function pointers which will have values assigned once the dynamic library is loaded 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); if (libHandle == NULL) { - DEBUG_ERROR("unable to load dynamic lib"); - exit(0); + DEBUG_ERROR("unable to load dynamic libs: %s", dlerror()); + exit(-1); } // 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"); 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 nwidstr = argv[2]; 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_family = AF_INET; - // --- BEGIN EXAMPLE CODE + // printf("Waiting for libzt to come online...\n"); uint64_t nwid = strtoull(nwidstr.c_str(),NULL,16); diff --git a/examples/cpp/sharedlib/ipv4server_shared.cpp b/examples/cpp/sharedlib/ipv4server_shared.cpp index 244b6fe..e5262cb 100644 --- a/examples/cpp/sharedlib/ipv4server_shared.cpp +++ b/examples/cpp/sharedlib/ipv4server_shared.cpp @@ -95,8 +95,8 @@ void load_library_symbols(char *library_path) { void *libHandle = dlopen(library_path, RTLD_LAZY); if (libHandle == NULL) { - DEBUG_ERROR("unable to load dynamic lib"); - exit(0); + DEBUG_ERROR("unable to load dynamic libs: %s", dlerror()); + exit(-1); } // 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"); } - int main(int argc, char **argv) { if (argc != 4) { @@ -158,6 +157,15 @@ int main(int argc, char **argv) printf("server [config_file_path] [nwid] [bind_port]\n"); 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 nwidstr = argv[2]; 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_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"); uint64_t nwid = strtoull(nwidstr.c_str(),NULL,16); diff --git a/examples/java/ExampleApp.java b/examples/java/ExampleApp.java index 23889e8..245e194 100644 --- a/examples/java/ExampleApp.java +++ b/examples/java/ExampleApp.java @@ -30,13 +30,9 @@ import com.zerotier.libzt.ZeroTier; import com.zerotier.libzt.ZTSocketAddress; import com.zerotier.libzt.ZTFDSet; -//import java.net.*; import java.lang.Thread; public class ExampleApp { - - public native int loadsymbols(); - public native void startOneService(); static { System.loadLibrary("zt"); } // load libzt.dylib or libzt.so @@ -143,11 +139,11 @@ public class ExampleApp { return; } 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]; lengthToRead = 100; System.out.println("reading bytes..."); - r = zt.read(fd, rxBuffer, lengthToRead); + r = zt.read(fd, rxBuffer); System.out.println("r="+r); System.out.println("string="+new String(rxBuffer)); } @@ -174,12 +170,12 @@ public class ExampleApp { rxBuffer = new byte[100]; lengthToRead = 100; 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("string="+new String(rxBuffer)); System.out.println("writing bytes..."); 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"); } } @@ -204,14 +200,14 @@ public class ExampleApp { if (loop) { while (true) { 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"); } else { System.out.println("sendto()=" + w); } } } 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"); } else { System.out.println("sendto()=" + w); @@ -252,7 +248,7 @@ public class ExampleApp { if (master_set.ISSET(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)); } } @@ -263,7 +259,7 @@ public class ExampleApp { { while(true) { 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)); } } diff --git a/packages/package.sh b/packages/package.sh index a7e29ae..011c29b 100755 --- a/packages/package.sh +++ b/packages/package.sh @@ -18,7 +18,7 @@ find . -type f \( -name '*.DS_Store' -o -name 'thumbs.db' \) -delete # 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 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}/release/README.md diff --git a/src/libztJNI.cpp b/src/libztJNI.cpp index db8097b..9ef44ce 100644 --- a/src/libztJNI.cpp +++ b/src/libztJNI.cpp @@ -54,6 +54,8 @@ namespace ZeroTier { void ss2zta(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 */ @@ -352,6 +354,80 @@ namespace ZeroTier { { 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(&fdData); + char *data = (char*)(*env).GetByteArrayElements(*arr, NULL); + for (int i=0; iGetFieldID(c, "fds_bits", "[B"); + jobject fdData = (*env).GetObjectField (dest_ztfd_set, fid); + jbyteArray * arr = reinterpret_cast(&fdData); + char *data = (char*)(*env).GetByteArrayElements(*arr, NULL); + for (int i=0; i