From 546e8a3b44cff7dc3525a672bfe9806d3ee6144e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Skowro=C5=84ski?= Date: Sun, 25 Dec 2016 20:59:12 +0100 Subject: [PATCH 01/22] initial netbsd support in makefile/flags --- Makefile | 4 +++ make-netbsd.mk | 65 ++++++++++++++++++++++++++++++++++++++++++++++ node/Constants.hpp | 2 +- 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 make-netbsd.mk diff --git a/Makefile b/Makefile index 5a5f6605e..d8eb7edf2 100644 --- a/Makefile +++ b/Makefile @@ -16,3 +16,7 @@ endif ifeq ($(OSTYPE),OpenBSD) include make-freebsd.mk endif + +ifeq ($(OSTYPE),NetBSD) + include make-netbsd.mk +endif diff --git a/make-netbsd.mk b/make-netbsd.mk new file mode 100644 index 000000000..e2a13d5a2 --- /dev/null +++ b/make-netbsd.mk @@ -0,0 +1,65 @@ +CC=gcc +CXX=g++ + +INCLUDES= +DEFS= +LIBS= + +include objects.mk +OBJS+=osdep/BSDEthernetTap.o ext/lz4/lz4.o ext/json-parser/json.o ext/http-parser/http_parser.o + +# "make official" is a shortcut for this +ifeq ($(ZT_OFFICIAL_RELEASE),1) + DEFS+=-DZT_OFFICIAL_RELEASE +endif + +# Build with ZT_ENABLE_CLUSTER=1 to build with cluster support +ifeq ($(ZT_ENABLE_CLUSTER),1) + DEFS+=-DZT_ENABLE_CLUSTER +endif + +# "make debug" is a shortcut for this +ifeq ($(ZT_DEBUG),1) + DEFS+=-DZT_TRACE + CFLAGS+=-Wall -g -pthread $(INCLUDES) $(DEFS) + LDFLAGS+= + STRIP=echo + # The following line enables optimization for the crypto code, since + # C25519 in particular is almost UNUSABLE in heavy testing without it. +ext/lz4/lz4.o node/Salsa20.o node/SHA512.o node/C25519.o node/Poly1305.o: CFLAGS = -Wall -O2 -g -pthread $(INCLUDES) $(DEFS) +else + CFLAGS?=-O3 -fstack-protector + CFLAGS+=-Wall -fPIE -fvisibility=hidden -fstack-protector -pthread $(INCLUDES) -DNDEBUG $(DEFS) + LDFLAGS+=-pie -Wl,-z,relro,-z,now + STRIP=strip --strip-all +endif + +CXXFLAGS+=$(CFLAGS) -fno-rtti + +all: one + +one: $(OBJS) service/OneService.o one.o + $(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-one $(OBJS) service/OneService.o one.o $(LIBS) + $(STRIP) zerotier-one + ln -sf zerotier-one zerotier-idtool + ln -sf zerotier-one zerotier-cli + +selftest: $(OBJS) selftest.o + $(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-selftest selftest.o $(OBJS) $(LIBS) + $(STRIP) zerotier-selftest + +# No installer on FreeBSD yet +#installer: one FORCE +# ./buildinstaller.sh + +clean: + rm -rf *.o node/*.o controller/*.o osdep/*.o service/*.o ext/http-parser/*.o ext/lz4/*.o ext/json-parser/*.o build-* zerotier-one zerotier-idtool zerotier-selftest zerotier-cli ZeroTierOneInstaller-* + +debug: FORCE + make -j 4 ZT_DEBUG=1 + +#official: FORCE +# make -j 4 ZT_OFFICIAL_RELEASE=1 +# ./buildinstaller.sh + +FORCE: diff --git a/node/Constants.hpp b/node/Constants.hpp index dc36b3a11..b137e6aed 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -70,7 +70,7 @@ #endif #endif -#if defined(__FreeBSD__) || defined(__OpenBSD__) +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) #ifndef __UNIX_LIKE__ #define __UNIX_LIKE__ #endif From f09eedbd7adee2a804978182c1f9fdc2a1ad1d6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Skowro=C5=84ski?= Date: Sun, 25 Dec 2016 22:54:27 +0100 Subject: [PATCH 02/22] make it compilable --- make-netbsd.mk | 8 +- osdep/NetBSDEthernetTap.cpp | 464 ++++++++++++++++++++++++++++++++++++ osdep/NetBSDEthernetTap.hpp | 84 +++++++ osdep/freebsd_getifmaddrs.c | 202 ++++++++++++++++ osdep/freebsd_getifmaddrs.h | 70 ++++++ service/OneService.cpp | 8 +- 6 files changed, 830 insertions(+), 6 deletions(-) create mode 100644 osdep/NetBSDEthernetTap.cpp create mode 100644 osdep/NetBSDEthernetTap.hpp create mode 100644 osdep/freebsd_getifmaddrs.c create mode 100644 osdep/freebsd_getifmaddrs.h diff --git a/make-netbsd.mk b/make-netbsd.mk index e2a13d5a2..b53c969c3 100644 --- a/make-netbsd.mk +++ b/make-netbsd.mk @@ -6,7 +6,7 @@ DEFS= LIBS= include objects.mk -OBJS+=osdep/BSDEthernetTap.o ext/lz4/lz4.o ext/json-parser/json.o ext/http-parser/http_parser.o +OBJS+=osdep/NetBSDEthernetTap.o ext/lz4/lz4.o ext/json-parser/json.o ext/http-parser/http_parser.o # "make official" is a shortcut for this ifeq ($(ZT_OFFICIAL_RELEASE),1) @@ -29,17 +29,17 @@ ifeq ($(ZT_DEBUG),1) ext/lz4/lz4.o node/Salsa20.o node/SHA512.o node/C25519.o node/Poly1305.o: CFLAGS = -Wall -O2 -g -pthread $(INCLUDES) $(DEFS) else CFLAGS?=-O3 -fstack-protector - CFLAGS+=-Wall -fPIE -fvisibility=hidden -fstack-protector -pthread $(INCLUDES) -DNDEBUG $(DEFS) + CFLAGS+=-fPIE -fvisibility=hidden -fstack-protector -pthread $(INCLUDES) -DNDEBUG $(DEFS) LDFLAGS+=-pie -Wl,-z,relro,-z,now STRIP=strip --strip-all endif -CXXFLAGS+=$(CFLAGS) -fno-rtti +CXXFLAGS+=$(CFLAGS) -fno-rtti -fpermissive -w all: one one: $(OBJS) service/OneService.o one.o - $(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-one $(OBJS) service/OneService.o one.o $(LIBS) + $(CXX) $(CXXFLAGS) $(LDFLAGS) -o zerotier-one $(OBJS) service/OneService.o one.o $(LIBS) $(STRIP) zerotier-one ln -sf zerotier-one zerotier-idtool ln -sf zerotier-one zerotier-cli diff --git a/osdep/NetBSDEthernetTap.cpp b/osdep/NetBSDEthernetTap.cpp new file mode 100644 index 000000000..109a2a34a --- /dev/null +++ b/osdep/NetBSDEthernetTap.cpp @@ -0,0 +1,464 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * 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 . + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "freebsd_getifmaddrs.h" + +#include +#include +#include +#include +#include + +#include "../node/Constants.hpp" +#include "../node/Utils.hpp" +#include "../node/Mutex.hpp" +#include "OSUtils.hpp" +#include "NetBSDEthernetTap.hpp" + +#define ZT_BASE32_CHARS "0123456789abcdefghijklmnopqrstuv" + +// ff:ff:ff:ff:ff:ff with no ADI +static const ZeroTier::MulticastGroup _blindWildcardMulticastGroup(ZeroTier::MAC(0xff),0); + +namespace ZeroTier { + +NetBSDEthernetTap::NetBSDEthernetTap( + const char *homePath, + const MAC &mac, + unsigned int mtu, + unsigned int metric, + uint64_t nwid, + const char *friendlyName, + void (*handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int), + void *arg) : + _handler(handler), + _arg(arg), + _nwid(nwid), + _mtu(mtu), + _metric(metric), + _fd(0), + _enabled(true) +{ + static Mutex globalTapCreateLock; + char devpath[64],ethaddr[64],mtustr[32],metstr[32],tmpdevname[32]; + struct stat stattmp; + + // On FreeBSD at least we can rename, so use nwid to generate a deterministic unique zt#### name using base32 + // As a result we don't use desiredDevice + _dev = "zt"; + _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 60) & 0x1f)]); + _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 55) & 0x1f)]); + _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 50) & 0x1f)]); + _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 45) & 0x1f)]); + _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 40) & 0x1f)]); + _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 35) & 0x1f)]); + _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 30) & 0x1f)]); + _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 25) & 0x1f)]); + _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 20) & 0x1f)]); + _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 15) & 0x1f)]); + _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 10) & 0x1f)]); + _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 5) & 0x1f)]); + _dev.push_back(ZT_BASE32_CHARS[(unsigned long)(nwid & 0x1f)]); + + Mutex::Lock _gl(globalTapCreateLock); + + if (mtu > 2800) + throw std::runtime_error("max tap MTU is 2800"); + + // On BSD we create taps and they can have high numbers, so use ones starting + // at 9993 to not conflict with other stuff. Then we rename it to zt + std::vector devFiles(OSUtils::listDirectory("/dev")); + for(int i=9993;i<(9993+128);++i) { + Utils::snprintf(tmpdevname,sizeof(tmpdevname),"tap%d",i); + Utils::snprintf(devpath,sizeof(devpath),"/dev/%s",tmpdevname); + if (std::find(devFiles.begin(),devFiles.end(),std::string(tmpdevname)) == devFiles.end()) { + long cpid = (long)vfork(); + if (cpid == 0) { + ::execl("/sbin/ifconfig","/sbin/ifconfig",tmpdevname,"create",(const char *)0); + ::_exit(-1); + } else if (cpid > 0) { + int exitcode = -1; + ::waitpid(cpid,&exitcode,0); + } else throw std::runtime_error("fork() failed"); + + if (!stat(devpath,&stattmp)) { + cpid = (long)vfork(); + if (cpid == 0) { + ::execl("/sbin/ifconfig","/sbin/ifconfig",tmpdevname,"name",_dev.c_str(),(const char *)0); + ::_exit(-1); + } else if (cpid > 0) { + int exitcode = -1; + ::waitpid(cpid,&exitcode,0); + if (exitcode) + throw std::runtime_error("ifconfig rename operation failed"); + } else throw std::runtime_error("fork() failed"); + + _fd = ::open(devpath,O_RDWR); + if (_fd > 0) + break; + else throw std::runtime_error("unable to open created tap device"); + } else { + throw std::runtime_error("cannot find /dev node for newly created tap device"); + } + } + } + + if (_fd <= 0) + throw std::runtime_error("unable to open TAP device or no more devices available"); + + if (fcntl(_fd,F_SETFL,fcntl(_fd,F_GETFL) & ~O_NONBLOCK) == -1) { + ::close(_fd); + throw std::runtime_error("unable to set flags on file descriptor for TAP device"); + } + + // Configure MAC address and MTU, bring interface up + Utils::snprintf(ethaddr,sizeof(ethaddr),"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",(int)mac[0],(int)mac[1],(int)mac[2],(int)mac[3],(int)mac[4],(int)mac[5]); + Utils::snprintf(mtustr,sizeof(mtustr),"%u",_mtu); + Utils::snprintf(metstr,sizeof(metstr),"%u",_metric); + long cpid = (long)vfork(); + if (cpid == 0) { + ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"lladdr",ethaddr,"mtu",mtustr,"metric",metstr,"up",(const char *)0); + ::_exit(-1); + } else if (cpid > 0) { + int exitcode = -1; + ::waitpid(cpid,&exitcode,0); + if (exitcode) { + ::close(_fd); + throw std::runtime_error("ifconfig failure setting link-layer address and activating tap interface"); + } + } + + // Set close-on-exec so that devices cannot persist if we fork/exec for update + fcntl(_fd,F_SETFD,fcntl(_fd,F_GETFD) | FD_CLOEXEC); + + ::pipe(_shutdownSignalPipe); + + _thread = Thread::start(this); +} + +NetBSDEthernetTap::~NetBSDEthernetTap() +{ + ::write(_shutdownSignalPipe[1],"\0",1); // causes thread to exit + Thread::join(_thread); + ::close(_fd); + ::close(_shutdownSignalPipe[0]); + ::close(_shutdownSignalPipe[1]); + + long cpid = (long)vfork(); + if (cpid == 0) { + ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"destroy",(const char *)0); + ::_exit(-1); + } else if (cpid > 0) { + int exitcode = -1; + ::waitpid(cpid,&exitcode,0); + } +} + +void NetBSDEthernetTap::setEnabled(bool en) +{ + _enabled = en; +} + +bool NetBSDEthernetTap::enabled() const +{ + return _enabled; +} + +static bool ___removeIp(const std::string &_dev,const InetAddress &ip) +{ + long cpid = (long)vfork(); + if (cpid == 0) { + execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"inet",ip.toIpString().c_str(),"-alias",(const char *)0); + _exit(-1); + } else if (cpid > 0) { + int exitcode = -1; + waitpid(cpid,&exitcode,0); + return (exitcode == 0); + } + return false; // never reached, make compiler shut up about return value +} + +bool NetBSDEthernetTap::addIp(const InetAddress &ip) +{ + if (!ip) + return false; + + std::vector allIps(ips()); + if (std::find(allIps.begin(),allIps.end(),ip) != allIps.end()) + return true; // IP/netmask already assigned + + // Remove and reconfigure if address is the same but netmask is different + for(std::vector::iterator i(allIps.begin());i!=allIps.end();++i) { + if ((i->ipsEqual(ip))&&(i->netmaskBits() != ip.netmaskBits())) { + if (___removeIp(_dev,*i)) + break; + } + } + + long cpid = (long)vfork(); + if (cpid == 0) { + ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),ip.isV4() ? "inet" : "inet6",ip.toString().c_str(),"alias",(const char *)0); + ::_exit(-1); + } else if (cpid > 0) { + int exitcode = -1; + ::waitpid(cpid,&exitcode,0); + return (exitcode == 0); + } + return false; +} + +bool NetBSDEthernetTap::removeIp(const InetAddress &ip) +{ + if (!ip) + return false; + std::vector allIps(ips()); + if (std::find(allIps.begin(),allIps.end(),ip) != allIps.end()) { + if (___removeIp(_dev,ip)) + return true; + } + return false; +} + +std::vector NetBSDEthernetTap::ips() const +{ + struct ifaddrs *ifa = (struct ifaddrs *)0; + if (getifaddrs(&ifa)) + return std::vector(); + + std::vector r; + + struct ifaddrs *p = ifa; + while (p) { + if ((!strcmp(p->ifa_name,_dev.c_str()))&&(p->ifa_addr)&&(p->ifa_netmask)&&(p->ifa_addr->sa_family == p->ifa_netmask->sa_family)) { + switch(p->ifa_addr->sa_family) { + case AF_INET: { + struct sockaddr_in *sin = (struct sockaddr_in *)p->ifa_addr; + struct sockaddr_in *nm = (struct sockaddr_in *)p->ifa_netmask; + r.push_back(InetAddress(&(sin->sin_addr.s_addr),4,Utils::countBits((uint32_t)nm->sin_addr.s_addr))); + } break; + case AF_INET6: { + struct sockaddr_in6 *sin = (struct sockaddr_in6 *)p->ifa_addr; + struct sockaddr_in6 *nm = (struct sockaddr_in6 *)p->ifa_netmask; + uint32_t b[4]; + memcpy(b,nm->sin6_addr.s6_addr,sizeof(b)); + r.push_back(InetAddress(sin->sin6_addr.s6_addr,16,Utils::countBits(b[0]) + Utils::countBits(b[1]) + Utils::countBits(b[2]) + Utils::countBits(b[3]))); + } break; + } + } + p = p->ifa_next; + } + + if (ifa) + freeifaddrs(ifa); + + std::sort(r.begin(),r.end()); + std::unique(r.begin(),r.end()); + + return r; +} + +void NetBSDEthernetTap::put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len) +{ + char putBuf[4096]; + if ((_fd > 0)&&(len <= _mtu)&&(_enabled)) { + to.copyTo(putBuf,6); + from.copyTo(putBuf + 6,6); + *((uint16_t *)(putBuf + 12)) = htons((uint16_t)etherType); + memcpy(putBuf + 14,data,len); + len += 14; + ::write(_fd,putBuf,len); + } +} + +std::string NetBSDEthernetTap::deviceName() const +{ + return _dev; +} + +void NetBSDEthernetTap::setFriendlyName(const char *friendlyName) +{ +} + +void NetBSDEthernetTap::scanMulticastGroups(std::vector &added,std::vector &removed) +{ + std::vector newGroups; + + struct ifmaddrs *ifmap = (struct ifmaddrs *)0; + if (!getifmaddrs(&ifmap)) { + struct ifmaddrs *p = ifmap; + while (p) { + if (p->ifma_addr->sa_family == AF_LINK) { + struct sockaddr_dl *in = (struct sockaddr_dl *)p->ifma_name; + struct sockaddr_dl *la = (struct sockaddr_dl *)p->ifma_addr; + if ((la->sdl_alen == 6)&&(in->sdl_nlen <= _dev.length())&&(!memcmp(_dev.data(),in->sdl_data,in->sdl_nlen))) + newGroups.push_back(MulticastGroup(MAC(la->sdl_data + la->sdl_nlen,6),0)); + } + p = p->ifma_next; + } + freeifmaddrs(ifmap); + } + + std::vector allIps(ips()); + for(std::vector::iterator ip(allIps.begin());ip!=allIps.end();++ip) + newGroups.push_back(MulticastGroup::deriveMulticastGroupForAddressResolution(*ip)); + + std::sort(newGroups.begin(),newGroups.end()); + std::unique(newGroups.begin(),newGroups.end()); + + for(std::vector::iterator m(newGroups.begin());m!=newGroups.end();++m) { + if (!std::binary_search(_multicastGroups.begin(),_multicastGroups.end(),*m)) + added.push_back(*m); + } + for(std::vector::iterator m(_multicastGroups.begin());m!=_multicastGroups.end();++m) { + if (!std::binary_search(newGroups.begin(),newGroups.end(),*m)) + removed.push_back(*m); + } + + _multicastGroups.swap(newGroups); +} + +/* +bool NetBSDEthernetTap::updateMulticastGroups(std::set &groups) +{ + std::set newGroups; + struct ifmaddrs *ifmap = (struct ifmaddrs *)0; + if (!getifmaddrs(&ifmap)) { + struct ifmaddrs *p = ifmap; + while (p) { + if (p->ifma_addr->sa_family == AF_LINK) { + struct sockaddr_dl *in = (struct sockaddr_dl *)p->ifma_name; + struct sockaddr_dl *la = (struct sockaddr_dl *)p->ifma_addr; + if ((la->sdl_alen == 6)&&(in->sdl_nlen <= _dev.length())&&(!memcmp(_dev.data(),in->sdl_data,in->sdl_nlen))) + newGroups.insert(MulticastGroup(MAC(la->sdl_data + la->sdl_nlen,6),0)); + } + p = p->ifma_next; + } + freeifmaddrs(ifmap); + } + + { + std::set allIps(ips()); + for(std::set::const_iterator i(allIps.begin());i!=allIps.end();++i) + newGroups.insert(MulticastGroup::deriveMulticastGroupForAddressResolution(*i)); + } + + bool changed = false; + + for(std::set::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) { + if (!groups.count(*mg)) { + groups.insert(*mg); + changed = true; + } + } + for(std::set::iterator mg(groups.begin());mg!=groups.end();) { + if ((!newGroups.count(*mg))&&(*mg != _blindWildcardMulticastGroup)) { + groups.erase(mg++); + changed = true; + } else ++mg; + } + + return changed; +} +*/ + +void NetBSDEthernetTap::threadMain() + throw() +{ + fd_set readfds,nullfds; + MAC to,from; + int n,nfds,r; + char getBuf[8194]; + + // Wait for a moment after startup -- wait for Network to finish + // constructing itself. + Thread::sleep(500); + + FD_ZERO(&readfds); + FD_ZERO(&nullfds); + nfds = (int)std::max(_shutdownSignalPipe[0],_fd) + 1; + + r = 0; + for(;;) { + FD_SET(_shutdownSignalPipe[0],&readfds); + FD_SET(_fd,&readfds); + select(nfds,&readfds,&nullfds,&nullfds,(struct timeval *)0); + + if (FD_ISSET(_shutdownSignalPipe[0],&readfds)) // writes to shutdown pipe terminate thread + break; + + if (FD_ISSET(_fd,&readfds)) { + n = (int)::read(_fd,getBuf + r,sizeof(getBuf) - r); + if (n < 0) { + if ((errno != EINTR)&&(errno != ETIMEDOUT)) + break; + } else { + // Some tap drivers like to send the ethernet frame and the + // payload in two chunks, so handle that by accumulating + // data until we have at least a frame. + r += n; + if (r > 14) { + if (r > ((int)_mtu + 14)) // sanity check for weird TAP behavior on some platforms + r = _mtu + 14; + + if (_enabled) { + to.setTo(getBuf,6); + from.setTo(getBuf + 6,6); + unsigned int etherType = ntohs(((const uint16_t *)getBuf)[6]); + // TODO: VLAN support + _handler(_arg,_nwid,from,to,etherType,0,(const void *)(getBuf + 14),r - 14); + } + + r = 0; + } + } + } + } +} + +} // namespace ZeroTier diff --git a/osdep/NetBSDEthernetTap.hpp b/osdep/NetBSDEthernetTap.hpp new file mode 100644 index 000000000..a555a4b12 --- /dev/null +++ b/osdep/NetBSDEthernetTap.hpp @@ -0,0 +1,84 @@ +/* + * ZeroTier One - Network Virtualization Everywhere + * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/ + * + * 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 . + */ + +#ifndef ZT_NetBSDEthernetTap_HPP +#define ZT_NetBSDEthernetTap_HPP + +#include +#include + +#include +#include +#include + +#include "../node/Constants.hpp" +#include "../node/MulticastGroup.hpp" +#include "../node/MAC.hpp" +#include "Thread.hpp" + + + + + +namespace ZeroTier { + +class NetBSDEthernetTap +{ +public: + NetBSDEthernetTap( + const char *homePath, + const MAC &mac, + unsigned int mtu, + unsigned int metric, + uint64_t nwid, + const char *friendlyName, + void (*handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int), + void *arg); + + ~NetBSDEthernetTap(); + + void setEnabled(bool en); + bool enabled() const; + bool addIp(const InetAddress &ip); + bool removeIp(const InetAddress &ip); + std::vector ips() const; + void put(const MAC &from,const MAC &to,unsigned int etherType,const void *data,unsigned int len); + std::string deviceName() const; + void setFriendlyName(const char *friendlyName); + void scanMulticastGroups(std::vector &added,std::vector &removed); + + void threadMain() + throw(); + +private: + void (*_handler)(void *,uint64_t,const MAC &,const MAC &,unsigned int,unsigned int,const void *,unsigned int); + void *_arg; + uint64_t _nwid; + Thread _thread; + std::string _dev; + std::vector _multicastGroups; + unsigned int _mtu; + unsigned int _metric; + int _fd; + int _shutdownSignalPipe[2]; + volatile bool _enabled; +}; + +} // namespace ZeroTier + +#endif diff --git a/osdep/freebsd_getifmaddrs.c b/osdep/freebsd_getifmaddrs.c new file mode 100644 index 000000000..559fdc065 --- /dev/null +++ b/osdep/freebsd_getifmaddrs.c @@ -0,0 +1,202 @@ +#define NET_RT_IFMALIST 4 /* return multicast address list */ +#define RTM_NEWMADDR 0xf /* mcast group membership being added to if */ + + +/* + * Copyright (c) 2003 Bruce M. Simpson. + * All rights reserved + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. + */ + +#include +/* +__FBSDID("$FreeBSD$"); + +#include "namespace.h"*/ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +//#include "un-namespace.h" + +#define SALIGN (sizeof(long) - 1) +#define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : \ + (SALIGN + 1)) +#define MAX_SYSCTL_TRY 5 +#define RTA_MASKS (RTA_GATEWAY | RTA_IFP | RTA_IFA) + +int +getifmaddrs(struct ifmaddrs **pif) +{ + int icnt = 1; + int dcnt = 0; + int ntry = 0; + size_t len; + size_t needed; + int mib[6]; + int i; + char *buf; + char *data; + char *next; + char *p; + struct ifma_msghdr *ifmam; + struct ifmaddrs *ifa, *ift; + struct rt_msghdr *rtm; + struct sockaddr *sa; + + mib[0] = CTL_NET; + mib[1] = PF_ROUTE; + mib[2] = 0; /* protocol */ + mib[3] = 0; /* wildcard address family */ + mib[4] = NET_RT_IFMALIST; + mib[5] = 0; /* no flags */ + do { + if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) + return (-1); + if ((buf = malloc(needed)) == NULL) + return (-1); + if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { + if (errno != ENOMEM || ++ntry >= MAX_SYSCTL_TRY) { + free(buf); + return (-1); + } + free(buf); + buf = NULL; + } + } while (buf == NULL); + + for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { + rtm = (struct rt_msghdr *)(void *)next; + if (rtm->rtm_version != RTM_VERSION) + continue; + switch (rtm->rtm_type) { + case RTM_NEWMADDR: + ifmam = (struct ifma_msghdr *)(void *)rtm; + if ((ifmam->ifmam_addrs & RTA_IFA) == 0) + break; + icnt++; + p = (char *)(ifmam + 1); + for (i = 0; i < RTAX_MAX; i++) { + if ((RTA_MASKS & ifmam->ifmam_addrs & + (1 << i)) == 0) + continue; + sa = (struct sockaddr *)(void *)p; + len = SA_RLEN(sa); + dcnt += len; + p += len; + } + break; + } + } + + data = malloc(sizeof(struct ifmaddrs) * icnt + dcnt); + if (data == NULL) { + free(buf); + return (-1); + } + + ifa = (struct ifmaddrs *)(void *)data; + data += sizeof(struct ifmaddrs) * icnt; + + memset(ifa, 0, sizeof(struct ifmaddrs) * icnt); + ift = ifa; + + for (next = buf; next < buf + needed; next += rtm->rtm_msglen) { + rtm = (struct rt_msghdr *)(void *)next; + if (rtm->rtm_version != RTM_VERSION) + continue; + + switch (rtm->rtm_type) { + case RTM_NEWMADDR: + ifmam = (struct ifma_msghdr *)(void *)rtm; + if ((ifmam->ifmam_addrs & RTA_IFA) == 0) + break; + + p = (char *)(ifmam + 1); + for (i = 0; i < RTAX_MAX; i++) { + if ((RTA_MASKS & ifmam->ifmam_addrs & + (1 << i)) == 0) + continue; + sa = (struct sockaddr *)(void *)p; + len = SA_RLEN(sa); + switch (i) { + case RTAX_GATEWAY: + ift->ifma_lladdr = + (struct sockaddr *)(void *)data; + memcpy(data, p, len); + data += len; + break; + + case RTAX_IFP: + ift->ifma_name = + (struct sockaddr *)(void *)data; + memcpy(data, p, len); + data += len; + break; + + case RTAX_IFA: + ift->ifma_addr = + (struct sockaddr *)(void *)data; + memcpy(data, p, len); + data += len; + break; + + default: + data += len; + break; + } + p += len; + } + ift->ifma_next = ift + 1; + ift = ift->ifma_next; + break; + } + } + + free(buf); + + if (ift > ifa) { + ift--; + ift->ifma_next = NULL; + *pif = ifa; + } else { + *pif = NULL; + free(ifa); + } + return (0); +} + +void +freeifmaddrs(struct ifmaddrs *ifmp) +{ + + free(ifmp); +} diff --git a/osdep/freebsd_getifmaddrs.h b/osdep/freebsd_getifmaddrs.h new file mode 100644 index 000000000..a3eeec713 --- /dev/null +++ b/osdep/freebsd_getifmaddrs.h @@ -0,0 +1,70 @@ +/* $FreeBSD$ */ + +/* + * Copyright (c) 1995, 1999 + * Berkeley Software Design, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``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 Berkeley Software Design, Inc. 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. + * + * BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp + */ + +#ifndef _freebsd_getifmaddrs.h_ +#define _freebsd_getifmaddrs.h_ + +/* + * This may have been defined in . Note that if is + * to be included it must be included before this header file. + */ +#ifndef ifa_broadaddr +#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ +#endif + +struct ifmaddrs { + struct ifmaddrs *ifma_next; + struct sockaddr *ifma_name; + struct sockaddr *ifma_addr; + struct sockaddr *ifma_lladdr; +}; + +#include + + +/* + * Message format for use in obtaining information about multicast addresses + * from the routing socket + */ +struct ifma_msghdr { + int ifmam_msglen; /* to skip over non-understood messages */ + int ifmam_version; /* future binary compatibility */ + int ifmam_type; /* message type */ + int ifmam_addrs; /* like rtm_addrs */ + int ifmam_flags; /* value of ifa_flags */ + int ifmam_index; /* index for associated ifp */ +}; + + +extern int getifaddrs(struct ifaddrs **); +extern void freeifaddrs(struct ifaddrs *); +extern int getifmaddrs(struct ifmaddrs **); +extern void freeifmaddrs(struct ifmaddrs *); +#include "freebsd_getifmaddrs.c" + + +#endif diff --git a/service/OneService.cpp b/service/OneService.cpp index 13820f5ca..4dd73c19c 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -114,6 +114,10 @@ namespace ZeroTier { typedef WindowsEthernetTap EthernetTap; } #include "../osdep/BSDEthernetTap.hpp" namespace ZeroTier { typedef BSDEthernetTap EthernetTap; } #endif // __FreeBSD__ +#ifdef __NetBSD__ +#include "../osdep/NetBSDEthernetTap.hpp" +namespace ZeroTier { typedef NetBSDEthernetTap EthernetTap; } +#endif // __FreeBSD__ #endif // ZT_SERVICE_NETCON @@ -1684,7 +1688,7 @@ public: inline int nodePathCheckFunction(const struct sockaddr_storage *localAddr,const struct sockaddr_storage *remoteAddr) { Mutex::Lock _l(_nets_m); - + for(std::map::const_iterator n(_nets.begin());n!=_nets.end();++n) { if (n->second.tap) { std::vector ips(n->second.tap->ips()); @@ -1695,7 +1699,7 @@ public: } } } - + /* Note: I do not think we need to scan for overlap with managed routes * because of the "route forking" and interface binding that we do. This * ensures (we hope) that ZeroTier traffic will still take the physical From 218ace51a749a976af7078a1bc433d82c7cd219e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Skowro=C5=84ski?= Date: Mon, 26 Dec 2016 02:52:07 +0100 Subject: [PATCH 03/22] use /dev/tap{0..3}; it is fully working now --- osdep/NetBSDEthernetTap.cpp | 41 ++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/osdep/NetBSDEthernetTap.cpp b/osdep/NetBSDEthernetTap.cpp index 109a2a34a..1dbe312f4 100644 --- a/osdep/NetBSDEthernetTap.cpp +++ b/osdep/NetBSDEthernetTap.cpp @@ -61,6 +61,8 @@ #include "OSUtils.hpp" #include "NetBSDEthernetTap.hpp" +#include +using namespace std; #define ZT_BASE32_CHARS "0123456789abcdefghijklmnopqrstuv" // ff:ff:ff:ff:ff:ff with no ADI @@ -111,13 +113,12 @@ NetBSDEthernetTap::NetBSDEthernetTap( if (mtu > 2800) throw std::runtime_error("max tap MTU is 2800"); - // On BSD we create taps and they can have high numbers, so use ones starting - // at 9993 to not conflict with other stuff. Then we rename it to zt + // On NetBSD there are /dev/tap{0..3} pre-created and for a moment I will stick with only them std::vector devFiles(OSUtils::listDirectory("/dev")); - for(int i=9993;i<(9993+128);++i) { + for(int i=0;i<4;++i) { Utils::snprintf(tmpdevname,sizeof(tmpdevname),"tap%d",i); Utils::snprintf(devpath,sizeof(devpath),"/dev/%s",tmpdevname); - if (std::find(devFiles.begin(),devFiles.end(),std::string(tmpdevname)) == devFiles.end()) { + //if (std::find(devFiles.begin(),devFiles.end(),std::string(tmpdevname)) == devFiles.end()) { long cpid = (long)vfork(); if (cpid == 0) { ::execl("/sbin/ifconfig","/sbin/ifconfig",tmpdevname,"create",(const char *)0); @@ -127,8 +128,10 @@ NetBSDEthernetTap::NetBSDEthernetTap( ::waitpid(cpid,&exitcode,0); } else throw std::runtime_error("fork() failed"); + _dev = tmpdevname; + _fd = ::open( devpath,O_RDWR); if (!stat(devpath,&stattmp)) { - cpid = (long)vfork(); + /*cpid = (long)vfork(); if (cpid == 0) { ::execl("/sbin/ifconfig","/sbin/ifconfig",tmpdevname,"name",_dev.c_str(),(const char *)0); ::_exit(-1); @@ -137,16 +140,16 @@ NetBSDEthernetTap::NetBSDEthernetTap( ::waitpid(cpid,&exitcode,0); if (exitcode) throw std::runtime_error("ifconfig rename operation failed"); - } else throw std::runtime_error("fork() failed"); + } else throw std::runtime_error("fork() failed");*/ + - _fd = ::open(devpath,O_RDWR); if (_fd > 0) break; - else throw std::runtime_error("unable to open created tap device"); + //else throw std::runtime_error("unable to open created tap device "); } else { throw std::runtime_error("cannot find /dev node for newly created tap device"); } - } + //} } if (_fd <= 0) @@ -163,7 +166,7 @@ NetBSDEthernetTap::NetBSDEthernetTap( Utils::snprintf(metstr,sizeof(metstr),"%u",_metric); long cpid = (long)vfork(); if (cpid == 0) { - ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"lladdr",ethaddr,"mtu",mtustr,"metric",metstr,"up",(const char *)0); + ::execl("/sbin/ifconfig","/sbin/ifconfig",_dev.c_str(),"link",ethaddr,"mtu",mtustr,"metric",metstr,"up",(const char *)0); ::_exit(-1); } else if (cpid > 0) { int exitcode = -1; @@ -174,12 +177,30 @@ NetBSDEthernetTap::NetBSDEthernetTap( } } + // ifconfig link seems to be different from address + // https://wiki.netbsd.org/tutorials/faking_a_mac_address/ + cpid = (long)vfork(); + if (cpid == 0) { + string cmdline = "net.link.tap."+string(_dev); + cmdline += "="+string(ethaddr); + ::execl("/sbin/sysctl","/sbin/sysctl","-w",cmdline.c_str(),(const char *)0); + ::_exit(-1); + } else if (cpid > 0) { + int exitcode = -1; + ::waitpid(cpid,&exitcode,0); + if (exitcode) { + ::close(_fd); + throw std::runtime_error("sysctl failure setting link-layer address and activating tap interface"); + } + } + // Set close-on-exec so that devices cannot persist if we fork/exec for update fcntl(_fd,F_SETFD,fcntl(_fd,F_GETFD) | FD_CLOEXEC); ::pipe(_shutdownSignalPipe); _thread = Thread::start(this); + } NetBSDEthernetTap::~NetBSDEthernetTap() From 9a2310395d8e4b9666530e5b57547482877b2668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Skowro=C5=84ski?= Date: Tue, 27 Dec 2016 11:42:43 +0100 Subject: [PATCH 04/22] mimic BSDEthernetTap but with creating/destroying char tap device --- osdep/NetBSDEthernetTap.cpp | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/osdep/NetBSDEthernetTap.cpp b/osdep/NetBSDEthernetTap.cpp index 1dbe312f4..8f715171e 100644 --- a/osdep/NetBSDEthernetTap.cpp +++ b/osdep/NetBSDEthernetTap.cpp @@ -115,7 +115,8 @@ NetBSDEthernetTap::NetBSDEthernetTap( // On NetBSD there are /dev/tap{0..3} pre-created and for a moment I will stick with only them std::vector devFiles(OSUtils::listDirectory("/dev")); - for(int i=0;i<4;++i) { +// for(int i=0;i<4;++i) { + for(int i=9993;i<(9993+128);++i) { Utils::snprintf(tmpdevname,sizeof(tmpdevname),"tap%d",i); Utils::snprintf(devpath,sizeof(devpath),"/dev/%s",tmpdevname); //if (std::find(devFiles.begin(),devFiles.end(),std::string(tmpdevname)) == devFiles.end()) { @@ -128,6 +129,20 @@ NetBSDEthernetTap::NetBSDEthernetTap( ::waitpid(cpid,&exitcode,0); } else throw std::runtime_error("fork() failed"); + cpid = (long)vfork(); + if (cpid == 0) { + string tmp; + sprintf((char*)tmp.c_str(), "%d", i); + string minor = tmp.c_str(); + ::execl("/sbin/mknod","/sbin/mknod",devpath,"c","169",minor.c_str(),(const char *)0); //major 169 => tap + ::_exit(-1); + } else if (cpid > 0) { + int exitcode = -1; + ::waitpid(cpid,&exitcode,0); + } else throw std::runtime_error("fork() failed"); + + cerr<<"created device "< 0) { + int exitcode = -1; + ::waitpid(cpid,&exitcode,0); + } else throw std::runtime_error("fork() failed"); } void NetBSDEthernetTap::setEnabled(bool en) From ba07d1f91d49203856a28890521daf1a5cb2cfcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Skowro=C5=84ski?= Date: Tue, 27 Dec 2016 11:57:05 +0100 Subject: [PATCH 05/22] cleanup --- README.md | 2 +- osdep/NetBSDEthernetTap.cpp | 43 +++++++------------------------------ osdep/freebsd_getifmaddrs.c | 5 +++++ osdep/freebsd_getifmaddrs.h | 5 +++++ 4 files changed, 19 insertions(+), 36 deletions(-) diff --git a/README.md b/README.md index a34a1a53a..f9ee85ee4 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ For Mac, Linux, and BSD, just type "make" (or "gmake" on BSD). You won't need mu * **Mac**: Xcode command line tools. It should build on OSX 10.7 or newer. * **Linux**: gcc/g++ (4.9 or newer recommended) or clang/clang++ (3.4 or newer recommended) Makefile will use clang by default if available. The Linux build will auto-detect the presence of development headers for *json-parser*, *http-parser*, *li8bnatpmp*, and *libminiupnpc* and will link against the system libraries for these if they are present and recent enough. Otherwise the bundled versions in [ext/](ext/) will be used. Type `make install` to install the binaries and other files on the system, though this will not create init.d or systemd links. - * **FreeBSD**: C++ compiler (G++ usually) and GNU make (gmake). + * **FreeBSD/OpenBSD/NetBSD**: C++ compiler (G++ usually) and GNU make (gmake). Each supported platform has its own *make-XXX.mk* file that contains the actual make rules for the platform. The right .mk file is included by the main Makefile based on the GNU make *OSTYPE* variable. Take a look at the .mk file for your platform for other targets, debug build rules, etc. diff --git a/osdep/NetBSDEthernetTap.cpp b/osdep/NetBSDEthernetTap.cpp index 8f715171e..5d1c96257 100644 --- a/osdep/NetBSDEthernetTap.cpp +++ b/osdep/NetBSDEthernetTap.cpp @@ -91,35 +91,17 @@ NetBSDEthernetTap::NetBSDEthernetTap( char devpath[64],ethaddr[64],mtustr[32],metstr[32],tmpdevname[32]; struct stat stattmp; - // On FreeBSD at least we can rename, so use nwid to generate a deterministic unique zt#### name using base32 - // As a result we don't use desiredDevice - _dev = "zt"; - _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 60) & 0x1f)]); - _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 55) & 0x1f)]); - _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 50) & 0x1f)]); - _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 45) & 0x1f)]); - _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 40) & 0x1f)]); - _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 35) & 0x1f)]); - _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 30) & 0x1f)]); - _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 25) & 0x1f)]); - _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 20) & 0x1f)]); - _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 15) & 0x1f)]); - _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 10) & 0x1f)]); - _dev.push_back(ZT_BASE32_CHARS[(unsigned long)((nwid >> 5) & 0x1f)]); - _dev.push_back(ZT_BASE32_CHARS[(unsigned long)(nwid & 0x1f)]); - Mutex::Lock _gl(globalTapCreateLock); if (mtu > 2800) throw std::runtime_error("max tap MTU is 2800"); - // On NetBSD there are /dev/tap{0..3} pre-created and for a moment I will stick with only them + // we can create /dev/tap* std::vector devFiles(OSUtils::listDirectory("/dev")); -// for(int i=0;i<4;++i) { for(int i=9993;i<(9993+128);++i) { Utils::snprintf(tmpdevname,sizeof(tmpdevname),"tap%d",i); Utils::snprintf(devpath,sizeof(devpath),"/dev/%s",tmpdevname); - //if (std::find(devFiles.begin(),devFiles.end(),std::string(tmpdevname)) == devFiles.end()) { + if (std::find(devFiles.begin(),devFiles.end(),std::string(tmpdevname)) == devFiles.end()) { long cpid = (long)vfork(); if (cpid == 0) { ::execl("/sbin/ifconfig","/sbin/ifconfig",tmpdevname,"create",(const char *)0); @@ -134,7 +116,9 @@ NetBSDEthernetTap::NetBSDEthernetTap( string tmp; sprintf((char*)tmp.c_str(), "%d", i); string minor = tmp.c_str(); - ::execl("/sbin/mknod","/sbin/mknod",devpath,"c","169",minor.c_str(),(const char *)0); //major 169 => tap + ::execl("/sbin/mknod","/sbin/mknod",devpath,"c","169",minor.c_str(),(const char *)0); + // http://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/sys/conf/majors + // major 169 => tap ::_exit(-1); } else if (cpid > 0) { int exitcode = -1; @@ -146,25 +130,14 @@ NetBSDEthernetTap::NetBSDEthernetTap( _dev = tmpdevname; _fd = ::open( devpath,O_RDWR); if (!stat(devpath,&stattmp)) { - /*cpid = (long)vfork(); - if (cpid == 0) { - ::execl("/sbin/ifconfig","/sbin/ifconfig",tmpdevname,"name",_dev.c_str(),(const char *)0); - ::_exit(-1); - } else if (cpid > 0) { - int exitcode = -1; - ::waitpid(cpid,&exitcode,0); - if (exitcode) - throw std::runtime_error("ifconfig rename operation failed"); - } else throw std::runtime_error("fork() failed");*/ - - if (_fd > 0) break; - //else throw std::runtime_error("unable to open created tap device "); + else + throw std::runtime_error("unable to open created tap device "); } else { throw std::runtime_error("cannot find /dev node for newly created tap device"); } - //} + } } if (_fd <= 0) diff --git a/osdep/freebsd_getifmaddrs.c b/osdep/freebsd_getifmaddrs.c index 559fdc065..8b1741466 100644 --- a/osdep/freebsd_getifmaddrs.c +++ b/osdep/freebsd_getifmaddrs.c @@ -1,3 +1,8 @@ +/* + this BSD licensed code is from https://github.com/freebsd/freebsd/blob/386ddae58459341ec567604707805814a2128a57/lib/libc/net/getifmaddrs.c + as in older OS X there is no getifmaddrs() and related functions is NetBSD +*/ + #define NET_RT_IFMALIST 4 /* return multicast address list */ #define RTM_NEWMADDR 0xf /* mcast group membership being added to if */ diff --git a/osdep/freebsd_getifmaddrs.h b/osdep/freebsd_getifmaddrs.h index a3eeec713..166b6d230 100644 --- a/osdep/freebsd_getifmaddrs.h +++ b/osdep/freebsd_getifmaddrs.h @@ -1,3 +1,8 @@ +/* + this BSD code is from https://github.com/freebsd/freebsd/blob/386ddae58459341ec567604707805814a2128a57/include/ifaddrs.h + as in older OS X there is no getifmaddrs() and related functions is NetBSD +*/ + /* $FreeBSD$ */ /* From 18c9dc8a0649c866eff9f299f20fa5b19c502e52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Skowro=C5=84ski?= Date: Tue, 27 Dec 2016 13:07:05 +0100 Subject: [PATCH 06/22] fix RTF_MULTICAST and g++ -w --- make-netbsd.mk | 2 +- node/Constants.hpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/make-netbsd.mk b/make-netbsd.mk index b53c969c3..f2490038b 100644 --- a/make-netbsd.mk +++ b/make-netbsd.mk @@ -34,7 +34,7 @@ else STRIP=strip --strip-all endif -CXXFLAGS+=$(CFLAGS) -fno-rtti -fpermissive -w +CXXFLAGS+=$(CFLAGS) -fno-rtti -fpermissive all: one diff --git a/node/Constants.hpp b/node/Constants.hpp index b137e6aed..b16cb9b56 100644 --- a/node/Constants.hpp +++ b/node/Constants.hpp @@ -124,6 +124,10 @@ #include #endif +#ifdef __NetBSD__ +#define RTF_MULTICAST 0x20000000 +#endif + /** * Length of a ZeroTier address in bytes */ From 50aef368f6661fce958b60c35ec984aa7e823588 Mon Sep 17 00:00:00 2001 From: Aleksandar Topuzovic Date: Tue, 2 Jan 2018 11:32:17 +0100 Subject: [PATCH 07/22] Add support for armv7l * GCC running on Raspberry Pi 3 on Arch linux ARM reports arch as armv7l-unknown-linux-gnueabihf --- make-linux.mk | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/make-linux.mk b/make-linux.mk index 87d29afe2..db85a89f1 100644 --- a/make-linux.mk +++ b/make-linux.mk @@ -130,6 +130,11 @@ ifeq ($(CC_MACH),armv7) override DEFS+=-DZT_NO_TYPE_PUNNING ZT_USE_ARM32_NEON_ASM_SALSA2012=1 endif +ifeq ($(CC_MACH),armv7l) + ZT_ARCHITECTURE=3 + override DEFS+=-DZT_NO_TYPE_PUNNING + ZT_USE_ARM32_NEON_ASM_SALSA2012=1 +endif ifeq ($(CC_MACH),arm64) ZT_ARCHITECTURE=4 override DEFS+=-DZT_NO_TYPE_PUNNING From e57d0fdccc78b01e93360245fd2a9c7b87214b34 Mon Sep 17 00:00:00 2001 From: Travis LaDuke Date: Fri, 2 Feb 2018 10:30:49 -0800 Subject: [PATCH 08/22] Update README.md this ip changes sometimes --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 47bfc8785..d4163b7f1 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ For testing purposes we provide a public virtual network called *Earth* with net sudo zerotier-cli join 8056c2e21c000001 -Now wait about 30 seconds and check your system with `ip addr list` or `ifconfig`. You'll see a new interface whose name starts with *zt* and it should quickly get an IPv4 and an IPv6 address. Once you see it get an IP, try pinging `earth.zerotier.net` at `29.209.112.93`. If you've joined Earth from more than one system, try pinging your other machine. If you don't want to belong to a giant Ethernet party line anymore, just type: +Now wait about 30 seconds and check your system with `ip addr list` or `ifconfig`. You'll see a new interface whose name starts with *zt* and it should quickly get an IPv4 and an IPv6 address. Once you see it get an IP, try pinging `earth.zerotier.net`. If you've joined Earth from more than one system, try pinging your other machine. If you don't want to belong to a giant Ethernet party line anymore, just type: sudo zerotier-cli leave 8056c2e21c000001 From 73ca9b6373a758bcba7d589064dd2cfb27208d3a Mon Sep 17 00:00:00 2001 From: neutronscott Date: Sat, 3 Feb 2018 14:53:46 -0500 Subject: [PATCH 09/22] check physical blacklist for interface binding as well --- service/OneService.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/service/OneService.cpp b/service/OneService.cpp index 27b71141e..250e4b382 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -2414,7 +2414,22 @@ public: return false; } } - + { + // Check global blacklists + const std::vector *gbl = (const std::vector *)0; + if (ifaddr.ss_family == AF_INET) { + gbl = &_globalV4Blacklist; + } else if (ifaddr.ss_family == AF_INET6) { + gbl = &_globalV6Blacklist; + } + if (gbl) { + Mutex::Lock _l(_localConfig_m); + for(std::vector::const_iterator a(gbl->begin());a!=gbl->end();++a) { + if (a->containsAddress(ifaddr)) + return false; + } + } + } { Mutex::Lock _l(_nets_m); for(std::map::const_iterator n(_nets.begin());n!=_nets.end();++n) { From a9778549f2a9b9a6c410516fae7d89f20ebe3e94 Mon Sep 17 00:00:00 2001 From: Pablo Hinojosa Date: Sun, 11 Mar 2018 03:39:13 +0100 Subject: [PATCH 10/22] Warn about invalid network id instead of help --- one.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/one.cpp b/one.cpp index b40e28fc8..495c3147b 100644 --- a/one.cpp +++ b/one.cpp @@ -443,7 +443,7 @@ static int cli(int argc,char **argv) } } else if (command == "join") { if (arg1.length() != 16) { - cliPrintHelp(argv[0],stderr); + printf("invalid network id" ZT_EOL_S); return 2; } requestHeaders["Content-Type"] = "application/json"; @@ -471,7 +471,7 @@ static int cli(int argc,char **argv) } } else if (command == "leave") { if (arg1.length() != 16) { - cliPrintHelp(argv[0],stderr); + printf("invalid network id" ZT_EOL_S); return 2; } unsigned int scode = Http::DEL( @@ -564,7 +564,7 @@ static int cli(int argc,char **argv) } } else if (command == "set") { if (arg1.length() != 16) { - cliPrintHelp(argv[0],stderr); + printf("invalid network id" ZT_EOL_S); return 2; } std::size_t eqidx = arg2.find('='); From e276b6463e3df3575386fdede8576c5c3179aac6 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 12 Apr 2018 10:33:06 -0400 Subject: [PATCH 11/22] Release notes, and shorten Linux canonical network ID derived device names a bit. --- RELEASE-NOTES.md | 38 ++++++++++++++++++++------------------ osdep/LinuxEthernetTap.cpp | 27 +++++++++++++++------------ 2 files changed, 35 insertions(+), 30 deletions(-) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index c71857929..9597fc54b 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,38 +1,40 @@ ZeroTier Release Notes ====== -# 2018-01-XX -- Version 1.2.6 +# 2018-04-12 -- Version 1.2.6 * Features and Core Improvements * Path selection has been overhauled to improve path stability, simplify code, and prepare for multi-path and trunking in the next major release. - * This version introduces remote tracing for remote diagnostics. Network controllers can set a node (usually the controller itself) to receive remote tracing events from all members of the network or from select members. Events are only sent if they pertain to a given network for security reasons. These can be used to help remotely diagnose problems. In the future we'll be refining and enhancing this feature. - * Multicast replication can now be done by designated multicast replicators on a network (flagged as such at the controller) rather than by the sender. This offers a hub-and-spoke multicast replication topology that may be faster or more bandwidth efficient in certain cases. It's also attractive for use on networks with low powered devices that need to send multicast or where there are very large numbers of multicast recipients. - * Documentation fixes in network controller. - * Performance improvements in crypto and memory operations. + * This version introduces remote tracing for remote diagnostics. Network controllers can set a node (usually the controller itself) to receive remote tracing events from all members of the network or from select members. Events are only sent if they pertain to a given network for security reasons. + * Multicast replication can now be done by designated multicast replicators on a network (flagged as such at the controller) rather than by the sender. Most users won't want this, but it's useful for specialized use cases on hub-and-spoke networks and for low-power devices. + * Cryptographic performance improvements. * Multithreaded performance improvements throughout the code base, including the use of an inline lightweight spinlock for low-contention resources. - * Bug fixes + * Bugs fixed * Disappearing routes on Mac (GitHub issue #600) * Route flapping and path instability in some dual-stack V4/V6 networks * Blacklist (in local.conf) doesn't work reliably (GitHub issue #656) - * Connection instabilities due to unsigned integer overflows in timing comparisons under high load on some multi-core systems - * Binaries don't run on some 32-bit ARM chips (build problem) + * Connection instabilities due to unsigned integer overflows in timing comparisons (use int64_t instead of uint64_t) + * Binaries don't run on some older or lower-end 32-bit ARM chips (build problem) * ARM NEON crypto code crashes (build problem) * Fixed some lock ordering issues revealed by "valgrind" tool * The "zerotier-idtool" command could not be accessed from "zerotier-one" via command line switch - * Leaking UDP sockets on some platforms when NAT-PMP is enabled - * Fixed a very very rare thread deadlock that seemed to only manifest on some systems + * Leaking sockets on some platforms when uPnP/NAT-PMP is enabled + * Fixed two very rare multithreading issues that were only observed on certain systems * Platform-Specific Changes * MacOS - * Installer now loads the kernel extension right away so that High Sierra users will see the prompt to authorize it. This is done in the "Security & Privacy" preference pane and must be done driectly on the console (not via remote desktop). - * About dialog in UI now actually contains something useful. + * Installer now loads the kernel extension right away so that High Sierra users will see the prompt to authorize it. This is done in the "Security & Privacy" preference pane and must be done driectly on the console (not via remote desktop). On High Sierra and newer kexts must be authorized at the console via security settings system preferences pane. * Windows - * The Windows installer should now install the driver without requiring a special prompt in most cases. This should make it easier for our packages to be accepted into and updated in the Chocolatey repository and should make it easier to perform remote installs. - * The Windows official packages are now signed with an EV certificate (with hardware key) from DigiCert for better security and fewer warnings in some cases. - * The Windows UI now contains a preview of features to more deeply integrate it with ZeroTier Central. You can enter a ZeroTier Central API key and join networks, etc. from the UI itself. We'll be expanding this in the future and possibly changing it, so this is just a test to see how users respond. - * The `zerotier-idtool` command should now work on Windows. - * Hopefully we've fixed all instances of the "Windows package will not uninstall" problem on Windows 10. + * The Windows installer should now install the driver without requiring a special prompt in most cases. This should make it easier for our packages to be accepted into and updated in the Chocolatey repository and should make it easier to perform remote installs across groups of machines using IT management and provisioning tools. + * The Windows official packages are now signed with an EV certificate (with hardware key). + * The Windows UI can now log into ZeroTier Central and join networks via the Central API. + * The `zerotier-idtool` command should now work on Windows without ugly hacks. + * Upgraded the installer version. + * Made a few changes to hopefully fix sporadic "will not uninstall" problems, though we cannot duplicate these issues ourselves. * Linux - * Devices are now named deterministically from a base32-encoded packed version of the network ID for newly joined networks. This makes device names longer but also makes them globally unique and canonical. Now a given network will always have the same device name on every Linux system. This makes a lot of devops, deployment, and scripting tasks easier since you can hard code device names by network and they will always work in things like iptables rules and routes. (It's been this way on FreeBSD since the beginning.) + * Device names are now generated deterministically based on network IDs for all newly joined networks. + * Android + * Multicast now works on Android in most cases! Android apps can send and receive multicast and subscribe to multicast group IPs. Note that in some cases the app must bind to the specific correct interface for this to work. + * IPv6 can be disabled in UI for cases where it causes problems. # 2017-04-20 -- Version 1.2.4 diff --git a/osdep/LinuxEthernetTap.cpp b/osdep/LinuxEthernetTap.cpp index 6ef427449..06bbbadac 100644 --- a/osdep/LinuxEthernetTap.cpp +++ b/osdep/LinuxEthernetTap.cpp @@ -146,18 +146,21 @@ LinuxEthernetTap::LinuxEthernetTap( OSUtils::ztsnprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name); } while (stat(procpath,&sbuf) == 0); // try zt#++ until we find one that does not exist #else - char devno = 0; + uint64_t trial = 0; // incremented in the very unlikely event of a name collision with another network do { - uint64_t tmp2[2]; - tmp2[0] = Utils::hton(nwid); - tmp2[1] = 0; - char tmp3[17]; + const uint64_t nwid40 = (nwid ^ (nwid >> 24)) + trial++; + uint8_t tmp2[5]; + char tmp3[11]; + tmp2[0] = (uint8_t)((nwid40 >> 32) & 0xff); + tmp2[1] = (uint8_t)((nwid40 >> 24) & 0xff); + tmp2[2] = (uint8_t)((nwid40 >> 16) & 0xff); + tmp2[3] = (uint8_t)((nwid40 >> 8) & 0xff); + tmp2[4] = (uint8_t)(nwid40 & 0xff); tmp3[0] = 'z'; - tmp3[1] = 't' + (devno++); - _base32_5_to_8(reinterpret_cast(tmp2),tmp3 + 2); - _base32_5_to_8(reinterpret_cast(tmp2) + 5,tmp3 + 10); - tmp3[15] = (char)0; - memcpy(ifr.ifr_name,tmp3,16); + tmp3[1] = 't'; + _base32_5_to_8(tmp2,tmp3 + 2); + tmp3[10] = (char)0; + memcpy(ifr.ifr_name,tmp3,11); OSUtils::ztsnprintf(procpath,sizeof(procpath),"/proc/sys/net/ipv4/conf/%s",ifr.ifr_name); } while (stat(procpath,&sbuf) == 0); #endif @@ -286,7 +289,7 @@ bool LinuxEthernetTap::addIpSyn(std::vector ips) if (cpid == 0) { OSUtils::redirectUnixOutputs("/dev/null",(const char *)0); setenv("PATH", "/sbin:/bin:/usr/sbin:/usr/bin", 1); - // We must know if there is at least (one) of each protocol version so we + // We must know if there is at least (one) of each protocol version so we // can properly enumerate address/netmask combinations in the ifcfg-dev file for(int i=0; i<(int)ips.size(); i++) { if (ips[i].isV4()) @@ -318,7 +321,7 @@ bool LinuxEthernetTap::addIpSyn(std::vector ips) if (ips[i].isV4()) ::execlp("ip","ip","addr","add",ips[i].toString(iptmp),"broadcast",ips[i].broadcast().toIpString(iptmp2),"dev",_dev.c_str(),(const char *)0); else - ::execlp("ip","ip","addr","add",ips[i].toString(iptmp),"dev",_dev.c_str(),(const char *)0); + ::execlp("ip","ip","addr","add",ips[i].toString(iptmp),"dev",_dev.c_str(),(const char *)0); } ::_exit(-1); } else if (cpid > 0) { From c14f9cc247f7c3bea53643dcde7536b67fabf63d Mon Sep 17 00:00:00 2001 From: "Elmar S. Heeb" Date: Sat, 14 Apr 2018 10:52:30 +0200 Subject: [PATCH 12/22] fix typo in documentation --- service/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service/README.md b/service/README.md index f5223f2d3..98492a637 100644 --- a/service/README.md +++ b/service/README.md @@ -59,7 +59,7 @@ An example `local.conf`: }, "settings": { "softwareUpdate": "apply", - "softwraeUpdateChannel": "release" + "softwareUpdateChannel": "release" } } ``` From f0a23ae0ea662bcc2d7f003a7a6b92f8adeba5e0 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 17 Apr 2018 10:48:00 -0700 Subject: [PATCH 13/22] docs --- README.md | 27 +++----- RELEASE-NOTES.md | 4 +- macui/ZeroTier One/about.html | 119 ++++++++++++++++------------------ zerotier-one.spec | 2 +- 4 files changed, 67 insertions(+), 85 deletions(-) diff --git a/README.md b/README.md index e0c5844ea..37f049829 100644 --- a/README.md +++ b/README.md @@ -1,29 +1,19 @@ ZeroTier - A Planetary Ethernet Switch ====== -ZeroTier is an enterprise Ethernet switch for planet Earth. +ZeroTier is a smart programmable Ethernet switch for planet Earth. -It erases the LAN/WAN distinction and makes VPNs, tunnels, proxies, and other kludges arising from the inflexible nature of physical networks obsolete. Everything is encrypted end-to-end and traffic takes the most direct (peer to peer) path available. +It replaces the physical LAN/WAN boundary with a virtual one, allowing devices of any type at any location to be managed as if they all reside in the same cloud region or data center. All traffic is encrypted end-to-end and takes the most direct path available for minimum latency and maximum performance. The goals and design of ZeroTier are inspired by among other things the original [Google BeyondCorp](https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/43231.pdf) paper and the [Jericho Forum](https://en.wikipedia.org/wiki/Jericho_Forum). Visit [ZeroTier's site](https://www.zerotier.com/?pk_campaign=github_ZeroTierOne) for more information and [pre-built binary packages](https://www.zerotier.com/download.shtml?pk_campaign=github_ZeroTierOne). Apps for Android and iOS are available for free in the Google Play and Apple app stores. ### Getting Started -ZeroTier's basic operation is easy to understand. Devices have 10-digit *ZeroTier addresses* like `89e92ceee5` and networks have 16-digit network IDs like `8056c2e21c000001`. All it takes for a device to join a network is its 16-digit ID, and all it takes for a network to authorize a device is its 10-digit address. Everything else is automatic. +Everything in the ZeroTier world is controlled by two types of identifier: 40-bit/10-digit *ZeroTier addresses* and 64-bit/16-digit *network IDs*. A ZeroTier address identifies a node or "device" (laptop, phone, server, VM, app, etc.) while a network ID identifies a virtual Ethernet network that can be joined by devices. -A "device" in our terminology is any "unit of compute" capable of talking to a network: desktops, laptops, phones, servers, VMs/VPSes, containers, and even user-space applications via our [SDK](https://github.com/zerotier/ZeroTierSDK). +Another way of thinking about it is that ZeroTier addresses are port numbers on a giant planetary-sized smart switch while network IDs are VLANs to which these ports can be assigned. For more details read about VL1 and VL2 in [the ZeroTier manual](https://www.zerotier.com/manual.shtml). -For testing purposes we provide a public virtual network called *Earth* with network ID `8056c2e21c000001`. You can join it with: - - sudo zerotier-cli join 8056c2e21c000001 - -Now wait about 30 seconds and check your system with `ip addr list` or `ifconfig`. You'll see a new interface whose name starts with *zt* and it should quickly get an IPv4 and an IPv6 address. Once you see it get an IP, try pinging `earth.zerotier.net` at `29.209.112.93`. If you've joined Earth from more than one system, try pinging your other machine. If you don't want to belong to a giant Ethernet party line anymore, just type: - - sudo zerotier-cli leave 8056c2e21c000001 - -The *zt* interface will disappear. You're no longer on the network. - -To create networks of your own, you'll need a network controller. ZeroTier One (for desktops and servers) includes controller functionality in its default build that can be configured via its JSON API (see [README.md in controller/](controller/)). ZeroTier provides a hosted solution with a nice web UI and SaaS add-ons at [my.zerotier.com](https://my.zerotier.com/?pk_campaign=github_ZeroTierOne). Basic controller functionality is free for up to 100 devices. +*Network controllers* are ZeroTier nodes that act as access control certificate authorities and configuration managers for virtual networks. The first 40 bits (or 10 digits) of a network ID is the ZeroTier address of its controller. You can create networks with our [hosted controllers](https://my.zerotier.com/) and web UI/API or [host your own](controller/) if you don't mind posting some JSON configuration info or writing a script to do so. ### Project Layout @@ -56,10 +46,9 @@ To build on Mac and Linux just type `make`. On FreeBSD and OpenBSD `gmake` (GNU - Linux makefiles automatically detect and prefer clang/clang++ if present as it produces smaller and slightly faster binaries in most cases. You can override by supplying CC and CXX variables on the make command line. - CentOS 7 ships with a version of GCC/G++ that is too old, but a new enough version of CLANG can be found in the *epel* repositories. Type `yum install epel-release` and then `yum install clang` to build there. - **Windows** - - Windows 7 or newer (and equivalent server versions) are supported. This *may* work on Vista but you're on your own there. Windows XP is not supported since it lacks many important network API functions. - - We build with Visual Studio 2015. Older versions may not work with the solution file and project files we ship and may not have new enough C++11 support. - - Pre-built signed Windows drivers are included in `ext/bin/tap-windows-ndis6`. The MSI files found there will install them on 32-bit and 64-bit systems. (These are included in our multi-architecture installer as chained MSIs.) - - Windows builds are more painful in general than other platforms and are for the adventurous. + - Windows 7 or newer is supported. This *may* work on Vista but isn't officially supported there. It will not work on Windows XP. + - We build with Visual Studio 2015. Older versions may not work. Clang or MinGW will also probably work but may require some makefile hacking. + - Pre-built signed Windows drivers are included in `ext/bin/tap-windows-ndis6`. The MSI files found there will install them on 32-bit and 64-bit systems. We don't recommend trying to build Windows drivers from scratch unless you know what you're doing. One does not simply "build" a Windows driver. - **FreeBSD** - Tested most recently on FreeBSD-11. Older versions may work but we're not sure. - GCC/G++ 4.9 and gmake are required. These can be installed from packages or ports. Type `gmake` to build. diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 9597fc54b..6d0fc5be4 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,13 +1,13 @@ ZeroTier Release Notes ====== -# 2018-04-12 -- Version 1.2.6 +# 2018-04-16 -- Version 1.2.6 * Features and Core Improvements * Path selection has been overhauled to improve path stability, simplify code, and prepare for multi-path and trunking in the next major release. * This version introduces remote tracing for remote diagnostics. Network controllers can set a node (usually the controller itself) to receive remote tracing events from all members of the network or from select members. Events are only sent if they pertain to a given network for security reasons. * Multicast replication can now be done by designated multicast replicators on a network (flagged as such at the controller) rather than by the sender. Most users won't want this, but it's useful for specialized use cases on hub-and-spoke networks and for low-power devices. - * Cryptographic performance improvements. + * Cryptographic performance improvements on several platforms. * Multithreaded performance improvements throughout the code base, including the use of an inline lightweight spinlock for low-contention resources. * Bugs fixed * Disappearing routes on Mac (GitHub issue #600) diff --git a/macui/ZeroTier One/about.html b/macui/ZeroTier One/about.html index 4fa41d7b3..09f6eb36a 100644 --- a/macui/ZeroTier One/about.html +++ b/macui/ZeroTier One/about.html @@ -1,65 +1,58 @@ - - - - - -
-
-
-
-
- -
-

