From 90fca8e23a3b1ead7c13cd764bc09acd39f64a9a Mon Sep 17 00:00:00 2001 From: Moritz Warning Date: Tue, 23 Jan 2018 11:39:37 +0100 Subject: [PATCH] zerotier: support controller mode * 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 --- net/zerotier/Makefile | 2 +- net/zerotier/files/zerotier.config | 18 ++- net/zerotier/files/zerotier.init | 49 +++++-- ...rve-controller-requests-until-init-i.patch | 138 ++++++++++++++++++ 4 files changed, 190 insertions(+), 17 deletions(-) create mode 100644 net/zerotier/patches/0004-Revert-Do-not-serve-controller-requests-until-init-i.patch diff --git a/net/zerotier/Makefile b/net/zerotier/Makefile index 15cf30ce0b..4731e0b4dc 100644 --- a/net/zerotier/Makefile +++ b/net/zerotier/Makefile @@ -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 diff --git a/net/zerotier/files/zerotier.config b/net/zerotier/files/zerotier.config index d9c33de27d..9d49490e3b 100644 --- a/net/zerotier/files/zerotier.config +++ b/net/zerotier/files/zerotier.config @@ -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' diff --git a/net/zerotier/files/zerotier.init b/net/zerotier/files/zerotier.init index 4a1bacc955..13aff5bf0a 100644 --- a/net/zerotier/files/zerotier.init +++ b/net/zerotier/files/zerotier.init @@ -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 index 0000000000..1c2e4e7c72 --- /dev/null +++ b/net/zerotier/patches/0004-Revert-Do-not-serve-controller-requests-until-init-i.patch @@ -0,0 +1,138 @@ +From ab8ececbe70f7c83667d6ebb592fc1df17ad26a4 Mon Sep 17 00:00:00 2001 +From: Moritz Warning +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 _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::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 dl(OSUtils::listDirectory(p.c_str(),true)); + for(std::vector::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 + inline void filter(const std::string &prefix,F func) + { +- while (!_ready) { +- Thread::sleep(250); +- _ready = _reload(_basePath,std::string()); +- } +- + for(std::map::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 _db; +- volatile bool _ready; + }; + + } // namespace ZeroTier +-- +2.15.1 + -- 2.30.2