zerotier: support controller mode 5489/head
authorMoritz Warning <moritzwarning@web.de>
Tue, 23 Jan 2018 10:39:37 +0000 (11:39 +0100)
committerMoritz Warning <moritzwarning@web.de>
Tue, 23 Jan 2018 10:49:07 +0000 (11:49 +0100)
* add config_path option since the controller mode needs a persisting path to be used
* add patch to fix a bug in the controller code (https://github.com/zerotier/ZeroTierOne/issues/553)
* disable zerotier by default, as the default settings let it connect to a public network

Signed-off-by: Moritz Warning <moritzwarning@web.de>
net/zerotier/Makefile
net/zerotier/files/zerotier.config
net/zerotier/files/zerotier.init
net/zerotier/patches/0004-Revert-Do-not-serve-controller-requests-until-init-i.patch [new file with mode: 0644]

index 15cf30ce0b840646de215ea23b8cac4bdd748fc3..4731e0b4dc37ec11b3901f3c7383f82ec6895607 100644 (file)
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=zerotier
 PKG_VERSION:=1.2.4
-PKG_RELEASE:=2
+PKG_RELEASE:=3
 
 PKG_LICENSE:=GPL-3.0
 
index d9c33de27de5f36aecc4429aa4c03e601acc771a..9d49490e3bffb58850c510265160bd421a350137 100644 (file)
@@ -1,7 +1,17 @@
 
 config zerotier sample_config
-       option enabled 1
-       option interface 'wan' # restart ZT when wan status changed
+       option enabled 0
+
+       # persistent configuration folder (for ZT controller mode)
+       #option config_path '/etc/zerotier'
+
+       # restart ZT when wan status changed
+       option interface 'wan'
+
        #option port '9993'
-       option secret 'generate' # generate secret on first start
-       list join '8056c2e21c000001' # a public network called Earth
+
+       # Generate secret on first start
+       option secret 'generate'
+
+       # Join a public network called Earth
+       list join '8056c2e21c000001'
index 4a1bacc95510d67dcbd535413285fb69a04cf7fd..13aff5bf0abda516d13a40409e54e4976c8949f6 100644 (file)
@@ -4,9 +4,8 @@ START=90
 
 USE_PROCD=1
 
-LIST_SEP="
-"
-ZT_COMMAND=/usr/bin/zerotier-one
+PROG=/usr/bin/zerotier-one
+CONFIG_PATH=/var/lib/zerotier-one
 
 section_enabled() {
        config_get_bool enabled "$1" 'enabled' 0
@@ -15,17 +14,31 @@ section_enabled() {
 
 start_instance() {
        local cfg="$1"
-       local port secret interface
+       local port secret interface config_path
        local ARGS=""
 
        section_enabled "$cfg" || return 1
 
-       mkdir -p /var/lib/zerotier-one/networks.d/
-
+       config_get config_path $cfg 'config_path'
        config_get_bool port $cfg 'port'
        config_get secret $cfg 'secret'
        config_get interface $cfg 'interface'
 
+       # Remove existing link or folder
+       rm -rf $CONFIG_PATH
+
+       # Create link from CONFIG_PATH to config_path
+       if [ -n "$config_path" -a $config_path != $CONFIG_PATH ]; then
+               if [ ! -d "$config_path" ]; then
+                       echo "ZeroTier config_path does not exist: $config_path"
+                       return
+               fi
+
+               ln -s $config_path $CONFIG_PATH
+       fi
+
+       mkdir -p $CONFIG_PATH/networks.d
+
        if [ -n "$port" ]; then
                ARGS="$ARGS -p$port"
        fi
@@ -42,21 +55,21 @@ start_instance() {
        fi
 
        if [ -n "$secret" ]; then
-               echo "$secret" > /var/lib/zerotier-one/identity.secret
-               #make sure there is not previous dentity.public
-               rm -f /var/lib/zerotier-one/identity.public
+               echo "$secret" > $CONFIG_PATH/identity.secret
+               # make sure there is not previous identity.public
+               rm -f $CONFIG_PATH/identity.public
        fi
 
        add_join() {
-               #an (empty) config file will cause ZT to join a network
-               touch /var/lib/zerotier-one/networks.d/$1.conf
+               # an (empty) config file will cause ZT to join a network
+               touch $CONFIG_PATH/networks.d/$1.conf
        }
 
        config_list_foreach $cfg 'join' add_join
 
        procd_open_instance
        procd_add_reload_interface_trigger "$interface"
-       procd_set_param command $ZT_COMMAND $ARGS
+       procd_set_param command $PROG $ARGS $CONFIG_PATH
        procd_close_instance
 }
 
@@ -68,3 +81,15 @@ start_service() {
        config_load 'zerotier'
        config_foreach start_instance 'zerotier'
 }
+
+stop_instance() {
+       local cfg="$1"
+
+       # Remove existing link or folder
+       rm -rf $CONFIG_PATH
+}
+
+stop_service() {
+       config_load 'zerotier'
+       config_foreach stop_instance 'zerotier'
+}
diff --git a/net/zerotier/patches/0004-Revert-Do-not-serve-controller-requests-until-init-i.patch b/net/zerotier/patches/0004-Revert-Do-not-serve-controller-requests-until-init-i.patch
new file mode 100644 (file)
index 0000000..1c2e4e7
--- /dev/null
@@ -0,0 +1,138 @@
+From ab8ececbe70f7c83667d6ebb592fc1df17ad26a4 Mon Sep 17 00:00:00 2001
+From: Moritz Warning <moritzwarning@web.de>
+Date: Sat, 20 Jan 2018 21:55:52 +0100
+Subject: [PATCH] Revert "Do not serve controller requests until init is done."
+
+This reverts commit f4feccc6265cc480b84c85f897b225714072d4ec.
+---
+ controller/JSONDB.cpp | 20 +++++++-------------
+ controller/JSONDB.hpp | 15 +++++++--------
+ 2 files changed, 14 insertions(+), 21 deletions(-)
+
+diff --git a/controller/JSONDB.cpp b/controller/JSONDB.cpp
+index d3e76fc1..007e0fec 100644
+--- a/controller/JSONDB.cpp
++++ b/controller/JSONDB.cpp
+@@ -26,8 +26,7 @@ static const nlohmann::json _EMPTY_JSON(nlohmann::json::object());
+ static const std::map<std::string,std::string> _ZT_JSONDB_GET_HEADERS;
+ JSONDB::JSONDB(const std::string &basePath) :
+-      _basePath(basePath),
+-      _ready(false)
++      _basePath(basePath)
+ {
+       if ((_basePath.length() > 7)&&(_basePath.substr(0,7) == "http://")) {
+               // TODO: this doesn't yet support IPv6 since bracketed address notiation isn't supported.
+@@ -50,7 +49,7 @@ JSONDB::JSONDB(const std::string &basePath) :
+               OSUtils::mkdir(_basePath.c_str());
+               OSUtils::lockDownFile(_basePath.c_str(),true); // networks might contain auth tokens, etc., so restrict directory permissions
+       }
+-      _ready = _reload(_basePath,std::string());
++      _reload(_basePath,std::string());
+ }
+ bool JSONDB::writeRaw(const std::string &n,const std::string &obj)
+@@ -84,13 +83,9 @@ bool JSONDB::put(const std::string &n,const nlohmann::json &obj)
+ const nlohmann::json &JSONDB::get(const std::string &n)
+ {
+-      while (!_ready) {
+-              Thread::sleep(250);
+-              _ready = _reload(_basePath,std::string());
+-      }
+-
+       if (!_isValidObjectName(n))
+               return _EMPTY_JSON;
++
+       std::map<std::string,_E>::iterator e(_db.find(n));
+       if (e != _db.end())
+               return e->second.obj;
+@@ -138,7 +133,7 @@ void JSONDB::erase(const std::string &n)
+       _db.erase(n);
+ }
+-bool JSONDB::_reload(const std::string &p,const std::string &b)
++void JSONDB::_reload(const std::string &p,const std::string &b)
+ {
+       if (_httpAddr) {
+               std::string body;
+@@ -155,11 +150,11 @@ bool JSONDB::_reload(const std::string &p,const std::string &b)
+                                                       _db[tmp].obj = i.value();
+                                               }
+                                       }
+-                                      return true;
+                               }
+-                      } catch ( ... ) {} // invalid JSON, so maybe incomplete request
++                      } catch ( ... ) {
++                              // TODO: report error?
++                      }
+               }
+-              return false;
+       } else {
+               std::vector<std::string> dl(OSUtils::listDirectory(p.c_str(),true));
+               for(std::vector<std::string>::const_iterator di(dl.begin());di!=dl.end();++di) {
+@@ -169,7 +164,6 @@ bool JSONDB::_reload(const std::string &p,const std::string &b)
+                               this->_reload((p + ZT_PATH_SEPARATOR + *di),(b + *di + ZT_PATH_SEPARATOR));
+                       }
+               }
+-              return true;
+       }
+ }
+diff --git a/controller/JSONDB.hpp b/controller/JSONDB.hpp
+index beafbaf5..c19112ed 100644
+--- a/controller/JSONDB.hpp
++++ b/controller/JSONDB.hpp
+@@ -36,7 +36,6 @@
+ #include "../ext/json/json.hpp"
+ #include "../osdep/OSUtils.hpp"
+ #include "../osdep/Http.hpp"
+-#include "../osdep/Thread.hpp"
+ namespace ZeroTier {
+@@ -48,6 +47,12 @@ class JSONDB
+ public:
+       JSONDB(const std::string &basePath);
++      inline void reload()
++      {
++              _db.clear();
++              _reload(_basePath,std::string());
++      }
++
+       bool writeRaw(const std::string &n,const std::string &obj);
+       bool put(const std::string &n,const nlohmann::json &obj);
+@@ -74,11 +79,6 @@ public:
+       template<typename F>
+       inline void filter(const std::string &prefix,F func)
+       {
+-              while (!_ready) {
+-                      Thread::sleep(250);
+-                      _ready = _reload(_basePath,std::string());
+-              }
+-
+               for(std::map<std::string,_E>::iterator i(_db.lower_bound(prefix));i!=_db.end();) {
+                       if ((i->first.length() >= prefix.length())&&(!memcmp(i->first.data(),prefix.data(),prefix.length()))) {
+                               if (!func(i->first,get(i->first))) {
+@@ -94,7 +94,7 @@ public:
+       inline bool operator!=(const JSONDB &db) const { return (!(*this == db)); }
+ private:
+-      bool _reload(const std::string &p,const std::string &b);
++      void _reload(const std::string &p,const std::string &b);
+       bool _isValidObjectName(const std::string &n);
+       std::string _genPath(const std::string &n,bool create);
+@@ -108,7 +108,6 @@ private:
+       InetAddress _httpAddr;
+       std::string _basePath;
+       std::map<std::string,_E> _db;
+-      volatile bool _ready;
+ };
+ } // namespace ZeroTier
+-- 
+2.15.1
+