diff --git a/api/csharp/README.md b/api/csharp/README.md
deleted file mode 100644
index 1b93754..0000000
--- a/api/csharp/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-C# Language Binding API for the ZeroTier SDK
-======
-
diff --git a/api/java/README.md b/api/java/README.md
deleted file mode 100644
index fa4b006..0000000
--- a/api/java/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-Java Language Binding API for the ZeroTier SDK
-======
-
diff --git a/api/README.md b/examples/README.md
similarity index 100%
rename from api/README.md
rename to examples/README.md
diff --git a/api/clojure/README.md b/examples/clojure/README.md
similarity index 100%
rename from api/clojure/README.md
rename to examples/clojure/README.md
diff --git a/api/cpp/README.md b/examples/cpp/README.md
similarity index 100%
rename from api/cpp/README.md
rename to examples/cpp/README.md
diff --git a/test/unit/simple.cpp b/examples/cpp/simple.cpp
similarity index 100%
rename from test/unit/simple.cpp
rename to examples/cpp/simple.cpp
diff --git a/api/go/README.md b/examples/go/README.md
similarity index 100%
rename from api/go/README.md
rename to examples/go/README.md
diff --git a/examples/java/README.md b/examples/java/README.md
new file mode 100644
index 0000000..18fc86c
--- /dev/null
+++ b/examples/java/README.md
@@ -0,0 +1,7 @@
+Java Examples
+======
+
+Uses API described in [api/java/README.md]
+ - Copy `ZeroTier.java` into `your_project/src/zerotier`
+ - Copy `Address.java` into `your_project/src/zerotier`
+ - Copy `libzt.jnilib` or `libzt.so` from `build/` into `your_project/lib`
\ No newline at end of file
diff --git a/examples/java/ZeroTierHelloWorld/.classpath b/examples/java/ZeroTierHelloWorld/.classpath
new file mode 100644
index 0000000..ac1a9db
--- /dev/null
+++ b/examples/java/ZeroTierHelloWorld/.classpath
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/java/ZeroTierHelloWorld/.project b/examples/java/ZeroTierHelloWorld/.project
new file mode 100644
index 0000000..424ba61
--- /dev/null
+++ b/examples/java/ZeroTierHelloWorld/.project
@@ -0,0 +1,17 @@
+
+
+ ZeroTierHelloWorld
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/examples/java/ZeroTierHelloWorld/.settings/org.eclipse.jdt.core.prefs b/examples/java/ZeroTierHelloWorld/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..3a21537
--- /dev/null
+++ b/examples/java/ZeroTierHelloWorld/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/examples/java/ZeroTierHelloWorld/README.md b/examples/java/ZeroTierHelloWorld/README.md
new file mode 100644
index 0000000..a670a6d
--- /dev/null
+++ b/examples/java/ZeroTierHelloWorld/README.md
@@ -0,0 +1,2 @@
+ZeroTierSDK Java API
+======
\ No newline at end of file
diff --git a/examples/java/ZeroTierHelloWorld/bin/.gitignore b/examples/java/ZeroTierHelloWorld/bin/.gitignore
new file mode 100644
index 0000000..0d2fe9b
--- /dev/null
+++ b/examples/java/ZeroTierHelloWorld/bin/.gitignore
@@ -0,0 +1,2 @@
+/MyClass$1.class
+/zerotier/
diff --git a/examples/java/ZeroTierHelloWorld/bin/MyClass.class b/examples/java/ZeroTierHelloWorld/bin/MyClass.class
new file mode 100644
index 0000000..fff559f
Binary files /dev/null and b/examples/java/ZeroTierHelloWorld/bin/MyClass.class differ
diff --git a/examples/java/ZeroTierHelloWorld/src/MyClass.java b/examples/java/ZeroTierHelloWorld/src/MyClass.java
new file mode 100644
index 0000000..d71377d
--- /dev/null
+++ b/examples/java/ZeroTierHelloWorld/src/MyClass.java
@@ -0,0 +1,40 @@
+// Hello World example for the ZeroTierSDK
+
+import zerotier.*;
+
+public class MyClass {
+
+ public native int loadsymbols();
+ public native void startOneService();
+
+ static {
+ System.loadLibrary("zt");
+ }
+
+ public static void main(String[] args) {
+
+ System.out.println("Welcome to the Machine");
+
+ final ZeroTier z = new ZeroTier();
+
+ new Thread(new Runnable() {
+ public void run() {
+ // Calls to JNI code
+ z.start("/Users/Joseph/op/code/zerotier/ZeroTierSDK/zt1");
+ }
+ }).start();
+
+ //while(!z.running()) { }
+
+ while(true)
+ {
+ try {
+ System.out.println("Welcome to the Machine");
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/examples/java/ZeroTierHelloWorld/src/zerotier/Address.java b/examples/java/ZeroTierHelloWorld/src/zerotier/Address.java
new file mode 100644
index 0000000..2400c91
--- /dev/null
+++ b/examples/java/ZeroTierHelloWorld/src/zerotier/Address.java
@@ -0,0 +1,84 @@
+package zerotier;
+
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.util.regex.Pattern;
+
+/*
+
+The ZTAddress object is merely a convenience object for moving address information
+across the JNI memory border.
+
+*/
+
+public class Address
+{
+ // int -> byte array
+ static public byte[] toIPByteArray(long addr){
+ return new byte[]{(byte)addr,(byte)(addr>>>8),(byte)(addr>>>16),(byte)(addr>>>24)};
+ }
+
+ // byte array -> int
+ long toIPInt(String _addr) {
+ long result = 0;
+ for(String part: _addr.split(Pattern.quote("."))) {
+ result = result << 8;
+ result |= Integer.parseInt(part);
+ }
+ return result;
+ }
+
+ public int port;
+ public int Port() {
+ return port;
+ }
+
+ public long _rawAddr;
+ public String Address()
+ {
+ try {
+ return InetAddress.getByAddress(toIPByteArray(_rawAddr)).getHostAddress();
+ } catch (UnknownHostException e) {
+ // should never happen
+ return null;
+ }
+ }
+
+ public String toString() {
+ return Address() + ":" + Port();
+ }
+
+ public Address()
+ {
+ port = -1;
+ _rawAddr = -1;
+ }
+
+ public Address(String _addr, int _port)
+ {
+ _rawAddr = toIPInt(_addr);
+ port = _port;
+ }
+
+ public void ZTAddress(InetSocketAddress ins)
+ {
+ port = ins.getPort();
+ _rawAddr = toIPInt(ins.getAddress().getHostAddress());
+ }
+
+ public InetSocketAddress ToInetSocketAddress() throws IllegalArgumentException {
+ InetSocketAddress sock_addr = null;
+ try {
+ sock_addr = new InetSocketAddress(Address(), port);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ }
+ return sock_addr;
+ }
+
+ public boolean isValid() {
+ return port != -1 && !Address().startsWith("-1.-1.-1.-1/-1");
+ }
+}
\ No newline at end of file
diff --git a/examples/java/ZeroTierHelloWorld/src/zerotier/ZeroTier.java b/examples/java/ZeroTierHelloWorld/src/zerotier/ZeroTier.java
new file mode 100644
index 0000000..b312f25
--- /dev/null
+++ b/examples/java/ZeroTierHelloWorld/src/zerotier/ZeroTier.java
@@ -0,0 +1,205 @@
+/*
+ * ZeroTier One - Network Virtualization Everywhere
+ * Copyright (C) 2011-2015 ZeroTier, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * --
+ *
+ * ZeroTier may be used and distributed under the terms of the GPLv3, which
+ * are available at: http://www.gnu.org/licenses/gpl-3.0.html
+ *
+ * If you would like to embed ZeroTier into a commercial application or
+ * redistribute it in a modified binary form, please contact ZeroTier Networks
+ * LLC. Start here: http://www.zerotier.com/
+ */
+
+package zerotier;
+
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.util.ArrayList;
+import java.util.zip.ZipError;
+
+public class ZeroTier {
+
+ public static String Version()
+ {
+ return "1.2.2";
+ }
+
+ // Socket families
+ public static int AF_UNIX = 1;
+ public static int AF_INET = 2;
+
+ // Socket types
+ public static int SOCK_STREAM = 1;
+ public static int SOCK_DGRAM = 2;
+
+ // fcntl flags
+ public static int O_APPEND = 1024;
+ public static int O_NONBLOCK = 2048;
+ public static int O_ASYNC = 8192;
+ public static int O_DIRECT = 65536;
+ public static int O_NOATIME = 262144;
+
+ // fcntl cmds
+ public static int F_GETFL = 3;
+ public static int F_SETFL = 4;
+
+ // Loads JNI code
+ static { System.loadLibrary("zt"); }
+
+ // ZeroTier service controls
+ public native void ztjni_start(String homeDir);
+ public void start(String homeDir) {
+ ztjni_start(homeDir);
+ }
+
+ public native void ztjni_join(String nwid);
+ public void join(String nwid) {
+ ztjni_join(nwid);
+ }
+
+ public native void ztjni_leave(String nwid);
+ public void leave(String nwid) {
+ ztjni_leave(nwid);
+ }
+
+ public native ArrayList ztjni_get_addresses(String nwid);
+ public ArrayList get_addresses(String nwid) {
+ int err = -1;
+ ArrayList addresses;
+ while (err < 0) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ }
+ addresses = ztjni_get_addresses(nwid);
+ if (addresses.size() > 0) {
+ return addresses;
+ }
+ }
+ return null;
+ }
+
+ public native boolean ztjni_running();
+ public boolean running() {
+ return ztjni_running();
+ }
+
+ public native int ztjni_socket(int family, int type, int protocol);
+ public int socket(int family, int type, int protocol) {
+ return ztjni_socket(family, type, protocol);
+ }
+
+ public native int ztjni_connect(int fd, String addr, int port);
+
+ public int connect(int sock, Address zaddr, String nwid) {
+ return connect(sock, zaddr.Address(), zaddr.Port(), nwid);
+ }
+
+ public int connect(int sock, String addr, int port, String nwid)
+ {
+ int err = -1;
+ ArrayList addresses;
+ while (err < 0) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ }
+ addresses = ztjni_get_addresses(nwid);
+ if (addresses.size() > 0) {
+ if(!addresses.get(0).startsWith("-1.-1.-1.-1/-1")) {
+ err = ztjni_connect(sock, addr, port);
+ }
+ }
+ }
+ return err;
+ }
+
+ public native int ztjni_bind(int fd, String addr, int port);
+
+ public int bind(int sock, Address zaddr, String nwid) {
+ return bind(sock, zaddr.Address(), zaddr.Port(), nwid);
+ }
+ public int bind(int sock, String addr, int port, String nwid) {
+ int err = -1;
+ ArrayList addresses;
+ while (err < 0) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ }
+ addresses = ztjni_get_addresses(nwid);
+ if (addresses.size() > 0) {
+ if(!addresses.get(0).startsWith("-1.-1.-1.-1/-1")) {
+ err = ztjni_bind(sock, addr, port);
+ }
+ }
+ }
+ return err;
+ }
+
+ public native int ztjni_accept4(int fd, String addr, int port);
+ public int accept4(int fd, String addr, int port) {
+ return ztjni_accept4(fd,addr,port);
+ }
+
+ public native int ztjni_accept(int fd, zerotier.Address addr);
+ public int accept(int fd, zerotier.Address addr) {
+ return ztjni_accept(fd, addr);
+ }
+
+ public native int ztjni_listen(int fd, int backlog);
+ public int listen(int fd, int backlog) {
+ return ztjni_listen(fd,backlog);
+ }
+
+ public native int ztjni_close(int fd);
+ public int close(int fd) {
+ return ztjni_close(fd);
+ }
+
+ public native int ztjni_read(int fd, byte[] buf, int len);
+ public int read(int fd, byte[] buf, int len) {
+ return ztjni_read(fd, buf, len);
+ }
+
+ public native int ztjni_write(int fd, byte[] buf, int len);
+ public int write(int fd, byte[] buf, int len) {
+ return ztjni_write(fd, buf, len);
+ }
+
+ public native int ztjni_sendto(int fd, byte[] buf, int len, int flags, zerotier.Address addr);
+ public int sendto(int fd, byte[] buf, int len, int flags, zerotier.Address addr){
+ return ztjni_sendto(fd,buf,len,flags,addr);
+ }
+
+ public native int ztjni_send(int fd, byte[] buf, int len, int flags);
+ public int send(int fd, byte[] buf, int len, int flags) {
+ return ztjni_send(fd, buf, len, flags);
+ }
+
+ public native int ztjni_recvfrom(int fd, byte[] buf, int len, int flags, zerotier.Address addr);
+ public int recvfrom(int fd, byte[] buf, int len, int flags, zerotier.Address addr){
+ return ztjni_recvfrom(fd,buf,len,flags,addr);
+ }
+
+ public native int ztjni_fcntl(int sock, int cmd, int flag);
+ public int fcntl(int sock, int cmd, int flag) {
+ return ztjni_fcntl(sock, F_SETFL, O_NONBLOCK);
+ }
+}
\ No newline at end of file
diff --git a/api/python/README.md b/examples/python/README.md
similarity index 100%
rename from api/python/README.md
rename to examples/python/README.md
diff --git a/api/swift/README.md b/examples/swift/README.md
similarity index 100%
rename from api/swift/README.md
rename to examples/swift/README.md
diff --git a/include/ZeroTierSDK.h b/include/ZeroTierSDK.h
index 3d79231..721d266 100644
--- a/include/ZeroTierSDK.h
+++ b/include/ZeroTierSDK.h
@@ -112,22 +112,22 @@ void zts_stop();
/**
* Join a network
*/
-void zts_join_network(const char * nwid);
+void zts_join(const char * nwid);
/**
* Join a network - Just create the dir and conf file required, don't instruct the core to do anything
*/
-void zts_join_network_soft(const char * filepath, const char * nwid);
+void zts_join_soft(const char * filepath, const char * nwid);
/**
* Leave a network
*/
-void zts_leave_network(const char * nwid);
+void zts_leave(const char * nwid);
/**
* Leave a network - Only delete the .conf file, this will prevent the service from joining upon next startup
*/
-void zts_leave_network_soft(const char * filepath, const char * nwid);
+void zts_leave_soft(const char * filepath, const char * nwid);
/**
* Return the home path for this instance of ZeroTier
@@ -154,7 +154,7 @@ int zts_get_device_id(char *devID);
/**
* Check whether the service is running
*/
-int zts_service_running();
+int zts_running();
/**
* Returns whether any IPv6 address has been assigned to the SockTap for this network
diff --git a/make-linux.mk b/make-linux.mk
index 7c5cf26..e9765cd 100644
--- a/make-linux.mk
+++ b/make-linux.mk
@@ -19,10 +19,12 @@ OSTYPE = $(shell uname -s | tr '[A-Z]' '[a-z]')
# Target output filenames
STATIC_LIB_NAME = libzt.a
PICO_LIB_NAME = libpicotcp.a
+JNI_LIB_NAME = libzt.jnilib
#
STATIC_LIB = $(BUILD)/$(STATIC_LIB_NAME)
PICO_DIR = ext/picotcp
PICO_LIB = $(PICO_DIR)/build/lib/$(PICO_LIB_NAME)
+SHARED_JNI_LIB = $(BUILD)/$(JNI_LIB_NAME)
#
TEST_BUILD_DIR = $(BUILD)/test
UNIT_TEST_SRC_DIR = test/unit
@@ -47,7 +49,7 @@ else
STRIP=strip
endif
-CXXFLAGS=$(CFLAGS) -Wno-format -fno-rtti -std=c++11 -DZT_SDK
+CXXFLAGS=$(CFLAGS) -Wno-format -fno-rtti -std=c++11
INCLUDES+= -Iext \
-I$(ZTO)/osdep \
@@ -69,32 +71,43 @@ COMMON_LIBS = -lpthread
## User Build Flags ##
##############################################################################
+CXXFLAGS+=-DZT_SDK
+
# Debug option, prints filenames, lines, functions, arguments, etc
# Also enables debug symbols for debugging with tools like gdb, etc
ifeq ($(SDK_DEBUG),1)
- SDK_FLAGS+=-DSDK_PICOTCP
+ CXXFLAGS+=-DSDK_PICOTCP
CXXFLAGS+=-g
INCLUDES+= -I$(PICOTCP_DIR)/include \
-I$(PICOTCP_DIR)/build/include \
-Isrc/stack_drivers/picotcp
endif
+# JNI (Java Native Interface)
+ifeq ($(SDK_JNI), 1)
+ # jni.h
+ INCLUDES+=-I$(shell /usr/libexec/java_home)/include
+ # jni_md.h
+ INCLUDES+=-I$(shell /usr/libexec/java_home)/include/$(SYSTEM)
+ CXXFLAGS+=-DSDK_JNI
+endif
+
##############################################################################
## Stack Configuration ##
##############################################################################
# Stack config flags
ifeq ($(SDK_PICOTCP),1)
- SDK_FLAGS+=-DSDK_PICOTCP
+ CXXFLAGS+=-DSDK_PICOTCP
INCLUDES+= -I$(PICOTCP_DIR)/include \
-I$(PICOTCP_DIR)/build/include \
-Isrc/stack_drivers/picotcp
endif
ifeq ($(SDK_IPV4),1)
- SDK_FLAGS+=-DSDK_IPV4
+ CXXFLAGS+=-DSDK_IPV4
endif
ifeq ($(SDK_IPV6),1)
- SDK_FLAGS+=-DSDK_IPV6
+ CXXFLAGS+=-DSDK_IPV6
endif
@@ -138,11 +151,15 @@ picotcp:
static_lib: picotcp $(ZTO_OBJS)
@mkdir -p $(BUILD)
- $(CXX) $(CXXFLAGS) $(SDK_FLAGS) $(TAP_FILES) $(STACK_DRIVER_FILES) -c -DSDK_STATIC
- #libtool --mode=link $(STATIC_LIB) $(ZTO_OBJS) $(SDK_OBJS) $(PICO_LIB)
+ $(CXX) $(CXXFLAGS) $(TAP_FILES) $(STACK_DRIVER_FILES) -c -DSDK_STATIC
ar rcs -o $(STATIC_LIB) ext/picotcp/build/modules/*.o $(PICO_OBJS) $(ZTO_OBJS) $(SDK_OBJS)
-jni_static_lib: picotcp $(ZTO_OBJS)
+##############################################################################
+## Java JNI ##
+##############################################################################
+
+shared_jni_lib: picotcp $(ZTO_OBJS)
+ $(CXX) $(CXXFLAGS) $(TAP_FILES) $(STACK_DRIVER_FILES) $(ZTO_OBJS) $(INCLUDES) $(PICO_LIB) -dynamiclib -o $(SHARED_JNI_LIB)
##############################################################################
## Unit Tests ##
diff --git a/make-mac.mk b/make-mac.mk
index b0c5fb9..eae2253 100644
--- a/make-mac.mk
+++ b/make-mac.mk
@@ -19,10 +19,12 @@ OSTYPE = $(shell uname -s | tr '[A-Z]' '[a-z]')
# Target output filenames
STATIC_LIB_NAME = libzt.a
PICO_LIB_NAME = libpicotcp.a
+JNI_LIB_NAME = libzt.jnilib
#
STATIC_LIB = $(BUILD)/$(STATIC_LIB_NAME)
PICO_DIR = ext/picotcp
PICO_LIB = $(PICO_DIR)/build/lib/$(PICO_LIB_NAME)
+SHARED_JNI_LIB = $(BUILD)/$(JNI_LIB_NAME)
#
TEST_BUILD_DIR = $(BUILD)/test
UNIT_TEST_SRC_DIR = test/unit
@@ -47,7 +49,7 @@ else
STRIP=strip
endif
-CXXFLAGS=$(CFLAGS) -Wno-format -fno-rtti -std=c++11 -DZT_SDK
+CXXFLAGS=$(CFLAGS) -Wno-format -fno-rtti -std=c++11
INCLUDES+= -Iext \
-I$(ZTO)/osdep \
@@ -67,32 +69,43 @@ INCLUDES+= -Iext \
## User Build Flags ##
##############################################################################
+CXXFLAGS+=-DZT_SDK
+
# Debug option, prints filenames, lines, functions, arguments, etc
# Also enables debug symbols for debugging with tools like gdb, etc
ifeq ($(SDK_DEBUG),1)
- SDK_FLAGS+=-DSDK_PICOTCP
+ CXXFLAGS+=-DSDK_PICOTCP
CXXFLAGS+=-g
INCLUDES+= -I$(PICOTCP_DIR)/include \
-I$(PICOTCP_DIR)/build/include \
-Isrc/stack_drivers/picotcp
endif
+# JNI (Java Native Interface)
+ifeq ($(SDK_JNI), 1)
+ # jni.h
+ INCLUDES+=-I$(shell /usr/libexec/java_home)/include
+ # jni_md.h
+ INCLUDES+=-I$(shell /usr/libexec/java_home)/include/$(OSTYPE)
+ CXXFLAGS+=-DSDK_JNI
+endif
+
##############################################################################
## Stack Configuration ##
##############################################################################
# Stack config flags
ifeq ($(SDK_PICOTCP),1)
- SDK_FLAGS+=-DSDK_PICOTCP
+ CXXFLAGS+=-DSDK_PICOTCP
INCLUDES+= -I$(PICOTCP_DIR)/include \
-I$(PICOTCP_DIR)/build/include \
-Isrc/stack_drivers/picotcp
endif
ifeq ($(SDK_IPV4),1)
- SDK_FLAGS+=-DSDK_IPV4
+ CXXFLAGS+=-DSDK_IPV4
endif
ifeq ($(SDK_IPV6),1)
- SDK_FLAGS+=-DSDK_IPV6
+ CXXFLAGS+=-DSDK_IPV6
endif
@@ -136,10 +149,15 @@ picotcp:
static_lib: picotcp $(ZTO_OBJS)
@mkdir -p $(BUILD)
- $(CXX) $(CXXFLAGS) $(SDK_FLAGS) $(TAP_FILES) $(STACK_DRIVER_FILES) -c -DSDK_STATIC
+ $(CXX) $(CXXFLAGS) $(TAP_FILES) $(STACK_DRIVER_FILES) -c -DSDK_STATIC
libtool -static -o $(STATIC_LIB) $(ZTO_OBJS) $(SDK_OBJS) $(PICO_LIB)
-jni_static_lib: picotcp $(ZTO_OBJS)
+##############################################################################
+## Java JNI ##
+##############################################################################
+
+shared_jni_lib: picotcp $(ZTO_OBJS)
+ $(CXX) $(CXXFLAGS) $(TAP_FILES) $(STACK_DRIVER_FILES) $(ZTO_OBJS) $(INCLUDES) $(PICO_LIB) -dynamiclib -o $(SHARED_JNI_LIB)
##############################################################################
## Unit Tests ##
diff --git a/src/Connection.hpp b/src/Connection.hpp
index 506a765..681d919 100644
--- a/src/Connection.hpp
+++ b/src/Connection.hpp
@@ -30,7 +30,7 @@
// SDK
#include "ZeroTierSDK.h"
#include "SocketTap.hpp"
-#include "RingBuffer.hpp"
+//#include "RingBuffer.hpp"
namespace ZeroTier {
@@ -42,7 +42,6 @@ namespace ZeroTier {
//circular_buffer crbuf = circular_buffer(ZT_TCP_RX_BUF_SZ);
//circular_buffer ctbuf = circular_buffer(ZT_TCP_TX_BUF_SZ);
-
int pid;
PhySocket *sock;
struct pico_socket *picosock;
diff --git a/src/RingBuffer.cpp b/src/RingBuffer.cpp
deleted file mode 100644
index e69de29..0000000
diff --git a/src/RingBuffer.hpp b/src/RingBuffer.hpp
deleted file mode 100644
index e69de29..0000000
diff --git a/src/SocketTap.cpp b/src/SocketTap.cpp
index 188e3aa..41bfcf5 100644
--- a/src/SocketTap.cpp
+++ b/src/SocketTap.cpp
@@ -92,10 +92,23 @@ namespace ZeroTier {
bool SocketTap::addIp(const InetAddress &ip)
{
- if(picostack) {
- DEBUG_INFO("addr = %s", ip.toString().c_str());
- picostack->pico_init_interface(this, ip);
- _ips.push_back(ip);
+ if(picostack) {
+ if(ip.isV4())
+ {
+ #if defined(SDK_IPV4)
+ DEBUG_INFO("addr = %s", ip.toString().c_str());
+ picostack->pico_init_interface(this, ip);
+ _ips.push_back(ip);
+ #endif
+ }
+ if(ip.isV6())
+ {
+ #if defined(SDK_IPV6)
+ DEBUG_INFO("addr = %s", ip.toString().c_str());
+ picostack->pico_init_interface(this, ip);
+ _ips.push_back(ip);
+ #endif
+ }
std::sort(_ips.begin(),_ips.end());
return true;
}
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
+
+ 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, "", "()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, "", "()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
/****************************************************************************/
diff --git a/src/picoTCP.cpp b/src/picoTCP.cpp
index 6aabbfe..e0295a0 100644
--- a/src/picoTCP.cpp
+++ b/src/picoTCP.cpp
@@ -32,7 +32,7 @@
#include "Utilities.hpp"
#include "SocketTap.hpp"
#include "picoTCP.hpp"
-#include "RingBuffer.hpp"
+//#include "RingBuffer.hpp"
// ZT
#include "Utils.hpp"
@@ -77,7 +77,8 @@ namespace ZeroTier {
{
DEBUG_INFO();
if (std::find(tap->_ips.begin(),tap->_ips.end(),ip) == tap->_ips.end()) {
- #if defined(SDK_IPV4)
+ tap->_ips.push_back(ip);
+ std::sort(tap->_ips.begin(),tap->_ips.end());
if(ip.isV4())
{
struct pico_ip4 ipaddr, netmask;
@@ -88,6 +89,7 @@ namespace ZeroTier {
// DEBUG_ATTN("mac = %s", tap->_mac.toString().c_str());
tap->picodev.send = pico_eth_send; // tx
tap->picodev.poll = pico_eth_poll; // rx
+ DEBUG_INFO("tap->picodev.poll = %p", tap->picodev.poll);
tap->picodev.mtu = tap->_mtu;
tap->picodev.tap = tap;
if(pico_device_init(&(tap->picodev), "p4", mac) != 0) {
@@ -95,11 +97,9 @@ namespace ZeroTier {
return false;
}
pico_ipv4_link_add(&(tap->picodev), ipaddr, netmask);
- DEBUG_ATTN("addr = %s", ip.toString().c_str());
+ DEBUG_INFO("addr = %s", ip.toString().c_str());
return true;
}
- #endif
- #if defined(SDK_IPV6)
if(ip.isV6())
{
struct pico_ip6 ipaddr, netmask;
@@ -123,10 +123,9 @@ namespace ZeroTier {
DEBUG_ERROR("dev init failed");
return false;
}
- DEBUG_ATTN("addr6 = %s", ip.toString().c_str());
+ DEBUG_INFO("addr6 = %s", ip.toString().c_str());
return true;
}
- #endif
}
return false;
}
@@ -261,6 +260,7 @@ namespace ZeroTier {
void picoTCP::pico_cb_socket_activity(uint16_t ev, struct pico_socket *s)
{
+ DEBUG_INFO();
if(!(SocketTap*)((ConnectionPair*)(s->priv)))
return;
SocketTap *tap = (SocketTap*)((ConnectionPair*)(s->priv))->tap;
@@ -353,6 +353,7 @@ namespace ZeroTier {
int pico_eth_send(struct pico_device *dev, void *buf, int len)
{
+ DEBUG_INFO();
SocketTap *tap = (SocketTap*)(dev->tap);
if(!tap) {
DEBUG_ERROR("invalid dev->tap");
@@ -373,6 +374,7 @@ namespace ZeroTier {
void picoTCP::pico_rx(SocketTap *tap, const MAC &from,const MAC &to,unsigned int etherType,
const void *data,unsigned int len)
{
+ DEBUG_INFO();
if(!tap) {
DEBUG_ERROR("invalid tap");
return;
@@ -444,7 +446,7 @@ namespace ZeroTier {
DEBUG_ERROR("invalid conn or conn->picosock");
return ZT_ERR_GENERAL_FAILURE;
}
- int err;
+ int err = 0;
#if defined(SDK_IPV4)
struct pico_ip4 zaddr;
struct sockaddr_in *in4 = (struct sockaddr_in*)addr;
@@ -483,7 +485,7 @@ namespace ZeroTier {
DEBUG_ERROR("invalid conn or conn->picosock");
return ZT_ERR_GENERAL_FAILURE;
}
- int err;
+ int err = 0;
#if defined(SDK_IPV4)
struct pico_ip4 zaddr;
struct sockaddr_in *in4 = (struct sockaddr_in*)addr;
diff --git a/test/unit/unit.cpp b/test/unit/unit.cpp
index 99cc300..3074f42 100644
--- a/test/unit/unit.cpp
+++ b/test/unit/unit.cpp
@@ -16,15 +16,15 @@
#include "ZeroTierSDK.h"
-#define PASSED 0
-#define FAILED -1
+#define PASSED 0
+#define FAILED -1
-#define ECHO_INTERVAL 100000 // us
-#define STR_SIZE 32
+#define ECHO_INTERVAL 100000 // us
+#define STR_SIZE 32
-#define TEST_OP_N_BYTES 10
-#define TEST_OP_N_SECONDS 11
-#define TEST_OP_N_TIMES 12
+#define TEST_OP_N_BYTES 10
+#define TEST_OP_N_SECONDS 11
+#define TEST_OP_N_TIMES 12
#define TEST_MODE_CLIENT 20
#define TEST_MODE_SERVER 21
@@ -618,10 +618,10 @@ int main(int argc , char *argv[])
if(stype == "simple" || stype == "sustained" || stype == "comprehensive") {
zts_start(path.c_str());
printf("waiting for service to start...\n");
- while(!zts_service_running())
+ while(!zts_running())
sleep(1);
printf("joining network...\n");
- zts_join_network(nwid.c_str());
+ zts_join(nwid.c_str());
printf("waiting for address assignment...\n");
while(!zts_has_address(nwid.c_str()))
sleep(1);