Getting Started

- -

Getting started is simple. Simply click Join Network from the ZeroTier status bar menu. To join the public network "Earth", enter 8056c2e21c000001 and click the Join button. Once connected, you'll be able to navigate to earth.zerotier.net.

- -

Create a Network

-

Visit my.zerotier.com to create and manage your own virtual networks.

- -

For more information, visit zerotier.com.

- -
- + + + + +
+
+

Welcome to ZeroTier

+

Getting Started

+

Networks are identified by 16-digit network IDs. If someone invited you to join theirs you probably received one. If not you can create your own at my.zerotier.com or by running running your own network controller. +

Your computer is identified by a 10-digit ZeroTier address. You can find it at the top of the ZeroTier app's pull-down menu or by typing "sudo zerotier-cli info" in a terminal window. This number is unique to your system and is how network administrators can recognize you. If someone invited you to a network, give them this ID so they can authorize you to join.

+

Starting, Stopping, and Uninstalling

+

The ZeroTier service is separate from the UI app and starts on system boot. The app can be started on login or only when needed. To stop the ZeroTier service use:

+      sudo launchctl unload /Library/LaunchDaemons/com.zerotier.one.plist

+ Replace "unload" with "load" to start it again.

+

ZeroTier can be uninstalled with:

+      sudo '/Library/Application Support/ZeroTier/One/uninstall.sh' +

