diff options
Diffstat (limited to 'node/Packet.hpp')
-rw-r--r-- | node/Packet.hpp | 335 |
1 files changed, 260 insertions, 75 deletions
diff --git a/node/Packet.hpp b/node/Packet.hpp index fa377964..ef0251e3 100644 --- a/node/Packet.hpp +++ b/node/Packet.hpp @@ -46,22 +46,24 @@ #include "../ext/lz4/lz4.h" /** - * Protocol version -- incremented only for MAJOR changes + * Protocol version -- incremented only for major changes * * 1 - 0.2.0 ... 0.2.5 * 2 - 0.3.0 ... 0.4.5 - * * Added signature and originating peer to multicast frame - * * Double size of multicast frame bloom filter + * + Added signature and originating peer to multicast frame + * + Double size of multicast frame bloom filter * 3 - 0.5.0 ... 0.6.0 - * * Yet another multicast redesign - * * New crypto completely changes key agreement cipher - * 4 - 0.6.0 ... CURRENT - * * New identity format based on hashcash design - * - * This isn't going to change again for a long time unless your - * author wakes up again at 4am with another great idea. :P + * + 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 + * 5 - 1.1.0 ... CURRENT + * + Supports circuit test, proof of work, and echo + * + Supports in-band world (root server definition) updates + * + Clustering! (Though this will work with protocol v4 clients.) + * + Otherwise backward compatible with protocol v4 */ -#define ZT_PROTO_VERSION 4 +#define ZT_PROTO_VERSION 5 /** * Minimum supported protocol version @@ -233,15 +235,6 @@ */ #define ZT_PROTO_MIN_FRAGMENT_LENGTH ZT_PACKET_FRAGMENT_IDX_PAYLOAD -// Destination address types from HELLO, OK(HELLO), and other message types -#define ZT_PROTO_DEST_ADDRESS_TYPE_NONE 0 -#define ZT_PROTO_DEST_ADDRESS_TYPE_ZEROTIER 1 // reserved but unused -#define ZT_PROTO_DEST_ADDRESS_TYPE_ETHERNET 2 // future use -#define ZT_PROTO_DEST_ADDRESS_TYPE_BLUETOOTH 3 // future use -#define ZT_PROTO_DEST_ADDRESS_TYPE_IPV4 4 -#define ZT_PROTO_DEST_ADDRESS_TYPE_LTE_DIRECT 5 // future use -#define ZT_PROTO_DEST_ADDRESS_TYPE_IPV6 6 - // Ephemeral key record flags #define ZT_PROTO_EPHEMERAL_KEY_FLAG_FIPS 0x01 // future use @@ -329,8 +322,6 @@ #define ZT_PROTO_VERB_WHOIS__OK__IDX_IDENTITY (ZT_PROTO_VERB_OK_IDX_PAYLOAD) -#define ZT_PROTO_VERB_WHOIS__ERROR__IDX_ZTADDRESS (ZT_PROTO_VERB_ERROR_IDX_PAYLOAD) - #define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_NETWORK_ID (ZT_PROTO_VERB_OK_IDX_PAYLOAD) #define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT_LEN (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_NETWORK_ID + 8) #define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST__OK__IDX_DICT_LEN + 2) @@ -354,11 +345,11 @@ namespace ZeroTier { * ZeroTier packet * * Packet format: - * <[8] random initialization vector (doubles as 64-bit packet ID)> + * <[8] 64-bit random packet ID and crypto initialization vector> * <[5] destination ZT address> * <[5] source ZT address> * <[1] flags/cipher (top 5 bits) and ZT hop count (last 3 bits)> - * <[8] 8-bit MAC (currently first 8 bytes of poly1305 tag)> + * <[8] 64-bit MAC> * [... -- begin encryption envelope -- ...] * <[1] encrypted flags (top 3 bits) and verb (last 5 bits)> * [... verb-specific payload ...] @@ -374,6 +365,10 @@ namespace ZeroTier { * immutable. This is because intermediate nodes can increment the hop * count up to 7 (protocol max). * + * A hop count of 7 also indicates that receiving peers should not attempt + * to learn direct paths from this packet. (Right now direct paths are only + * learned from direct packets anyway.) + * * http://tonyarcieri.com/all-the-crypto-code-youve-ever-written-is-probably-broken * * For unencrypted packets, MAC is computed on plaintext. Only HELLO is ever @@ -530,10 +525,13 @@ public: */ enum Verb /* Max value: 32 (5 bits) */ { - /* No operation, payload ignored, no reply */ + /** + * No operation (ignored, no reply) + */ VERB_NOP = 0, - /* Announcement of a node's existence: + /** + * Announcement of a node's existence: * <[1] protocol version> * <[1] software major version> * <[1] software minor version> @@ -542,6 +540,8 @@ public: * <[...] 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. @@ -553,10 +553,10 @@ public: * address that require re-establishing connectivity. * * Destination address types and formats (not all of these are used now): - * 0 - None -- no destination address data present - * 1 - Ethernet address -- format: <[6] Ethernet MAC> - * 4 - 6-byte IPv4 UDP address/port -- format: <[4] IP>, <[2] port> - * 6 - 18-byte IPv6 UDP address/port -- format: <[16] IP>, <[2] port> + * 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> * * OK payload: * <[8] timestamp (echoed from original HELLO)> @@ -566,12 +566,15 @@ public: * <[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] * * ERROR has no payload. */ VERB_HELLO = 1, - /* Error response: + /** + * Error response: * <[1] in-re verb> * <[8] in-re packet ID> * <[1] error code> @@ -579,25 +582,31 @@ public: */ VERB_ERROR = 2, - /* Success response: + /** + * Success response: * <[1] in-re verb> * <[8] in-re packet ID> * <[...] request-specific payload> */ VERB_OK = 3, - /* Query an identity by address: + /** + * Query an identity by address: * <[5] address to look up> * * OK response payload: * <[...] binary serialized identity> * - * ERROR response payload: - * <[5] address> + * If querying a cluster, duplicate OK responses may occasionally occur. + * These should be discarded. + * + * If the address is not found, no response is generated. WHOIS requests + * will time out much like ARP requests and similar do in L2. */ VERB_WHOIS = 4, - /* Meet another node at a given protocol address: + /** + * Meet another node at a given protocol address: * <[1] flags (unused, currently 0)> * <[5] ZeroTier address of peer that might be found at this address> * <[2] 16-bit protocol address port> @@ -616,11 +625,16 @@ public: * 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, - /* ZT-to-ZT unicast ethernet frame (shortened EXT_FRAME): + /** + * ZT-to-ZT unicast ethernet frame (shortened EXT_FRAME): * <[8] 64-bit network ID> * <[2] 16-bit ethertype> * <[...] ethernet payload> @@ -635,7 +649,8 @@ public: */ VERB_FRAME = 6, - /* Full Ethernet frame with MAC addressing and optional fields: + /** + * Full Ethernet frame with MAC addressing and optional fields: * <[8] 64-bit network ID> * <[1] flags> * [<[...] certificate of network membership>] @@ -658,23 +673,44 @@ public: */ VERB_EXT_FRAME = 7, - /* DEPRECATED */ - VERB_P5_MULTICAST_FRAME = 8, + /** + * ECHO request (a.k.a. ping): + * <[...] arbitrary payload to be echoed back> + * + * This generates OK with a copy of the transmitted payload. No ERROR + * is generated. Response to ECHO requests is optional. + * + * Support for fragmented echo packets is optional and their use is not + * recommended. + */ + VERB_ECHO = 8, - /* Announce interest in multicast group(s): + /** + * Announce interest in multicast group(s): * <[8] 64-bit network ID> * <[6] multicast Ethernet address> * <[4] multicast additional distinguishing information (ADI)> * [... additional tuples of network/address/adi ...] * - * LIKEs are sent to peers with whom you have a direct peer to peer - * connection, and always including root servers. + * LIKEs may be sent to any peer, though a good implementation should + * restrict them to peers on the same network they're for and to network + * 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.) * * OK/ERROR are not generated. */ VERB_MULTICAST_LIKE = 9, - /* Network member certificate replication/push: + /** + * Network member certificate replication/push: * <[...] serialized certificate of membership> * [ ... additional certificates may follow ...] * @@ -685,7 +721,8 @@ public: */ VERB_NETWORK_MEMBERSHIP_CERTIFICATE = 10, - /* Network configuration request: + /** + * Network configuration request: * <[8] 64-bit network ID> * <[2] 16-bit length of request meta-data dictionary> * <[...] string-serialized request meta-data> @@ -720,7 +757,8 @@ public: */ VERB_NETWORK_CONFIG_REQUEST = 11, - /* Network configuration refresh request: + /** + * Network configuration refresh request: * <[...] array of 64-bit network IDs> * * This can be sent by the network controller to inform a node that it @@ -731,7 +769,8 @@ public: */ VERB_NETWORK_CONFIG_REFRESH = 12, - /* Request endpoints for multicast distribution: + /** + * Request endpoints for multicast distribution: * <[8] 64-bit network ID> * <[1] flags> * <[6] MAC address of multicast group being queried> @@ -747,6 +786,9 @@ public: * to send multicast but does not have the desired number of recipient * peers. * + * More than one OK response can occur if the response is broken up across + * multiple packets or if querying a clustered node. + * * OK response payload: * <[8] 64-bit network ID> * <[6] MAC address of multicast group being queried> @@ -756,20 +798,12 @@ public: * <[2] 16-bit number of members enumerated in this packet> * <[...] series of 5-byte ZeroTier addresses of enumerated members> * - * If no endpoints are known, OK and ERROR are both optional. It's okay - * to return nothing in that case since gathering is "lazy." - * - * ERROR response payload: - * <[8] 64-bit network ID> - * <[6] MAC address of multicast group being queried> - * <[4] 32-bit ADI for multicast group being queried> - * - * ERRORs are optional and are only generated if permission is denied, - * certificate of membership is out of date, etc. + * ERROR is not generated; queries that return no response are dropped. */ VERB_MULTICAST_GATHER = 13, - /* Multicast frame: + /** + * Multicast frame: * <[8] 64-bit network ID> * <[1] flags> * [<[...] network certificate of membership>] @@ -810,7 +844,8 @@ public: */ VERB_MULTICAST_FRAME = 14, - /* Ephemeral (PFS) key push: (UNFINISHED, NOT IMPLEMENTED YET) + /** + * Ephemeral (PFS) key push: (UNFINISHED, NOT IMPLEMENTED YET) * <[2] flags (unused and reserved, must be 0)> * <[2] length of padding / extra field section> * <[...] padding / extra field section> @@ -866,7 +901,8 @@ public: */ VERB_SET_EPHEMERAL_KEY = 15, - /* Push of potential endpoints for direct communication: + /** + * Push of potential endpoints for direct communication: * <[2] 16-bit number of paths> * <[...] paths> * @@ -880,13 +916,10 @@ public: * * Path record flags: * 0x01 - Forget this path if it is currently known - * 0x02 - Blacklist this path, do not use + * 0x02 - (Unused) * 0x04 - Disable encryption (trust: privacy) * 0x08 - Disable encryption and authentication (trust: ultimate) * - * Address types and addresses are of the same format as the destination - * address type and address in HELLO. - * * The receiver may, upon receiving a push, attempt to establish a * direct link to one or more of the indicated addresses. It is the * responsibility of the sender to limit which peers it pushes direct @@ -904,7 +937,166 @@ public: * * OK and ERROR are not generated. */ - VERB_PUSH_DIRECT_PATHS = 16 + VERB_PUSH_DIRECT_PATHS = 16, + + /** + * 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, + + /** + * Circuit test hop report: + * <[8] 64-bit timestamp (from original test)> + * <[8] 64-bit test ID (from original test)> + * <[8] 64-bit reporter timestamp (reporter's clock, 0 if unspec)> + * <[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> + * + * 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. + * + * If a test report is received and no circuit test was sent, it should be + * ignored. This message generates no OK or ERROR response. + */ + VERB_CIRCUIT_TEST_REPORT = 18, + + /** + * 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. + */ + VERB_REQUEST_PROOF_OF_WORK = 19 }; /** @@ -921,7 +1113,7 @@ public: /* Bad/unsupported protocol version */ ERROR_BAD_PROTOCOL_VERSION = 2, - /* Unknown object queried (e.g. with WHOIS) */ + /* Unknown object queried */ ERROR_OBJ_NOT_FOUND = 3, /* HELLO pushed an identity whose address is already claimed */ @@ -940,19 +1132,12 @@ public: ERROR_UNWANTED_MULTICAST = 8 }; - /** - * @param v Verb - * @return String representation (e.g. HELLO, OK) - */ +#ifdef ZT_TRACE static const char *verbString(Verb v) throw(); - - /** - * @param e Error code - * @return String error name - */ static const char *errorString(ErrorCode e) throw(); +#endif template<unsigned int C2> Packet(const Buffer<C2> &b) : |