diff --git a/.gitignore b/.gitignore
index 8bf3c55..bd884dc 100755
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+<<<<<<< HEAD
# Main binaries created in *nix builds
/zerotier-one
/zerotier-idtool
@@ -9,6 +10,7 @@
.DS_Store
.Apple*
Thumbs.db
+@eaDir
# Windows build droppings
/windows/ZeroTierOne.sdf
@@ -29,6 +31,15 @@ Thumbs.db
/ext/installfiles/windows/Prerequisites
/ext/installfiles/windows/*-cache
/ZeroTier One.msi
+/windows/.vs
+*.vcxproj.backup
+/windows/TapDriver6/Win7Debug
+/windows/TapDriver6/win7Release
+/windows/*.db
+/windows/*.opendb
+enc_temp_folder
+/windows/copyutil/bin
+/windows/copyutil/obj
# *nix/Mac build droppings
/build-*
@@ -49,7 +60,7 @@ zt1-src.tar.gz
*.pid
*.pkg
*.o
-*.a
+/*.a
*.dylib
*.so
*.so.*
@@ -59,16 +70,15 @@ zt1-src.tar.gz
*.rpm
*.autosave
*.tmp
-doc/*.1
-doc/*.2
-doc/*.8
.depend
node_modules
+zt1_update_*
debian/files
debian/zerotier-one
debian/zerotier-one*.debhelper
debian/*.log
debian/zerotier-one.substvars
+root-watcher/config.json
# Java/Android/JNI build droppings
java/obj/
@@ -83,3 +93,21 @@ windows/WinUI/obj/
windows/WinUI/bin/
windows/ZeroTierOne/Debug/
/ext/installfiles/windows/chocolatey/zerotier-one/*.nupkg
+
+# Miscellaneous mac/Xcode droppings
+.DS_Store
+.Trashes
+*.swp
+*~.nib
+DerivedData/
+build/
+*.pbxuser
+*.mode1v3
+*.mode2v3
+*.perspectivev3
+!default.pbxuser
+!default.mode1v3
+!default.mode2v3
+!default.perspectivev3
+*.xccheckout
+xcuserdata/
diff --git a/AUTHORS.md b/AUTHORS.md
index aa9e911..043ff00 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -25,13 +25,13 @@
## Third-Party Code
-These are included in ext/ for platforms that do not have them available in common repositories. Otherwise they may be linked and the package may ship with them as dependencies.
+ZeroTier includes the following third party code, either in ext/ or incorporated into the ZeroTier core.
* LZ4 compression algorithm by Yann Collet
- * Files: ext/lz4/*
+ * Files: node/Packet.cpp (bundled within anonymous namespace)
* Home page: http://code.google.com/p/lz4/
- * License grant: BSD attribution
+ * License grant: BSD 2-clause
* http-parser by Joyent, Inc. (many authors)
@@ -39,11 +39,11 @@ These are included in ext/ for platforms that do not have them available in comm
* Home page: https://github.com/joyent/http-parser/
* License grant: MIT/Expat
- * json-parser by James McLaughlin
+ * C++11 json (nlohmann/json) by Niels Lohmann
- * Files: ext/json-parser/*
- * Home page: https://github.com/udp/json-parser/
- * License grant: BSD attribution
+ * Files: ext/json/*
+ * Home page: https://github.com/nlohmann/json
+ * License grant: MIT
* TunTapOSX by Mattias Nissler
@@ -55,26 +55,19 @@ These are included in ext/ for platforms that do not have them available in comm
* tap-windows6 by the OpenVPN project
* Files: windows/TapDriver6/*
- * Home page:
- https://github.com/OpenVPN/tap-windows6/
+ * Home page: https://github.com/OpenVPN/tap-windows6/
* License grant: GNU GPL v2
* ZeroTier Modifications: change name of driver to ZeroTier, add ioctl() to get L2 multicast memberships (source is in ext/ and modifications inherit GPL)
- * Salsa20 stream cipher, Curve25519 elliptic curve cipher, Ed25519
- digital signature algorithm, and Poly1305 MAC algorithm, all by
- Daniel J. Bernstein
+ * Salsa20 stream cipher, Curve25519 elliptic curve cipher, Ed25519 digital signature algorithm, and Poly1305 MAC algorithm, all by Daniel J. Bernstein
- * Files:
- node/Salsa20.hpp
- node/C25519.hpp
- node/Poly1305.hpp
+ * Files: node/Salsa20.* node/C25519.* node/Poly1305.*
* Home page: http://cr.yp.to/
* License grant: public domain
+ * ZeroTier Modifications: slight cryptographically-irrelevant modifications for inclusion into ZeroTier core
* MiniUPNPC and libnatpmp by Thomas Bernard
- * Files:
- ext/libnatpmp/*
- ext/miniupnpc/*
+ * Files: ext/libnatpmp/* ext/miniupnpc/*
* Home page: http://miniupnp.free.fr/
* License grant: BSD attribution no-endorsement
diff --git a/Jenkinsfile b/Jenkinsfile
new file mode 100644
index 0000000..74c8624
--- /dev/null
+++ b/Jenkinsfile
@@ -0,0 +1,82 @@
+#!/usr/bin/env groovy
+
+node('master') {
+ def changelog = getChangeLog currentBuild
+
+ slackSend "Building ${env.JOB_NAME} #${env.BUILD_NUMBER} \n Change Log: \n ${changelog}"
+}
+
+parallel 'centos7': {
+ node('centos7') {
+ try {
+ checkout scm
+
+ stage('Build Centos 7') {
+ sh 'make -f make-linux.mk'
+ }
+ }
+ catch (err) {
+ currentBuild.result = "FAILURE"
+ slackSend color: '#ff0000', message: "${env.JOB_NAME} broken on Centos 7 (<${env.BUILD_URL}|Open>)"
+
+ throw err
+ }
+ }
+}, 'android-ndk': {
+ node('android-ndk') {
+ try {
+ checkout scm
+
+ stage('Build Android NDK') {
+ sh "/android/android-ndk-r13b/ndk-build -C $WORKSPACE/java ZT1=${WORKSPACE}"
+ }
+ }
+ catch (err) {
+ currentBuild.result = "FAILURE"
+ slackSend color: '#ff0000', message: "${env.JOB_NAME} broken on Android NDK (<${env.BUILD_URL}|Open>)"
+
+ throw err
+ }
+ }
+}, 'macOS': {
+ node('macOS') {
+ try {
+ checkout scm
+
+ stage('Build macOS') {
+ sh 'make -f make-mac.mk'
+ }
+
+ stage('Build macOS UI') {
+ sh 'cd macui && xcodebuild -target "ZeroTier One" -configuration Debug'
+ }
+ }
+ catch (err) {
+ currentBuild.result = "FAILURE"
+ slackSend color: '#ff0000', message: "${env.JOB_NAME} broken on macOS (<${env.BUILD_URL}|Open>)"
+
+ throw err
+ }
+ }
+}, 'windows': {
+ node('windows') {
+ try {
+ checkout scm
+
+ stage('Build Windows') {
+ bat '''CALL "C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\vcvarsall.bat" amd64
+git clean -dfx
+msbuild windows\\ZeroTierOne.sln
+'''
+ }
+ }
+ catch (err) {
+ currentBuild.result = "FAILURE"
+ slackSend color: '#ff0000', message: "${env.JOB_NAME} broken on Windows (<${env.BUILD_URL}|Open>)"
+
+ throw err
+ }
+ }
+}
+
+slackSend color: "#00ff00", message: "${env.JOB_NAME} #${env.BUILD_NUMBER} Complete (<${env.BUILD_URL}|Show More...>)"
diff --git a/Makefile b/Makefile
index 5a5f660..9511862 100644
--- a/Makefile
+++ b/Makefile
@@ -11,8 +11,14 @@ ifeq ($(OSTYPE),Linux)
endif
ifeq ($(OSTYPE),FreeBSD)
- include make-freebsd.mk
+ CC=clang
+ CXX=clang++
+ ZT_BUILD_PLATFORM=7
+ include make-bsd.mk
endif
ifeq ($(OSTYPE),OpenBSD)
- include make-freebsd.mk
+ CC=egcc
+ CXX=eg++
+ ZT_BUILD_PLATFORM=9
+ include make-bsd.mk
endif
diff --git a/OFFICIAL-RELEASE-STEPS.md b/OFFICIAL-RELEASE-STEPS.md
index 37e6791..d0f42e3 100644
--- a/OFFICIAL-RELEASE-STEPS.md
+++ b/OFFICIAL-RELEASE-STEPS.md
@@ -15,6 +15,7 @@ The version must be incremented in all of the following files:
/ext/installfiles/mac/ZeroTier One.pkgproj
/ext/installfiles/windows/chocolatey/zerotier-one.nuspec
/ext/installfiles/windows/ZeroTier One.aip
+ /windows/WinUI/AboutView.xaml
The final .AIP file can only be edited on Windows with [Advanced Installer Enterprise](http://www.advancedinstaller.com/). In addition to incrementing the version be sure that a new product code is generated. (The "upgrade code" GUID on the other hand must never change.)
diff --git a/README.md b/README.md
index a34a1a5..47bfc87 100644
--- a/README.md
+++ b/README.md
@@ -1,52 +1,76 @@
ZeroTier - A Planetary Ethernet Switch
======
-ZeroTier is a software-based managed Ethernet switch for planet Earth.
+ZeroTier is an enterprise 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.
-This repository contains ZeroTier One, a service that provides ZeroTier network connectivity to devices running Windows, Mac, Linux, iOS, Android, and FreeBSD and makes joining virtual networks as easy as joining IRC or Slack channels. It also contains the OS-independent core ZeroTier protocol implementation in [node/](node/).
-
Visit [ZeroTier's site](https://www.zerotier.com/) for more information and [pre-built binary packages](https://www.zerotier.com/download.shtml). 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.
-A "device" can be anything really: desktops, laptops, phones, servers, VMs/VPSes, containers, and even (soon) apps.
+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).
-For testing we provide a public virtual network called *Earth* with network ID `8056c2e21c000001`. On Linux and Mac you can do this with:
+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.
-
-*(IPv4 addresses for Earth are assigned from the block 28.0.0.0/7, which is not a part of the public Internet but is non-standard for private networks. It's used to avoid IP conflicts during testing. Your networks can run any IP addressing scheme you want.)*
-
-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` 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. You can use [our hosted controller at my.zerotier.com](https://my.zerotier.com) which is free for up to 100 devices on an unlimited number of networks, or you can build your own controller and run it through its local JSON API. See [README.md in controller/](controller/) for more information.
+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/). Basic controller functionality is free for up to 100 devices.
-### Building from Source
+### Project Layout
-For Mac, Linux, and BSD, just type "make" (or "gmake" on BSD). You won't need much installed; here are the requirements for various platforms:
+ - `artwork/`: icons, logos, etc.
+ - `attic/`: old stuff and experimental code that we want to keep around for reference.
+ - `controller/`: the reference network controller implementation, which is built and included by default on desktop and server build targets.
+ - `debian/`: files for building Debian packages on Linux.
+ - `doc/`: manual pages and other documentation.
+ - `ext/`: third party libraries, binaries that we ship for convenience on some platforms (Mac and Windows), and installation support files.
+ - `include/`: include files for the ZeroTier core.
+ - `java/`: a JNI wrapper used with our Android mobile app. (The whole Android app is not open source but may be made so in the future.)
+ - `macui/`: a Macintosh menu-bar app for controlling ZeroTier One, written in Objective C.
+ - `node/`: the ZeroTier virtual Ethernet switch core, which is designed to be entirely separate from the rest of the code and able to be built as a stand-alone OS-independent library. Note to developers: do not use C++11 features in here, since we want this to build on old embedded platforms that lack C++11 support. C++11 can be used elsewhere.
+ - `osdep/`: code to support and integrate with OSes, including platform-specific stuff only built for certain targets.
+ - `service/`: the ZeroTier One service, which wraps the ZeroTier core and provides VPN-like connectivity to virtual networks for desktops, laptops, servers, VMs, and containers.
+ - `tcp-proxy/`: TCP proxy code run by ZeroTier, Inc. to provide TCP fallback (this will die soon!).
+ - `windows/`: Visual Studio solution files, Windows service code for ZeroTier One, and the Windows task bar app UI.
- * **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).
+The base path contains the ZeroTier One service main entry point (`one.cpp`), self test code, makefiles, etc.
-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.
+### Build and Platform Notes
+
+To build on Mac and Linux just type `make`. On FreeBSD and OpenBSD `gmake` (GNU make) is required and can be installed from packages or ports. For Windows there is a Visual Studio solution in `windows/'.
+
+ - **Mac**
+ - Xcode command line tools for OSX 10.7 or newer are required.
+ - Tap device driver kext source is in `ext/tap-mac` and a signed pre-built binary can be found in `ext/bin/tap-mac`. You should not need to build it yourself. It's a fork of [tuntaposx](http://tuntaposx.sourceforge.net) with device names changed to `zt#`, support for a larger MTU, and tun functionality removed.
+ - **Linux**
+ - The minimum compiler versions required are GCC/G++ 4.9.3 or CLANG/CLANG++ 3.4.2.
+ - 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.
+ - **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.
+ - **OpenBSD**
+ - There is a limit of four network memberships on OpenBSD as there are only four tap devices (`/dev/tap0` through `/dev/tap3`). We're not sure if this can be increased.
+ - OpenBSD lacks `getifmaddrs` (or any equivalent method) to get interface multicast memberships. As a result multicast will only work on OpenBSD for ARP and NDP (IP/MAC lookup) and not for other purposes.
+ - Only tested on OpenBSD 6.0. Older versions may not work.
+ - GCC/G++ 4.9 and gmake are required and can be installed using `pkg_add` or from ports. They get installed in `/usr/local/bin` as `egcc` and `eg++` and our makefile is pre-configured to use them on OpenBSD.
Typing `make selftest` will build a *zerotier-selftest* binary which unit tests various internals and reports on a few aspects of the build environment. It's a good idea to try this on novel platforms or architectures.
-Windows, of course, is special. We build for Windows with Microsoft Visual Studio 2012 on Windows 7. A solution file is located in the *windows/* subfolder. Newer versions of Visual Studio (and Windows) may work but haven't been tested. Older versions almost certainly will not, since they lack things like *stdint.h* and certain STL features. MinGW or other ports of gcc/clang to Windows should also work but haven't been tested.
-
-32 and 64 bit X86 and ARM (e.g. Raspberry Pi, Android) are officially supported. Community members have built for MIPS and Sparc without issues.
-
### Running
Running *zerotier-one* with -h will show help.
@@ -62,7 +86,7 @@ The service is controlled via the JSON API, which by default is available at 127
Here's where home folders live (by default) on each OS:
* **Linux**: `/var/lib/zerotier-one`
- * **FreeBSD**: `/var/db/zerotier-one`
+ * **FreeBSD** / **OpenBSD**: `/var/db/zerotier-one`
* **Mac**: `/Library/Application Support/ZeroTier/One`
* **Windows**: `\ProgramData\ZeroTier\One` (That's for Windows 7. The base 'shared app data' folder might be different on different Windows versions.)
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
new file mode 100644
index 0000000..195e888
--- /dev/null
+++ b/RELEASE-NOTES.md
@@ -0,0 +1,138 @@
+ZeroTier Release Notes
+======
+
+# 2017-04-20 -- Version 1.2.4
+
+ * Managed routes are now only bifurcated for the default route. This is a change in behavior, though few people will probably notice. Bifurcating all managed routes was causing more trouble than it was worth for most users.
+ * Up to 2X crypto speedup on x86-64 (except Windows, which will take some porting) and 32-bit ARM platforms due to integration of fast assembly language implementations of Salsa20/12 from the [supercop](http://bench.cr.yp.to/supercop.html) code base. These were written by Daniel J. Bernstein and are in the public domain. My Macbook Pro (Core i5 2.8ghz) now does almost 1.5GiB/sec Salsa20/12 per core and a Raspberry Pi got a 2X boost. 64-bit ARM support and Windows support will take some work but should not be too hard.
+ * Refactored code that manages credentials to greatly reduce memory use in most cases. This may also result in a small performance improvement.
+ * Reworked and simplified path selection and priority logic to fix path instability and dead path persistence edge cases. There have been some sporadic reports of persistent path instabilities and dead paths hanging around that take minutes to resolve. These have proven difficult to reproduce in house, but hopefully this will fix them. In any case it seems to speed up path establishment in our tests and it makes the code simpler and more readable.
+ * Eliminated some unused cruft from the code around path management and in the peer class.
+ * Fixed an issue causing build problems on some MIPS architecture systems.
+ * Fixed Windows forgetting routes on sleep/wake or in some other circumstances. (GitHub issue #465)
+
+# 2017-03-17 -- Version 1.2.2
+
+ * A bug causing unreliable multicast propagation (GitHub issue #461).
+ * A crash in ARM binaries due to a build chain and flags problem.
+ * A bug in the network controller preventing members from being listed (GitHub issue #460).
+
+# 2017-03-14 -- Version 1.2.0
+
+Version 1.2.0 is a major milestone release representing almost nine months of work. It includes our rules engine for distributed network packet filtering and security monitoring, federated roots, and many other architectural and UI improvements and bug fixes.
+
+## New Features in 1.2.0
+
+### The ZeroTier Rules Engine
+
+The largest new feature in 1.2.0, and the product of many months of work, is our advanced network rules engine. With this release we achieve traffic control, security monitoring, and micro-segmentation capability on par with many enterprise SDN solutions designed for use in advanced data centers and corporate networks.
+
+Rules allow you to filter packets on your network and vector traffic to security observers. Security observation can be performed in-band using REDIRECT or out of band using TEE.
+
+Tags and capabilites provide advanced methods for implementing fine grained permission structures and micro-segmentation schemes without bloating the size and complexity of your rules table.
+
+See the [rules engine announcement blog post](https://www.zerotier.com/blog/?p=927) for an in-depth discussion of theory and implementation. The [manual](https://www.zerotier.com/manual.shtml) contains detailed information on rule, tag, and capability use, and the `rule-compiler/` subfolder of the ZeroTier source tree contains a JavaScript function to compile rules in our human-readable rule definition language into rules suitable for import into a network controller. (ZeroTier Central uses this same script to compile rules on [my.zerotier.com](https://my.zerotier.com/).)
+
+### Root Server Federation
+
+It's now possible to create your own root servers and add them to the root server pool on your nodes. This is done by creating what's called a "moon," which is a signed enumeration of root servers and their stable points on the network. Refer to the [manual](https://www.zerotier.com/manual.shtml) for instructions.
+
+Federated roots achieve a number of things:
+
+ * You can deploy your own infrastructure to reduce dependency on ours.
+ * You can deploy roots *inside your LAN* to ensure that network connectivity inside your facility still works if the Internet goes down. This is the first step toward making ZeroTier viable as an in-house SDN solution.
+ * Roots can be deployed inside national boundaries for countries with data residency laws or "great firewalls." (As of 1.2.0 there is still no way to force all traffic to use these roots, but that will be easy to do in a later version.)
+ * Last but not least this makes ZeroTier somewhat less centralized by eliminating any hard dependency on ZeroTier, Inc.'s infrastructure.
+
+Our roots will of course remain and continue to provide zero-configuration instant-on deployment, a secure global authority for identities, and free traffic relaying for those who can't establish peer to peer connections.
+
+### Local Configuration
+
+An element of our design philosophy is "features are bugs." This isn't an absolute dogma but more of a guiding principle. We try as hard as we can to avoid adding features, especially "knobs" that must be tweaked by a user.
+
+As of 1.2.0 we've decided that certain knobs are unavoidable, and so there is now a `local.conf` file that can be used to configure them. See the ZeroTier One documentation for these. They include:
+
+ * Blacklisting interfaces you want to make sure ZeroTier doesn't use for network traffic, such as VPNs, slow links, or backplanes designated for only certain kinds of traffic.
+ * Turning uPnP/NAT-PMP on or off.
+ * Configuring software updates on Windows and Mac platforms.
+ * Defining trusted paths (the old trusted paths file is now deprecated)
+ * Setting the ZeroTier main port so it doesn't have to be changed on the command line, which is very inconvenient in many cases.
+
+### Improved In-Band Software Updates
+
+A good software update system for Windows and Mac clients has been a missing feature in previous versions. It does exist but we've been shy about using it so far due to its fragility in some environments.
+
+We've greatly improved this mechanism in 1.2.0. Not only does it now do a better job of actually invoking the update, but it also transfers updates in-band using the ZeroTier protocol. This means it can work in environments that do not allows http/https traffic or that force it through proxies. There's also now an update channel setting: `beta` or `release` (the default).
+
+Software updates are authenticated three ways:
+
+ 1. ZeroTier's own signing key is used to sign all updates and this signature is checked prior to installation. ZeroTier, Inc.'s signatures are performed on an air-gapped machine.
+
+ 2. Updates for Mac and Windows are signed using Apple and Microsoft (DigiCert EV) keys and will not install unless these signatures are also valid.
+
+ 3. The new in-band update mechanism also authenticates the source of the update via ZeroTier's built-in security features. This provides transport security, while 1 and 2 provide security of the update at rest.
+
+Updates are now configurable via `local.conf`. There are three options: `disable`, `download`, and `apply`. The third (apply) is the default for official builds on Windows and Mac, making updates happen silently and automatically as they do for popular browsers like Chrome and Firefox. Updates are disabled by default on Linux and other Unix-type systems as these are typically updated through package managers.
+
+### Path Link Quality Awareness
+
+Version 1.2.0 is now aware of the link quality of direct paths with other 1.2.0 nodes. This information isn't used yet but is visible through the JSON API. (Quality always shows as 100% with pre-1.2.0 nodes.) Quality is measured passively with no additional overhead using a counter based packet loss detection algorithm.
+
+This information is visible from the command line via `listpeers`:
+
+ 200 listpeers XXXXXXXXXX 199.XXX.XXX.XXX/9993;10574;15250;1.00 48 1.2.0 LEAF
+ 200 listpeers XXXXXXXXXX 195.XXX.XXX.XXX/45584;467;7608;0.44 290 1.2.0 LEAF
+
+The first peer's path is at 100% (1.00), while the second peer's path is suffering quite a bit of packet loss (0.44).
+
+Link quality awareness is a precursor to intelligent multi-path and QoS support, which will in future versions bring us to feature parity with SD-WAN products like Cisco iWAN.
+
+### Security Improvements
+
+Version 1.2.0 adds anti-DOS (denial of service) rate limits and other hardening for improved resiliency against a number of denial of service attack scenarios.
+
+It also adds a mechanism for instantaneous credential revocation. This can be used to revoke certificates of membership instantly to kick a node off a network (for private networks) and also to revoke capabilities and tags. The new controller sends revocations by default when a peer is de-authorized.
+
+Revocations propagate using a "rumor mill" peer to peer algorithm. This means that a controller need only successfully send a revocation to at least one member of a network with connections to other active members. At this point the revocation will flood through the network peer to peer very quickly. This helps make revocations more robust in the face of poor connectivity with the controller or attempts to incapacitate the controller with denial of service attacks, as well as making revocations faster on huge networks.
+
+### Windows and Macintosh UI Improvements (ZeroTier One)
+
+The Mac has a whole new UI built natively in Objective-C. It provides a pulldown similar in appearance and operation to the Mac WiFi task bar menu.
+
+The Windows UI has also been improved and now provides a task bar icon that can be right-clicked to manage networks. Both now expose managed route and IP permissions, allowing nodes to easily opt in to full tunnel operation if you have a router configured on your network.
+
+### Ad-Hoc Networks
+
+A special kind of public network called an ad-hoc network may be accessed by joining a network ID with the format:
+
+ ffSSSSEEEE000000
+ | | | |
+ | | | Reserved for future use, must be 0
+ | | End of port range (hex)
+ | Start of port range (hex)
+ Reserved ZeroTier address prefix indicating a controller-less network
+
+Ad-hoc networks are public (no access control) networks that have no network controller. Instead their configuration and other credentials are generated locally. Ad-hoc networks permit only IPv6 UDP and TCP unicast traffic (no multicast or broadcast) using 6plane format NDP-emulated IPv6 addresses. In addition an ad-hoc network ID encodes an IP port range. UDP packets and TCP SYN (connection open) packets are only allowed to desintation ports within the encoded range.
+
+For example `ff00160016000000` is an ad-hoc network allowing only SSH, while `ff0000ffff000000` is an ad-hoc network allowing any UDP or TCP port.
+
+Keep in mind that these networks are public and anyone in the entire world can join them. Care must be taken to avoid exposing vulnerable services or sharing unwanted files or other resources.
+
+### Network Controller (Partial) Rewrite
+
+The network controller has been largely rewritten to use a simple in-filesystem JSON data store in place of SQLite, and it is now included by default in all Windows, Mac, Linux, and BSD builds. This means any desktop or server node running ZeroTier One can now be a controller with no recompilation needed.
+
+If you have data in an old SQLite3 controller we've included a NodeJS script in `controller/migrate-sqlite` to migrate data to the new format. If you don't migrate, members will start getting `NOT_FOUND` when they attempt to query for updates.
+
+## Major Bug Fixes in 1.2.0
+
+ * **The Windows HyperV 100% CPU bug is FINALLY DEAD**: This long-running problem turns out to have been an issue with Windows itself, but one we were triggering by placing invalid data into the Windows registry. Microsoft is aware of the issue but we've also fixed the triggering problem on our side. ZeroTier should now co-exist quite well with HyperV and should now be able to be bridged with a HyperV virtual switch.
+ * **Segmenation faults on musl-libc based Linux systems**: Alpine Linux and some embedded Linux systems that use musl libc (a minimal libc) experienced segmentation faults. These were due to a smaller default stack size. A work-around that sets the stack size for new threads has been added.
+ * **Windows firewall blocks local JSON API**: On some Windows systems the firewall likes to block 127.0.0.1:9993 for mysterious reasons. This is now fixed in the installer via the addition of another firewall exemption rule.
+ * **UI crash on embedded Windows due to missing fonts**: The MSI installer now ships fonts and will install them if they are not present, so this should be fixed.
+
+## Other Improvements in 1.2.0
+
+ * **Improved dead path detection**: ZeroTier is now more aggressive about expiring paths that do not seem to be active. If a path seems marginal it is re-confirmed before re-use.
+ * **Minor performance improvements**: We've reduced unnecessary memcpy's and made a few other performance improvements in the core.
+ * **Linux static binaries**: For our official packages (the ones in the download.zerotier.com apt and yum repositories) we now build Linux binaries with static linking. Hopefully this will stop all the bug reports relating to library inconsistencies, as well as allowing our deb packages to run on a wider variety of Debian-based distributions. (There are far too many of these to support officially!) The overhead for this is very small, especially since we built our static versions against musl-libc. Distribution maintainers are of course free to build dynamically linked versions for inclusion into distributions; this only affects our official binaries.
diff --git a/attic/Filter.cpp b/attic/Filter.cpp
deleted file mode 100644
index a701e8b..0000000
--- a/attic/Filter.cpp
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * ZeroTier One - Network Virtualization Everywhere
- * Copyright (C) 2011-2015 ZeroTier, Inc.
- *
- * 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 .
- *
- * --
- *
- * ZeroTier may be used and distributed under the terms of the GPLv3, which
- * are available at: http://www.gnu.org/licenses/gpl-3.0.html
- *
- * If you would like to embed ZeroTier into a commercial application or
- * redistribute it in a modified binary form, please contact ZeroTier Networks
- * LLC. Start here: http://www.zerotier.com/
- */
-
-#include
-#include
-#include
-#include
-
-#include
-
-#include "RuntimeEnvironment.hpp"
-#include "Logger.hpp"
-#include "Filter.hpp"
-#include "Utils.hpp"
-
-namespace ZeroTier {
-
-const char *const Filter::UNKNOWN_NAME = "(unknown)";
-const Range Filter::ANY;
-
-static inline Range __parseRange(char *r)
- throw(std::invalid_argument)
-{
- char *saveptr = (char *)0;
- unsigned int a = 0;
- unsigned int b = 0;
- unsigned int fn = 0;
- for(char *f=Utils::stok(r,"-",&saveptr);(f);f=Utils::stok((char *)0,"-",&saveptr)) {
- if (*f) {
- switch(fn++) {
- case 0:
- if (*f != '*')
- a = b = (unsigned int)strtoul(f,(char **)0,10);
- break;
- case 1:
- if (*f != '*')
- b = (unsigned int)strtoul(f,(char **)0,10);
- break;
- default:
- throw std::invalid_argument("rule range must be , -, or *");
- }
- }
- }
- return Range(a,b);
-}
-
-Filter::Rule::Rule(const char *s)
- throw(std::invalid_argument)
-{
- char *saveptr = (char *)0;
- char tmp[256];
- if (!Utils::scopy(tmp,sizeof(tmp),s))
- throw std::invalid_argument("rule string too long");
- unsigned int fn = 0;
- for(char *f=Utils::stok(tmp,";",&saveptr);(f);f=Utils::stok((char *)0,";",&saveptr)) {
- if (*f) {
- switch(fn++) {
- case 0:
- _etherType = __parseRange(f);
- break;
- case 1:
- _protocol = __parseRange(f);
- break;
- case 2:
- _port = __parseRange(f);
- break;
- default:
- throw std::invalid_argument("rule string has unknown extra fields");
- }
- }
- }
- if (fn != 3)
- throw std::invalid_argument("rule string must contain 3 fields");
-}
-
-bool Filter::Rule::operator()(unsigned int etype,const void *data,unsigned int len) const
- throw(std::invalid_argument)
-{
- if ((!_etherType)||(_etherType(etype))) { // ethertype is ANY, or matches
- // Ethertype determines meaning of protocol and port
- switch(etype) {
- case ZT_ETHERTYPE_IPV4:
- if (len > 20) {
- if ((!_protocol)||(_protocol(((const uint8_t *)data)[9]))) { // protocol is ANY or match
- if (!_port) // port is ANY
- return true;
-
- // Don't match on fragments beyond fragment 0. If we've blocked
- // fragment 0, further fragments will fall on deaf ears anyway.
- if ((Utils::ntoh(((const uint16_t *)data)[3]) & 0x1fff))
- return false;
-
- // Internet header length determines where data begins, in multiples of 32 bits
- unsigned int ihl = 4 * (((const uint8_t *)data)[0] & 0x0f);
-
- switch(((const uint8_t *)data)[9]) { // port's meaning depends on IP protocol
- case ZT_IPPROTO_ICMP:
- // For ICMP, port is ICMP type
- return _port(((const uint8_t *)data)[ihl]);
- case ZT_IPPROTO_TCP:
- case ZT_IPPROTO_UDP:
- case ZT_IPPROTO_SCTP:
- case ZT_IPPROTO_UDPLITE:
- // For these, port is destination port. Protocol designers were
- // nice enough to put the field in the same place.
- return _port(((const uint16_t *)data)[(ihl / 2) + 1]);
- default:
- // port has no meaning for other IP types, so ignore it
- return true;
- }
-
- return false; // no match on port
- }
- } else throw std::invalid_argument("undersized IPv4 packet");
- break;
-
- case ZT_ETHERTYPE_IPV6:
- if (len > 40) {
- int nextHeader = ((const uint8_t *)data)[6];
- unsigned int pos = 40;
- while ((pos < len)&&(nextHeader >= 0)&&(nextHeader != 59)) { // 59 == no next header
- fprintf(stderr,"[rule] V6: start header parse, header %.2x pos %d\n",nextHeader,pos);
-
- switch(nextHeader) {
- case 0: // hop-by-hop options
- case 60: // destination options
- case 43: // routing
- case 135: // mobility (mobile IPv6 options)
- if (_protocol((unsigned int)nextHeader))
- return true; // match if our goal was to match any of these
- nextHeader = ((const uint8_t *)data)[pos];
- pos += 8 + (8 * ((const uint8_t *)data)[pos + 1]);
- break;
- case 44: // fragment
- if (_protocol(44))
- return true; // match if our goal was to match fragments
- nextHeader = ((const uint8_t *)data)[pos];
- pos += 8;
- break;
- case ZT_IPPROTO_AH: // AH
- return _protocol(ZT_IPPROTO_AH); // true if AH is matched protocol, otherwise false since packet will be IPsec
- case ZT_IPPROTO_ESP: // ESP
- return _protocol(ZT_IPPROTO_ESP); // true if ESP is matched protocol, otherwise false since packet will be IPsec
- case ZT_IPPROTO_ICMPV6:
- // Only match ICMPv6 if we've selected it specifically
- if (_protocol(ZT_IPPROTO_ICMPV6)) {
- // Port is interpreted as ICMPv6 type
- if ((!_port)||(_port(((const uint8_t *)data)[pos])))
- return true;
- }
- break;
- case ZT_IPPROTO_TCP:
- case ZT_IPPROTO_UDP:
- case ZT_IPPROTO_SCTP:
- case ZT_IPPROTO_UDPLITE:
- // If we encounter any of these, match if protocol matches or is wildcard as
- // we'll consider these the "real payload" if present.
- if ((!_protocol)||(_protocol(nextHeader))) {
- if ((!_port)||(_port(((const uint16_t *)data)[(pos / 2) + 1])))
- return true; // protocol matches or is ANY, port is ANY or matches
- }
- break;
- default: {
- char foo[128];
- Utils::snprintf(foo,sizeof(foo),"unrecognized IPv6 header type %d",(int)nextHeader);
- throw std::invalid_argument(foo);
- }
- }
-
- fprintf(stderr,"[rule] V6: end header parse, next header %.2x, new pos %d\n",nextHeader,pos);
- }
- } else throw std::invalid_argument("undersized IPv6 packet");
- break;
-
- default:
- // For other ethertypes, protocol and port are ignored. What would they mean?
- return true;
- }
- }
-
- return false;
-}
-
-std::string Filter::Rule::toString() const
-{
- char buf[128];
- std::string s;
-
- switch(_etherType.magnitude()) {
- case 0:
- s.push_back('*');
- break;
- case 1:
- Utils::snprintf(buf,sizeof(buf),"%u",_etherType.start);
- s.append(buf);
- break;
- default:
- Utils::snprintf(buf,sizeof(buf),"%u-%u",_etherType.start,_etherType.end);
- s.append(buf);
- break;
- }
- s.push_back(';');
- switch(_protocol.magnitude()) {
- case 0:
- s.push_back('*');
- break;
- case 1:
- Utils::snprintf(buf,sizeof(buf),"%u",_protocol.start);
- s.append(buf);
- break;
- default:
- Utils::snprintf(buf,sizeof(buf),"%u-%u",_protocol.start,_protocol.end);
- s.append(buf);
- break;
- }
- s.push_back(';');
- switch(_port.magnitude()) {
- case 0:
- s.push_back('*');
- break;
- case 1:
- Utils::snprintf(buf,sizeof(buf),"%u",_port.start);
- s.append(buf);
- break;
- default:
- Utils::snprintf(buf,sizeof(buf),"%u-%u",_port.start,_port.end);
- s.append(buf);
- break;
- }
-
- return s;
-}
-
-Filter::Filter(const char *s)
- throw(std::invalid_argument)
-{
- char tmp[16384];
- if (!Utils::scopy(tmp,sizeof(tmp),s))
- throw std::invalid_argument("filter string too long");
- char *saveptr = (char *)0;
- unsigned int fn = 0;
- for(char *f=Utils::stok(tmp,",",&saveptr);(f);f=Utils::stok((char *)0,",",&saveptr)) {
- try {
- _rules.push_back(Rule(f));
- ++fn;
- } catch (std::invalid_argument &exc) {
- char tmp[256];
- Utils::snprintf(tmp,sizeof(tmp),"invalid rule at index %u: %s",fn,exc.what());
- throw std::invalid_argument(tmp);
- }
- }
- std::sort(_rules.begin(),_rules.end());
-}
-
-std::string Filter::toString() const
-{
- std::string s;
-
- for(std::vector::const_iterator r(_rules.begin());r!=_rules.end();++r) {
- if (s.length() > 0)
- s.push_back(',');
- s.append(r->toString());
- }
-
- return s;
-}
-
-void Filter::add(const Rule &r)
-{
- for(std::vector::iterator rr(_rules.begin());rr!=_rules.end();++rr) {
- if (r == *rr)
- return;
- }
- _rules.push_back(r);
- std::sort(_rules.begin(),_rules.end());
-}
-
-const char *Filter::etherTypeName(const unsigned int etherType)
- throw()
-{
- switch(etherType) {
- case ZT_ETHERTYPE_IPV4: return "ETHERTYPE_IPV4";
- case ZT_ETHERTYPE_ARP: return "ETHERTYPE_ARP";
- case ZT_ETHERTYPE_RARP: return "ETHERTYPE_RARP";
- case ZT_ETHERTYPE_ATALK: return "ETHERTYPE_ATALK";
- case ZT_ETHERTYPE_AARP: return "ETHERTYPE_AARP";
- case ZT_ETHERTYPE_IPX_A: return "ETHERTYPE_IPX_A";
- case ZT_ETHERTYPE_IPX_B: return "ETHERTYPE_IPX_B";
- case ZT_ETHERTYPE_IPV6: return "ETHERTYPE_IPV6";
- }
- return UNKNOWN_NAME;
-}
-
-const char *Filter::ipProtocolName(const unsigned int ipp)
- throw()
-{
- switch(ipp) {
- case ZT_IPPROTO_ICMP: return "IPPROTO_ICMP";
- case ZT_IPPROTO_IGMP: return "IPPROTO_IGMP";
- case ZT_IPPROTO_TCP: return "IPPROTO_TCP";
- case ZT_IPPROTO_UDP: return "IPPROTO_UDP";
- case ZT_IPPROTO_GRE: return "IPPROTO_GRE";
- case ZT_IPPROTO_ESP: return "IPPROTO_ESP";
- case ZT_IPPROTO_AH: return "IPPROTO_AH";
- case ZT_IPPROTO_ICMPV6: return "IPPROTO_ICMPV6";
- case ZT_IPPROTO_OSPF: return "IPPROTO_OSPF";
- case ZT_IPPROTO_IPIP: return "IPPROTO_IPIP";
- case ZT_IPPROTO_IPCOMP: return "IPPROTO_IPCOMP";
- case ZT_IPPROTO_L2TP: return "IPPROTO_L2TP";
- case ZT_IPPROTO_SCTP: return "IPPROTO_SCTP";
- case ZT_IPPROTO_FC: return "IPPROTO_FC";
- case ZT_IPPROTO_UDPLITE: return "IPPROTO_UDPLITE";
- case ZT_IPPROTO_HIP: return "IPPROTO_HIP";
- }
- return UNKNOWN_NAME;
-}
-
-const char *Filter::icmpTypeName(const unsigned int icmpType)
- throw()
-{
- switch(icmpType) {
- case ZT_ICMP_ECHO_REPLY: return "ICMP_ECHO_REPLY";
- case ZT_ICMP_DESTINATION_UNREACHABLE: return "ICMP_DESTINATION_UNREACHABLE";
- case ZT_ICMP_SOURCE_QUENCH: return "ICMP_SOURCE_QUENCH";
- case ZT_ICMP_REDIRECT: return "ICMP_REDIRECT";
- case ZT_ICMP_ALTERNATE_HOST_ADDRESS: return "ICMP_ALTERNATE_HOST_ADDRESS";
- case ZT_ICMP_ECHO_REQUEST: return "ICMP_ECHO_REQUEST";
- case ZT_ICMP_ROUTER_ADVERTISEMENT: return "ICMP_ROUTER_ADVERTISEMENT";
- case ZT_ICMP_ROUTER_SOLICITATION: return "ICMP_ROUTER_SOLICITATION";
- case ZT_ICMP_TIME_EXCEEDED: return "ICMP_TIME_EXCEEDED";
- case ZT_ICMP_BAD_IP_HEADER: return "ICMP_BAD_IP_HEADER";
- case ZT_ICMP_TIMESTAMP: return "ICMP_TIMESTAMP";
- case ZT_ICMP_TIMESTAMP_REPLY: return "ICMP_TIMESTAMP_REPLY";
- case ZT_ICMP_INFORMATION_REQUEST: return "ICMP_INFORMATION_REQUEST";
- case ZT_ICMP_INFORMATION_REPLY: return "ICMP_INFORMATION_REPLY";
- case ZT_ICMP_ADDRESS_MASK_REQUEST: return "ICMP_ADDRESS_MASK_REQUEST";
- case ZT_ICMP_ADDRESS_MASK_REPLY: return "ICMP_ADDRESS_MASK_REPLY";
- case ZT_ICMP_TRACEROUTE: return "ICMP_TRACEROUTE";
- case ZT_ICMP_MOBILE_HOST_REDIRECT: return "ICMP_MOBILE_HOST_REDIRECT";
- case ZT_ICMP_MOBILE_REGISTRATION_REQUEST: return "ICMP_MOBILE_REGISTRATION_REQUEST";
- case ZT_ICMP_MOBILE_REGISTRATION_REPLY: return "ICMP_MOBILE_REGISTRATION_REPLY";
- }
- return UNKNOWN_NAME;
-}
-
-const char *Filter::icmp6TypeName(const unsigned int icmp6Type)
- throw()
-{
- switch(icmp6Type) {
- case ZT_ICMP6_DESTINATION_UNREACHABLE: return "ICMP6_DESTINATION_UNREACHABLE";
- case ZT_ICMP6_PACKET_TOO_BIG: return "ICMP6_PACKET_TOO_BIG";
- case ZT_ICMP6_TIME_EXCEEDED: return "ICMP6_TIME_EXCEEDED";
- case ZT_ICMP6_PARAMETER_PROBLEM: return "ICMP6_PARAMETER_PROBLEM";
- case ZT_ICMP6_ECHO_REQUEST: return "ICMP6_ECHO_REQUEST";
- case ZT_ICMP6_ECHO_REPLY: return "ICMP6_ECHO_REPLY";
- case ZT_ICMP6_MULTICAST_LISTENER_QUERY: return "ICMP6_MULTICAST_LISTENER_QUERY";
- case ZT_ICMP6_MULTICAST_LISTENER_REPORT: return "ICMP6_MULTICAST_LISTENER_REPORT";
- case ZT_ICMP6_MULTICAST_LISTENER_DONE: return "ICMP6_MULTICAST_LISTENER_DONE";
- case ZT_ICMP6_ROUTER_SOLICITATION: return "ICMP6_ROUTER_SOLICITATION";
- case ZT_ICMP6_ROUTER_ADVERTISEMENT: return "ICMP6_ROUTER_ADVERTISEMENT";
- case ZT_ICMP6_NEIGHBOR_SOLICITATION: return "ICMP6_NEIGHBOR_SOLICITATION";
- case ZT_ICMP6_NEIGHBOR_ADVERTISEMENT: return "ICMP6_NEIGHBOR_ADVERTISEMENT";
- case ZT_ICMP6_REDIRECT_MESSAGE: return "ICMP6_REDIRECT_MESSAGE";
- case ZT_ICMP6_ROUTER_RENUMBERING: return "ICMP6_ROUTER_RENUMBERING";
- case ZT_ICMP6_NODE_INFORMATION_QUERY: return "ICMP6_NODE_INFORMATION_QUERY";
- case ZT_ICMP6_NODE_INFORMATION_RESPONSE: return "ICMP6_NODE_INFORMATION_RESPONSE";
- case ZT_ICMP6_INV_NEIGHBOR_SOLICITATION: return "ICMP6_INV_NEIGHBOR_SOLICITATION";
- case ZT_ICMP6_INV_NEIGHBOR_ADVERTISEMENT: return "ICMP6_INV_NEIGHBOR_ADVERTISEMENT";
- case ZT_ICMP6_MLDV2: return "ICMP6_MLDV2";
- case ZT_ICMP6_HOME_AGENT_ADDRESS_DISCOVERY_REQUEST: return "ICMP6_HOME_AGENT_ADDRESS_DISCOVERY_REQUEST";
- case ZT_ICMP6_HOME_AGENT_ADDRESS_DISCOVERY_REPLY: return "ICMP6_HOME_AGENT_ADDRESS_DISCOVERY_REPLY";
- case ZT_ICMP6_MOBILE_PREFIX_SOLICITATION: return "ICMP6_MOBILE_PREFIX_SOLICITATION";
- case ZT_ICMP6_MOBILE_PREFIX_ADVERTISEMENT: return "ICMP6_MOBILE_PREFIX_ADVERTISEMENT";
- case ZT_ICMP6_CERTIFICATION_PATH_SOLICITATION: return "ICMP6_CERTIFICATION_PATH_SOLICITATION";
- case ZT_ICMP6_CERTIFICATION_PATH_ADVERTISEMENT: return "ICMP6_CERTIFICATION_PATH_ADVERTISEMENT";
- case ZT_ICMP6_MULTICAST_ROUTER_ADVERTISEMENT: return "ICMP6_MULTICAST_ROUTER_ADVERTISEMENT";
- case ZT_ICMP6_MULTICAST_ROUTER_SOLICITATION: return "ICMP6_MULTICAST_ROUTER_SOLICITATION";
- case ZT_ICMP6_MULTICAST_ROUTER_TERMINATION: return "ICMP6_MULTICAST_ROUTER_TERMINATION";
- case ZT_ICMP6_RPL_CONTROL_MESSAGE: return "ICMP6_RPL_CONTROL_MESSAGE";
- }
- return UNKNOWN_NAME;
-}
-
-} // namespace ZeroTier
diff --git a/attic/Filter.hpp b/attic/Filter.hpp
deleted file mode 100644
index 4bea371..0000000
--- a/attic/Filter.hpp
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * ZeroTier One - Network Virtualization Everywhere
- * Copyright (C) 2011-2015 ZeroTier, Inc.
- *
- * 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 .
- *
- * --
- *
- * ZeroTier may be used and distributed under the terms of the GPLv3, which
- * are available at: http://www.gnu.org/licenses/gpl-3.0.html
- *
- * If you would like to embed ZeroTier into a commercial application or
- * redistribute it in a modified binary form, please contact ZeroTier Networks
- * LLC. Start here: http://www.zerotier.com/
- */
-
-#ifndef _ZT_FILTER_HPP
-#define _ZT_FILTER_HPP
-
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#include "Range.hpp"
-
-/* Ethernet frame types that might be relevant to us */
-#define ZT_ETHERTYPE_IPV4 0x0800
-#define ZT_ETHERTYPE_ARP 0x0806
-#define ZT_ETHERTYPE_RARP 0x8035
-#define ZT_ETHERTYPE_ATALK 0x809b
-#define ZT_ETHERTYPE_AARP 0x80f3
-#define ZT_ETHERTYPE_IPX_A 0x8137
-#define ZT_ETHERTYPE_IPX_B 0x8138
-#define ZT_ETHERTYPE_IPV6 0x86dd
-
-/* IP protocols we might care about */
-#define ZT_IPPROTO_ICMP 0x01
-#define ZT_IPPROTO_IGMP 0x02
-#define ZT_IPPROTO_TCP 0x06
-#define ZT_IPPROTO_UDP 0x11
-#define ZT_IPPROTO_GRE 0x2f
-#define ZT_IPPROTO_ESP 0x32
-#define ZT_IPPROTO_AH 0x33
-#define ZT_IPPROTO_ICMPV6 0x3a
-#define ZT_IPPROTO_OSPF 0x59
-#define ZT_IPPROTO_IPIP 0x5e
-#define ZT_IPPROTO_IPCOMP 0x6c
-#define ZT_IPPROTO_L2TP 0x73
-#define ZT_IPPROTO_SCTP 0x84
-#define ZT_IPPROTO_FC 0x85
-#define ZT_IPPROTO_UDPLITE 0x88
-#define ZT_IPPROTO_HIP 0x8b
-
-/* IPv4 ICMP types */
-#define ZT_ICMP_ECHO_REPLY 0
-#define ZT_ICMP_DESTINATION_UNREACHABLE 3
-#define ZT_ICMP_SOURCE_QUENCH 4
-#define ZT_ICMP_REDIRECT 5
-#define ZT_ICMP_ALTERNATE_HOST_ADDRESS 6
-#define ZT_ICMP_ECHO_REQUEST 8
-#define ZT_ICMP_ROUTER_ADVERTISEMENT 9
-#define ZT_ICMP_ROUTER_SOLICITATION 10
-#define ZT_ICMP_TIME_EXCEEDED 11
-#define ZT_ICMP_BAD_IP_HEADER 12
-#define ZT_ICMP_TIMESTAMP 13
-#define ZT_ICMP_TIMESTAMP_REPLY 14
-#define ZT_ICMP_INFORMATION_REQUEST 15
-#define ZT_ICMP_INFORMATION_REPLY 16
-#define ZT_ICMP_ADDRESS_MASK_REQUEST 17
-#define ZT_ICMP_ADDRESS_MASK_REPLY 18
-#define ZT_ICMP_TRACEROUTE 30
-#define ZT_ICMP_MOBILE_HOST_REDIRECT 32
-#define ZT_ICMP_MOBILE_REGISTRATION_REQUEST 35
-#define ZT_ICMP_MOBILE_REGISTRATION_REPLY 36
-
-/* IPv6 ICMP types */
-#define ZT_ICMP6_DESTINATION_UNREACHABLE 1
-#define ZT_ICMP6_PACKET_TOO_BIG 2
-#define ZT_ICMP6_TIME_EXCEEDED 3
-#define ZT_ICMP6_PARAMETER_PROBLEM 4
-#define ZT_ICMP6_ECHO_REQUEST 128
-#define ZT_ICMP6_ECHO_REPLY 129
-#define ZT_ICMP6_MULTICAST_LISTENER_QUERY 130
-#define ZT_ICMP6_MULTICAST_LISTENER_REPORT 131
-#define ZT_ICMP6_MULTICAST_LISTENER_DONE 132
-#define ZT_ICMP6_ROUTER_SOLICITATION 133
-#define ZT_ICMP6_ROUTER_ADVERTISEMENT 134
-#define ZT_ICMP6_NEIGHBOR_SOLICITATION 135
-#define ZT_ICMP6_NEIGHBOR_ADVERTISEMENT 136
-#define ZT_ICMP6_REDIRECT_MESSAGE 137
-#define ZT_ICMP6_ROUTER_RENUMBERING 138
-#define ZT_ICMP6_NODE_INFORMATION_QUERY 139
-#define ZT_ICMP6_NODE_INFORMATION_RESPONSE 140
-#define ZT_ICMP6_INV_NEIGHBOR_SOLICITATION 141
-#define ZT_ICMP6_INV_NEIGHBOR_ADVERTISEMENT 142
-#define ZT_ICMP6_MLDV2 143
-#define ZT_ICMP6_HOME_AGENT_ADDRESS_DISCOVERY_REQUEST 144
-#define ZT_ICMP6_HOME_AGENT_ADDRESS_DISCOVERY_REPLY 145
-#define ZT_ICMP6_MOBILE_PREFIX_SOLICITATION 146
-#define ZT_ICMP6_MOBILE_PREFIX_ADVERTISEMENT 147
-#define ZT_ICMP6_CERTIFICATION_PATH_SOLICITATION 148
-#define ZT_ICMP6_CERTIFICATION_PATH_ADVERTISEMENT 149
-#define ZT_ICMP6_MULTICAST_ROUTER_ADVERTISEMENT 151
-#define ZT_ICMP6_MULTICAST_ROUTER_SOLICITATION 152
-#define ZT_ICMP6_MULTICAST_ROUTER_TERMINATION 153
-#define ZT_ICMP6_RPL_CONTROL_MESSAGE 155
-
-namespace ZeroTier {
-
-class RuntimeEnvironment;
-
-/**
- * A simple Ethernet frame level filter
- *
- * This doesn't specify actions, since it's used as a deny filter. The rule
- * in ZT1 is "that which is not explicitly prohibited is allowed." (Except for
- * ethertypes, which are handled by a whitelist.)
- */
-class Filter
-{
-public:
- /**
- * Value returned by etherTypeName, etc. on unknown
- *
- * These static methods return precisely this, so a pointer equality
- * check will work.
- */
- static const char *const UNKNOWN_NAME;
-
- /**
- * An empty range as a more idiomatic way of specifying a wildcard match
- */
- static const Range ANY;
-
- /**
- * A filter rule
- */
- class Rule
- {
- public:
- Rule()
- throw() :
- _etherType(),
- _protocol(),
- _port()
- {
- }
-
- /**
- * Construct a rule from a string-serialized value
- *
- * @param s String formatted rule, such as returned by toString()
- * @throws std::invalid_argument String formatted rule is not valid
- */
- Rule(const char *s)
- throw(std::invalid_argument);
-
- /**
- * Construct a new rule
- *
- * @param etype Ethernet type or empty range for ANY
- * @param prot Protocol or empty range for ANY (meaning depends on ethertype, e.g. IP protocol numbers)
- * @param prt Port or empty range for ANY (only applies to some protocols)
- */
- Rule(const Range &etype,const Range &prot,const Range &prt)
- throw() :
- _etherType(etype),
- _protocol(prot),
- _port(prt)
- {
- }
-
- inline const Range ðerType() const throw() { return _etherType; }
- inline const Range &protocol() const throw() { return _protocol; }
- inline const Range &port() const throw() { return _port; }
-
- /**
- * Test this rule against a frame
- *
- * @param etype Type of ethernet frame
- * @param data Ethernet frame data
- * @param len Length of ethernet frame
- * @return True if rule matches
- * @throws std::invalid_argument Frame invalid or not parseable
- */
- bool operator()(unsigned int etype,const void *data,unsigned int len) const
- throw(std::invalid_argument);
-
- /**
- * Serialize rule as string
- *
- * @return Human readable representation of rule
- */
- std::string toString() const;
-
- inline bool operator==(const Rule &r) const throw() { return ((_etherType == r._etherType)&&(_protocol == r._protocol)&&(_port == r._port)); }
- inline bool operator!=(const Rule &r) const throw() { return !(*this == r); }
- inline bool operator<(const Rule &r) const
- throw()
- {
- if (_etherType < r._etherType)
- return true;
- else if (_etherType == r._etherType) {
- if (_protocol < r._protocol)
- return true;
- else if (_protocol == r._protocol) {
- if (_port < r._port)
- return true;
- }
- }
- return false;
- }
- inline bool operator>(const Rule &r) const throw() { return (r < *this); }
- inline bool operator<=(const Rule &r) const throw() { return !(r < *this); }
- inline bool operator>=(const Rule &r) const throw() { return !(*this < r); }
-
- private:
- Range _etherType;
- Range _protocol;
- Range _port;
- };
-
- Filter() {}
-
- /**
- * @param s String-serialized filter representation
- */
- Filter(const char *s)
- throw(std::invalid_argument);
-
- /**
- * @return Comma-delimited list of string-format rules
- */
- std::string toString() const;
-
- /**
- * Add a rule to this filter
- *
- * @param r Rule to add to filter
- */
- void add(const Rule &r);
-
- inline bool operator()(unsigned int etype,const void *data,unsigned int len) const
- throw(std::invalid_argument)
- {
- for(std::vector::const_iterator r(_rules.begin());r!=_rules.end();++r) {
- if ((*r)(etype,data,len))
- return true;
- }
- return false;
- }
-
- static const char *etherTypeName(const unsigned int etherType)
- throw();
- static const char *ipProtocolName(const unsigned int ipp)
- throw();
- static const char *icmpTypeName(const unsigned int icmpType)
- throw();
- static const char *icmp6TypeName(const unsigned int icmp6Type)
- throw();
-
-private:
- std::vector _rules;
-};
-
-} // namespace ZeroTier
-
-#endif
diff --git a/attic/SECURITY.md b/attic/SECURITY.md
deleted file mode 100644
index 5ca125e..0000000
--- a/attic/SECURITY.md
+++ /dev/null
@@ -1,84 +0,0 @@
-ZeroTier Security
-======
-
-## Summary
-
-
-## Using ZeroTier Securely
-
-### Overall Recommendations
-
-*TL;DR: same as anything else: defense in depth defense in depth defense in depth.*
-
-We encourage our users to treat private ZeroTier networks as being rougly equivalent in security to WPA2-enterprise securied WiFi or on-premise wired Ethernet. (Public networks on the other hand are open by design.) That means they're networks with perimeters, but like all networks the compromise of any participating device or network controller allows an attacker to breach this perimeter.
-
-**Never trust the network.** Many modern security professionals discourage reliance on network perimeters as major components in any security strategy, and we strongly agree regardless of whether your network is physical or virtual.
-
-As part of a defense in depth approach **we specifically encourage the use of other secure protocols and authentication systems over ZeroTier networks**. While the use of secure encrypted protocols like SSH and SSL over ZeroTier adds a bit more overhead, it greatly reduces the chance of total compromise.
-
-Imagine that the per-day probability of a major "0-day" security flaw in ZeroTier and OpenSSH are both roughly 0.001 or one per thousand days. Using both at the same time gives you a cumulative 0-day risk of roughly 0.000001 or one per one million days.
-
-Those are made-up numbers. In reality these probabilities can't be known ahead of time. History shows that a 0-day could be found in anything tomorrow, next week, or never. But layers of security give you an overall posture that is the product -- more than the sum -- of its parts. That's how defense in depth works.
-
-### ZeroTier Specifics
-
-#### Protect Your Identity
-
-Each ZeroTier device has an identity. The secret portion of this identity is stored in a file called "identity.secret." *Protect this file.* If it's stolen your device's identity (as represented by its 10-digit ZeroTier address) can easily be stolen or impersonated and your traffic can be decrypted or man-in-the-middle'd.
-
-#### Protect Your Controller
-
-The second major component of ZeroTier network security is the network controller. It's responsible for issuing certificates and configuration information to all network members. That makes it a certificate authority. Compromise of the controller allows an attacker to join or disrupt any network the controller controls. It does *not*, however, allow an attacker to decrypt peer to peer unicast traffic.
-
-If you are using our controller-as-a-service at [my.zerotier.com](https://my.zerotier.com), you are delegating this responsibility to us.
-
-## Security Priorities
-
-These are our security "must-haves." If the system fails in any of these objectives it is broken.
-
-* ZeroTier must be secure against remote vulnerabilities. This includes things like unauthorized remote control, remote penetration of the device using ZeroTier as a vector, or remote injection of malware.
-
-* The content (but not meta-data) of communication must be secure against eavesdropping on the wire by any known means. (We can't warrant against secret vulnerabilities against ciphers, etc., or anything else we don't know about.)
-
-* Communication must be secure against man-in-the-middle attacks and remote device impersonation.
-
-## Security Non-Priorities
-
-There are a few aspects of security we knowingly do not address, since doing so would be beyond scope or would conflict too greatly with other priorities.
-
-* ZeroTier makes no effort to conceal communication meta-data such as source and destination addresses and the amount of information transferred between peers. To do this more or less requires onion routing or other "heavy" approaches to anonymity, and this is beyond scope.
-
-* ZeroTier does not implement complex certificate chains, X.509, or other feature-rich (some would say feature-laden) cryptographic stuff. We only implement the crypto we need to get the job done.
-
-* We don't take extraordinary measures to preserve security under conditions in which an endpoint device has been penetrated by other means (e.g. "rooted" by third party malware) or physicall compromised. If someone steals your keys they've stolen your keys, and if they've "pwned" your device they can easily eavesdrop on everything directly.
-
-## Insecurities and Areas for Improvement
-
-The only perfectly secure system is one that is off. All real world systems have potential security weaknesses. If possible, we like to know what these are and acknowledge their existence.
-
-In some cases we plan to improve these. In other cases we have deliberately decided to "punt" on them in favor of some other priority (see philosophy). We may or may not revisit this decision in the future.
-
-* We don't implement forward secrecy / ephemeral keys. A [discussion of this can be found at the closed GitHub issue for this feature](https://github.com/zerotier/ZeroTierOne/issues/204). In short: we've decided to "punt" on this feature because it introduces complexity and state negotiation. One of the design goals of ZeroTier is "reliability convergence" -- the reliability of ZeroTier virtual networks should rapidly converge with that of the underlying physical wire. Any state that must be negotiated prior to communication multiplies the probability of delay or failure due to packet loss. We *may* revisit this decision at a later date.
-
-## Secure Coding Practices
-
-The first line of defense employed against remote vulnerabilities and other major security flaws is the use of secure coding practices. These are, in no particular order:
-
-* All parsing of remote messages is performed via higher level safe bounds-checked data structures and interfaces. See node/Buffer.hpp for one of the core elements of this.
-
-* C++ exceptions are used to ensure that any unhandled failure or error condition (such as a bounds checking violation) results in the safe and complete termination of message processing. Invalid messages are dropped and ignored.
-
-* Minimalism is a secure coding practice. There is an exponential relationship between complexity and the probability of bugs, and complex designs are much harder to audit and reason about.
-
-* Our build scripts try to enable any OS and compiler level security features such as ASLR and "stack canaries" on non-debug builds.
-
-## Cryptographic Security Practices
-
-* We use [boring crypto](https://cr.yp.to/talks/2015.10.05/slides-djb-20151005-a4.pdf). A single symmetric algorithm (Salsa20/12), a single asymmetric algorithm (Curve25519 ECDH-256), and a single MAC (Poly1305). The way these algorithms are used is identical to how they're used in the NaCl reference implementation. The protocol supports selection of alternative algorithms but only for "future proofing" in the case that a serious flaw is discovered in any of these. Avoding algorithm bloat and cryptographic state negotiation helps guard against down-grade, "oracle," and other protocol level attacks.
-
-* Authenticated encryption is employed with authentication being performed prior to any other operations on received messages. See also: [the cryptographic doom principle](https://moxie.org/blog/the-cryptographic-doom-principle/).
-
-* "Never branch on anything secret" -- deterministic-time comparisons and other operations are used in cryptographic operations. See Utils::secureEq() in node/Utils.hpp.
-
-* OS-derived crypographic random numbers (/dev/urandom or Windows CryptGenRandom) are further randomized using encryption by a secondary key with a secondary source of entropy to guard against CSPRNG bugs. Such OS-level CSPRNG bugs have been found in the past. See Utils::getSecureRandom() in node/Utils.hpp.
-
diff --git a/attic/cli/README.md b/attic/cli/README.md
new file mode 100644
index 0000000..595df07
--- /dev/null
+++ b/attic/cli/README.md
@@ -0,0 +1,57 @@
+The new ZeroTier CLI!
+====
+
+With this update we've expanded upon the previous CLI's functionality, so things should seem pretty familiar. Here are some of the new features we've introduced:
+
+ - Create and administer networks on ZeroTier Central directly from the console.
+ - Service configurations, allows you to control local/remote instances of ZeroTier One
+ - Identity generation and management is now part of the same CLI tool
+
+***
+## Configurations
+
+Configurations are a way for you to nickname and logically organize the control of ZeroTier services running locally or remotely (this includes ZeroTier Central!). They're merely groupings of service API url's and auth tokens. The CLI's settings data is contained within `.zerotierCliSettings`.
+
+For instance, you can control your local instance of ZeroTier One via the `@local` config. By default it is represented as follows:
+
+```
+"local": {
+ "auth": "7tyqRoFytajf21j2l2t9QPm5",
+ "type": "one",
+ "url": "http://127.0.0.1:9993/"
+}
+```
+
+As an example, if you issue the command `zerotier ls` is it implicitly stating `zerotier @local ls`.
+
+With the same line of thinking, you could create a `@my.zerotier.com` which would allow for something like `zerotier @my.zerotier.com net-create` which talks to our hosted ZeroTier Central to create a new network.
+
+
+
+## Command families
+
+- `cli-` is for configuring the settings data for the CLI itself, such as adding/removing `@thing` configurations, variables, etc.
+- `net-` is for operating on a *ZeroTier Central* service such as `https://my.zerotier.com`
+- `id-` is for handling ZeroTier identities.
+
+And those commands with no prefix are there to allow you to operate ZeroTier One instances either local or remote.
+
+***
+## Useful command examples
+
+*Add a ZeroTier One configuration:*
+
+ - `zerotier cli-add-zt MyLocalConfigName https://127.0.0.1:9993/ `
+
+*Add a ZeroTier Central configuration:*
+
+ - `zerotier cli-add-central MyZTCentralConfigName https://my.zerotier.com/ `
+
+*Set a default ZeroTier One instance:*
+
+ - `zerotier cli-set defaultOne MyLocalConfigName`
+
+*Set a default ZeroTier Central:*
+
+ - `zerotier cli-set defaultCentral MyZTCentralConfigName`
+
diff --git a/attic/cli/zerotier.cpp b/attic/cli/zerotier.cpp
new file mode 100644
index 0000000..e75268d
--- /dev/null
+++ b/attic/cli/zerotier.cpp
@@ -0,0 +1,957 @@
+/*
+ * 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 .
+ */
+
+// Note: unlike the rest of ZT's code base, this requires C++11 due to
+// the JSON library it uses and other things.
+
+#include
+#include
+#include
+#include
+
+#include "../node/Constants.hpp"
+#include "../node/Identity.hpp"
+#include "../version.h"
+#include "../osdep/OSUtils.hpp"
+#include "../ext/offbase/json/json.hpp"
+
+#ifdef __WINDOWS__
+#include
+#include
+#include
+#include
+#else
+#include
+#include
+#endif
+
+#include
+#include
+#include