+

For more information, visit zerotier.com.

+
+ \ No newline at end of file diff --git a/zerotier-one.spec b/zerotier-one.spec index 306a5bfd4..1bf71d7c8 100644 --- a/zerotier-one.spec +++ b/zerotier-one.spec @@ -1,5 +1,5 @@ Name: zerotier-one -Version: 1.2.4 +Version: 1.2.5 Release: 1%{?dist} Summary: ZeroTier One network virtualization service From 3f1d1fb3c386d1f745c5db67bfbd518b54c0f1db Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 17 Apr 2018 12:12:49 -0700 Subject: [PATCH 14/22] 'versioning' --- version.h | 2 +- windows/WinUI/AboutView.xaml | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/version.h b/version.h index d80bec806..064f2585c 100644 --- a/version.h +++ b/version.h @@ -40,7 +40,7 @@ /** * Revision */ -#define ZEROTIER_ONE_VERSION_REVISION 5 +#define ZEROTIER_ONE_VERSION_REVISION 6 /** * Build version diff --git a/windows/WinUI/AboutView.xaml b/windows/WinUI/AboutView.xaml index f207af4cd..39213b73c 100644 --- a/windows/WinUI/AboutView.xaml +++ b/windows/WinUI/AboutView.xaml @@ -14,22 +14,22 @@ - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + From ae4fb799e4a04b02809e3b69fba4aeb96326dc11 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 17 Apr 2018 12:14:59 -0700 Subject: [PATCH 15/22] More versioning --- RELEASE-NOTES.md | 2 +- debian/changelog | 6 ++++++ .../windows/chocolatey/zerotier-one/zerotier-one.nuspec | 8 ++++---- zerotier-one.spec | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 6d0fc5be4..a73671d73 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,7 +1,7 @@ ZeroTier Release Notes ====== -# 2018-04-16 -- Version 1.2.6 +# 2018-04-17 -- Version 1.2.6 * Features and Core Improvements * Path selection has been overhauled to improve path stability, simplify code, and prepare for multi-path and trunking in the next major release. diff --git a/debian/changelog b/debian/changelog index 338431500..b13e179a0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +zerotier-one (1.2.6) unstable; urgency=medium + + * See https://github.com/zerotier/ZeroTierOne for release notes. + + -- Adam Ierymenko Tue, 17 Apr 2018 01:00:00 -0700 + zerotier-one (1.2.4) unstable; urgency=medium * See https://github.com/zerotier/ZeroTierOne for release notes. diff --git a/ext/installfiles/windows/chocolatey/zerotier-one/zerotier-one.nuspec b/ext/installfiles/windows/chocolatey/zerotier-one/zerotier-one.nuspec index 32fa5a9c6..3d090a7b3 100644 --- a/ext/installfiles/windows/chocolatey/zerotier-one/zerotier-one.nuspec +++ b/ext/installfiles/windows/chocolatey/zerotier-one/zerotier-one.nuspec @@ -8,8 +8,8 @@ This is a nuspec. It mostly adheres to https://docs.nuget.org/create/Nuspec-Reference. Chocolatey uses a special version of NuGet.Core that allows us to do more than was initially possible. As such there are certain things to be aware of: * the package xmlns schema url may cause issues with nuget.exe -* Any of the following elements can ONLY be used by choco tools - projectSourceUrl, docsUrl, mailingListUrl, bugTrackerUrl, packageSourceUrl, provides, conflicts, replaces -* nuget.exe can still install packages with those elements but they are ignored. Any authoring tools or commands will error on those elements +* Any of the following elements can ONLY be used by choco tools - projectSourceUrl, docsUrl, mailingListUrl, bugTrackerUrl, packageSourceUrl, provides, conflicts, replaces +* nuget.exe can still install packages with those elements but they are ignored. Any authoring tools or commands will error on those elements --> @@ -26,7 +26,7 @@ This is a nuspec. It mostly adheres to https://docs.nuget.org/create/Nuspec-Refe - 1.2.4 + 1.2.6 @@ -51,7 +51,7 @@ This is a nuspec. It mostly adheres to https://docs.nuget.org/create/Nuspec-Refe ZeroTier One Virtual Network Endpoint for Windows ZeroTier is a smart switch for Earth with VLAN capability. See https://www.zerotier.com/ for more information. - +