summaryrefslogtreecommitdiff
path: root/node/Packet.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'node/Packet.hpp')
-rw-r--r--node/Packet.hpp575
1 files changed, 260 insertions, 315 deletions
diff --git a/node/Packet.hpp b/node/Packet.hpp
index 3d95b0ba..27da6fb5 100644
--- a/node/Packet.hpp
+++ b/node/Packet.hpp
@@ -1,6 +1,6 @@
/*
* ZeroTier One - Network Virtualization Everywhere
- * Copyright (C) 2011-2016 ZeroTier, Inc. https://www.zerotier.com/
+ * Copyright (C) 2011-2018 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
@@ -14,6 +14,14 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * --
+ *
+ * You can be released from the requirements of the license by purchasing
+ * a commercial license. Buying such a license is mandatory as soon as you
+ * develop commercial closed-source software that incorporates or links
+ * directly against ZeroTier software without disclosing the source code
+ * of your own application.
*/
#ifndef ZT_N_PACKET_HPP
@@ -34,12 +42,6 @@
#include "Utils.hpp"
#include "Buffer.hpp"
-#ifdef ZT_USE_SYSTEM_LZ4
-#include <lz4.h>
-#else
-#include "../ext/lz4/lz4.h"
-#endif
-
/**
* Protocol version -- incremented only for major changes
*
@@ -51,19 +53,23 @@
* + Yet another multicast redesign
* + New crypto completely changes key agreement cipher
* 4 - 0.6.0 ... 1.0.6
- * + New identity format based on hashcash design
+ * + BREAKING CHANGE: New identity format based on hashcash design
* 5 - 1.1.0 ... 1.1.5
- * + Supports circuit test, proof of work, and echo
+ * + Supports echo
* + Supports in-band world (root server definition) updates
* + Clustering! (Though this will work with protocol v4 clients.)
* + Otherwise backward compatible with protocol v4
* 6 - 1.1.5 ... 1.1.10
- * + Deprecate old dictionary-based network config format
- * + Introduce new binary serialized network config and meta-data
- * 7 - 1.1.10 -- CURRENT
+ * + Network configuration format revisions including binary values
+ * 7 - 1.1.10 ... 1.1.17
* + Introduce trusted paths for local SDN use
+ * 8 - 1.1.17 ... 1.2.0
+ * + Multipart network configurations for large network configs
+ * + Tags and Capabilities
+ * + Inline push of CertificateOfMembership deprecated
+ * 9 - 1.2.0 ... CURRENT
*/
-#define ZT_PROTO_VERSION 7
+#define ZT_PROTO_VERSION 9
/**
* Minimum supported protocol version
@@ -217,12 +223,8 @@
/**
* Packet buffer size (can be changed)
- *
- * The current value is big enough for ZT_MAX_PACKET_FRAGMENTS, the pragmatic
- * packet fragment limit, times the default UDP MTU. Most packets won't be
- * this big.
*/
-#define ZT_PROTO_MAX_PACKET_LENGTH (ZT_MAX_PACKET_FRAGMENTS * ZT_UDP_DEFAULT_PAYLOAD_MTU)
+#define ZT_PROTO_MAX_PACKET_LENGTH (ZT_MAX_PACKET_FRAGMENTS * ZT_DEFAULT_PHYSMTU)
/**
* Minimum viable packet length (a.k.a. header length)
@@ -303,6 +305,7 @@
#define ZT_PROTO_VERB_MULTICAST_GATHER_IDX_MAC (ZT_PROTO_VERB_MULTICAST_GATHER_IDX_FLAGS + 1)
#define ZT_PROTO_VERB_MULTICAST_GATHER_IDX_ADI (ZT_PROTO_VERB_MULTICAST_GATHER_IDX_MAC + 6)
#define ZT_PROTO_VERB_MULTICAST_GATHER_IDX_GATHER_LIMIT (ZT_PROTO_VERB_MULTICAST_GATHER_IDX_ADI + 4)
+#define ZT_PROTO_VERB_MULTICAST_GATHER_IDX_COM (ZT_PROTO_VERB_MULTICAST_GATHER_IDX_GATHER_LIMIT + 4)
// Note: COM, GATHER_LIMIT, and SOURCE_MAC are optional, and so are specified without size
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_NETWORK_ID (ZT_PACKET_IDX_PAYLOAD)
@@ -346,7 +349,7 @@ namespace ZeroTier {
* ZeroTier packet
*
* Packet format:
- * <[8] 64-bit random packet ID and crypto initialization vector>
+ * <[8] 64-bit packet ID / crypto IV / packet counter>
* <[5] destination ZT address>
* <[5] source ZT address>
* <[1] flags/cipher/hops>
@@ -357,6 +360,14 @@ namespace ZeroTier {
*
* Packets smaller than 28 bytes are invalid and silently discarded.
*
+ * The 64-bit packet ID is a strongly random value used as a crypto IV.
+ * Its least significant 3 bits are also used as a monotonically increasing
+ * (and looping) counter for sending packets to a particular recipient. This
+ * can be used for link quality monitoring and reporting and has no crypto
+ * impact as it does not increase the likelihood of an IV collision. (The
+ * crypto we use is not sensitive to the nature of the IV, only that it does
+ * not repeat.)
+ *
* The flags/cipher/hops bit field is: FFCCCHHH where C is a 3-bit cipher
* selection allowing up to 7 cipher suites, F is outside-envelope flags,
* and H is hop count.
@@ -407,8 +418,7 @@ public:
}
template<unsigned int C2>
- Fragment(const Buffer<C2> &b)
- throw(std::out_of_range) :
+ Fragment(const Buffer<C2> &b) :
Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(b)
{
}
@@ -426,10 +436,8 @@ public:
* @param fragLen Length of fragment in bytes
* @param fragNo Which fragment (>= 1, since 0 is Packet with end chopped off)
* @param fragTotal Total number of fragments (including 0)
- * @throws std::out_of_range Packet size would exceed buffer
*/
Fragment(const Packet &p,unsigned int fragStart,unsigned int fragLen,unsigned int fragNo,unsigned int fragTotal)
- throw(std::out_of_range)
{
init(p,fragStart,fragLen,fragNo,fragTotal);
}
@@ -442,13 +450,11 @@ public:
* @param fragLen Length of fragment in bytes
* @param fragNo Which fragment (>= 1, since 0 is Packet with end chopped off)
* @param fragTotal Total number of fragments (including 0)
- * @throws std::out_of_range Packet size would exceed buffer
*/
inline void init(const Packet &p,unsigned int fragStart,unsigned int fragLen,unsigned int fragNo,unsigned int fragTotal)
- throw(std::out_of_range)
{
if ((fragStart + fragLen) > p.size())
- throw std::out_of_range("Packet::Fragment: tried to construct fragment of packet past its length");
+ throw ZT_EXCEPTION_OUT_OF_BOUNDS;
setSize(fragLen + ZT_PROTO_MIN_FRAGMENT_LENGTH);
// NOTE: this copies both the IV/packet ID and the destination address.
@@ -523,50 +529,56 @@ public:
/**
* No operation (ignored, no reply)
*/
- VERB_NOP = 0,
+ VERB_NOP = 0x00,
/**
- * Announcement of a node's existence:
+ * Announcement of a node's existence and vitals:
* <[1] protocol version>
* <[1] software major version>
* <[1] software minor version>
* <[2] software revision>
- * <[8] timestamp (ms since epoch)>
+ * <[8] timestamp for determining latency>
* <[...] binary serialized identity (see Identity)>
- * <[1] destination address type>
- * [<[...] destination address>]
- * <[8] 64-bit world ID of current world>
- * <[8] 64-bit timestamp of current world>
- *
- * This is the only message that ever must be sent in the clear, since it
- * is used to push an identity to a new peer.
+ * <[...] physical destination address of packet>
+ * <[8] 64-bit world ID of current planet>
+ * <[8] 64-bit timestamp of current planet>
+ * [... remainder if packet is encrypted using cryptField() ...]
+ * <[2] 16-bit number of moons>
+ * [<[1] 8-bit type ID of moon>]
+ * [<[8] 64-bit world ID of moon>]
+ * [<[8] 64-bit timestamp of moon>]
+ * [... additional moon type/ID/timestamp tuples ...]
+ *
+ * HELLO is sent in the clear as it is how peers share their identity
+ * public keys. A few additional fields are sent in the clear too, but
+ * these are things that are public info or are easy to determine. As
+ * of 1.2.0 we have added a few more fields, but since these could have
+ * the potential to be sensitive we introduced the encryption of the
+ * remainder of the packet. See cryptField(). Packet MAC is still
+ * performed of course, so authentication occurs as normal.
+ *
+ * Destination address is the actual wire address to which the packet
+ * was sent. See InetAddress::serialize() for format.
*
- * The destination address is the wire address to which this packet is
- * being sent, and in OK is *also* the destination address of the OK
- * packet. This can be used by the receiver to detect NAT, learn its real
- * external address if behind NAT, and detect changes to its external
- * address that require re-establishing connectivity.
+ * OK payload:
+ * <[8] HELLO timestamp field echo>
+ * <[1] protocol version>
+ * <[1] software major version>
+ * <[1] software minor version>
+ * <[2] software revision>
+ * <[...] physical destination address of packet>
+ * <[2] 16-bit length of world update(s) or 0 if none>
+ * [[...] updates to planets and/or moons]
*
- * Destination address types and formats (not all of these are used now):
- * 0x00 - None -- no destination address data present
- * 0x01 - Ethernet address -- format: <[6] Ethernet MAC>
- * 0x04 - 6-byte IPv4 UDP address/port -- format: <[4] IP>, <[2] port>
- * 0x06 - 18-byte IPv6 UDP address/port -- format: <[16] IP>, <[2] port>
+ * With the exception of the timestamp, the other fields pertain to the
+ * respondent who is sending OK and are not echoes.
*
- * OK payload:
- * <[8] timestamp (echoed from original HELLO)>
- * <[1] protocol version (of responder)>
- * <[1] software major version (of responder)>
- * <[1] software minor version (of responder)>
- * <[2] software revision (of responder)>
- * <[1] destination address type (for this OK, not copied from HELLO)>
- * [<[...] destination address>]
- * <[2] 16-bit length of world update or 0 if none>
- * [[...] world update]
+ * Note that OK is fully encrypted so no selective cryptField() of
+ * potentially sensitive fields is needed.
*
* ERROR has no payload.
*/
- VERB_HELLO = 1,
+ VERB_HELLO = 0x01,
/**
* Error response:
@@ -575,7 +587,7 @@ public:
* <[1] error code>
* <[...] error-dependent payload>
*/
- VERB_ERROR = 2,
+ VERB_ERROR = 0x02,
/**
* Success response:
@@ -583,50 +595,43 @@ public:
* <[8] in-re packet ID>
* <[...] request-specific payload>
*/
- VERB_OK = 3,
+ VERB_OK = 0x03,
/**
* Query an identity by address:
* <[5] address to look up>
+ * [<[...] additional addresses to look up>
*
* OK response payload:
* <[...] binary serialized identity>
+ * [<[...] additional binary serialized identities>]
*
* If querying a cluster, duplicate OK responses may occasionally occur.
- * These should be discarded.
+ * These must be tolerated, which is easy since they'll have info you
+ * already have.
*
- * If the address is not found, no response is generated. WHOIS requests
- * will time out much like ARP requests and similar do in L2.
+ * If the address is not found, no response is generated. The semantics
+ * of WHOIS is similar to ARP and NDP in that persistent retrying can
+ * be performed.
*/
- VERB_WHOIS = 4,
+ VERB_WHOIS = 0x04,
/**
- * Meet another node at a given protocol address:
+ * Relay-mediated NAT traversal or firewall punching initiation:
* <[1] flags (unused, currently 0)>
* <[5] ZeroTier address of peer that might be found at this address>
* <[2] 16-bit protocol address port>
* <[1] protocol address length (4 for IPv4, 16 for IPv6)>
* <[...] protocol address (network byte order)>
*
- * This is sent by a relaying node to initiate NAT traversal between two
- * peers that are communicating by way of indirect relay. The relay will
- * send this to both peers at the same time on a periodic basis, telling
- * each where it might find the other on the network.
+ * An upstream node can send this to inform both sides of a relay of
+ * information they might use to establish a direct connection.
*
* Upon receipt a peer sends HELLO to establish a direct link.
*
- * Nodes should implement rate control, limiting the rate at which they
- * respond to these packets to prevent their use in DDOS attacks. Nodes
- * may also ignore these messages if a peer is not known or is not being
- * actively communicated with.
- *
- * Unfortunately the physical address format in this message pre-dates
- * InetAddress's serialization format. :( ZeroTier is four years old and
- * yes we've accumulated a tiny bit of cruft here and there.
- *
* No OK or ERROR is generated.
*/
- VERB_RENDEZVOUS = 5,
+ VERB_RENDEZVOUS = 0x05,
/**
* ZT-to-ZT unicast ethernet frame (shortened EXT_FRAME):
@@ -642,31 +647,44 @@ public:
* ERROR may be generated if a membership certificate is needed for a
* closed network. Payload will be network ID.
*/
- VERB_FRAME = 6,
+ VERB_FRAME = 0x06,
/**
* Full Ethernet frame with MAC addressing and optional fields:
* <[8] 64-bit network ID>
* <[1] flags>
- * [<[...] certificate of network membership>]
* <[6] destination MAC or all zero for destination node>
* <[6] source MAC or all zero for node of origin>
* <[2] 16-bit ethertype>
* <[...] ethernet payload>
*
* Flags:
- * 0x01 - Certificate of network membership is attached
- *
- * An extended frame carries full MAC addressing, making them a
- * superset of VERB_FRAME. They're used for bridging or when we
- * want to attach a certificate since FRAME does not support that.
- *
- * Multicast frames may not be sent as EXT_FRAME.
- *
- * ERROR may be generated if a membership certificate is needed for a
- * closed network. Payload will be network ID.
+ * 0x01 - Certificate of network membership attached (DEPRECATED)
+ * 0x02 - Most significant bit of subtype (see below)
+ * 0x04 - Middle bit of subtype (see below)
+ * 0x08 - Least significant bit of subtype (see below)
+ * 0x10 - ACK requested in the form of OK(EXT_FRAME)
+ *
+ * Subtypes (0..7):
+ * 0x0 - Normal frame (bridging can be determined by checking MAC)
+ * 0x1 - TEEd outbound frame
+ * 0x2 - REDIRECTed outbound frame
+ * 0x3 - WATCHed outbound frame (TEE with ACK, ACK bit also set)
+ * 0x4 - TEEd inbound frame
+ * 0x5 - REDIRECTed inbound frame
+ * 0x6 - WATCHed inbound frame
+ * 0x7 - (reserved for future use)
+ *
+ * An extended frame carries full MAC addressing, making it a
+ * superset of VERB_FRAME. It is used for bridged traffic,
+ * redirected or observed traffic via rules, and can in theory
+ * be used for multicast though MULTICAST_FRAME exists for that
+ * purpose and has additional options and capabilities.
+ *
+ * OK payload (if ACK flag is set):
+ * <[8] 64-bit network ID>
*/
- VERB_EXT_FRAME = 7,
+ VERB_EXT_FRAME = 0x07,
/**
* ECHO request (a.k.a. ping):
@@ -676,7 +694,7 @@ public:
* is generated. Response to ECHO requests is optional and ECHO may be
* ignored if a node detects a possible flood.
*/
- VERB_ECHO = 8,
+ VERB_ECHO = 0x08,
/**
* Announce interest in multicast group(s):
@@ -690,77 +708,117 @@ public:
* controllers and root servers. In the current network, root servers
* will provide the service of final multicast cache.
*
- * It is recommended that NETWORK_MEMBERSHIP_CERTIFICATE pushes be sent
- * along with MULTICAST_LIKE when pushing LIKEs to peers that do not
- * share a network membership (such as root servers), since this can be
- * used to authenticate GATHER requests and limit responses to peers
- * authorized to talk on a network. (Should be an optional field here,
- * but saving one or two packets every five minutes is not worth an
- * ugly hack or protocol rev.)
+ * VERB_NETWORK_CREDENTIALS should be pushed along with this, especially
+ * if using upstream (e.g. root) nodes as multicast databases. This allows
+ * GATHERs to be authenticated.
*
* OK/ERROR are not generated.
*/
- VERB_MULTICAST_LIKE = 9,
+ VERB_MULTICAST_LIKE = 0x09,
/**
- * Network member certificate replication/push:
- * <[...] serialized certificate of membership>
- * [ ... additional certificates may follow ...]
- *
- * This is sent in response to ERROR_NEED_MEMBERSHIP_CERTIFICATE and may
- * be pushed at any other time to keep exchanged certificates up to date.
+ * Network credentials push:
+ * [<[...] one or more certificates of membership>]
+ * <[1] 0x00, null byte marking end of COM array>
+ * <[2] 16-bit number of capabilities>
+ * <[...] one or more serialized Capability>
+ * <[2] 16-bit number of tags>
+ * <[...] one or more serialized Tags>
+ * <[2] 16-bit number of revocations>
+ * <[...] one or more serialized Revocations>
+ * <[2] 16-bit number of certificates of ownership>
+ * <[...] one or more serialized CertificateOfOwnership>
+ *
+ * This can be sent by anyone at any time to push network credentials.
+ * These will of course only be accepted if they are properly signed.
+ * Credentials can be for any number of networks.
+ *
+ * The use of a zero byte to terminate the COM section is for legacy
+ * backward compatiblity. Newer fields are prefixed with a length.
*
* OK/ERROR are not generated.
*/
- VERB_NETWORK_MEMBERSHIP_CERTIFICATE = 10,
+ VERB_NETWORK_CREDENTIALS = 0x0a,
/**
* Network configuration request:
* <[8] 64-bit network ID>
* <[2] 16-bit length of request meta-data dictionary>
* <[...] string-serialized request meta-data>
- * [<[8] 64-bit revision of netconf we currently have>]
+ * <[8] 64-bit revision of netconf we currently have>
+ * <[8] 64-bit timestamp of netconf we currently have>
*
* This message requests network configuration from a node capable of
- * providing it. If the optional revision is included, a response is
- * only generated if there is a newer network configuration available.
+ * providing it.
*
- * OK response payload:
- * <[8] 64-bit network ID>
- * <[2] 16-bit length of network configuration dictionary>
- * <[...] network configuration dictionary>
+ * Respones to this are always whole configs intended for the recipient.
+ * For patches and other updates a NETWORK_CONFIG is sent instead.
*
- * OK returns a Dictionary (string serialized) containing the network's
- * configuration and IP address assignment information for the querying
- * node. It also contains a membership certificate that the querying
- * node can push to other peers to demonstrate its right to speak on
- * a given network.
+ * It would be valid and correct as of 1.2.0 to use NETWORK_CONFIG always,
+ * but OK(NTEWORK_CONFIG_REQUEST) should be sent for compatibility.
*
- * When a new network configuration is received, another config request
- * should be sent with the new netconf's revision. This confirms receipt
- * and also causes any subsequent changes to rapidly propagate as this
- * cycle will repeat until there are no changes. This is optional but
- * recommended behavior.
+ * OK response payload:
+ * <[8] 64-bit network ID>
+ * <[2] 16-bit length of network configuration dictionary chunk>
+ * <[...] network configuration dictionary (may be incomplete)>
+ * [ ... end of legacy single chunk response ... ]
+ * <[1] 8-bit flags>
+ * <[8] 64-bit config update ID (should never be 0)>
+ * <[4] 32-bit total length of assembled dictionary>
+ * <[4] 32-bit index of chunk>
+ * [ ... end signed portion ... ]
+ * <[1] 8-bit chunk signature type>
+ * <[2] 16-bit length of chunk signature>
+ * <[...] chunk signature>
+ *
+ * The chunk signature signs the entire payload of the OK response.
+ * Currently only one signature type is supported: ed25519 (1).
+ *
+ * Each config chunk is signed to prevent memory exhaustion or
+ * traffic crowding DOS attacks against config fragment assembly.
+ *
+ * If the packet is from the network controller it is permitted to end
+ * before the config update ID or other chunking related or signature
+ * fields. This is to support older controllers that don't include
+ * these fields and may be removed in the future.
*
* ERROR response payload:
* <[8] 64-bit network ID>
- *
- * UNSUPPORTED_OPERATION is returned if this service is not supported,
- * and OBJ_NOT_FOUND if the queried network ID was not found.
*/
- VERB_NETWORK_CONFIG_REQUEST = 11,
+ VERB_NETWORK_CONFIG_REQUEST = 0x0b,
/**
- * Network configuration refresh request:
- * <[...] array of 64-bit network IDs>
+ * Network configuration data push:
+ * <[8] 64-bit network ID>
+ * <[2] 16-bit length of network configuration dictionary chunk>
+ * <[...] network configuration dictionary (may be incomplete)>
+ * <[1] 8-bit flags>
+ * <[8] 64-bit config update ID (should never be 0)>
+ * <[4] 32-bit total length of assembled dictionary>
+ * <[4] 32-bit index of chunk>
+ * [ ... end signed portion ... ]
+ * <[1] 8-bit chunk signature type>
+ * <[2] 16-bit length of chunk signature>
+ * <[...] chunk signature>
+ *
+ * This is a direct push variant for network config updates. It otherwise
+ * carries the same payload as OK(NETWORK_CONFIG_REQUEST) and has the same
+ * semantics.
+ *
+ * The legacy mode missing the additional chunking fields is not supported
+ * here.
+ *
+ * Flags:
+ * 0x01 - Use fast propagation
*
- * This can be sent by the network controller to inform a node that it
- * should now make a NETWORK_CONFIG_REQUEST.
+ * An OK should be sent if the config is successfully received and
+ * accepted.
*
- * It does not generate an OK or ERROR message, and is treated only as
- * a hint to refresh now.
+ * OK payload:
+ * <[8] 64-bit network ID>
+ * <[8] 64-bit config update ID>
*/
- VERB_NETWORK_CONFIG_REFRESH = 12,
+ VERB_NETWORK_CONFIG = 0x0c,
/**
* Request endpoints for multicast distribution:
@@ -769,10 +827,10 @@ public:
* <[6] MAC address of multicast group being queried>
* <[4] 32-bit ADI for multicast group being queried>
* <[4] 32-bit requested max number of multicast peers>
- * [<[...] network certificate of membership>]
+ * [<[...] network certificate of membership>]
*
* Flags:
- * 0x01 - Network certificate of membership is attached
+ * 0x01 - COM is attached
*
* This message asks a peer for additional known endpoints that have
* LIKEd a given multicast group. It's sent when the sender wishes
@@ -782,6 +840,9 @@ public:
* More than one OK response can occur if the response is broken up across
* multiple packets or if querying a clustered node.
*
+ * The COM should be included so that upstream nodes that are not
+ * members of our network can validate our request.
+ *
* OK response payload:
* <[8] 64-bit network ID>
* <[6] MAC address of multicast group being queried>
@@ -793,13 +854,12 @@ public:
*
* ERROR is not generated; queries that return no response are dropped.
*/
- VERB_MULTICAST_GATHER = 13,
+ VERB_MULTICAST_GATHER = 0x0d,
/**
* Multicast frame:
* <[8] 64-bit network ID>
* <[1] flags>
- * [<[...] network certificate of membership>]
* [<[4] 32-bit implicit gather limit>]
* [<[6] source MAC>]
* <[6] destination MAC (multicast address)>
@@ -808,9 +868,10 @@ public:
* <[...] ethernet payload>
*
* Flags:
- * 0x01 - Network certificate of membership is attached
+ * 0x01 - Network certificate of membership attached (DEPRECATED)
* 0x02 - Implicit gather limit field is present
* 0x04 - Source MAC is specified -- otherwise it's computed from sender
+ * 0x08 - Please replicate (sent to multicast replicators)
*
* OK and ERROR responses are optional. OK may be generated if there are
* implicit gather results or if the recipient wants to send its own
@@ -823,11 +884,11 @@ public:
* <[6] MAC address of multicast group>
* <[4] 32-bit ADI for multicast group>
* <[1] flags>
- * [<[...] network certficate of membership>]
+ * [<[...] network certficate of membership (DEPRECATED)>]
* [<[...] implicit gather results if flag 0x01 is set>]
*
* OK flags (same bits as request flags):
- * 0x01 - OK includes certificate of network membership
+ * 0x01 - OK includes certificate of network membership (DEPRECATED)
* 0x02 - OK includes implicit gather results
*
* ERROR response payload:
@@ -835,7 +896,7 @@ public:
* <[6] multicast group MAC>
* <[4] 32-bit multicast group ADI>
*/
- VERB_MULTICAST_FRAME = 14,
+ VERB_MULTICAST_FRAME = 0x0e,
/**
* Push of potential endpoints for direct communication:
@@ -865,172 +926,42 @@ public:
* be used unless they are blacklisted explicitly or unless flag 0x01
* is set.
*
- * Only a subset of this functionality is currently implemented: basic
- * path pushing and learning. Blacklisting and trust are not fully
- * implemented yet (encryption is still always used).
- *
* OK and ERROR are not generated.
*/
- VERB_PUSH_DIRECT_PATHS = 16,
+ VERB_PUSH_DIRECT_PATHS = 0x10,
- /**
- * Source-routed circuit test message:
- * <[5] address of originator of circuit test>
- * <[2] 16-bit flags>
- * <[8] 64-bit timestamp>
- * <[8] 64-bit test ID (arbitrary, set by tester)>
- * <[2] 16-bit originator credential length (includes type)>
- * [[1] originator credential type (for authorizing test)]
- * [[...] originator credential]
- * <[2] 16-bit length of additional fields>
- * [[...] additional fields]
- * [ ... end of signed portion of request ... ]
- * <[2] 16-bit length of signature of request>
- * <[...] signature of request by originator>
- * <[2] 16-bit previous hop credential length (including type)>
- * [[1] previous hop credential type]
- * [[...] previous hop credential]
- * <[...] next hop(s) in path>
- *
- * Flags:
- * 0x01 - Report back to originator at middle hops
- * 0x02 - Report back to originator at last hop
- *
- * Originator credential types:
- * 0x01 - 64-bit network ID for which originator is controller
- *
- * Previous hop credential types:
- * 0x01 - Certificate of network membership
- *
- * Path record format:
- * <[1] 8-bit flags (unused, must be zero)>
- * <[1] 8-bit breadth (number of next hops)>
- * <[...] one or more ZeroTier addresses of next hops>
- *
- * The circuit test allows a device to send a message that will traverse
- * the network along a specified path, with each hop optionally reporting
- * back to the tester via VERB_CIRCUIT_TEST_REPORT.
- *
- * Each circuit test packet includes a digital signature by the originator
- * of the request, as well as a credential by which that originator claims
- * authorization to perform the test. Currently this signature is ed25519,
- * but in the future flags might be used to indicate an alternative
- * algorithm. For example, the originator might be a network controller.
- * In this case the test might be authorized if the recipient is a member
- * of a network controlled by it, and if the previous hop(s) are also
- * members. Each hop may include its certificate of network membership.
- *
- * Circuit test paths consist of a series of records. When a node receives
- * an authorized circuit test, it:
- *
- * (1) Reports back to circuit tester as flags indicate
- * (2) Reads and removes the next hop from the packet's path
- * (3) Sends the packet along to next hop(s), if any.
- *
- * It is perfectly legal for a path to contain the same hop more than
- * once. In fact, this can be a very useful test to determine if a hop
- * can be reached bidirectionally and if so what that connectivity looks
- * like.
- *
- * The breadth field in source-routed path records allows a hop to forward
- * to more than one recipient, allowing the tester to specify different
- * forms of graph traversal in a test.
- *
- * There is no hard limit to the number of hops in a test, but it is
- * practically limited by the maximum size of a (possibly fragmented)
- * ZeroTier packet.
- *
- * Support for circuit tests is optional. If they are not supported, the
- * node should respond with an UNSUPPORTED_OPERATION error. If a circuit
- * test request is not authorized, it may be ignored or reported as
- * an INVALID_REQUEST. No OK messages are generated, but TEST_REPORT
- * messages may be sent (see below).
- *
- * ERROR packet format:
- * <[8] 64-bit timestamp (echoed from original>
- * <[8] 64-bit test ID (echoed from original)>
- */
- VERB_CIRCUIT_TEST = 17,
+ // 0x11, 0x12 -- deprecated
/**
- * Circuit test hop report:
- * <[8] 64-bit timestamp (from original test)>
- * <[8] 64-bit test ID (from original test)>
- * <[8] 64-bit reserved field (set to 0, currently unused)>
- * <[1] 8-bit vendor ID (set to 0, currently unused)>
- * <[1] 8-bit reporter protocol version>
- * <[1] 8-bit reporter major version>
- * <[1] 8-bit reporter minor version>
- * <[2] 16-bit reporter revision>
- * <[2] 16-bit reporter OS/platform>
- * <[2] 16-bit reporter architecture>
- * <[2] 16-bit error code (set to 0, currently unused)>
- * <[8] 64-bit report flags (set to 0, currently unused)>
- * <[8] 64-bit source packet ID>
- * <[5] upstream ZeroTier address from which test was received>
- * <[1] 8-bit source packet hop count (ZeroTier hop count)>
- * <[...] local wire address on which packet was received>
- * <[...] remote wire address from which packet was received>
- * <[2] 16-bit length of additional fields>
- * <[...] additional fields>
- * <[1] 8-bit number of next hops (breadth)>
- * <[...] next hop information>
- *
- * Next hop information record format:
- * <[5] ZeroTier address of next hop>
- * <[...] current best direct path address, if any, 0 if none>
+ * A message with arbitrary user-definable content:
+ * <[8] 64-bit arbitrary message type ID>
+ * [<[...] message payload>]
*
- * Circuit test reports can be sent by hops in a circuit test to report
- * back results. They should include information about the sender as well
- * as about the paths to which next hops are being sent.
+ * This can be used to send arbitrary messages over VL1. It generates no
+ * OK or ERROR and has no special semantics outside of whatever the user
+ * (via the ZeroTier core API) chooses to give it.
*
- * If a test report is received and no circuit test was sent, it should be
- * ignored. This message generates no OK or ERROR response.
+ * Message type IDs less than or equal to 65535 are reserved for use by
+ * ZeroTier, Inc. itself. We recommend making up random ones for your own
+ * implementations.
*/
- VERB_CIRCUIT_TEST_REPORT = 18,
+ VERB_USER_MESSAGE = 0x14,
/**
- * Request proof of work:
- * <[1] 8-bit proof of work type>
- * <[1] 8-bit proof of work difficulty>
- * <[2] 16-bit length of proof of work challenge>
- * <[...] proof of work challenge>
- *
- * This requests that a peer perform a proof of work calucation. It can be
- * sent by highly trusted peers (e.g. root servers, network controllers)
- * under suspected denial of service conditions in an attempt to filter
- * out "non-serious" peers and remain responsive to those proving their
- * intent to actually communicate.
- *
- * If the peer obliges to perform the work, it does so and responds with
- * an OK containing the result. Otherwise it may ignore the message or
- * response with an ERROR_INVALID_REQUEST or ERROR_UNSUPPORTED_OPERATION.
- *
- * Proof of work type IDs:
- * 0x01 - Salsa20/12+SHA512 hashcash function
- *
- * Salsa20/12+SHA512 is based on the following composite hash function:
- *
- * (1) Compute SHA512(candidate)
- * (2) Use the first 256 bits of the result of #1 as a key to encrypt
- * 131072 zero bytes with Salsa20/12 (with a zero IV).
- * (3) Compute SHA512(the result of step #2)
- * (4) Accept this candiate if the first [difficulty] bits of the result
- * from step #3 are zero. Otherwise generate a new candidate and try
- * again.
- *
- * This is performed repeatedly on candidates generated by appending the
- * supplied challenge to an arbitrary nonce until a valid candidate
- * is found. This chosen prepended nonce is then returned as the result
- * in OK.
- *
- * OK payload:
- * <[2] 16-bit length of result>
- * <[...] computed proof of work>
- *
- * ERROR has no payload.
+ * A trace for remote debugging or diagnostics:
+ * <[...] null-terminated dictionary containing trace information>
+ * [<[...] additional null-terminated dictionaries>]
+ *
+ * This message contains a remote trace event. Remote trace events can
+ * be sent to observers configured at the network level for those that
+ * pertain directly to actiity on a network, or to global observers if
+ * locally configured.
+ *
+ * The instance ID is a random 64-bit value generated by each ZeroTier
+ * node on startup. This is helpful in identifying traces from different
+ * members of a cluster.
*/
- VERB_REQUEST_PROOF_OF_WORK = 19
+ VERB_REMOTE_TRACE = 0x15
};
/**
@@ -1039,40 +970,33 @@ public:
enum ErrorCode
{
/* No error, not actually used in transit */
- ERROR_NONE = 0,
+ ERROR_NONE = 0x00,
/* Invalid request */
- ERROR_INVALID_REQUEST = 1,
+ ERROR_INVALID_REQUEST = 0x01,
/* Bad/unsupported protocol version */
- ERROR_BAD_PROTOCOL_VERSION = 2,
+ ERROR_BAD_PROTOCOL_VERSION = 0x02,
/* Unknown object queried */
- ERROR_OBJ_NOT_FOUND = 3,
+ ERROR_OBJ_NOT_FOUND = 0x03,
/* HELLO pushed an identity whose address is already claimed */
- ERROR_IDENTITY_COLLISION = 4,
+ ERROR_IDENTITY_COLLISION = 0x04,
/* Verb or use case not supported/enabled by this node */
- ERROR_UNSUPPORTED_OPERATION = 5,
+ ERROR_UNSUPPORTED_OPERATION = 0x05,
- /* Message to private network rejected -- no unexpired certificate on file */
- ERROR_NEED_MEMBERSHIP_CERTIFICATE = 6,
+ /* Network membership certificate update needed */
+ ERROR_NEED_MEMBERSHIP_CERTIFICATE = 0x06,
/* Tried to join network, but you're not a member */
- ERROR_NETWORK_ACCESS_DENIED_ = 7, /* extra _ to avoid Windows name conflict */
+ ERROR_NETWORK_ACCESS_DENIED_ = 0x07, /* extra _ at end to avoid Windows name conflict */
/* Multicasts to this group are not wanted */
- ERROR_UNWANTED_MULTICAST = 8
+ ERROR_UNWANTED_MULTICAST = 0x08
};
-//#ifdef ZT_TRACE
- static const char *verbString(Verb v)
- throw();
- static const char *errorString(ErrorCode e)
- throw();
-//#endif
-
template<unsigned int C2>
Packet(const Buffer<C2> &b) :
Buffer<ZT_PROTO_MAX_PACKET_LENGTH>(b)
@@ -1268,6 +1192,12 @@ public:
/**
* Get this packet's unique ID (the IV field interpreted as uint64_t)
*
+ * Note that the least significant 3 bits of this ID will change when armor()
+ * is called to armor the packet for transport. This is because armor() will
+ * mask the last 3 bits against the send counter for QoS monitoring use prior
+ * to actually using the IV to encrypt and MAC the packet. Be aware of this
+ * when grabbing the packetId of a new packet prior to armor/send.
+ *
* @return Packet ID
*/
inline uint64_t packetId() const { return at<uint64_t>(ZT_PACKET_IDX_IV); }
@@ -1318,6 +1248,21 @@ public:
bool dearmor(const void *key);
/**
+ * Encrypt/decrypt a separately armored portion of a packet
+ *
+ * This is currently only used to mask portions of HELLO as an extra
+ * security precation since most of that message is sent in the clear.
+ *
+ * This must NEVER be used more than once in the same packet, as doing
+ * so will result in re-use of the same key stream.
+ *
+ * @param key 32-byte key
+ * @param start Start of encrypted portion
+ * @param len Length of encrypted portion
+ */
+ void cryptField(const void *key,unsigned int start,unsigned int len);
+
+ /**
* Attempt to compress payload if not already (must be unencrypted)
*
* This requires that the payload at least contain the verb byte already