diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..342dc15
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,83 @@
+# This is a basic workflow to help you get started with Actions
+
+name: CI
+
+# Controls when the workflow will run
+on:
+ # Triggers the workflow on push or pull request events but only for the "master" branch
+ # push:
+ # branches: [ "master" ]
+ # pull_request:
+ # branches: [ "master" ]
+
+ # Allows you to run this workflow manually from the Actions tab
+ workflow_dispatch:
+
+env:
+ api_version: 21 # min. 21
+ ndk: r26d # android-ndk-$ndk-linux.zip
+
+# A workflow run is made up of one or more jobs that can run sequentially or in parallel
+jobs:
+ # This workflow contains a single job called "build"
+ build:
+ # The type of runner that the job will run on
+ runs-on: ubuntu-latest
+
+ # Steps represent a sequence of tasks that will be executed as part of the job
+ steps:
+ # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
+ - name: Checkout zerotier-magisk
+ uses: actions/checkout@v4
+
+ - name: Checkout ZeroTierOne
+ uses: actions/checkout@v4
+ with:
+ repository: zerotier/ZeroTierOne
+ path: ZeroTierOne
+
+ # Runs a single command using the runners shell
+ - name: Prepare NDK Toolchain
+ run: |
+ wget -qO ndk.zip https://dl.google.com/android/repository/android-ndk-$ndk-linux.zip
+ unzip -qq ndk.zip "android-ndk-$ndk/toolchains/*" && rm ndk.zip -f
+
+ - name: Build for aarch64
+ run: |
+ PATH=`pwd`/android-ndk-$ndk/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH
+
+ CC=aarch64-linux-android$api_version-clang
+ CXX=aarch64-linux-android$api_version-clang++
+
+ # "-D__GLIBC__=0" is a bypass, see zerotier/ZeroTierOne#2289
+ make -j $(nproc) ZT_DEBUG=0 ZT_SSO_SUPPORTED=0 CC=$CC CXX=$CXX LDFLAGS="-L../deps/aarch64" DEFS="-I../deps/include -D__GLIBC__=0"
+
+ cd ..
+
+ mkdir -p magisk/zerotier/lib
+ mv ZeroTierOne/zerotier-one magisk/zerotier
+ mv deps/aarch64/lic++_shared.so magisk/zerotier/lib
+ cd magisk
+ zip -q -r ../zerotier-magisk-aarch64.zip .
+
+ make clean
+
+ - name: Build for arm
+ run: |
+ PATH=`pwd`/android-ndk-$ndk/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH
+
+ CC=armv7a-linux-androideabi$api_version-clang
+ CXX=armv7a-linux-androideabi$api_version-clang++
+
+ # "-D__GLIBC__=0" is a bypass, see zerotier/ZeroTierOne#2289
+ make -j $(nproc) ZT_DEBUG=0 ZT_SSO_SUPPORTED=0 CC=$CC CXX=$CXX LDFLAGS="-L../deps/aarch64" DEFS="-I../deps/include -D__GLIBC__=0"
+
+ cd ..
+
+ mv ZeroTierOne/zerotier-one magisk/zerotier/
+ mv deps/aarch64/lic++_shared.so magisk/zerotier/lib/
+ cd magisk
+ zip -q -r ../zerotier-magisk-arm64.zip .
+
+ - name: Debugging with tmate
+ uses: mxschmitt/action-tmate@v3.18
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..14ff33f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+zerotier-magisk.zip
diff --git a/README.md b/README.md
index cd126a8..0f4fc46 100644
--- a/README.md
+++ b/README.md
@@ -1,20 +1,29 @@
-# zerotier-magisk
-This magisk module enables you to start zerotier in the background after booting.
+# ZeroTier for Magisk - run ZeroTier in the background
+
+
+
+[[中文](https://github.com/eventlOwOp/zerotier-magisk/blob/master/README_ZH.md) | English]
+
+
+
+**Run zerotier in the background after booting!**
+
+**No conflicts with other android VPN service!**
## Installation
If you're using a device with an older kernel where this version does not work, you can move to branch kernel-4.14 and installation steps are the same.
but scripts in this branch may be **OUTDATED**.
-1. download zipped code file from github
-2. install.
-3. modify the config file at `/sdcard/Android/zerotier/network_id.txt" and put your 16-character network id in it with no trailing new line.
+1. download release from github.
+2. install with magisk.
+3. modify the config file at `/sdcard/Android/zerotier/network_id.txt` and put your 16-character network id in it.
4. restart and enjoy.
-To restart, you can just restart the whole system, or just execute `/data/adb/zerotier/restart.sh`; An android application to control zerotier (networkid, restart, ...) has been add to the todo list.
+To restart, you can just restart the whole system, or just execute `/data/adb/zerotier/restart.sh`; An android application to control zerotier (networkid, restart, ...) has been added to the todo list.
### Scripts and binaries
-all the scripts and binaries are placed in `/data/adb/zerotier/` , you can use termux to run them if needed.
+all the scripts and binaries are placed in `/data/adb/zerotier/` , you can use termux to run them if needed.
`add_ip_rule.sh` is used to make the `main` route table, which zerotier writes its routes to, available.
### Build binaries yourself
@@ -23,7 +32,7 @@ The following steps have only been tested in "Termux" with the package manager "
Note that the zerotier binaries are only built for aarch64, you can build it yourself in "Termux".
-Download source files from [zerotier/ZeroTierOne](/zerotier/ZeroTierOne).
+Download source files from [zerotier/ZeroTierOne](https://www.github.com/zerotier/ZeroTierOne).
Delete `ZT_SSO_SUPPORTED=1` in `make-linux.mk` for "aarch64" (or your architecture). this will prevent building zeroidc with rust; the author encountered some problems building zeroidc
diff --git a/README_ZH.md b/README_ZH.md
new file mode 100644
index 0000000..45e2b21
--- /dev/null
+++ b/README_ZH.md
@@ -0,0 +1,36 @@
+# ZeroTier for Magisk - 后台运行你的 ZeroTier
+
+
+
+[中文 | [English](https://github.com/eventlOwOp/zerotier-magisk/blob/master/README.md)]
+
+
+
+将 ZeroTier 保持后台运行,不与其他 Android VPN 应用程序冲突
+
+## 安装
+部分较老内核版本可能不受支持,可以移步 kernel-4.14 分支进行尝试,但是该分支不保证更新
+
+1. 从 Release 下载压缩包
+2. 导入 magisk 进行安装
+3. 将你的 16 位 ZeroTier network id 写入 `/sdcard/Android/zerotier/network_id.txt`
+4. 重启
+
+你可以用 `su` 执行 `/data/adb/zerotier/restart.sh` 来重启,或者干脆重启手机,计划写一个 app 来完成
+
+### 路径
+
+ZeroTier 可执行文件和操作的 Shell 脚本放在 `/data/adb/zerotier/`
+`add_ip_rule.sh` is used to make the `main` route table, which zerotier writes its routes to, available.
+
+### 自行编译
+
+仅使用 termux (aarch64) 进行过测试
+
+从 [zerotier/ZeroTierOne](https://www.github.com/zerotier/ZeroTierOne) 下载代码
+
+在 `make-linux.mk` 中对 "aarch64" 或你的架构删除 `ZT_SSO_SUPPORTED=1` 即删除 zeroidc 支持,无需安装 rust 进行编译(目前未找到方法编译 zeroidc )
+
+`apt-get -y install natpmpc libnpth` 安装依赖库
+
+最后 `make` 编译(多线程使用 `make -j8`)
diff --git a/deps/aarch64/libc++_shared.so b/deps/aarch64/libc++_shared.so
new file mode 100644
index 0000000..a0a5d1a
Binary files /dev/null and b/deps/aarch64/libc++_shared.so differ
diff --git a/deps/aarch64/libnatpmp.a b/deps/aarch64/libnatpmp.a
new file mode 100644
index 0000000..b8f8ea4
Binary files /dev/null and b/deps/aarch64/libnatpmp.a differ
diff --git a/deps/aarch64/libnatpmp.so b/deps/aarch64/libnatpmp.so
new file mode 100644
index 0000000..7849665
Binary files /dev/null and b/deps/aarch64/libnatpmp.so differ
diff --git a/deps/arm/libc++_shared.so b/deps/arm/libc++_shared.so
new file mode 100644
index 0000000..2d2477b
Binary files /dev/null and b/deps/arm/libc++_shared.so differ
diff --git a/deps/arm/libnatpmp.a b/deps/arm/libnatpmp.a
new file mode 100644
index 0000000..ad24f4d
Binary files /dev/null and b/deps/arm/libnatpmp.a differ
diff --git a/deps/arm/libnatpmp.so b/deps/arm/libnatpmp.so
new file mode 100644
index 0000000..6f7803a
Binary files /dev/null and b/deps/arm/libnatpmp.so differ
diff --git a/deps/include/natpmp.h b/deps/include/natpmp.h
new file mode 100644
index 0000000..5642255
--- /dev/null
+++ b/deps/include/natpmp.h
@@ -0,0 +1,222 @@
+/* $Id: natpmp.h,v 1.22 2023/04/23 10:50:11 nanard Exp $ */
+/* libnatpmp
+Copyright (c) 2007-2014, Thomas BERNARD
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+ * The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+#ifndef __NATPMP_H__
+#define __NATPMP_H__
+
+/* NAT-PMP Port as defined by the NAT-PMP draft */
+#define NATPMP_PORT (5351)
+
+#include
+#if !defined(_MSC_VER)
+#include
+#endif /* !defined(_MSC_VER) */
+
+#ifdef _WIN32
+#include
+#if !defined(_MSC_VER) || _MSC_VER >= 1600
+#include
+#else /* !defined(_MSC_VER) || _MSC_VER >= 1600 */
+typedef unsigned long uint32_t;
+typedef unsigned short uint16_t;
+#endif /* !defined(_MSC_VER) || _MSC_VER >= 1600 */
+#define in_addr_t uint32_t
+#else /* _WIN32 */
+#include
+#endif /* _WIN32 */
+#include "natpmp_declspec.h"
+
+/* Set to 9 by https://tools.ietf.org/html/rfc6886#section-3.1 which leads to a
+ * maximum timeout of 127.75 seconds, due to the initial 250 ms timeout doubling
+ * each time, so we allow a compile-time modification here.*/
+#ifndef NATPMP_MAX_RETRIES
+#define NATPMP_MAX_RETRIES (9)
+#endif
+
+typedef struct {
+ int s; /* socket */
+ in_addr_t gateway; /* default gateway (IPv4) */
+ int has_pending_request;
+ unsigned char pending_request[12];
+ int pending_request_len;
+ int try_number;
+ struct timeval retry_time;
+} natpmp_t;
+
+typedef struct {
+ uint16_t type; /* NATPMP_RESPTYPE_* */
+ uint16_t resultcode; /* NAT-PMP response code */
+ uint32_t epoch; /* Seconds since start of epoch */
+ union {
+ struct {
+ //in_addr_t addr;
+ struct in_addr addr;
+ } publicaddress;
+ struct {
+ uint16_t privateport;
+ uint16_t mappedpublicport;
+ uint32_t lifetime;
+ } newportmapping;
+ } pnu;
+} natpmpresp_t;
+
+/* possible values for type field of natpmpresp_t */
+#define NATPMP_RESPTYPE_PUBLICADDRESS (0)
+#define NATPMP_RESPTYPE_UDPPORTMAPPING (1)
+#define NATPMP_RESPTYPE_TCPPORTMAPPING (2)
+
+/* Values to pass to sendnewportmappingrequest() */
+#define NATPMP_PROTOCOL_UDP (1)
+#define NATPMP_PROTOCOL_TCP (2)
+
+/* return values */
+/* NATPMP_ERR_INVALIDARGS : invalid arguments passed to the function */
+#define NATPMP_ERR_INVALIDARGS (-1)
+/* NATPMP_ERR_SOCKETERROR : socket() failed. check errno for details */
+#define NATPMP_ERR_SOCKETERROR (-2)
+/* NATPMP_ERR_CANNOTGETGATEWAY : can't get default gateway IP */
+#define NATPMP_ERR_CANNOTGETGATEWAY (-3)
+/* NATPMP_ERR_CLOSEERR : close() failed. check errno for details */
+#define NATPMP_ERR_CLOSEERR (-4)
+/* NATPMP_ERR_RECVFROM : recvfrom() failed. check errno for details */
+#define NATPMP_ERR_RECVFROM (-5)
+/* NATPMP_ERR_NOPENDINGREQ : readnatpmpresponseorretry() called while
+ * no NAT-PMP request was pending */
+#define NATPMP_ERR_NOPENDINGREQ (-6)
+/* NATPMP_ERR_NOGATEWAYSUPPORT : the gateway does not support NAT-PMP */
+#define NATPMP_ERR_NOGATEWAYSUPPORT (-7)
+/* NATPMP_ERR_CONNECTERR : connect() failed. check errno for details */
+#define NATPMP_ERR_CONNECTERR (-8)
+/* NATPMP_ERR_WRONGPACKETSOURCE : packet not received from the network gateway */
+#define NATPMP_ERR_WRONGPACKETSOURCE (-9)
+/* NATPMP_ERR_SENDERR : send() failed. check errno for details */
+#define NATPMP_ERR_SENDERR (-10)
+/* NATPMP_ERR_FCNTLERROR : fcntl() failed. check errno for details */
+#define NATPMP_ERR_FCNTLERROR (-11)
+/* NATPMP_ERR_GETTIMEOFDAYERR : gettimeofday() failed. check errno for details */
+#define NATPMP_ERR_GETTIMEOFDAYERR (-12)
+
+/* */
+#define NATPMP_ERR_UNSUPPORTEDVERSION (-14)
+#define NATPMP_ERR_UNSUPPORTEDOPCODE (-15)
+
+/* Errors from the server : */
+#define NATPMP_ERR_UNDEFINEDERROR (-49)
+#define NATPMP_ERR_NOTAUTHORIZED (-51)
+#define NATPMP_ERR_NETWORKFAILURE (-52)
+#define NATPMP_ERR_OUTOFRESOURCES (-53)
+
+/* NATPMP_TRYAGAIN : no data available for the moment. try again later */
+#define NATPMP_TRYAGAIN (-100)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* initnatpmp()
+ * initialize a natpmp_t object
+ * With forcegw=1 the gateway is not detected automaticaly.
+ * Return values :
+ * 0 = OK
+ * NATPMP_ERR_INVALIDARGS
+ * NATPMP_ERR_SOCKETERROR
+ * NATPMP_ERR_FCNTLERROR
+ * NATPMP_ERR_CANNOTGETGATEWAY
+ * NATPMP_ERR_CONNECTERR */
+NATPMP_LIBSPEC int initnatpmp(natpmp_t * p, int forcegw, in_addr_t forcedgw);
+
+/* closenatpmp()
+ * close resources associated with a natpmp_t object
+ * Return values :
+ * 0 = OK
+ * NATPMP_ERR_INVALIDARGS
+ * NATPMP_ERR_CLOSEERR */
+NATPMP_LIBSPEC int closenatpmp(natpmp_t * p);
+
+/* sendpublicaddressrequest()
+ * send a public address NAT-PMP request to the network gateway
+ * Return values :
+ * 2 = OK (size of the request)
+ * NATPMP_ERR_INVALIDARGS
+ * NATPMP_ERR_SENDERR */
+NATPMP_LIBSPEC int sendpublicaddressrequest(natpmp_t * p);
+
+/* sendnewportmappingrequest()
+ * send a new port mapping NAT-PMP request to the network gateway
+ * Arguments :
+ * protocol is either NATPMP_PROTOCOL_TCP or NATPMP_PROTOCOL_UDP,
+ * lifetime is in seconds.
+ * To remove a port mapping, set lifetime to zero.
+ * To remove all port mappings to the host, set lifetime and both ports
+ * to zero.
+ * Return values :
+ * 12 = OK (size of the request)
+ * NATPMP_ERR_INVALIDARGS
+ * NATPMP_ERR_SENDERR */
+NATPMP_LIBSPEC int sendnewportmappingrequest(natpmp_t * p, int protocol,
+ uint16_t privateport, uint16_t publicport,
+ uint32_t lifetime);
+
+/* getnatpmprequesttimeout()
+ * fills the timeval structure with the timeout duration of the
+ * currently pending NAT-PMP request.
+ * Return values :
+ * 0 = OK
+ * NATPMP_ERR_INVALIDARGS
+ * NATPMP_ERR_GETTIMEOFDAYERR
+ * NATPMP_ERR_NOPENDINGREQ */
+NATPMP_LIBSPEC int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout);
+
+/* readnatpmpresponseorretry()
+ * fills the natpmpresp_t structure if possible
+ * Return values :
+ * 0 = OK
+ * NATPMP_TRYAGAIN
+ * NATPMP_ERR_INVALIDARGS
+ * NATPMP_ERR_NOPENDINGREQ
+ * NATPMP_ERR_NOGATEWAYSUPPORT
+ * NATPMP_ERR_RECVFROM
+ * NATPMP_ERR_WRONGPACKETSOURCE
+ * NATPMP_ERR_UNSUPPORTEDVERSION
+ * NATPMP_ERR_UNSUPPORTEDOPCODE
+ * NATPMP_ERR_NOTAUTHORIZED
+ * NATPMP_ERR_NETWORKFAILURE
+ * NATPMP_ERR_OUTOFRESOURCES
+ * NATPMP_ERR_UNSUPPORTEDOPCODE
+ * NATPMP_ERR_UNDEFINEDERROR */
+NATPMP_LIBSPEC int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response);
+
+#ifdef ENABLE_STRNATPMPERR
+NATPMP_LIBSPEC const char * strnatpmperr(int t);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/deps/include/natpmp_declspec.h b/deps/include/natpmp_declspec.h
new file mode 100644
index 0000000..49ce27f
--- /dev/null
+++ b/deps/include/natpmp_declspec.h
@@ -0,0 +1,21 @@
+#ifndef NATPMP_DECLSPEC_H_INCLUDED
+#define NATPMP_DECLSPEC_H_INCLUDED
+
+#if defined(_WIN32) && !defined(NATPMP_STATICLIB)
+ /* for windows dll */
+ #ifdef NATPMP_EXPORTS
+ #define NATPMP_LIBSPEC __declspec(dllexport)
+ #else
+ #define NATPMP_LIBSPEC __declspec(dllimport)
+ #endif
+#else
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ /* fix dynlib for OS X 10.9.2 and Apple LLVM version 5.0 */
+ #define NATPMP_LIBSPEC __attribute__ ((visibility ("default")))
+ #else
+ #define NATPMP_LIBSPEC
+ #endif
+#endif
+
+#endif
+
diff --git a/LICENSE b/magisk/LICENSE
similarity index 100%
rename from LICENSE
rename to magisk/LICENSE
diff --git a/META-INF/com/google/android/update-binary b/magisk/META-INF/com/google/android/update-binary
similarity index 100%
rename from META-INF/com/google/android/update-binary
rename to magisk/META-INF/com/google/android/update-binary
diff --git a/META-INF/com/google/android/updater-script b/magisk/META-INF/com/google/android/updater-script
similarity index 100%
rename from META-INF/com/google/android/updater-script
rename to magisk/META-INF/com/google/android/updater-script
diff --git a/customize.sh b/magisk/customize.sh
similarity index 84%
rename from customize.sh
rename to magisk/customize.sh
index 1af2e96..e7dd9a1 100644
--- a/customize.sh
+++ b/magisk/customize.sh
@@ -15,6 +15,7 @@ set_perm_recursive ${MODPATH}/zerotier 0 0 0755 0755
ui_print "- create work dir"
mkdir -p ${ZT_PATH}
+mkdir ${ZT_PATH}/run ${ZT_PATH}/home
mv ${MODPATH}/zerotier/* ${ZT_PATH}
ln -s ${ZT_PATH}/zerotier-one ${ZT_PATH}/zerotier-cli
@@ -22,8 +23,10 @@ ln -s ${ZT_PATH}/zerotier-one ${ZT_PATH}/zerotier-idtool
ui_print "- create config dir"
mkdir -p ${CONF_PATH}
-touch ${CONF_PATH}/${CONF_NAME}
-echo "1111111111111111" > ${CONF_PATH}/${CONF_NAME}
+if [[ ! -e ${CONF_PATH}/${CONF_NAME} ]]; then
+ touch ${CONF_PATH}/${CONF_NAME}
+ echo "1111111111111111" > ${CONF_PATH}/${CONF_NAME}
+fi
ui_print "- clean up"
rm -rf ${MODPATH}/customize.sh 2>/dev/null
diff --git a/module.prop b/magisk/module.prop
similarity index 100%
rename from module.prop
rename to magisk/module.prop
diff --git a/magisk/service.sh b/magisk/service.sh
new file mode 100644
index 0000000..43771a3
--- /dev/null
+++ b/magisk/service.sh
@@ -0,0 +1,121 @@
+#!/system/bin/sh
+
+MODDIR=${0%/*}
+
+pipe=/data/adb/zerotier/run/pipe
+zerotier_log=/data/adb/zerotier/run/zerotier.log
+daemon_log=/data/adb/zerotier/run/daemon.log
+network_id_path=/sdcard/Android/zerotier/network_id.txt
+pid=-1
+
+log() {
+ t=`date +"%m-%d %H:%M:%S.%3N"`
+ echo "[$t][$$][L] $1" >> $daemon_log
+}
+_stop() {
+ if [ $pid -eq -1 ]; then
+ log "zerotier-one not running"
+ return 1
+ fi
+
+ kill -9 $pid
+ ret=$?
+ pid=-1
+
+ echo $pid > ./run/pid
+
+ if [ $ret -eq 0 ]; then
+ log "stopped zerotier-one"
+ return 0
+ else
+ log "kill zerotier-one failed"
+ fi
+
+ return 1
+}
+
+_join() {
+ nid=$(cat $network_id_path)
+
+ ./zerotier-cli -D./home join $nid > $zerotier_log 2>&1
+
+ if [ $? -ne 0 ]; then
+ log "join network failed"
+ return 1
+ else
+ log "joined $nid"
+ fi
+
+ return 0
+}
+
+_leave() {
+ nid=$(cat $network_id_path)
+
+ ./zerotier-cli -D./home leave $nid > $zerotier_log 2>&1
+
+ if [ $? -ne 0 ]; then
+ log "leave network failed"
+ return 1
+ else
+ log "left $nid"
+ fi
+
+ return 0
+}
+__start() {
+ nohup ./zerotier-one -d home > $zerotier_log 2>&1 &
+
+ sleep 1
+
+ pid=$(pidof zerotier-one)
+
+ echo $pid > ./run/pid
+}
+_start() {
+ if [ $pid -ne -1 ]; then
+ log "zerotier-one already running"
+ else
+ __start
+ log "started zerotier-one pid $pid"
+ fi
+
+ return 0
+}
+
+cd /data/adb/zerotier
+rm -f $daemon_log
+ip rule add from all lookup main pref 1
+export LD_LIBRARY_PATH=/data/adb/zerotier/lib
+
+__start
+
+trap "rm -f $pipe" EXIT
+
+rm -f $pipe
+mkfifo $pipe
+
+while true
+do
+ if read line < $pipe; then
+ log "received commad $line"
+ if [[ "$line" == 'quit' ]]; then
+ log "stopped"
+ break
+ elif [[ "$line" == 'start' ]]; then
+ _start
+ elif [[ "$line" == 'stop' ]]; then
+ _stop
+ elif [[ "$line" == 'restart' ]]; then
+ _stop
+ sleep 1
+ _start
+ elif [[ "$line" == 'join' ]]; then
+ _join
+ elif [[ "$line" == 'leave' ]]; then
+ _leave
+ else
+ log "unknown command $line"
+ fi
+ fi
+done
diff --git a/uninstall.sh b/magisk/uninstall.sh
similarity index 100%
rename from uninstall.sh
rename to magisk/uninstall.sh
diff --git a/magisk/zerotier/zerotier.sh b/magisk/zerotier/zerotier.sh
new file mode 100644
index 0000000..3b2aab6
--- /dev/null
+++ b/magisk/zerotier/zerotier.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+pipe=/data/adb/zerotier/run/pipe
+if [[ ! -p $pipe ]]; then
+ echo "daemon not running"
+ exit 1
+fi
+
+if [[ "$1" ]]; then
+ echo "$1" > $pipe
+else
+ echo "Usage: zerotier.sh {start|stop|restart|join|leave}"
+fi
diff --git a/service.sh b/service.sh
deleted file mode 100644
index 31a056e..0000000
--- a/service.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/system/bin/sh
-
-MODDIR=${0%/*}
-
-cd /data/adb/zerotier
-
-sh ./add_ip_rule.sh
-sh ./start.sh
-sh ./join.sh
diff --git a/zerotier/add_ip_rule.sh b/zerotier/add_ip_rule.sh
deleted file mode 100755
index 6d4c522..0000000
--- a/zerotier/add_ip_rule.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-ip rule add from all lookup main pref 1
-
diff --git a/zerotier/home/.gitkeep b/zerotier/home/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/zerotier/join.sh b/zerotier/join.sh
deleted file mode 100755
index e7c9a29..0000000
--- a/zerotier/join.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-export LD_LIBRARY_PATH=/data/adb/zerotier/lib
-cd /data/adb/zerotier/
-cat /sdcard/Android/zerotier/network_id.txt | xargs ./zerotier-cli -D./home join
diff --git a/zerotier/leave.sh b/zerotier/leave.sh
deleted file mode 100755
index bb02f13..0000000
--- a/zerotier/leave.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-export LD_LIBRARY_PATH=/data/adb/zerotier/lib
-cd /data/adb/zerotier
-cat /sdcard/Android/zerotier/network_id.txt | xargs ./zerotier-cli -D./home leave
diff --git a/zerotier/lib/ld-android.so b/zerotier/lib/ld-android.so
deleted file mode 100755
index 9f9e6a6..0000000
Binary files a/zerotier/lib/ld-android.so and /dev/null differ
diff --git a/zerotier/lib/libc++_shared.so b/zerotier/lib/libc++_shared.so
deleted file mode 100755
index f70e7f7..0000000
Binary files a/zerotier/lib/libc++_shared.so and /dev/null differ
diff --git a/zerotier/lib/libc.so b/zerotier/lib/libc.so
deleted file mode 100755
index ebb7cbd..0000000
Binary files a/zerotier/lib/libc.so and /dev/null differ
diff --git a/zerotier/lib/libdl.so b/zerotier/lib/libdl.so
deleted file mode 100755
index 46496d8..0000000
Binary files a/zerotier/lib/libdl.so and /dev/null differ
diff --git a/zerotier/lib/libm.so b/zerotier/lib/libm.so
deleted file mode 100755
index 25b7864..0000000
Binary files a/zerotier/lib/libm.so and /dev/null differ
diff --git a/zerotier/restart.sh b/zerotier/restart.sh
deleted file mode 100755
index e6adf68..0000000
--- a/zerotier/restart.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-pkill -9 zerotier-one
-cd /data/adb/zerotier
-sleep 1
-sh ./start.sh
-sleep 1
-sh ./join.sh
diff --git a/zerotier/start.sh b/zerotier/start.sh
deleted file mode 100755
index 50a7e73..0000000
--- a/zerotier/start.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-export LD_LIBRARY_PATH=/data/adb/zerotier/lib
-./zerotier-one -d home &
diff --git a/zerotier/zerotier-one b/zerotier/zerotier-one
deleted file mode 100755
index bfcfec4..0000000
Binary files a/zerotier/zerotier-one and /dev/null differ