Browse Source

Merge branch 'dev' of github.com:zerotier/ZeroTierOne into dev

Adam Ierymenko 3 years ago
parent
commit
8217cadc08

+ 1 - 1
dockerbuild/Dockerfile.alpine

@@ -1,4 +1,4 @@
-FROM alpine:3.11.3
+FROM alpine:3.15
 
 ARG go_pkg_url
 

+ 2 - 1
include/ZeroTierOne.h

@@ -1079,7 +1079,8 @@ enum ZT_Architecture
 	ZT_ARCHITECTURE_DOTNET_CLR = 13,
 	ZT_ARCHITECTURE_JAVA_JVM = 14,
 	ZT_ARCHITECTURE_WEB = 15,
-	ZT_ARCHITECTURE_S390X = 16
+	ZT_ARCHITECTURE_S390X = 16,
+	ZT_ARCHITECTURE_LOONGARCH64 = 17
 };
 
 /**

+ 33 - 15
make-linux.mk

@@ -1,12 +1,12 @@
 # Automagically pick CLANG or RH/CentOS newer GCC if present
 # This is only done if we have not overridden these with an environment or CLI variable
 ifeq ($(origin CC),default)
-        CC:=$(shell if [ -e /usr/bin/clang ]; then echo clang; else echo gcc; fi)
-        CC:=$(shell if [ -e /opt/rh/devtoolset-8/root/usr/bin/gcc ]; then echo /opt/rh/devtoolset-8/root/usr/bin/gcc; else echo $(CC); fi)
+	CC:=$(shell if [ -e /usr/bin/clang ]; then echo clang; else echo gcc; fi)
+	CC:=$(shell if [ -e /opt/rh/devtoolset-8/root/usr/bin/gcc ]; then echo /opt/rh/devtoolset-8/root/usr/bin/gcc; else echo $(CC); fi)
 endif
 ifeq ($(origin CXX),default)
-        CXX:=$(shell if [ -e /usr/bin/clang++ ]; then echo clang++; else echo g++; fi)
-        CXX:=$(shell if [ -e /opt/rh/devtoolset-8/root/usr/bin/g++ ]; then echo /opt/rh/devtoolset-8/root/usr/bin/g++; else echo $(CXX); fi)
+	CXX:=$(shell if [ -e /usr/bin/clang++ ]; then echo clang++; else echo g++; fi)
+	CXX:=$(shell if [ -e /opt/rh/devtoolset-8/root/usr/bin/g++ ]; then echo /opt/rh/devtoolset-8/root/usr/bin/g++; else echo $(CXX); fi)
 endif
 
 INCLUDES?=-Izeroidc/target
@@ -75,16 +75,19 @@ else
 endif
 
 ifeq ($(ZT_QNAP), 1)
-        override DEFS+=-D__QNAP__
+	override DEFS+=-D__QNAP__
+	ZT_EMBEDDED=1
 endif
 ifeq ($(ZT_UBIQUITI), 1)
-        override DEFS+=-D__UBIQUITI__
+	override DEFS+=-D__UBIQUITI__
+	ZT_EMBEDDED=1
 endif
 
 ifeq ($(ZT_SYNOLOGY), 1)
 	override CFLAGS+=-fPIC
 	override CXXFLAGS+=-fPIC
 	override DEFS+=-D__SYNOLOGY__
+	ZT_EMBEDDED=1
 endif
 
 ifeq ($(ZT_DISABLE_COMPRESSION), 1)
@@ -213,9 +216,9 @@ ifeq ($(CC_MACH),armv7hl)
 	ZT_USE_ARM32_NEON_ASM_CRYPTO=1
 endif
 ifeq ($(CC_MACH),armv7ve)
-        ZT_ARCHITECTURE=3
-        override DEFS+=-DZT_NO_TYPE_PUNNING
-        ZT_USE_ARM32_NEON_ASM_CRYPTO=1
+	ZT_ARCHITECTURE=3
+	override DEFS+=-DZT_NO_TYPE_PUNNING
+	ZT_USE_ARM32_NEON_ASM_CRYPTO=1
 endif
 ifeq ($(CC_MACH),arm64)
 	ZT_ARCHITECTURE=4
@@ -249,6 +252,10 @@ endif
 ifeq ($(CC_MACH),riscv64)
 	ZT_ARCHITECTURE=0
 endif
+ifeq ($(CC_MACH),loongarch64)
+	ZT_ARCHITECTURE=17
+	override DEFS+=-DZT_NO_TYPE_PUNNING
+endif
 
 # Fail if system architecture could not be determined
 ifeq ($(ZT_ARCHITECTURE),999)
@@ -268,10 +275,13 @@ ifeq ($(ZT_IA32),1)
 endif
 
 ifeq ($(ZT_SSO_SUPPORTED), 1)
-	ifeq ($(ZT_DEBUG),1)
-		LDLIBS+=zeroidc/target/debug/libzeroidc.a -ldl -lssl -lcrypto
-	else
-		LDLIBS+=zeroidc/target/release/libzeroidc.a -ldl -lssl -lcrypto
+	ifeq ($(ZT_EMBEDDED),)
+		override DEFS+=-DZT_SSO_SUPPORTED=1
+		ifeq ($(ZT_DEBUG),1)
+			LDLIBS+=zeroidc/target/debug/libzeroidc.a -ldl -lssl -lcrypto
+		else
+			LDLIBS+=zeroidc/target/release/libzeroidc.a -ldl -lssl -lcrypto
+		endif
 	endif
 endif
 
@@ -306,8 +316,8 @@ ifeq ($(ZT_ARCHITECTURE),3)
 		override CXXFLAGS+=-march=armv5t -mfloat-abi=soft -msoft-float -mno-unaligned-access -marm
 		ZT_USE_ARM32_NEON_ASM_CRYPTO=0
 	else
-		override CFLAGS+=-mfloat-abi=hard -march=armv6kz -marm -mfpu=vfp -mno-unaligned-access -mtp=cp15 -mcpu=arm1176jzf-s
-		override CXXFLAGS+=-mfloat-abi=hard -march=armv6kz -marm -mfpu=vfp -fexceptions -mno-unaligned-access -mtp=cp15 -mcpu=arm1176jzf-s
+		override CFLAGS+=-mfloat-abi=hard -march=armv6zk -marm -mfpu=vfp -mno-unaligned-access -mtp=cp15 -mcpu=arm1176jzf-s
+		override CXXFLAGS+=-mfloat-abi=hard -march=armv6zk -marm -mfpu=vfp -fexceptions -mno-unaligned-access -mtp=cp15 -mcpu=arm1176jzf-s
 		ZT_USE_ARM32_NEON_ASM_CRYPTO=0
 	endif
 endif
@@ -384,9 +394,11 @@ debug:	FORCE
 	make ZT_DEBUG=1 selftest
 
 ifeq ($(ZT_SSO_SUPPORTED), 1)
+ifeq ($(ZT_EMBEDDED),)
 zeroidc:	FORCE
 #	export PATH=/root/.cargo/bin:$$PATH; cd zeroidc && cargo build -j1 $(RUSTFLAGS)
 	export PATH=/root/.cargo/bin:$$PATH; cd zeroidc && cargo build $(RUSTFLAGS)
+endif
 else
 zeroidc:
 endif
@@ -478,4 +490,10 @@ snap-upload-stable: FORCE
 		snapcraft upload --release=stable $${SNAPFILE};\
 	done
 
+synology-pkg: FORCE
+	cd synology ; ./build.sh build
+
+synology-docker: FORCE
+	cd synology/dsm7-docker/; ./build.sh build
+
 FORCE:

+ 12 - 7
node/Constants.hpp

@@ -50,16 +50,17 @@
 #define __UNIX_LIKE__
 #endif
 #include <endian.h>
-
 #if (defined(__amd64) || defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || defined(__AMD64) || defined(__AMD64__) || defined(_M_X64) || defined(__aarch64__))
-#define OIDC_SUPPORTED 1
-#else
-#define OIDC_SUPPORTED 0
+#ifdef ZT_SSO_SUPPORTED
+#define ZT_SSO_ENABLED 1
+#endif
 #endif
 #endif
 
 #ifdef __APPLE__
-#define OIDC_SUPPORTED 1
+#ifdef ZT_SSO_SUPPORTED
+#define ZT_SSO_ENABLED 1
+#endif
 #define likely(x) __builtin_expect((x),1)
 #define unlikely(x) __builtin_expect((x),0)
 #include <TargetConditionals.h>
@@ -73,7 +74,9 @@
 #endif
 
 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
-#define OIDC_SUPPORTED 0
+#ifdef ZT_SSO_SUPPORTED
+#define ZT_SSO_ENABLED 0
+#endif
 #ifndef __UNIX_LIKE__
 #define __UNIX_LIKE__
 #endif
@@ -89,7 +92,9 @@
 #endif
 
 #if defined(_WIN32) || defined(_WIN64)
-#define OIDC_SUPPORTED 1
+#ifdef ZT_SSO_SUPPORTED
+#define ZT_SSO_ENABLED 1
+#endif
 #ifndef __WINDOWS__
 #define __WINDOWS__
 #endif

+ 20 - 35
service/OneService.cpp

@@ -53,7 +53,7 @@
 #include "OneService.hpp"
 #include "SoftwareUpdater.hpp"
 
-#if OIDC_SUPPORTED
+#if ZT_SSO_ENABLED
 #include <zeroidc.h>
 #endif
 
@@ -195,7 +195,7 @@ public:
 	NetworkState() 
 		: _webPort(9993)
 		, _tap((EthernetTap *)0)
-#if OIDC_SUPPORTED
+#if ZT_SSO_ENABLED
 		, _idc(nullptr)
 #endif
 	{
@@ -212,7 +212,7 @@ public:
 		this->_managedRoutes.clear();
 		this->_tap.reset();
 
-#if OIDC_SUPPORTED
+#if ZT_SSO_ENABLED
 		if (_idc) {
 			zeroidc::zeroidc_stop(_idc);
 			zeroidc::zeroidc_delete(_idc);
@@ -296,7 +296,7 @@ public:
 
 		if (_config.ssoEnabled && _config.ssoVersion == 1) {
 			//  fprintf(stderr, "ssoEnabled for %s\n", nwid);
-#if OIDC_SUPPORTED
+#if ZT_SSO_ENABLED
 			if (_idc == nullptr)
 			{
 				assert(_config.issuerURL != nullptr);
@@ -353,7 +353,7 @@ public:
 	}
 
 	const char* getAuthURL() {
-#if OIDC_SUPPORTED
+#if ZT_SSO_ENABLED
 		if (_idc != nullptr) {
 			return zeroidc::zeroidc_get_auth_url(_idc);
 		}
@@ -363,7 +363,7 @@ public:
 	}
 
 	const char* doTokenExchange(const char *code) {
-#if OIDC_SUPPORTED
+#if ZT_SSO_ENABLED
 		if (_idc == nullptr) {
 			fprintf(stderr, "ainfo or idc null\n");
 			return "";
@@ -386,7 +386,7 @@ public:
 	}
 
 	uint64_t getExpiryTime() {
-#if OIDC_SUPPORTED
+#if ZT_SSO_ENABLED
 		if (_idc == nullptr) {
 			fprintf(stderr, "idc is null\n");
 			return 0;
@@ -404,7 +404,7 @@ private:
 	std::vector<InetAddress> _managedIps;
 	std::map< InetAddress, SharedPtr<ManagedRoute> > _managedRoutes;
 	OneService::NetworkSettings _settings;
-#if OIDC_SUPPORTED
+#if ZT_SSO_ENABLED
 	zeroidc::ZeroIDC *_idc;
 #endif
 };
@@ -1002,27 +1002,16 @@ public:
 				// If we're running uPnP/NAT-PMP, bind a *third* port for that. We can't
 				// use the other two ports for that because some NATs do really funky
 				// stuff with ports that are explicitly mapped that breaks things.
-				if (_ports[1]) {
-					if (_tertiaryPort) {
-						_ports[2] = _tertiaryPort;
-					} else {
-						_ports[2] = 20000 + (_ports[0] % 40000);
-						for(int i=0;;++i) {
-							if (i > 1000) {
-								_ports[2] = 0;
-								break;
-							} else if (++_ports[2] >= 65536) {
-								_ports[2] = 20000;
-							}
-							if (_trialBind(_ports[2]))
-								break;
-						}
-						if (_ports[2]) {
-							char uniqueName[64];
-							OSUtils::ztsnprintf(uniqueName,sizeof(uniqueName),"ZeroTier/%.10llx@%u",_node->address(),_ports[2]);
-							_portMapper = new PortMapper(_ports[2],uniqueName);
-						}
-					}
+				if (_tertiaryPort) {
+					_ports[2] = _tertiaryPort;
+				} else {
+					_ports[2] = _getRandomPort();
+				}
+
+				if (_ports[2]) {
+					char uniqueName[64];
+					OSUtils::ztsnprintf(uniqueName,sizeof(uniqueName),"ZeroTier/%.10llx@%u",_node->address(),_ports[2]);
+					_portMapper = new PortMapper(_ports[2],uniqueName);
 				}
 			}
 #endif
@@ -1705,7 +1694,7 @@ public:
 						scode = _controller->handleControlPlaneHttpGET(std::vector<std::string>(ps.begin()+1,ps.end()),urlArgs,headers,body,responseBody,responseContentType);
 					} else scode = 404;
 				}
-#if OIDC_SUPPORTED
+#if ZT_SSO_ENABLED
 			} else if (ps[0] == "sso") {
 				char resBuf[4096] = {0};
 				const char *error = zeroidc::zeroidc_get_url_param_value("error", path.c_str());
@@ -2298,10 +2287,7 @@ public:
 						fprintf(stderr,"ERROR: unable to remove ip address %s" ZT_EOL_S, ip->toString(ipbuf));
 				}
 			}
-#ifdef __SYNOLOGY__
-			if (!n.tap->addIpSyn(newManagedIps))
-				fprintf(stderr,"ERROR: unable to add ip addresses to ifcfg" ZT_EOL_S);
-#else
+
 			for(std::vector<InetAddress>::iterator ip(newManagedIps.begin());ip!=newManagedIps.end();++ip) {
 				if (std::find(n.managedIps().begin(),n.managedIps().end(),*ip) == n.managedIps().end()) {
 					if (!n.tap()->addIp(*ip))
@@ -2312,7 +2298,6 @@ public:
 #ifdef __APPLE__
 			if (!MacDNSHelper::addIps(n.config().nwid, n.config().mac, n.tap()->deviceName().c_str(), newManagedIps))
 				fprintf(stderr, "ERROR: unable to add v6 addresses to system configuration" ZT_EOL_S);
-#endif
 #endif
 			n.setManagedIps(newManagedIps);
 		}

+ 20 - 0
synology/Dockerfile.spksrc

@@ -0,0 +1,20 @@
+# vim: ft=dockerfile
+
+FROM debian:buster
+
+ENV LANG C.UTF-8
+
+# Manage i386 arch
+RUN dpkg --add-architecture i386
+
+RUN apt-get update && apt-get install --no-install-recommends -y make imagemagick curl jq wget procps intltool
+
+RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
+
+# Volume pointing to spksrc sources
+VOLUME /spksrc
+
+WORKDIR /spksrc
+
+COPY syn-pkg-entrypoint.sh /syn-pkg-entrypoint.sh
+ENTRYPOINT ["/syn-pkg-entrypoint.sh"]

+ 8 - 0
synology/README.md

@@ -0,0 +1,8 @@
+## Package for Synology's DSM 6
+
+Documentation and downloads: [docs.zerotier.com/devices/synology](https://docs.zerotier.com/devices/synology)
+
+
+```
+./build.sh build
+```

+ 139 - 0
synology/build.sh

@@ -0,0 +1,139 @@
+#!/bin/bash
+
+ZTO_VER=$(jq -r '.version' synology/config.json)
+PKG_REV=$(jq -r '.rev' synology/config.json)
+echo $ZTO_VER-$PKG_REV
+ZTO_DESC=$(jq -r '.desc' synology/config.json)
+echo $ZTO_DESC
+ZTO_EMAIL=$(jq -r '.email' synology/config.json)
+echo $ZTO_EMAIL
+read -p "Confirm details [y/n] ? " -n 1 -r; echo; if [[ ! $REPLY =~ ^[Yy]$ ]]; then echo "Exiting."; exit; fi
+
+build_environment()
+{
+  git clone https://github.com/SynoCommunity/spksrc.git
+  sudo docker build --load -t zt-spksrc -f Dockerfile.spksrc .
+}
+
+generate_package_sources()
+{
+  # Clean up any intermediate files
+  sudo make -C spksrc clean
+  rm -rf spksrc/distrib/*
+  rm -rf spksrc/packages/*
+  rm -rf spksrc/distrib/*source.tar.gz*
+  rm -rf spksrc/cross/*
+  mkdir -p spksrc/cross/zerotier
+
+  # Generate the SPK contents
+
+  # Copy package scripts to spksrc so they're accessible to container
+  rm -rf spksrc/dsm6-pkg
+  cp -rf dsm6-pkg spksrc/dsm6-pkg
+
+  TAB="$(printf '\t')"
+
+  cd ..
+
+  # Generate ZTO source tarball used by spksrc
+  git ls-files -z | xargs -0 tar -czvf source.tar.gz
+  mkdir -p synology/spksrc/distrib
+  cp source.tar.gz synology/spksrc/distrib/source.tar.gz
+
+cat > synology/spksrc/cross/zerotier/digests <<- EOM
+source.tar.gz SHA1 $(sha1sum source.tar.gz | awk '{print $1}')
+source.tar.gz SHA256 $(sha256sum source.tar.gz | awk '{print $1}')
+source.tar.gz MD5 $(md5sum source.tar.gz | awk '{print $1}')
+EOM
+
+  cd -
+
+
+  STAGING_DIR='$(STAGING_DIR)'
+  RUN='$(RUN)'
+
+cat > spksrc/cross/zerotier/Makefile <<- EOM
+PKG_NAME = ZeroTierOne
+PKG_VERS = $ZTO_VER
+PKG_EXT = tar.gz
+PKG_DIST_NAME = source.tar.gz
+PKG_DIR =
+PKG_DIST_SITE = http://localhost:8000
+DEPENDS =
+GNU_CONFIGURE = 1
+CONFIGURE_ARGS = HAVE_CXX=yes
+
+INSTALL_TARGET = zerotier_custom_install
+CONFIGURE_TARGET = zerotier_custom_configure
+
+ENV += ZT_SYNOLOGY=1
+
+include ../../mk/spksrc.cross-cc.mk
+
+.PHONY: zerotier_custom_install
+zerotier_custom_install:
+${TAB}$RUN mkdir -p $STAGING_DIR/bin
+${TAB}$RUN cp zerotier-one $STAGING_DIR/bin/zerotier-one
+EOM
+
+cat > spksrc/cross/zerotier/PLIST <<- EOM
+bin:bin/zerotier-one
+EOM
+
+  #
+  # Set up (spk) directory contents
+  #
+  rm -rf spksrc/spk/*
+  mkdir -p spksrc/spk/zerotier
+
+  STAGING_DIR='$(STAGING_DIR)'
+  WORK_DIR='$(WORK_DIR)'
+  PRODUCT_DIR='$(PRODUCT_DIR)'
+
+cat > spksrc/spk/zerotier/Makefile <<- EOM
+SPK_NAME = zerotier
+SPK_VERS = $ZTO_VER
+SPK_REV = $PKG_REV
+SPK_ICON = /spksrc/dsm6-pkg/PACKAGE_ICON_256.png
+DEPENDS = cross/zerotier
+MAINTAINER = ZeroTier, Inc.
+DESCRIPTION = $ZTO_DESC
+LICENSE  = BUSL-1.1
+CHANGELOG =
+HOMEPAGE = https://my.zerotier.com
+REPORT_URL = https://github.com/zerotier/ZeroTierOne/issues
+DISPLAY_NAME = ZeroTier
+PRODUCT_DIR = $WORK_DIR
+
+STARTABLE = yes
+REQUIRED_DSM = 6.2.4
+
+ENV += ZT_SYNOLOGY=1
+
+SSS_SCRIPT = ../../dsm6-pkg/start-stop-status.sh
+
+PRE_STRIP_TARGET = zerotier_install
+
+include ../../mk/spksrc.spk.mk
+
+.PHONY: zerotier_install
+zerotier_install:
+${TAB}install -m 755 -d $STAGING_DIR/bin
+${TAB}install -m 755 $PRODUCT_DIR/zerotier-one $STAGING_DIR/bin/zerotier-one
+EOM
+
+cat > spksrc/spk/zerotier/PLIST <<- EOM
+bin:bin/zerotier-one
+EOM
+}
+
+build()
+{
+  pushd synology
+  build_environment
+  generate_package_sources
+  sudo docker run -it -v $(pwd)/spksrc:/spksrc zt-spksrc /bin/bash
+  popd
+}
+
+"$@"

+ 6 - 0
synology/config.json

@@ -0,0 +1,6 @@
+{
+	"version": "1.8.7",
+	"rev": "1",
+	"desc": "Securely connect any device, anywhere.",
+	"email": "[email protected]"
+}

BIN
synology/dsm6-pkg/PACKAGE_ICON.png


BIN
synology/dsm6-pkg/PACKAGE_ICON_256.png


+ 3 - 0
synology/dsm6-pkg/scripts/postinst

@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exit 0

+ 3 - 0
synology/dsm6-pkg/scripts/postuninst

@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exit 0

+ 2 - 0
synology/dsm6-pkg/scripts/postupgrade

@@ -0,0 +1,2 @@
+#!/bin/sh
+exit 0

+ 2 - 0
synology/dsm6-pkg/scripts/preinst

@@ -0,0 +1,2 @@
+#!/bin/sh
+exit 0

+ 3 - 0
synology/dsm6-pkg/scripts/preuninst

@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exit 0

+ 2 - 0
synology/dsm6-pkg/scripts/preupgrade

@@ -0,0 +1,2 @@
+#!/bin/sh
+exit 0

+ 30 - 0
synology/dsm6-pkg/service-setup.sh

@@ -0,0 +1,30 @@
+
+service_postinst()
+{
+	exit 0
+}
+
+service_postuninst()
+{
+	exit 0
+}
+
+service_postupgrade()
+{
+	exit 0
+}
+
+service_preinst()
+{
+	exit 0
+}
+
+service_preuninst()
+{
+	exit 0
+}
+
+service_preupgrade()
+{
+	exit 0
+}

+ 162 - 0
synology/dsm6-pkg/start-stop-status.sh

@@ -0,0 +1,162 @@
+#!/bin/sh
+
+PKGVAR=/var/packages/zerotier/var
+
+ZTO_PID_FILE="$PKGVAR/zerotier-one.pid"
+WAT_PID_FILE="$PKGVAR/zerotier-watchdog.pid"
+ZTO_LOG_FILE="$PKGVAR/zerotier-one.log"
+
+log()
+{
+    local timestamp=$(date --iso-8601=second)
+    echo "$timestamp $1" >> $ZTO_LOG_FILE
+}
+
+configure_tun()
+{
+    log "Checking for TUN device"
+    # Create /dev/net/tun if needed
+    if ( [ ! -c /dev/net/tun ] ); then
+        if ( [ ! -d /dev/net ] ); then
+            mkdir -m 755 /dev/net
+        fi
+        log "Adding TUN device"
+        mknod /dev/net/tun c 10 200
+        chmod 0755 /dev/net/tun
+    fi
+
+    # Load TUN kernel module
+    if ( !( lsmod | grep -q "^tun\s" ) ); then
+        log "Loading TUN kernel module"
+        insmod /lib/modules/tun.ko
+    fi
+}
+
+configure_cli()
+{
+    # Create ZT CLI symlinks if needed
+    mkdir -p /usr/local/bin/
+    ln -s $SYNOPKG_PKGDEST/bin/zerotier-one /usr/local/bin/zerotier-cli
+    ln -s $SYNOPKG_PKGDEST/bin/zerotier-one /usr/local/bin/zerotier-idtool
+    rm -rf /var/lib/zerotier-one
+    ln -s /var/packages/zerotier/var /var/lib/zerotier-one
+}
+
+apply_routes()
+{
+    echo $BASHPID >> $WAT_PID_FILE
+    log "Started Watchdog ($(cat $WAT_PID_FILE))"
+
+    # Wait for ZT service to come online before attempting queries
+    sleep 15
+
+    # Loop until killed, check for required routes and add if needed
+    while true
+    do
+        NETWORK_COUNT=$(zerotier-cli -j listnetworks | jq -r '. | length')
+        if [ "$NETWORK_COUNT" -gt 0 ]; then
+            for ((j=0; j<=$((NETWORK_COUNT-1)); j++))
+            do
+                ROUTE_COUNT=$(zerotier-cli -j listnetworks | jq -r '.['$j'].routes | length')
+                for ((k=0; k<=$((ROUTE_COUNT-1)); k++))
+                do
+                    ROUTE=$(zerotier-cli -j listnetworks | jq -r '.['$j'].routes['$k'].target')
+                    EXIST=$(ip route show $ROUTE | wc -l)
+                    if [ $EXIST -eq 0 ];
+                    then
+                        IFNAME=$(zerotier-cli -j listnetworks | jq -r '.['$j'] | .portDeviceName')
+                        ip route add $ROUTE dev $IFNAME
+                        log "Added route $ROUTE to dev $IFNAME"
+                        # Routes will be deleted when ZT brings the interface down
+                    fi
+                done
+            done
+        fi
+        sleep 15
+    done
+}
+
+configure_routes()
+{
+    if [ -r "${WAT_PID_FILE}" ]; then
+        exit 0
+    else
+        apply_routes &
+    fi
+}
+
+start_daemon()
+{
+    ${SYNOPKG_PKGDEST}/bin/zerotier-one $PKGVAR -d
+    echo $(pidof zerotier-one) > ${ZTO_PID_FILE}
+    log "Started ZeroTier ($(cat $ZTO_PID_FILE))"
+}
+
+stop_daemon() {
+    if [ -r "$ZTO_PID_FILE" ]; then
+        local ZTO_PID=$(cat "${ZTO_PID_FILE}")
+        log "Stopped ZeroTier ($(cat $ZTO_PID_FILE))"
+        kill -TERM $ZTO_PID
+        wait_for_status 1 || kill -KILL $PID >> $LOG_FILE 2>&1
+        rm -f $ZTO_PID_FILE > /dev/null
+    fi
+    if [ -r "$WAT_PID_FILE" ]; then
+        local WAT_PID=$(cat "${WAT_PID_FILE}")
+        log "Stopped Watchdog ($(cat $WAT_PID_FILE))"
+        kill -TERM $WAT_PID
+        rm -f $WAT_PID_FILE > /dev/null
+    fi
+}
+
+daemon_status()
+{
+    if [ -f $ZTO_PID_FILE ] && kill -0 `cat $ZTO_PID_FILE` > /dev/null 2>&1; then
+        return
+    fi
+    rm -f $ZTO_PID_FILE
+    return 1
+}
+
+wait_for_status()
+{
+    counter=$2
+    while [ $counter -gt 0 ]; do
+        daemon_status
+        [ $? -eq $1 ] && return
+        let counter=counter-1
+        sleep 1
+    done
+    return 1
+}
+
+case "$1" in
+  start)
+    if ( pidof zerotier-one ); then
+        exit 0
+    else
+        configure_tun
+        configure_cli
+        start_daemon
+        configure_routes
+    fi
+    ;;
+  stop)
+    if ( pidof zerotier-one ); then
+        stop_daemon
+    else
+        exit 0
+    fi
+    ;;
+  status)
+    if ( pidof zerotier-one ); then
+        exit 0
+    else
+        exit 1
+    fi
+    ;;
+  *)
+    exit 1
+    ;;
+esac
+
+exit 0

+ 30 - 0
synology/dsm7-docker/Dockerfile

@@ -0,0 +1,30 @@
+# vim: ft=dockerfile
+
+FROM alpine:latest as builder
+
+RUN apk add --no-cache rust cargo
+RUN apk add  openssl-dev
+
+RUN apk add --update alpine-sdk linux-headers \
+  && git clone --quiet https://github.com/zerotier/ZeroTierOne.git /src \
+  && git -C src reset --quiet --hard ${ZTO_COMMIT} \
+  && cd /src \
+  && make -f make-linux.mk
+
+FROM alpine:latest
+LABEL version=${ZTO_VER}
+LABEL description="ZeroTier One docker image for Synology NAS"
+
+RUN apk add --update --no-cache bash jq libc6-compat libstdc++
+
+EXPOSE 9993/udp
+
+COPY --from=builder /src/zerotier-one /usr/sbin/
+RUN mkdir -p /var/lib/zerotier-one \
+  && ln -s /usr/sbin/zerotier-one /usr/sbin/zerotier-idtool \
+  && ln -s /usr/sbin/zerotier-one /usr/sbin/zerotier-cli
+
+COPY entrypoint.sh /entrypoint.sh
+RUN chmod 755 /entrypoint.sh
+
+ENTRYPOINT ["/entrypoint.sh"]

+ 3 - 0
synology/dsm7-docker/README.md

@@ -0,0 +1,3 @@
+## Docker image for Synology's DSM7
+
+Documentation: [docs.zerotier.com/devices/synology](https://docs.zerotier.com/devices/synology)

+ 21 - 0
synology/dsm7-docker/build.sh

@@ -0,0 +1,21 @@
+#!/bin/bash
+
+ZTO_VER=$(git describe --abbrev=0 --tags)
+ZTO_COMMIT=$(git rev-parse HEAD)
+
+build()
+{
+  sudo docker build --load --rm -t zerotier-synology . --build-arg ZTO_COMMIT=${ZTO_COMMIT} --build-arg ZTO_VER=${ZTO_VER}
+  LATEST_DOCKER_IMAGE_HASH=$(sudo docker images -q zerotier-synology)
+  sudo docker tag ${LATEST_DOCKER_IMAGE_HASH} zerotier/zerotier-synology:${ZTO_VER}
+  sudo docker tag ${LATEST_DOCKER_IMAGE_HASH} zerotier/zerotier-synology:latest
+}
+
+push()
+{
+  sudo docker login --username=${DOCKERHUB_USERNAME}
+  sudo docker push zerotier/zerotier-synology:${ZTO_VER}
+  sudo docker push zerotier/zerotier-synology:latest
+}
+
+"$@"

+ 29 - 0
synology/dsm7-docker/entrypoint.sh

@@ -0,0 +1,29 @@
+#!/bin/bash
+
+zerotier-one -d
+
+# Wait for ZT service to come online before attempting queries
+sleep 15
+
+while true
+do
+    NETWORK_COUNT=$(zerotier-cli -j listnetworks | jq -r '. | length')
+    if [ "$NETWORK_COUNT" -gt 0 ]; then
+        for ((j=0; j<=$((NETWORK_COUNT-1)); j++))
+        do
+            ROUTE_COUNT=$(zerotier-cli -j listnetworks | jq -r '.['$j'].routes | length')
+            for ((k=0; k<=$((ROUTE_COUNT-1)); k++))
+            do
+                ROUTE=$(zerotier-cli -j listnetworks | jq -r '.['$j'].routes['$k'].target')
+                EXIST=$(ip route show $ROUTE | wc -l)
+                if [ $EXIST -eq 0 ];
+                then
+                    IFNAME=$(zerotier-cli -j listnetworks | jq -r '.['$j'] | .portDeviceName')
+                    ip route add $ROUTE dev $IFNAME
+                    # Routes will be deleted when ZT brings the interface down
+                fi
+            done
+        done
+        sleep 15
+    fi
+done

+ 38 - 0
synology/syn-pkg-entrypoint.sh

@@ -0,0 +1,38 @@
+#!/bin/bash
+
+pushd spk/zerotier
+
+make arch-x64-6.2.4
+make arch-braswell-6.2.4
+# make arch-88f6281-6.2.4 #(std11)
+# make arch-monaco-6.2.4 #(ZT_AES_NO_ACCEL=1)
+# make arch-hi3535-6.2.4 #(take out -mfloat-abi=hard)
+# make arch-comcerto2k-6.2.4 #(ZT_AES_NO_ACCEL=1, remove all flags from arm hf section)
+# make arch-alpine4k-6.2.4 #(problem?)
+# make arch-alpine-6.2.4 #(problem?)
+make arch-aarch64-6.2.4
+make arch-apollolake-6.2.4
+make arch-armada370-6.2.4
+make arch-armada375-6.2.4
+make arch-armada37xx-6.2.4
+make arch-armada38x-6.2.4
+make arch-armadaxp-6.2.4
+make arch-armv7-6.2.4
+make arch-avoton-6.2.4
+make arch-broadwell-6.2.4
+make arch-broadwellnk-6.2.4
+make arch-bromolow-6.2.4
+make arch-cedarview-6.2.4
+make arch-denverton-6.2.4
+make arch-evansport-6.2.4
+make arch-geminilake-6.2.4
+make arch-grantley-6.2.4
+make arch-kvmx64-6.2.4
+make arch-dockerx64-6.2.3
+make arch-purley-6.2.4
+make arch-qoriq-6.2.4
+make arch-rtd1296-6.2.4
+make arch-v1000-6.2.4
+make arch-x86-6.2.4
+
+popd