Work in progress...

This commit is contained in:
Adam Ierymenko 2013-09-26 17:45:19 -04:00
parent 24bad9f3d1
commit 4e010da54b
10 changed files with 231 additions and 257 deletions

View file

@ -98,14 +98,9 @@
#define ZT_PACKET_IDX_PAYLOAD 28
/**
* ZeroTier packet buffer size
*
* This can be changed. This provides enough room for MTU-size packet
* payloads plus some overhead. The subtraction of sizeof(unsigned int)
* makes it an even multiple of 1024 (see Buffer), which might reduce
* memory use a little.
* Packet buffer size (can be changed)
*/
#define ZT_PROTO_MAX_PACKET_LENGTH (3072 - sizeof(unsigned int))
#define ZT_PROTO_MAX_PACKET_LENGTH (ZT_MAX_PACKET_FRAGMENTS * ZT_UDP_DEFAULT_PAYLOAD_MTU)
/**
* Minimum viable packet length (also length of header)
@ -164,22 +159,37 @@
#define ZT_PROTO_VERB_FRAME_IDX_ETHERTYPE (ZT_PROTO_VERB_FRAME_IDX_NETWORK_ID + 8)
#define ZT_PROTO_VERB_FRAME_IDX_PAYLOAD (ZT_PROTO_VERB_FRAME_IDX_ETHERTYPE + 2)
#define ZT_PROTO_VERB_MULTICAST_GOT_IDX_NETWORK_ID (ZT_PACKET_IDX_PAYLOAD)
#define ZT_PROTO_VERB_MULTICAST_GOT_IDX_MULTICAST_GUID (ZT_PROTO_VERB_MULTICAST_GOT_IDX_NETWORK_ID + 8)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FORWARD_COUNT (ZT_PACKET_IDX_PAYLOAD)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_QUEUE (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FORWARD_COUNT + 4)
#define ZT_PROTO_VERB_MULTICAST_FRAME_LEN_QUEUE 320
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_MAGNET (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_QUEUE + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_QUEUE)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SUBMITTER (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_MAGNET + 5)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SUBMITTER_UNIQUE_ID (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SUBMITTER + 5)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_NETWORK_ID (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SUBMITTER_UNIQUE_ID + 3)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SOURCE_MAC (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_NETWORK_ID + 8)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DESTINATION_MAC (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SOURCE_MAC + 6)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DESTINATION_ADI (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DESTINATION_MAC + 6)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ETHERTYPE (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DESTINATION_ADI + 4)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PAYLOAD_LENGTH (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ETHERTYPE + 2)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PAYLOAD (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PAYLOAD_LENGTH + 2)
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_DEPTH (ZT_PACKET_IDX_PAYLOAD)
#define ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_DEPTH 2
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_FIFO (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_DEPTH + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_DEPTH)
#define ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_FIFO 320
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_BLOOM (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_FIFO + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_FIFO)
#define ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_BLOOM 1024
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_NETWORK_ID (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_BLOOM + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_BLOOM)
#define ZT_PROTO_VERB_MULTICAST_FRAME_LEN_NETWORK_ID 8
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_BLOOM_NONCE (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_NETWORK_ID + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_NETWORK_ID)
#define ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_BLOOM_NONCE 2
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_PREFIX_BITS (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_BLOOM_NONCE + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_BLOOM_NONCE)
#define ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_PREFIX_BITS 1
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_PREFIX (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_PREFIX_BITS + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_PREFIX_BITS)
#define ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_PREFIX 2
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ORIGIN (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PROPAGATION_PREFIX + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PROPAGATION_PREFIX)
#define ZT_PROTO_VERB_MULTICAST_FRAME_LEN_ORIGIN 5
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ORIGIN_MCID (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ORIGIN + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_ORIGIN)
#define ZT_PROTO_VERB_MULTICAST_FRAME_LEN_ORIGIN_MCID 3
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_GUID (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ORIGIN)
#define ZT_PROTO_VERB_MULTICAST_FRAME_LEN_GUID 8
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SOURCE_MAC (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ORIGIN_MCID + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_ORIGIN_MCID)
#define ZT_PROTO_VERB_MULTICAST_FRAME_LEN_SOURCE_MAC 6
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_MAC (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_SOURCE_MAC + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_SOURCE_MAC)
#define ZT_PROTO_VERB_MULTICAST_FRAME_LEN_DEST_MAC 6
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_ADI (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_MAC + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_DEST_MAC)
#define ZT_PROTO_VERB_MULTICAST_FRAME_LEN_DEST_ADI 4
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ETHERTYPE (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_DEST_ADI + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_DEST_ADI)
#define ZT_PROTO_VERB_MULTICAST_FRAME_LEN_ETHERTYPE 2
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME_LEN (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_ETHERTYPE + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_ETHERTYPE)
#define ZT_PROTO_VERB_MULTICAST_FRAME_LEN_FRAME_LEN 2
#define ZT_PROTO_VERB_MULTICAST_FRAME_IDX_FRAME (ZT_PROTO_VERB_MULTICAST_FRAME_IDX_PAYLOAD_LEN + ZT_PROTO_VERB_MULTICAST_FRAME_LEN_PAYLOAD_LEN)
#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID (ZT_PACKET_IDX_PAYLOAD)
#define ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_DICT_LEN (ZT_PROTO_VERB_NETWORK_CONFIG_REQUEST_IDX_NETWORK_ID + 8)
@ -459,35 +469,23 @@ public:
*/
VERB_FRAME = 6,
/* 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 ...]
*
* OK/ERROR are not generated.
*/
VERB_MULTICAST_LIKE = 7,
/* Announce receipt of a multicast to propagation magnet node:
* <[8] 64-bit network ID>
* <[8] 64-bit multicast GUID>
*
* OK/ERROR are not generated.
*/
VERB_MULTICAST_GOT = 8,
/* TODO: not implemented yet */
VERB_PROXY_FRAME = 7,
/* A multicast frame:
* <[4] 32-bit forwarding counter>
* <[320] FIFO queue of up to 64 ZT addresses, zero address terminated>
* [... start of signed portion, signed by original submitter below ...]
* <[5] ZeroTier address of propagation magnet node>
* <[5] ZeroTier address of original submitter/signer>
* <[3] 24-bit multicast ID, combined with signer address to form GUID>
* <[2] 16-bit propagation depth>
* <[320] propagation FIFO>
* <[1024] propagation bloom filter>
* [... begin signed portion ...]
* <[8] 64-bit network ID>
* <[2] 16-bit random propagation bloom filter nonce>
* <[1] number of significant bits in propagation restrict prefix>
* <[2] 16-bit propagation restriction prefix (left to right)>
* <[5] ZeroTier address of node of origin>
* <[3] 24-bit multicast ID, together with origin forms GUID>
* <[6] source MAC address>
* <[6] destination multicast group MAC address>
* <[4] destination multicast group 32-bit ADI field>
* <[4] destination multicast group ADI field>
* <[2] 16-bit frame ethertype>
* <[2] 16-bit length of payload>
* <[...] ethernet frame payload>
@ -495,46 +493,57 @@ public:
* <[2] 16-bit length of signature>
* <[...] signature (currently Ed25519/SHA-512, 96 bytes in length)>
*
* Multicast frames are propagated using a graph exploration algorithm in
* which the FIFO queue is embedded in the multicast packet.
* When a multicast frame is received:
*
* Upon receipt:
* (1) packet is possibly injected into the local TAP
* (2) send a MULTICAST_GOT message to magnet node with 64-bit
* multicast GUID
* (3) forwarding counter is incremented, STOP of max exceeded
* (4) topmost value is removed from FIFO and saved (next hop)
* (5) deduplicate FIFO (helps prevent floods)
* (6) FIFO is filled with as many known peers that have LIKED this
* multicast group as possible, excluding peers to whom this
* multicast has already been sent or (if magnet node) have GOT
* this multicast
* (7) packet is sent to next hop (if possible)
* (1) Check the signature of the signed portion of packet, discard on fail
* (2) Check for duplicate multicast, STOP if duplicate
* (3) Check rate limits, STOP if over limit
* (4) Inject into tap if member of network and packet passes other checks
* (5) Increment propagation depth, STOP if over limit
* (6) Pop topmost element off FIFO -- this is next hop
* (7) Push suggested next hops onto FIFO until full -- set corresponding
* bits in bloom filter
* (8) Send to next hop, or to a supernode if none
*
* If there was no next hop -- empty FIFO -- and no new hops are known,
* the packet is sent to the magnet node. The magnet node must be aware
* of all members of a given multicast group. It is the node responsible
* for bridging sparse multicast groups. When other nodes receive the
* multicast, they send GOT to the magnet node so that it will not
* send it back to them.
* When choosing next hops, exclude addresses corresponding to bits already
* set in the bloom filter and addresses outside the propagation restrict
* prefix.
*
* Right now the magnet is a supernode. In the future there may be
* dedicated magnets and/or magnets elected via some kind of DHT or
* something to act as such for given multicast groups. This latter
* might happen if we evolve more toward a totally decentralized model
* instead of today's partially decentralized model.
* Algorithm for setting bits in bloom filter:
*
* The multicast GUID is formed by packing the original sender / signer
* address into the most significant 5 bytes of a 64-bit big-endian
* number, and then packing the 24-bit sender unique ID into the least
* significant 3 bytes. This can be used to locally deduplicate, and
* to identify the multicast in a GOT sent to the magnet. The 24-bit
* ID must be unique for a given sender over recent (say, 10min) time
* spans and across networks. Random or sequential values are fine.
* (1) Place the address in the least significant 40 bits of a 64-bit int.
* (2) Add the bloom filter nonce to this value.
* (3) XOR the least significant 13 bits of this value with the next most
* significant 13 bits and so on, 4 times.
* (4) This value ANDed with 0x1fff is the bit to set in the bloom filter.
* (5) Set this bit via: byte[bit >> 3] |= (0x80 >> (bit & 7))
*
* OK/ERROR are not generated, but GOT is sent to magnet.
* To check bits in bloom filter perform the same computation but mask the
* bit instead of ORing it.
*
* Propagation occurs within a restrict prefix. The restrict prefix is
* applied to the least significant 16 bits of an address. The original
* sender of the multicast sets the restrict prefix and sends 2^N copies
* of the multicast frame, one for each address prefix. This permits
* propagation to be partitioned into realms, and places the majority of
* the burden for this upon the sender.
*
* OK/ERROR are not generated.
*/
VERB_MULTICAST_FRAME = 9,
VERB_MULTICAST_FRAME = 8,
/* 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 supernodes.
*
* OK/ERROR are not generated.
*/
VERB_MULTICAST_LIKE = 9,
/* Network member certificate for sending peer:
* <[8] 64-bit network ID>