This is the common background service implementation for ZeroTier One, the VPN-like OS-level network virtualization service.
It provides a ready-made core I/O loop and a local HTTP-based JSON control bus for controlling the service. This control bus HTTP server can also serve the files in ui/ if this folder's contents are installed in the ZeroTier home folder. The ui/ implements a React-based HTML5 user interface which is then wrappered for various platforms via MacGap, Windows .NET WebControl, etc. It can also be used locally from scripts or via *curl*.
Values POSTed to the JSON API are *extremely* type sensitive. Things *must* be of the indicated type, otherwise they will be ignored or will generate an error. Anything quoted is a string so booleans and integers must lack quotes. Booleans must be *true* or *false* and nothing else. Integers cannot contain decimal points or they are floats (and vice versa). If something seems to be getting ignored or set to a strange value, or if you receive errors, check the type of all JSON fields you are submitting against the types listed below. Unrecognized fields in JSON objects are also ignored.
API requests must be authenticated via an authentication token. ZeroTier One saves this token in the *authtoken.secret* file in its working directory. This token may be supplied via the *auth* URL parameter (e.g. '?auth=...') or via the *X-ZT1-Auth* HTTP request header. Static UI pages are the only thing the server will allow without authentication.
A *jsonp* URL argument may be supplied to request JSONP encapsulation. A JSONP response is sent as a script with its JSON response payload wrapped in a call to the function name supplied as the argument to *jsonp*.
To join a network, POST to it. Since networks have no mandatory writable parameters, POST data is optional and may be omitted. Example: POST to /network/8056c2e21c000001 to join the public "Earth" network. To leave a network, DELETE it e.g. DELETE /network/8056c2e21c000001.
<tr><td>lastUnicastFrame</td><td>integer</td><td>Time of last unicast frame in ms since epoch</td><td>no</td></tr>
<tr><td>lastMulticastFrame</td><td>integer</td><td>Time of last multicast frame in ms since epoch</td><td>no</td></tr>
<tr><td>versionMajor</td><td>integer</td><td>Major version of remote if known</td><td>no</td></tr>
<tr><td>versionMinor</td><td>integer</td><td>Minor version of remote if known</td><td>no</td></tr>
<tr><td>versionRev</td><td>integer</td><td>Revision of remote if known</td><td>no</td></tr>
<tr><td>version</td><td>string</td><td>Version in major.minor.rev format</td><td>no</td></tr>
<tr><td>latency</td><td>integer</td><td>Latency in milliseconds if known</td><td>no</td></tr>
<tr><td>role</td><td>string</td><td>LEAF, HUB, or SUPERNODE</td><td>no</td></tr>
<tr><td>paths</td><td>[object]</td><td>Array of path objects (see below)</td><td>no</td></tr>
</table>
Path objects describe direct physical paths to peer. If no path objects are listed, peer is only reachable via indirect relay fallback. Path object format is:
<tr><td>address</td><td>string</td><td>Physical socket address e.g. IP/port for UDP</td><td>no</td></tr>
<tr><td>lastSend</td><td>integer</td><td>Last send via this path in ms since epoch</td><td>no</td></tr>
<tr><td>lastReceive</td><td>integer</td><td>Last receive via this path in ms since epoch</td><td>no</td></tr>
<tr><td>fixed</td><td>boolean</td><td>If true, this is a statically-defined "fixed" path</td><td>no</td></tr>
<tr><td>preferred</td><td>boolean</td><td>If true, this is the current preferred path</td><td>no</td></tr>
</table>
### Network Controller API
If ZeroTier One was built with *ZT\_ENABLE\_NETWORK\_CONTROLLER* defined, the following API paths are available. Otherwise these paths will return 404.
#### /controller
* Purpose: Check for controller function and return controller status
<tr><td>controller</td><td>boolean</td><td>Always 'true' if controller is running</td><td>no</td></tr>
<tr><td>apiVersion</td><td>integer</td><td>JSON API version, currently 1</td><td>no</td></tr>
<tr><td>clock</td><td>integer</td><td>Controller system clock in ms since epoch</td><td>no</td></tr>
</table>
#### /controller/network
* Purpose: List all networks hosted by this controller
* Methods: GET
* Returns: [ string, ... ]
This returns an array of 16-digit hexadecimal network IDs. Unlike /network under the top-level API, it does not dump full network information for all networks as this may be quite large for a large controller.
#### /controller/network/\<network ID\>
* Purpose: Create, configure, and delete hosted networks
By making queries to this path you can create, configure, and delete networks. DELETE is final, so don't do it unless you really mean it.
It's important to understand how network IDs work. The first ten digits (most significant 40 bits) of a network ID are the ZeroTier address of the controller. This is how clients find it. The last six digits (least significant 24 bits) are arbitrary and serve to identify the network uniquely on the controller.
Thus a network's first ten digits *must* be the controller's address. If your controller is *deadbeef01*, then the networks it controls must have IDs like *deadbeef01feed02* or *deadbeef01beef03*. This API however *does not* enforce this requirement. It will allow you to add arbitrary network IDs, but they won't work since clients will never be able to find them.
To create a new network with a random last six digits safely and atomically, you can POST to */controller/network/##########\_\_\_\_\_\_* where ########## is the controller's address and the underscores are as shown. This will pick a random unallocated network ID, which will be returned in the 'nwid' field of the returned JSON object.
<tr><td>members</td><td>[string]</td><td>Array of ZeroTier addresses of network members</td><td>no</td></tr>
<tr><td>relays</td><td>[object]</td><td>Array of network-specific relay nodes (see below)</td><td>yes</td></tr>
<tr><td>ipAssignmentPools</td><td>[object]</td><td>Array of IP auto-assignment pools for 'zt' assignment mode</td><td>yes</td></tr>
<tr><td>rules</td><td>[object]</td><td>Array of network flow rules (see below)</td><td>yes</td></tr>
</table>
The network member list includes both authorized and unauthorized members. DELETE unauthorized members to remove them from the list.
Relays, IP assignment pools, and rules are edited via direct POSTs to the network object. New values replace all previous values.
**Relay object format:**
Relay objects define network-specific preferred relay nodes. Traffic to peers on this network will preferentially use these relays if they are available, and otherwise will fall back to the global supernode infrastructure.
<tr><td>network</td><td>string</td><td>IP network e.g. 192.168.0.0</td></tr>
<tr><td>netmaskBits</td><td>integer</td><td>IP network netmask bits e.g. 16 for 255.255.0.0</td></tr>
</table>
**Rule object format:**
* **Note**: at the moment, <u>only rules specifying allowed Ethernet types are used</u>. The database supports a richer rule set, but this is not implemented yet in the client. <u>Other types of rules will have no effect</u> (yet).
Rules are matched in order of ruleId. If no rules match, the default action is 'drop'. To allow all traffic, create a single rule with all *null* fields and an action of 'accept'.
Rule object fields can be *null*, in which case they are omitted from the object. A null field indicates "no match on this criteria."
IP related fields apply only to Ethernet frames of type IPv4 or IPV6. Otherwise they are ignored.