RFC 7787
Distributed Node Consensus Protocol
RFC 7787: Distributed Node Consensus Protocol ๐
Part 1 of 9 ๐
Title block tea โ
- RFC number: 7787
- Title: Distributed Node Consensus Protocol
- Authors: M. Stenberg and S. Barth, both listed with affiliation Independent ๐ธ
- Published by: Internet Engineering Task Force (IETF)
- Category: Standards Track
- ISSN: 2070-1721
- Date: April 2016
- Obsoletes / Updates: this header doesn't list either one ๐
Abstract โจ
So this doc is all about DNCP, the Distributed Node Consensus Protocol ๐ . It's a generic state synchronization protocol, which basically means it keeps state in sync across a bunch of nodes, and it's built on the Trickle algorithm and hash trees ๐ง. Fair warning though: DNCP on its own is abstract, so it must be combined with a specific profile before you get a complete protocol you can actually implement ๐ฅ.
Status of This Memo ๐
This is an Internet Standards Track document ๐.
This document is a product of the Internet Engineering Task Force (IETF) ๐. It represents the consensus of the IETF community, it got public review, and the Internet Engineering Steering Group (IESG) approved it for publication ๐. If you want more on Internet Standards, check out Section 2 of RFC 5741 ๐ฆ.
Info about this doc's current status, any errata, and how to give feedback lives at http://www.rfc-editor.org/info/rfc7787 โจ.
Copyright Notice โญ
Copyright (c) 2016 IETF Trust and the persons identified as the document authors. All rights reserved ๐ซถ.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) as they're in effect on the date this document was published ๐. Please actually read these, because they spell out your rights and restrictions for this document ๐. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they come without warranty as described in the Simplified BSD License ๐
.
Table of Contents ๐
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1. Applicability . . . . . . . . . . . . . . . . . . . . . . 4
2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1. Requirements Language . . . . . . . . . . . . . . . . . . 8
3. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . 8
4. Operation . . . . . . . . . . . . . . . . . . . . . . . . . . 9
4.1. Hash Tree . . . . . . . . . . . . . . . . . . . . . . . . 9
4.1.1. Calculating Network State and Node Data Hashes . . . 10
4.1.2. Updating Network State and Node Data Hashes . . . . . 10
4.2. Data Transport . . . . . . . . . . . . . . . . . . . . . 10
4.3. Trickle-Driven Status Updates . . . . . . . . . . . . . . 12
4.4. Processing of Received TLVs . . . . . . . . . . . . . . . 13
4.5. Discovering, Adding, and Removing Peers . . . . . . . . . 15
4.6. Data Liveliness Validation . . . . . . . . . . . . . . . 16
5. Data Model . . . . . . . . . . . . . . . . . . . . . . . . . 17
6. Optional Extensions . . . . . . . . . . . . . . . . . . . . . 19
6.1. Keep-Alives . . . . . . . . . . . . . . . . . . . . . . . 19
6.1.1. Data Model Additions . . . . . . . . . . . . . . . . 20
6.1.2. Per-Endpoint Periodic Keep-Alives . . . . . . . . . . 20
6.1.3. Per-Peer Periodic Keep-Alives . . . . . . . . . . . . 20
6.1.4. Received TLV Processing Additions . . . . . . . . . . 21
6.1.5. Peer Removal . . . . . . . . . . . . . . . . . . . . 21
6.2. Support for Dense Multicast-Enabled Links . . . . . . . . 21
7. Type-Length-Value Objects . . . . . . . . . . . . . . . . . . 22
7.1. Request TLVs . . . . . . . . . . . . . . . . . . . . . . 23
7.1.1. Request Network State TLV . . . . . . . . . . . . . . 23
7.1.2. Request Node State TLV . . . . . . . . . . . . . . . 24
7.2. Data TLVs . . . . . . . . . . . . . . . . . . . . . . . . 24
7.2.1. Node Endpoint TLV . . . . . . . . . . . . . . . . . . 24
7.2.2. Network State TLV . . . . . . . . . . . . . . . . . . 25
7.2.3. Node State TLV . . . . . . . . . . . . . . . . . . . 25
7.3. Data TLVs within Node State TLV . . . . . . . . . . . . . 26
7.3.1. Peer TLV . . . . . . . . . . . . . . . . . . . . . . 26
7.3.2. Keep-Alive Interval TLV . . . . . . . . . . . . . . . 27
8. Security and Trust Management . . . . . . . . . . . . . . . . 27
8.1. Trust Method Based on Pre-Shared Key . . . . . . . . . . 27
8.2. PKI-Based Trust Method . . . . . . . . . . . . . . . . . 28
8.3. Certificate-Based Trust Consensus Method . . . . . . . . 28
8.3.1. Trust Verdicts . . . . . . . . . . . . . . . . . . . 28
8.3.2. Trust Cache . . . . . . . . . . . . . . . . . . . . . 29
8.3.3. Announcement of Verdicts . . . . . . . . . . . . . . 30
8.3.4. Bootstrap Ceremonies . . . . . . . . . . . . . . . . 31
9. DNCP Profile-Specific Definitions . . . . . . . . . . . . . . 32
10. Security Considerations . . . . . . . . . . . . . . . . . . . 34
11. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 35
12. References . . . . . . . . . . . . . . . . . . . . . . . . . 36
12.1. Normative References . . . . . . . . . . . . . . . . . . 36
12.2. Informative References . . . . . . . . . . . . . . . . . 36
Appendix A. Alternative Modes of Operation . . . . . . . . . . . 38
A.1. Read-Only Operation . . . . . . . . . . . . . . . . . . . 38
A.2. Forwarding Operation . . . . . . . . . . . . . . . . . . 38
Appendix B. DNCP Profile Additional Guidance . . . . . . . . . . 38
B.1. Unicast Transport -- UDP or TCP? . . . . . . . . . . . . 38
B.2. (Optional) Multicast Transport . . . . . . . . . . . . . 39
B.3. (Optional) Transport Security . . . . . . . . . . . . . . 39
Appendix C. Example Profile . . . . . . . . . . . . . . . . . . 40
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 41
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 41
1. Introduction โจ
DNCP is designed so every participating node can publish a small set of TLV (Type-Length-Value) tuples, at most 64 KB ๐, and everyone gets a shared, common view of the data published by every DNCP node that's currently bidirectionally reachable in the network ๐.
For state synchronization, there's a hash tree ๐ณ. First, a hash is calculated for the data set each node publishes, which is called node data. Then another hash gets calculated over those node data hashes ๐ง. The single resulting hash is the network state hash, and it's sent around using the Trickle algorithm [RFC6206] so every node agrees on the current state of the published data in the network ๐ฆ. Here's the lowkey genius part: Trickle only sends these short network state hashes, and it sends them infrequently (in steady state, once the maximum Trickle interval per link or unicast connection has been reached). That makes DNCP super thrifty when updates happen rarely ๐ โจ.
For keeping the topology and the data inside it alive, you get a combo of Trickled network state, keep-alives, and "other" ways of making sure reachability holds ๐ซถ. The core idea is that if every node makes sure its peers are present, transitively, the whole network state stays up to date too ๐.
1.1. Applicability ๐ฆ
okay so DNCP is seriously useful for stuff like autonomous bootstrapping, discovery, and negotiation of embedded network devices like routers ๐ค. It can also be the base for running distributed algorithms like [RFC7596] or the use cases in Appendix C ๐ . DNCP is super abstract, so you can tune it for loads of different apps by defining profiles ๐. A profile is where you pick:
- unicast transport: a datagram or stream-oriented protocol (e.g., TCP, UDP, or the Stream Control Transmission Protocol (SCTP)) for generic protocol operation.
- optional transport security: whether and when to use security based on Transport Layer Security (TLS) or Datagram Transport Layer Security (DTLS), if supported over the chosen transport.
- optional multicast transport: a multicast-capable protocol like UDP that allows autonomous peer discovery or more efficient use of multiple access links.
- communication scopes: either hop by hop only, relying on link-local addressing (e.g., for LANs), addresses with broader scopes (e.g., over WANs or the Internet) relying on an existing routing infrastructure, or a combination of both (e.g., to exchange state between multiple LANs over a WAN or the Internet).
- payloads: additional specific payloads (e.g., IANA standardized, enterprise-specific, or private use).
- extensions: possible protocol extensions, either predefined in this document or specific to a particular use case.
ngl, there are some situations where the protocol as defined here is kinda the wrong pick ๐. This list is the quick overview, and the paragraphs after it go deeper on each one.
- large amounts of data: nodes are limited to 64 KB of published data.
- very dense unicast-only networks: nodes include information about all immediate neighbors as part of their published data.
- predominantly minimal data changes: node data is always transported as is, which leads to a relatively large transmission overhead for changes affecting only a small part of it.
- frequently changing data: DNCP with its use of Trickle is optimized for the steady state and less efficient otherwise.
- large amounts of very constrained nodes: DNCP requires each node to store the entirety of the data published by all nodes.
The topology of the devices isn't limited, and it's automatically discovered โจ. When you rely on link-local communication exclusively, all links with DNCP nodes need to be at least transitively connected by routers running the protocol on multiple endpoints, so they form one connected network ๐. That said, there's no requirement for every device in a physical network to run the protocol. Especially if globally scoped addresses are used, DNCP peers don't need to be on the same or even neighboring physical links ๐. Autonomous discovery features are usually used in local network scenarios, but with security enabled, DNCP can also be used over unsecured public networks ๐. Network size is restricted merely by the capabilities of the devices, meaning each DNCP node needs to be able to store the entirety of the data published by all nodes ๐พ. The data associated with each individual node identifier is limited to about 64 KB in this document. However, protocol extensions could be defined to mitigate this or other protocol limitations if the need arises ๐งฉ.
DNCP is most suitable for data that changes only infrequently, so you get the maximum benefit from using Trickle ๐ธ. As the network of nodes grows, or the frequency of data changes per node increases, Trickle is eventually used less and less, and the benefit of using DNCP shrinks. In these cases, Trickle just adds extra complexity to the specification with very little added value ๐ญ.
You can roughly evaluate how suitable DNCP is for an application by looking at the expected average network-wide state change interval A_NC_I. You compute it by dividing the mean interval at which a node originates a new TLV set by the number of participating nodes ๐งฎ. If keep-alives are used, A_NC_I is the minimum of the computed A_NC_I and the keep-alive interval. If A_NC_I is less than the (application-specific) Trickle minimum interval, DNCP is most likely unsuitable for the application, because Trickle won't be utilized most of the time ๐
โโ๏ธ.
If constant rapid state changes are needed, the better choice is an additional point-to-point channel whose address or locator is published using DNCP ๐ฆ. Still, if doing that doesn't raise A_NC_I above the (sensibly chosen) Trickle interval parameters for a particular application, using DNCP is probably not suitable for that application.
Another thing to think about is the size of the TLV set a node publishes compared to the size of the deltas in that TLV set ๐. If the TLV set published by a node is very large and has frequent small changes, DNCP as currently specified may be unsuitable, because it lacks a delta synchronization scheme. That's how it keeps the implementation simple ๐งธ.
DNCP can be used in networks where only unicast transport is available ๐ก. DNCP uses the least amount of bandwidth when multicast is utilized, but even in pure unicast mode, using Trickle (ideally with k < 2) gives you a protocol with an exponential backoff timer and fewer transmissions than a simpler protocol that doesn't use Trickle ๐.
2. Terminology ๐
here's the glossary, bestie, so we're all speaking the same language ๐
DNCP profile the values for the set of parameters given in
Section 9. They are prefixed with DNCP_ in this
document. The profile also specifies the set of
optional DNCP extensions to be used. For a simple
example DNCP profile, see Appendix C.
DNCP-based a protocol that provides a DNCP profile, according
protocol to Section 9, and zero or more TLV assignments from
the per-DNCP profile TLV registry as well as their
processing rules.
DNCP node a single node that runs a DNCP-based protocol.
Link a link-layer media over which directly connected
nodes can communicate.
DNCP network a set of DNCP nodes running a DNCP-based
protocol(s) with a matching DNCP profile(s). The
set consists of nodes that have discovered each
other using the transport method defined in the
DNCP profile, via multicast on local links, and/or
by using unicast communication.
Node identifier an opaque fixed-length identifier consisting of
DNCP_NODE_IDENTIFIER_LENGTH bytes that uniquely
identifies a DNCP node within a DNCP network.
Interface a node's attachment to a particular link.
Address an identifier used as the source or destination of
a DNCP message flow, e.g., a tuple (IPv6 address,
UDP port) for an IPv6 UDP transport.
Endpoint a locally configured termination point for
(potential or established) DNCP message flows. An
endpoint is the source and destination for separate
unicast message flows to individual nodes and
optionally for multicast messages to all thereby
reachable nodes (e.g., for node discovery).
Endpoints are usually in one of the transport modes
specified in Section 4.2.
Endpoint a 32-bit opaque and locally unique value, which
identifier identifies a particular endpoint of a particular
DNCP node. The value 0 is reserved for DNCP and
DNCP-based protocol purposes and not used to
identify an actual endpoint. This definition is in
sync with the interface index definition in
[RFC3493], as the non-zero small positive integers
should comfortably fit within 32 bits.
Peer another DNCP node with which a DNCP node
communicates using at least one particular local
and remote endpoint pair.
Node data a set of TLVs published and owned by a node in the
DNCP network. Other nodes pass it along as is,
even if they cannot fully interpret it.
Origination time the (estimated) time when the node data set with
the current sequence number was published.
Node state a set of metadata attributes for node data. It
includes a sequence number for versioning, a hash
value for comparing equality of stored node data,
and a timestamp indicating the time passed since
its last publication (i.e., since the origination
time). The hash function and the length of the
hash value are defined in the DNCP profile.
Network state a hash value that represents the current state of
hash the network. The hash function and the length of
the hash value are defined in the DNCP profile.
Whenever a node is added, removed, or updates its
published node data, this hash value changes as
well. For calculation, please see Section 4.1.
Trust verdict a statement about the trustworthiness of a
certificate announced by a node participating in
the certificate-based trust consensus mechanism.
Effective trust the trust verdict with the highest priority within
verdict the set of trust verdicts announced for the
certificate in the DNCP network.
Topology graph the undirected graph of DNCP nodes produced by
retaining only bidirectional peer relationships
between nodes.
Bidirectionally a peer is locally unidirectionally reachable if a
reachable consistent multicast or any unicast DNCP message
has been received by the local node (see Section
4.5). If said peer in return also considers the
local node unidirectionally reachable, then
bidirectionally reachability is established. As
this process is based on publishing peer
relationships and evaluating the resulting topology
graph as described in Section 4.6, this information
is available to the whole DNCP network.
Trickle instance a distinct Trickle [RFC6206] algorithm state kept
by a node (Section 5) and related to an endpoint or
a particular (peer, endpoint) tuple with Trickle
variables I, t, and c. See Section 4.3.
2.1. Requirements Language ๐ซถ
so, the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be read as described in RFC 2119 [RFC2119] ๐โจ
3. Overview โจ
okay bestie, so DNCP mostly chats one-on-one with each node over unicast ๐ but it can also shout to everyone with multicast ๐ข for Trickle-based shared state updates and topology discovery. If you're running pure unicast over an unreliable transport, Trickle also runs between peers ๐
DNCP talks in TLVs (Section 7) ๐ฌ and defines a set of mandatory and optional ones it needs to work. They sort into three groups: ones for asking for info (Section 7.1), ones for sending data (Section 7.2), and ones that get published as data (Section 7.3). DNCP-based protocols usually add their own TLVs on top to level up their features ๐
DNCP maps out the topology of the network ๐บ๏ธ and keeps published node data feeling alive by making sure the publishing node can be reached both ways ๐ซถ New potential peers can be found on their own on multicast-enabled links ๐ฆ Their addresses can be configured by hand, or found some other way that the DNCP profile defines. The profile might name a well-known anycast address, or hand over the remote address to contact through another protocol, like DHCPv6 [RFC3315] ๐
Every node keeps a hash tree of height 1 that's rooted in itself ๐ณ It represents the state of every node it can currently reach (see Section 4.1), and Trickle is what kicks off synchronization (see Section 4.3). So whether peers need to check for state changes just comes down to comparing their roots, aka their own calculated network state hashes ๐
Before a node joins a DNCP network, it starts with a hash tree that has one leaf if it publishes any TLVs, and zero leaves if it doesn't ๐ฑ Then it announces its network state hash, calculated from that tree, via Trickle on every endpoint it's configured with ๐ฃ
When a node notices an update (like getting a different network state hash from a peer ๐), the one who started the event gets asked for a list of the state of every node, which is all the info needed to work out its own hash tree ๐ The node checks that list to see if its own info is out of date. If it is, it asks for the actual node data that changed ๐
Anytime a node's local copy of node data and its hash tree get updated (because its own node state changed, another node's did, or a peer got added or removed) ๐, its Trickle instances get reset. That eventually pushes the update out to all of its peers ๐
4. Operation
4.1. Hash Tree
Every DNCP node keeps an arbitrary-width hash tree of height 1 ๐ฒ The root is the overall network state hash, and it's how nodes (two or more of them) check that they all see the same network ๐ฏ Each leaf stands for one bidirectionally reachable DNCP node. Whenever a node gets added to or removed from the topology graph (Section 4.6), it gets added or removed as a leaf too ๐ At any moment, the leaves are lined up in ascending order of the node identifiers they represent ๐
4.1.1. Calculating Network State and Node Data Hashes
The network state hash and the node data hashes both get calculated with the hash function from the DNCP profile (Section 9), truncated to however many bits the profile says ๐
Each node data hash comes from running that function and truncation on that node's node data, exactly as it's published in the Node State TLV ๐ง Those node data sets are always kept in the order defined in Section 7.2.3 ๐
The network state hash is the function and truncation run on the concatenated network state ๐ซ To build that, each node's sequence number (in network byte order) gets glued onto its node data hash, making one per-node datum for every node ๐งฉ Then all those per-node data get concatenated in ascending order of node identifier, which is the same order the nodes sit in the hash tree ๐ธ
4.1.2. Updating Network State and Node Data Hashes
The network state hash and node data hashes get updated on demand, and any time locally stored per-node state changes ๐ง That includes local unidirectional reachability as encoded in the published Peer TLVs (Section 7.3.1). Combined with remote data, it also gives a node awareness of bidirectional reachability changes ๐โจ
4.2. Data Transport
DNCP doesn't ask much from the underlying transport ๐ฅฐ It just needs some way to send either unicast datagrams or stream data to a peer, plus a way to send multicast datagrams if multicast mode is in use. Multicast only exists to spot potential new DNCP nodes and to send status messages that simply say "hey, go start a unicast exchange" ๐ฃ So the multicast transport doesn't have to be secured ๐ If you want unicast security and one of the built-in security methods, you need some TLS-derived transport too, like TLS [RFC5246] on top of TCP or DTLS [RFC6347] on top of UDP ๐ Those give you integrity protection and confidentiality for node data, plus authentication and authorization using the schemes in "Security and Trust Management" (Section 8) ๐ก๏ธ The DNCP profile MUST provide a specific definition of the transport(s) in use and their parameters ๐
TLVs (Section 7) get sent over the transport exactly as they are ๐ฆ They SHOULD go out together, unless things like MTU considerations mean they have to be split into several batches ๐ฎ DNCP doesn't fragment or reassemble TLVs, so the underlying transport MUST be ensured to handle those jobs if they're needed ๐งต When this document says to send one or more TLVs, the sender doesn't have to keep track of packets once they've been handed to the transport ๐ โโ๏ธ Reliability comes entirely from the explicitly defined timers and state machines, like Trickle (Section 4.3) โฐ TLVs are handled one at a time and statelessly, so they don't have to arrive in any particular order ๐ There's one exception ๐จ To form bidirectional peer relationships, DNCP needs to know the endpoints used for communication. Since bidirectional peer relationships are needed to validate liveliness of published node data (Section 4.6), a DNCP node MUST send a Node Endpoint TLV (Section 7.2.1) ๐ซถ When it gets sent depends on the transport, but conceptually it should be available whenever a Network State TLV is being processed ๐ฏ
- If you're using a stream transport, the TLV MUST be sent at least once per connection, but SHOULD NOT be sent more than once ๐
- If you're using a datagram transport, it MUST be included in every datagram that also contains a Network State TLV (Section 7.2.2), and it MUST be located before any such TLV ๐จ It SHOULD also be included in any other datagram to speed up initial peer detection ๐โโ๏ธ
With all the different transport options and possible endpoint configurations, a DNCP endpoint can be used in a few transport modes ๐
Unicast:
- If only reliable unicast transport is used, Trickle isn't used at all ๐ โโ๏ธ Whenever the locally calculated network state hash changes, one Network State TLV (Section 7.2.2) gets sent to every unicast peer ๐ Recently changed Node State TLVs (Section 7.2.3) MAY be included too ๐
- If only unreliable unicast transport is used, Trickle state is kept per peer, and it's used to send Network State TLVs now and then, as specified in Section 4.3 โณ
Multicast+Unicast: If multicast datagram transport is available on an endpoint, Trickle state is only kept for the endpoint as a whole ๐ It's used to send Network State TLVs periodically, as specified in Section 4.3 ๐ On top of that, per-endpoint keep-alives MAY be defined in the DNCP profile, as specified in Section 6.1.2 ๐
MulticastListen+Unicast: This is basically just like unicast, except multicast transmissions get listened to so the node can notice changes to the highest node identifier ๐ This mode is only used if the DNCP profile supports dense multicast-enabled link optimization (Section 6.2) โจ
4.3. Trickle-Driven Status Updates
The Trickle algorithm [RFC6206] keeps protocol reliability intact over unreliable multicast or unicast transports ๐ฆ For reliable unicast transports, the actual algorithm isn't needed, so it's skipped (Section 4.2) ๐ DNCP keeps multiple Trickle states, as defined in Section 5 ๐งฉ Each one can run on different parameters (more on that below) and has one job: make sure a specific peer, or all peers on that endpoint, keep getting the node's current locally calculated network state hash so they can compare notes and catch any divergence in what they think the network looks like ๐๐
Trickle has 3 parameters: Imin, Imax, and k ๐ Imin and Imax are the minimum value for I and the maximum number of doublings of Imin, where I is the time interval during which at least k Trickle updates have to be seen on an endpoint to stop local state from being sent ๐ The actual suggested Trickle parameters are specific to the DNCP profile, as described in Section 9 ๐
All Trickle instances from Section 5 are treated as inconsistent and reset if, and only if, the locally calculated network state hash changes โจ That happens either because the local node's own node data changed, or because it got newer data from another node (Section 4.1) ๐ A node MUST NOT reset its Trickle state just because it received a Network State TLV (Section 7.2.2) with a network state hash that's different from its own calculated one ๐ โโ๏ธ๐
Every time a particular Trickle instance says an update should go out, the node MUST send a Network State TLV (Section 7.2.2) if and only if one of these is true ๐ฃ
- The endpoint is in Multicast+Unicast transport mode, and then the TLV MUST be sent over multicast ๐ข
- The endpoint is NOT in Multicast+Unicast transport mode, and the unicast transport is unreliable, and then the TLV MUST be sent over unicast ๐
A (sub)set of all Node State TLVs (Section 7.2.3) MAY also be included ๐ธ That's unless the DNCP profile says it's undesirable for some reason, or unless sending them over insecure multicast would expose node state TLVs when unicast is secure ๐ Don't let those node state TLVs leak, bestie! ๐ญ๐ซถ
4.4. Processing of Received TLVs โจ
Okay bestie, this section is where we figure out what a node does with each TLV it receives ๐ . The DNCP profile can say when to ignore certain TLVs, like if they'd mess with security stuff ๐. Check Section 9 for what can safely be ignored in a profile ๐. Any "reply" mentioned below just means sending the TLV(s) back to whoever sent the TLV we're handling ๐. All replies MUST be sent using unicast ๐ฆ. If the TLV we're replying to came in over multicast and was sent to a multiple access link, the reply MUST be delayed by a random time in [0, Imin/2] ๐ซถ. This keeps everyone from replying at the exact same moment and causing chaos on some links ๐ญ, unless the DNCP profile says otherwise ๐ธ. An implementation MAY also rate limit replies or skip them for a little while โจ. BUT, if the profile doesn't forbid the TLV, an implementation MUST still reply to retransmissions with a non-zero probability, or else it could starve and break state synchronization ๐.
A DNCP node MUST process TLVs from any valid (correctly scoped, you know the vibe) address, as the DNCP profile and endpoint configuration say ๐. This is true whether or not the address belongs to a known peer ๐ง. It's super useful for monitoring or other host software that wants to map the DNCP topology without adding anything to the network state ๐.
Upon receipt of:
- Request Network State TLV (Section 7.1.1): The receiver MUST reply with a Network State TLV (Section 7.2.2) and a Node State TLV (Section 7.2.3) for each node data used to calculate the network state hash ๐. The Node State TLVs SHOULD NOT contain the optional node data part to avoid redundant transmission of node data, unless the DNCP profile explicitly specifies otherwise ๐.
- Request Node State TLV (Section 7.1.2): If the receiver has node data for the corresponding node, it MUST reply with a Node State TLV (Section 7.2.3) for that node. The optional node data part MUST be included in the TLV ๐ฅ.
- Network State TLV (Section 7.2.2): If the network state hash differs from the locally calculated one, and the receiver doesn't know about any particular node state differences with the sender, the receiver MUST reply with a Request Network State TLV (Section 7.1.1) ๐. These replies MUST be rate limited to at most one reply per link per unique network state hash within Imin โญ. The simplest way to do this is to keep a timestamp of requests and only send at most one Request Network State TLV (Section 7.1.1) per Imin โฐ. To speed up state synchronization, if a Request Network State TLV is sent in a reply, a local, current Network State TLV MAY also be sent ๐.
- Node State TLV (Section 7.2.3):
- If the node identifier matches the local node identifier and the TLV has a greater sequence number than the current local value, or the same sequence number with a different hash, the node SHOULD republish its own node data with a sequence number significantly greater than the received one (e.g., 1000) to reclaim the node identifier ๐. This gap is needed so it's higher than any lingering copies of the node state floating around the network ๐ซง. This can happen normally once because the local node restarted and didn't store its most recently used sequence number ๐. If it happens more than once, or for nodes that aren't republishing their own node data, the DNCP profile MUST provide guidance on handling it, since it means another active node has the same node identifier ๐จ.
- If the node identifier does NOT match the local node identifier, and one or more of these are true:
- The local information is outdated for the corresponding node (the local sequence number is less than the one in the TLV) ๐ฐ๏ธ.
- The local information is potentially incorrect (the local sequence number matches but the node data hash differs) ๐ค.
- There is no data for that node at all ๐ซฅ.
Then:
- If the TLV contains the Node Data field, it SHOULD also be verified by checking that the locally calculated hash of the node data matches the content of the H(Node Data) field in the TLV ๐. If they differ, the TLV SHOULD be ignored and not processed further ๐ โโ๏ธ.
- If the TLV does NOT contain the Node Data field, and the H(Node Data) field differs from the local node data hash for that node (or there is none), the receiver MUST reply with a Request Node State TLV (Section 7.1.2) for that node ๐.
- Otherwise, the receiver MUST update its locally stored state for that node (node data based on the Node Data field if present, sequence number, and relative time) to match the received TLV ๐.
For comparison purposes of the sequence number, a looping comparison function MUST be used to avoid problems on overflow ๐. The comparison function a < b <=> ((a - b) % (2^32)) & (2^31) != 0, where (a % b) is the remainder of a modulo b and (a & b) is the bitwise conjunction of a and b, is RECOMMENDED unless the DNCP profile defines another one ๐งฎ.
- Any other TLV: TLVs the receiver doesn't recognize MUST be silently ignored, unless they're sent inside another TLV (like TLVs within the Node Data field of a Node State TLV) ๐ซ . Unrecognized TLVs inside the Node Data field of a Node State TLV MUST be retained for distribution to other nodes and for calculating the node data hash as described in Section 7.2.3, but they're ignored for every other purpose ๐ง โจ.
If secure unicast transport is configured for an endpoint, any Node State TLVs received over insecure multicast MUST be silently ignored ๐๐ซถ.
4.5. Discovering, Adding, and Removing Peers ๐ฆ
Okay so peer relations get set up between neighbors using one or more mutually connected endpoints ๐ค. Neighbors swap info about network state and published data directly, and then through transitivity, that info spreads across the whole network ๐โจ. Lowkey iconic.
New peers are found using the regular unicast or multicast transport the DNCP profile defines (Section 9) ๐. Finding a peer and adding a peer are the same thing here ๐. An unknown peer just gets discovered by receiving regular DNCP protocol TLVs from it, and there are no dedicated discovery messages or TLVs at all ๐ โโ๏ธ. For unicast-only transports, each node's transport addresses are either preconfigured or obtained through an external service discovery protocol ๐บ๏ธ. When there's a multicast transport, messages from unknown peers are handled the same way as multicast messages from peers that are already known, so new peers are simply discovered when they send their regular DNCP protocol TLVs over multicast ๐ก.
When receiving a Node Endpoint TLV (Section 7.2.1) on an endpoint from an unknown peer:
- If it's received over unicast, the remote node MUST be added as a peer on the endpoint, and a Peer TLV (Section 7.3.1) MUST be created for it ๐.
- If it's received over multicast, the node MAY be sent a (possibly rate-limited) unicast Request Network State TLV (Section 7.1.1) ๐ซ.
If keep-alives specified in Section 6.1 are NOT sent by the peer (either the DNCP profile doesn't specify keep-alives, or that particular peer chooses not to send them), some other existing local transport-specific means (such as Ethernet carrier detection or TCP keep-alive) MUST be used to make sure it's still there ๐. If the peer doesn't send keep-alives and there's no way to verify its presence, the peer MUST be considered no longer present, and it SHOULD NOT be added back as a peer until it starts sending keep-alives again ๐ข. When the peer is gone, the Peer TLV and the local DNCP peer state MUST be removed ๐งน. DNCP doesn't define an explicit message or TLV for a node announcing it's terminating DNCP operation ๐ช; however, a derived protocol could specify an extension if the need ever comes up ๐.
If the local endpoint is in the Multicast-Listen+Unicast transport mode, a Peer TLV (Section 7.3.1) MUST NOT be published for peers that don't have the highest node identifier ๐๐ โโ๏ธ.
4.6. Data Liveliness Validation ๐ซง
Okay this one is giving main character energy ๐ฌ. Keeping the hash tree (Section 4.1) up to date, and therefore updating the network state hash, depends on having current info about bidirectional node reachability, which comes from a topology graph โจ. That graph changes whenever nodes get added or removed, or when bidirectional connectivity between existing nodes is gained or lost ๐. So the graph MUST be updated either immediately or after a small delay that is shorter than the DNCP profile-defined Trickle Imin, whenever:
- A Peer TLV or a whole node is added or removed, or
- The origination time (in milliseconds) of some node's node data is less than current time - 2^32 + 2^15 โณ.
That artificial upper limit on the origination time is there to gracefully avoid overflows of the origination time, and to let the node republish its data as noted in Section 7.2.3 ๐ธ.
The topology graph update starts with the local node marked as reachable and every other node marked as unreachable ๐. Then other nodes get iteratively marked as reachable using this algorithm: a candidate not-yet-reachable node N with an endpoint NE is marked as reachable if there's a reachable node R with an endpoint RE that meets ALL of these criteria ๐ง:
- The origination time (in milliseconds) of R's node data is greater than current time - 2^32 + 2^15 โฐ.
- R publishes a Peer TLV with:
- Peer Node Identifier = N's node identifier
- Peer Endpoint Identifier = NE's endpoint identifier
- Endpoint Identifier = RE's endpoint identifier
- N publishes a Peer TLV with:
- Peer Node Identifier = R's node identifier
- Peer Endpoint Identifier = RE's endpoint identifier
- Endpoint Identifier = NE's endpoint identifier
The algorithm stops when no more candidate nodes meeting these criteria can be found ๐.
DNCP nodes that haven't been reachable in the most recent topology graph traversal MUST NOT be used for calculating the network state hash, MUST NOT be provided to any applications that need the whole TLV graph, and MUST NOT be provided to remote nodes ๐ซ. They MAY be forgotten right after the topology graph traversal; however, it is RECOMMENDED to keep them at least briefly to speed up DNCP network state convergence ๐. This cuts down on the number of queries needed to reconverge, both during initial network convergence and when part of the network loses and then regains bidirectional connectivity within that time period ๐ซถโจ.
- Data Model ๐
Okay so this section is basically a little tour of the local data structures a minimal implementation might use ๐ง It's only a convenience for the implementor, bestie, not a hard rule ๐ Some of the optional extensions (Section 6) describe extra data requirements, and some optional parts of the core protocol may also require more ๐
A DNCP node has:
- A data structure containing data about the most recently sent Request Network State TLVs (Section 7.1.1). The simplest option is keeping a timestamp of the most recent request (required to fulfill reply rate limiting specified in Section 4.4) โจ
A DNCP node has the following for every DNCP node in the DNCP network:
- Node identifier: the unique identifier of the node. The length, how it is produced, and how collisions are handled is up to the DNCP profile ๐ธ
- Node data: the set of TLV tuples published by that particular node. As they are transmitted in a particular order (see Node State TLV (Section 7.2.3) for details), maintaining the order within the data structure here may be reasonable ๐ฆ
- Latest sequence number: the 32-bit sequence number that is incremented any time the TLV set is published. The comparison function used to compare them is described in Section 4.4 ๐ฅ
- Origination time: the (estimated) time when the current TLV set with the current sequence number was published. It is used to populate the Milliseconds Since Origination field in a Node State TLV (Section 7.2.3). Ideally, it also has millisecond accuracy ๐ซถ
Additionally, a DNCP node has a set of endpoints for which DNCP is configured to be used. For each such endpoint, a node has:
- Endpoint identifier: the 32-bit opaque locally unique value identifying the endpoint within a node. It SHOULD NOT be reused immediately after an endpoint is disabled ๐
- Trickle instance: the endpoint's Trickle instance with parameters I, T, and c (only on an endpoint in Multicast+Unicast transport mode) ๐
and one (or more) of the following:
- Interface: the assigned local network interface ๐
- Unicast address: the DNCP node it should connect with ๐
- Set of addresses: the DNCP nodes from which connections are accepted ๐
For each remote (peer, endpoint) pair detected on a local endpoint, a DNCP node has:
- Node identifier: the unique identifier of the peer ๐ธ
- Endpoint identifier: the unique endpoint identifier used by the peer ๐
- Peer address: the most recently used address of the peer (authenticated and authorized, if security is enabled) ๐โจ
- Trickle instance: the particular peer's Trickle instance with parameters I, T, and c (only on an endpoint in unicast mode, when using an unreliable unicast transport) ๐ฆ
6. Optional Extensions ๐
Okay so this section is all about extensions to the core protocol that a DNCP profile may choose to use ๐ If the profile doesn't pick them, they just don't apply ๐ง
6.1. Keep-Alives ๐
So DNCP already has ways to discover and add new peers on an endpoint (Section 4.5), plus state change notifications โจ But sometimes you still need another way to clear out old peers that aren't valid anymore, especially if the transport or lower layers don't handle it, as noted in Section 4.6 ๐ซถ
If keep-alives are not specified in the DNCP profile, the rest of this subsection MUST be ignored ๐
A DNCP profile MAY specify either per-endpoint keep-alive support (sent using multicast to all DNCP nodes connected to a multicast-enabled link) or per-peer keep-alive support (sent using unicast to each peer individually) ๐
For every endpoint that a keep-alive is specified for in the DNCP profile, the endpoint-specific keep-alive interval MUST be maintained ๐ By default, it is DNCP_KEEPALIVE_INTERVAL ๐ If there's a local value that is preferred for any reason (configuration, energy conservation, media type, ...), it can be substituted instead ๐ธ If a non-default keep-alive interval is used on any endpoint, a DNCP node MUST publish an appropriate Keep-Alive Interval TLV(s) (Section 7.3.2) within its node data ๐
6.1.1. Data Model Additions ๐ง
These are the extra data model bits needed to support keep-alives ๐
For each configured endpoint that has per-endpoint keep-alives enabled:
- Last sent: If a timestamp that indicates the last time a Network State TLV (Section 7.2.2) was sent over that interface ๐ฆ
For each remote (peer, endpoint) pair detected on a local endpoint, a DNCP node has:
- Last contact timestamp: A timestamp that indicates the last time a consistent Network State TLV (Section 7.2.2) was received from the peer over multicast or when anything was received over unicast. Failing to update it for a certain amount of time as specified in Section 6.1.5 results in the removal of the peer. When adding a new peer, it is initialized to the current time โฐ๐
- Last sent: If per-peer keep-alives are enabled, a timestamp that indicates the last time a Network State TLV (Section 7.2.2) was sent to that point-to-point peer. When adding a new peer, it is initialized to the current time ๐ท
6.1.2. Per-Endpoint Periodic Keep-Alives ๐ฅ
If per-endpoint keep-alives are enabled on an endpoint in Multicast+Unicast transport mode, and if no traffic containing a Network State TLV (Section 7.2.2) has been sent to a particular endpoint within the endpoint-specific keep-alive interval, a Network State TLV (Section 7.2.2) MUST be sent on that endpoint, and a new Trickle interval started, as specified in step 2 of Section 4.2 of [RFC6206]. The actual sending time SHOULD be further delayed by a random time span in [0, Imin/2] ๐ซถ
6.1.3. Per-Peer Periodic Keep-Alives ๐ธ
If per-peer keep-alives are enabled on a unicast-only endpoint, and if no traffic containing a Network State TLV (Section 7.2.2) has been sent to a particular peer within the endpoint-specific keep-alive interval, a Network State TLV (Section 7.2.2) MUST be sent to the peer, and a new Trickle interval started, as specified in step 2 of Section 4.2 of [RFC6206] ๐ฆ
6.1.4. Received TLV Processing Additions ๐
If a TLV is received over unicast from the peer, the Last contact timestamp for the peer MUST be updated ๐
On receipt of a Network State TLV (Section 7.2.2) that is consistent with the locally calculated network state hash, the Last contact timestamp for the peer MUST be updated in order to maintain it as a peer ๐
6.1.5. Peer Removal ๐
For every peer on every endpoint, the endpoint-specific keep-alive interval must be calculated by looking for Keep-Alive Interval TLVs (Section 7.3.2) published by the node, and if none exist, use the default value of DNCP_KEEPALIVE_INTERVAL ๐ง If the peer's Last contact timestamp has not been updated for at least a locally chosen potentially endpoint-specific keep-alive multiplier (defaults to DNCP_KEEPALIVE_MULTIPLIER) times the peer's endpoint-specific keep-alive interval, the Peer TLV for that peer and the local DNCP peer state MUST be removed ๐ญ
6.2. Support for Dense Multicast-Enabled Links ๐
This optimization is needed to avoid a state space explosion ๐ Given a large set of DNCP nodes publishing data on an endpoint that uses multicast on a link, every node will add a Peer TLV (Section 7.3.1) for each peer ๐ While Trickle limits the amount of traffic on the link in stable state to some extent, the total amount of data that is added to and maintained in the DNCP network given N nodes on a multicast-enabled link is O(N^2) ๐ฑ Additionally, if per-peer keep-alives are used, there will be O(N^2) keep-alives running on the link if the liveliness of peers is not ensured using some other way (e.g., TCP connection lifetime, Layer 2 notification, or per-endpoint keep-alive) ๐
An upper bound for the number of peers that are allowed for a particular type of link that an endpoint in Multicast+Unicast transport mode is used on SHOULD be provided by a DNCP profile, but it MAY also be chosen at runtime ๐ The main consideration when selecting a bound (if any) for a particular type of link should be whether it supports multicast traffic and whether a too large number of peers case is likely to happen during the use of that DNCP profile on that particular type of link ๐ซถ If neither is likely, there is little point specifying support for this for that particular link type ๐คทโโ๏ธ
If a DNCP profile does not support this extension at all, the rest of this subsection MUST be ignored ๐ This is because when this extension is used, the state within the DNCP network only contains a subset of the full topology of the network ๐ง Therefore, every node must be aware of the potential of it being used in a particular DNCP profile ๐
If the specified upper bound is exceeded for some endpoint in Multicast+Unicast transport mode and if the node does not have the highest node identifier on the link, it SHOULD treat the endpoint as a unicast endpoint connected to the node that has the highest node identifier detected on the link, therefore transitioning to Multicast-listen+Unicast transport mode ๐ฆ See Section 4.2 for implications on the specific endpoint behavior ๐ธ The nodes in Multicast-listen+Unicast transport mode MUST keep listening to multicast traffic to both receive messages from the node(s) still in Multicast+Unicast mode and react to nodes with a greater node identifier appearing ๐ If the highest node identifier present on the link changes, the remote unicast address of the endpoints in Multicast-Listen+Unicast transport mode MUST be changed ๐ If the node identifier of the local node is the highest one, the node MUST switch back to, or stay in, Multicast+Unicast mode and form peer relationships with all peers as specified in Section 4.5 ๐
7. Type-Length-Value Objects โจ
okay so TLVs are literally the building blocks of everything here ๐งฑ every piece of info is wrapped in a little Type + Length + Value box, and it's giving tidy ๐
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Value (if any) (+padding (if any)) |
..
| (variable # of bytes) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| (optional nested TLVs) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Each TLV is encoded as:
- a 2-byte Type field
- a 2-byte Length field, which holds the length of the Value field in bytes; 0 means no value ๐ธ
- the value itself (if any)
- padding bytes with a value of zero up to the next 4-byte boundary if the Length is not divisible by 4
Okay, the padding bit is lowkey important ๐ While padding bytes MUST NOT be included in the number stored in the Length field of the TLV, if the TLV is enclosed within another TLV, then the padding is included in the enclosing TLV's Length value. So the outer box counts the padding, but the inner one doesn't. Not me getting confused by this ๐
Each TLV that does not define optional fields or variable-length content MAY be sent with additional sub-TLVs appended after the TLV, so it can grow over time ๐ฆ When handling such TLV types, each node MUST accept received TLVs that are longer than the fixed fields specified for the particular type, and ignore the sub-TLVs with either unknown types or types not supported within that particular TLV. If any sub-TLVs are present, the Length field of the TLV describes the number of bytes from the first byte of the TLV's own Value (if any) to the last (padding) byte of the last sub-TLV.
Here's a cute example ๐ง a type=123 (0x7b) TLV with value 'x' (120 = 0x78) is encoded as 007B 0001 7800 0000. If it also had a sub-TLV of type=124 (0x7c) with value 'y', it would be encoded as 007B 000C 7800 0000 007C 0001 7900 0000. Iconic, right? ๐
In this section, the following special notation is used:
..= octet string concatenation operation.H(x)= non-cryptographic hash function specified by the DNCP profile.
In addition to the TLV types defined in this document, TLV Types 11-31 and 512-767 are unassigned and may be sequentially registered, starting at 11, by Standards Action [RFC5226] by extensions to DNCP that may be applicable in multiple DNCP profiles. ๐
7.1. Request TLVs
7.1.1. Request Network State TLV
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Type: Request network state (1)| Length: >= 0 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
This TLV is used to ask for a response with a Network State TLV (Section 7.2.2) and all Node State TLVs (Section 7.2.3) (without node data). Basically "send me the overview, bestie" ๐ฌ
7.1.2. Request Node State TLV
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type: Request node state (2) | Length: > 0 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Node Identifier |
| (length fixed in DNCP profile) |
...
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
This TLV is used to request a Node State TLV (Section 7.2.3) (including node data) for the node with the matching node identifier. The full tea, not the summary โ
7.2. Data TLVs
7.2.1. Node Endpoint TLV
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type: Node endpoint (3) | Length: > 4 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Node Identifier |
| (length fixed in DNCP profile) |
...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Endpoint Identifier |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
This TLV identifies both the local node's node identifier and the particular endpoint's endpoint identifier, so it's a whole two-part vibe ๐ซถ Section 4.2 specifies when it is sent.
7.2.2. Network State TLV
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type: Network state (4) | Length: > 0 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| H(sequence number of node 1 .. H(node data of node 1) .. |
| .. sequence number of node N .. H(node data of node N)) |
| (length fixed in DNCP profile) |
...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
This TLV contains the current network state hash calculated by its sender, like a vibe check for the whole network โจ (Section 4.1 describes the algorithm).
7.2.3. Node State TLV
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type: Node state (5) | Length: > 8 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Node Identifier |
| (length fixed in DNCP profile) |
...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Milliseconds Since Origination |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| H(Node Data) |
| (length fixed in DNCP profile) |
...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| (optionally) Node Data (a set of nested TLVs) |
...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
This TLV represents the local node's knowledge about the published state of a node in the DNCP network, identified by the Node Identifier field in the TLV. It's the full gossip, spilled โ
Every node, including the node publishing the node data, MUST update the Milliseconds Since Origination whenever it sends a Node State TLV, based on when the node estimates the data was originally published. This is, e.g., to ensure that any relative timestamps contained within the published node data can be correctly offset and interpreted. Ultimately, what is provided is just an approximation, as transmission delays are not accounted for. โฑ๏ธ
Absent any changes, if the originating node notices that the 32-bit Milliseconds Since Origination value would be close to overflow (greater than 2^32 - 2^16), the node MUST republish its TLVs even if there is no change. In other words, absent any other changes, the TLV set MUST be republished roughly every 48 days. the clock is ticking, bestie ๐ฐ๏ธ
The actual node data of the node may be included within the TLV as well as in the optional Node Data field. The set of TLVs MUST be strictly ordered based on ascending binary content (including TLV type and length). This enables, e.g., efficient state delta processing and no-copy indexing by TLV type by the recipient, which is so organised ๐ The node data content MUST be passed along exactly as it was received. It SHOULD be also verified on receipt that the locally calculated H(Node Data) matches the content of the field within the TLV, and if the hash differs, the TLV SHOULD be ignored. ๐
7.3. Data TLVs within Node State TLV
These TLVs are published by the DNCP nodes and are therefore only encoded in the Node Data field of Node State TLVs. If encountered outside Node State TLV, they MUST be silently ignored. Not invited to the party, so they just quietly leave ๐
7.3.1. Peer TLV
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type: Peer (8) | Length: > 8 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Peer Node Identifier |
| (length fixed in DNCP profile) |
...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Peer Endpoint Identifier |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| (Local) Endpoint Identifier |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
This TLV indicates that the node in question vouches that the specified peer is reachable by it on the specified local endpoint. The presence of this TLV at least guarantees that the node publishing it has received traffic from the peer recently. For guaranteed up-to-date bidirectional reachability, the existence of both nodes' matching Peer TLVs needs to be checked. It's a mutual follow situation, honestly ๐ฆ
7.3.2. Keep-Alive Interval TLV
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type: Keep-alive interval (9) | Length: >= 8 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Endpoint Identifier |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Interval |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
This TLV indicates a non-default interval being used to send keep-alives, as specified in Section 6.1. ๐
Endpoint identifier is used to identify the particular (local) endpoint for which the interval applies on the sending node. If 0, it applies for ALL endpoints for which no specific TLV exists. Main character energy for the default ๐
Interval specifies the interval in milliseconds at which the node sends keep-alives. A value of zero means no keep-alives are sent at all; in that case, some lower-layer mechanism that ensures the presence of nodes MUST be available and used. So no keep-alives doesn't mean no checking, it just means something else has to do the job ๐ซ
8. Security and Trust Management ๐
If specified in the DNCP profile, either DTLS [RFC6347] or TLS [RFC5246] may be used to authenticate and encrypt either some (if specified optional in the profile) or all unicast traffic. The following methods for establishing trust are defined, but it is up to the DNCP profile to specify which ones may, should, or must be supported. Security is serious, so the profile gets the final say ๐
8.1. Trust Method Based on Pre-Shared Key
A trust model based on Pre-Shared Key (PSK) is a simple security management mechanism that allows an administrator to deploy devices to an existing network by configuring them with a predefined key, similar to the configuration of an administrator password or Wi-Fi Protected Access (WPA) key. Although limited in nature, it is useful to provide a user-friendly security mechanism for smaller networks. A lil key, a lil trust, and everybody gets in ๐๏ธโจ
8.2. PKI-Based Trust Method ๐
Okay so a PKI-based trust model is a bit more work to set up, ngl, because you need a bootstrapping process first ๐ฉ. But the payoff is huge: trust gets managed from one central place, so it's the move for bigger networks that need an authoritative say over who's trusted ๐ โจ.
8.3. Certificate-Based Trust Consensus Method ๐ชช
Sometimes the methods above don't hit the sweet spot between security and user experience, like when you're bootstrapping a network that's mostly unmanaged ๐. This section gives you guidance for building an opportunistic security method [RFC7435] that DNCP profiles can build on and tweak for their own needs ๐ธ.
The certificate-based consensus model is all about balance: less trust-management effort, more flexibility ๐ฆ. It runs on X.509 certificates, and every DNCP node can share a trust verdict on any other certificate. Then the network reaches a consensus on whether a node using that certificate, or any certificate signed by it, is trusted ๐ซถ.
A DNCP node that isn't using this security method MUST ignore all announced trust verdicts and MUST NOT announce any such verdicts by itself. In other words, any other normative language in this subsection doesn't apply to it ๐ โโ๏ธ.
The current effective trust verdict for any certificate is the one with the highest priority out of all the trust verdicts announced for that certificate at that moment ๐.
8.3.1. Trust Verdicts
Trust verdicts are basically DNCP nodes spilling the tea on how trustworthy an X.509 certificate is ๐. There are 5 possible verdicts, listed here in ascending priority:
- 0 (Neutral): no trust verdict exists yet, but the DNCP network should work out one.
- 1 (Cached Trust): the last known effective trust verdict was Configured or Cached Trust.
- 2 (Cached Distrust): the last known effective trust verdict was Configured or Cached Distrust.
- 3 (Configured Trust): trustworthy based on an external ceremony or configuration.
- 4 (Configured Distrust): not trustworthy based on an external ceremony or configuration.
Trust verdicts fall into 3 groups, and each one has its own vibe ๐:
- Configured verdicts announce the explicit trust verdicts a node has, based on any external trust bootstrap or predefined relationships it has with a given certificate ๐.
- Cached verdicts hold on to the last known trust state, just in case every node with configured verdicts about a given certificate has been disconnected or turned off ๐พ.
- The Neutral verdict is for a brand new node that wants to join the network, so a final verdict can be figured out for it ๐ง.
The current effective trust verdict for any certificate is the one with the highest priority within the set of trust verdicts announced for that certificate in the DNCP network. A node MUST be trusted for participating in the DNCP network if and only if the current effective trust verdict for its own certificate, or for any certificate in its certificate hierarchy, is (Cached or Configured) Trust, and none of the certificates in its hierarchy have an effective trust verdict of (Cached or Configured) Distrust ๐ฅ. If a node has a configured verdict that's different from the current effective trust verdict for a certificate, the current effective trust verdict wins when deciding trustworthiness ๐ . Even so, the node still keeps and announces its configured verdict ๐ซถ.
8.3.2. Trust Cache
Every node SHOULD keep a trust cache with the current effective trust verdicts for all certificates currently announced in the DNCP network ๐๏ธ. The cache is your backup plan for the last known state, for when no node is announcing a configured verdict for a known certificate ๐. It SHOULD also be saved to non-volatile memory at reasonable time intervals, so it survives a reboot or power outage ๐.
Whenever a node (re)joins the network, or notices that the effective trust verdict for any certificate has changed, it syncs its cache. That means it stores the new effective trust verdicts and overwrites any old cached ones โจ. Configured verdicts get stored in the cache as their matching cached counterparts ๐. Neutral verdicts are never stored, and they never override existing cached verdicts ๐ โโ๏ธ.
8.3.3. Announcement of Verdicts
A node SHOULD always announce any configured verdicts it has set up by itself. It MUST announce them if doing so changes the current effective trust verdict for the matching certificate ๐ฃ. If there are no configured verdicts, the node MUST announce the Cached Trust verdicts it has stored in its trust cache when either of these is true ๐:
- The stored trust verdict is Cached Trust, and the current effective trust verdict for the certificate is Neutral or doesn't exist.
- The stored trust verdict is Cached Distrust, and the current effective trust verdict for the certificate is Cached Trust.
A node rechecks these conditions every time it notices announced trust verdicts changing anywhere in the network ๐.
When a node runs into another node with a certificate hierarchy that has no effective trust verdict, it adds a Neutral Trust-Verdict TLV to its node data for every certificate in that hierarchy ๐งฉ. It keeps publishing it until an effective trust verdict other than Neutral shows up for any of those certificates, or until a reasonable amount of time has passed with no reaction and no further authentication attempts (10 minutes is suggested) โณ. These trust verdicts SHOULD also be limited in rate and number, so nobody can pull off a denial-of-service attack ๐ก๏ธ.
Trust verdicts are announced using Trust-Verdict TLVs ๐:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type: Trust-Verdict (10) | Length: > 36 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Verdict | (reserved) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| |
| |
| SHA-256 Fingerprint |
| |
| |
| |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Common Name |
- Verdict represents the numerical index of the trust verdict ๐ข.
- (reserved) is reserved for future additions. It MUST be set to 0 when creating TLVs and ignored when parsing them ๐ซ.
- SHA-256 Fingerprint contains the SHA-256 [RFC6234] hash value of the certificate in DER format ๐.
- Common Name contains the variable-length (1-64 bytes) common name of the certificate ๐ท๏ธ.
8.3.4. Bootstrap Ceremonies
The list below isn't exhaustive, but it covers some of the ways to set up trust between DNCP nodes and node certificates ๐ค. Trust establishment goes both ways. The existing network has to trust the new node, and the new node has to trust at least one of its peers. So both the new node and an already trusted node have to do a ceremony to bring a node into the DNCP network ๐. In every case, an administrator MUST be given external means to identify the node that belongs to a certificate, based on its fingerprint and a meaningful common name ๐ต๏ธโโ๏ธ.
8.3.4.1. Trust by Identification
A node doing certificate-based trust MUST provide an interface that can retrieve the current set of effective trust verdicts, fingerprints, and names of all known certificates, and that can set configured verdicts to be announced ๐. As an alternative, it MAY hand these capabilities to a companion DNCP node or application it already has a pre-established trust relationship with ๐ค.
8.3.4.2. Preconfigured Trust
A node MAY be preconfigured to trust a certain set of node or CA certificates ๐. But those trust relationships MUST NOT spill over into unwanted or unrelated trust for nodes that aren't meant to run inside the same network (for example, all the other devices from the same manufacturer) ๐ โโ๏ธ๐.
8.3.4.3. Trust on Button Press
A node MAY offer a physical or virtual interface that temporarily puts one or more of its internal network interfaces into a mode where it trusts the certificate of the first DNCP node it can successfully connect with ๐โจ.
8.3.4.4. Trust on First Use
A node that isn't associated with any other DNCP node MAY trust the certificate of the first DNCP node it can successfully establish a connection with ๐ฅน. This method MUST NOT be used once the node has already associated with any other DNCP node ๐ซ๐ .
9. DNCP Profile-Specific Definitions โจ
Okay bestie, every DNCP profile MUST spell out the following things, no skipping ๐
- Transport ๐: It needs unicast and, optionally, multicast transport protocol(s). If you want multicast-based node and status discovery, a datagram-based transport that supports multicast has to be available.
- Security ๐: The profile says how the transport is secured. The options are not at all, optionally, always with the TLS scheme defined here using one or more of the methods, or something else. If the links between DNCP nodes are secure or isolated enough, you can run DNCP securely without any authentication or encryption. Lowkey genius.
- Transport parameters ๐ข: This covers things like port numbers and multicast addresses. Unicast, multicast, and secure unicast might each need their own parameters, if that applies.
- Ignoring TLVs ๐: Here the profile says which TLVs get ignored on top of the ones in Section 4.4, for example for security reasons. The base spec already keeps node data inside Node State TLVs safe. If secure unicast is used, Node State TLVs are only sent over unicast, because multicast ones get ignored on receipt. But if a profile adds TLVs that live outside the node data, it should say whether those get ignored when they come in over multicast or non-secured unicast. A DNCP profile may define these DNCP TLVs as safe to ignore:
- Anything received over multicast, except the Node Endpoint TLV (Section 7.2.1) and the Network State TLV (Section 7.2.2).
- Any TLVs received over unreliable unicast or multicast at a rate that is too high. Trickle will still get everyone to eventual convergence, as long as the rate slows down at some point. ๐
- Node identifier collisions ๐ฅ: The profile needs to say how to handle a node identifier collision, as described in Section 4.4. The main options are for one or both nodes to give themselves new node identifiers, or to notify someone about a fatal error condition in the DNCP network.
- Trickle ranges ๐ข: The profile suggests Imin, Imax, and k ranges for implementations to use in the Trickle algorithm. Trickle doesn't need every implementation to use the same values to work. But values in similar orders of magnitude help implementations of a DNCP profile behave more consistently, and make it easier to estimate the lower and upper bounds for how long convergence takes. Main character energy for sure.
- Hash function ๐งฎ: The profile says which hash function H(x) to use and how many bits of its output actually get used. The chosen hash function handles both hashing node data and producing the network state hash, which is a hash of the node data hashes. SHA-256, defined in [RFC6234], is the recommended default choice, but a non-cryptographic hash function could be used too. โ ๏ธ If the network state hash has a collision, the network gets split into partitions that think they're up to date when they actually aren't converged anymore. The network only converges again when some node data somewhere in the network changes, or when conflicting Node State TLVs get sent across the partition. That can happen either through "Trickle-Driven Status Updates" (Section 4.3) or as part of "Processing of Received TLVs" (Section 4.4). Also, if a node publishes node data with a hash that collides with any node data published before, the update may not be fully propagated, and the old version of the node data might get used instead. ๐ญ
- DNCP_NODE_IDENTIFIER_LENGTH ๐: This is the fixed length of a node identifier, in bytes.
- Keep-alives ๐: The profile says whether to send keep-alives, and if so, whether they're per-endpoint (which requires multicast transport) or per-peer. Keep-alives have their own parameters too:
- DNCP_KEEPALIVE_INTERVAL: how often keep-alives get sent by default, if they're turned on.
- DNCP_KEEPALIVE_MULTIPLIER: how many DNCP_KEEPALIVE_INTERVAL periods (or the keep-alive interval value supplied by the peer) a node can go unheard from and still count as valid. This is just a default, used when there's no other configuration info or per-endpoint configuration.
- Dense multicast optimization ๐: The profile says whether to support the dense multicast-enabled link optimization (Section 6.2) or not.
For some guidance on picking transport and security options, check out Appendix B. ๐
10. Security Considerations ๐จ
Okay, this section is serious, so let's get into it ๐ซฃ
DNCP-based protocols may use multicast to signal DNCP state changes and for keep-alive purposes. However, no actual published data TLVs get sent across that channel. So an attacker can only learn hash values of the state within DNCP, and may be able to trigger unicast synchronization attempts between nodes on a local link this way. A DNCP node MUST therefore rate limit its reactions to multicast packets. Non-negotiable, bestie. ๐
When you use DNCP to bootstrap a network, PKI-based solutions can run into problems when validating certificates. That's because accurate time might not be available, or because the network can't be used to check Certificate Revocation Lists or to do online validation. ๐ฐ๏ธ
The Certificate-based trust consensus mechanism defined in this document allows for a consenting revocation. But if a device gets compromised, the trust cache could be poisoned before the actual revocation happens. That would let the distrusted device rejoin the network under a different identity. ๐ฑ Stopping an attack like this might require physical intervention and flushing the trust caches. Scary, but true.
11. IANA Considerations ๐งพ
IANA has set up a registry for the (decimal 16-bit) "DNCP TLV Types" under "Distributed Node Consensus Protocol (DNCP)". The registration procedure is Standards Action [RFC5226]. The initial contents are:
0: Reserved
1: Request network state
2: Request node state
3: Node endpoint
4: Network state
5: Node state
6: Reserved for future use (was: Custom)
7: Reserved for future use (was: Fragment count)
8: Peer
9: Keep-alive interval
10: Trust-Verdict
11-31: Unassigned
32-511: Reserved for per-DNCP profile use
512-767: Unassigned
768-1023: Reserved for Private Use [RFC5226]
1024-65535: Reserved for future use
12. References ๐
12.1. Normative References ๐ช
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997,
<http://www.rfc-editor.org/info/rfc2119>. - [RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 5226, DOI 10.17487/RFC5226, May 2008,
<http://www.rfc-editor.org/info/rfc5226>. - [RFC6206] Levis, P., Clausen, T., Hui, J., Gnawali, O., and J. Ko, "The Trickle Algorithm", RFC 6206, DOI 10.17487/RFC6206, March 2011,
<http://www.rfc-editor.org/info/rfc6206>. - [RFC6234] Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)", RFC 6234, DOI 10.17487/RFC6234, May 2011,
<http://www.rfc-editor.org/info/rfc6234>.
12.2. Informative References ๐ง
- [RFC3315] Droms, R., Ed., Bound, J., Volz, B., Lemon, T., Perkins, C., and M. Carney, "Dynamic Host Configuration Protocol for IPv6 (DHCPv6)", RFC 3315, DOI 10.17487/RFC3315, July 2003,
<http://www.rfc-editor.org/info/rfc3315>. - [RFC3493] Gilligan, R., Thomson, S., Bound, J., McCann, J., and W. Stevens, "Basic Socket Interface Extensions for IPv6", RFC 3493, DOI 10.17487/RFC3493, February 2003,
<http://www.rfc-editor.org/info/rfc3493>. - [RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security (TLS) Protocol Version 1.2", RFC 5246, DOI 10.17487/RFC5246, August 2008,
<http://www.rfc-editor.org/info/rfc5246>. - [RFC6347] Rescorla, E. and N. Modadugu, "Datagram Transport Layer Security Version 1.2", RFC 6347, DOI 10.17487/RFC6347, January 2012,
<http://www.rfc-editor.org/info/rfc6347>. - [RFC7435] Dukhovni, V., "Opportunistic Security: Some Protection Most of the Time", RFC 7435, DOI 10.17487/RFC7435, December 2014,
<http://www.rfc-editor.org/info/rfc7435>. - [RFC7596] Cui, Y., Sun, Q., Boucadair, M., Tsou, T., Lee, Y., and I. Farrer, "Lightweight 4over6: An Extension to the Dual-Stack Lite Architecture", RFC 7596, DOI 10.17487/RFC7596, July 2015,
<http://www.rfc-editor.org/info/rfc7596>.
Appendix A. Alternative Modes of Operation ๐ฆ
Beyond what's in the main text, the protocol allows for other uses too. These are just examples. ๐ธ
A.1. Read-Only Operation ๐
If a node uses just a single endpoint and doesn't need to publish any TLVs, it doesn't need full DNCP node functionality. A limited node like this can get and keep a view of the TLV space by implementing the processing logic in Section 4.4. Such a node wouldn't need Trickle, peer maintenance, or even keep-alives at all. The DNCP nodes' use of those already guarantees that it eventually receives network state hashes and synchronizes node data, even when the transport is unreliable. Lowkey clever. ๐ง โจ
A.2. Forwarding Operation ๐ฌ
If a node with a pair of endpoints doesn't need to publish any TLVs, it can detect (for example) the nodes with the highest node identifier on each of the endpoints, if there are any. Any TLVs received from one of them get forwarded verbatim as unicast to the other node with the highest node identifier. ๐
Tinkering with the TLVs would remove the guarantees this scheme depends on. Passive monitoring, though, would obviously be fine ๐. This kind of simple forwarding can't be chained, because it doesn't send anything proactively. ๐ โโ๏ธ
Appendix B. DNCP Profile Additional Guidance ๐
This appendix explains what the design choices behind a DNCP profile mean for particular transport or security options. Read it before you pick your transport and security setup, it's giving very helpful energy ๐
B.1. Unicast Transport -- UDP or TCP? ๐
okay so the node data a DNCP node publishes is capped at 64 KB ๐ because the length field of the TLV it sits in is only 16 bits. Some transport choices can make that limit even smaller. If you use UDP datagrams for unicast, the upper bound is whatever the nodes and the underlying network can pass between each other, because DNCP doesn't define its own fragmentation scheme ๐. So a profile that picks UDP has to either keep node data small (for example, a bit under the IPv6 default MTU if you're on IPv6) or specify a minimum that every node has to support. Even then, if you're doing non-link-local communication, you have to think about what middleboxes do to fragmented packets ๐ญ. That's why a stream transport like TCP is probably the move if you want non-link-local communication or if fragmentation is likely to cause problems ๐ซถ.
TCP comes with some extra perks too โจ. It has a relatively long built-in keep-alive, and combined with connections closing after eventual failed retransmissions, that might be enough that you don't need the in-protocol keep-alive from Section 6.1 ๐ฆ. It's also reliable, so you don't need Trickle on those unicast connections. Iconic ๐ .
The big catch with TCP instead of UDP for DNCP-based profiles is that you lose control over when TLVs get received ๐ฉ. UDP datagrams have some delay too, but TLVs sent over a reliable stream can get held up for a long time because of retransmissions. This isn't a problem if no relative, time-dependent information is stored in the TLVs of your DNCP-based protocol. For a protocol like that, TCP is a totally reasonable choice for unicast transport whenever it's available ๐ธ.
B.2. (Optional) Multicast Transport ๐ก
Multicast is needed for dynamic peer discovery and for triggering unicast exchanges ๐ง. For that job, unreliable datagram transport (=typically UDP) is the only transport option defined in this specification. DNCP-based protocols are allowed to define their own transport or peer discovery mechanism though, for example one based on Multicast DNS (mDNS) or DNS ๐.
If you do use multicast, you should specify a well-known address, plus the desired address scopes (for IPv6, for example) ๐. In most cases, link-local and possibly site-local are the useful scopes โจ.
B.3. (Optional) Transport Security ๐
In terms of security, DTLS and TLS are equivalent, and they use a similar amount of state on devices ๐. TLS sits on top of a stream protocol, but DTLS needs relatively long session caching inside the DTLS layer. Without it, you'd keep paying for expensive reauthentication and reauthorization whenever any state in the DNCP network changes, or whenever a per-peer keep-alive gets sent (if you've enabled one) ๐ฉ.
TLS implementations seem more mature and more widely available as open source than DTLS ones, at least at the time of writing ๐. This may be because TLS has a long history of use with HTTPS, which is very real ๐.
Some libraries don't seem to support multiplexing insecure and secure communication on the same port ๐. So giving secured and unsecured communication distinct ports may be beneficial ๐.
Appendix C. Example Profile ๐งช
This is the DNCP profile of SHSP, an experimental (and, for the purposes of this document, fictional) home automation protocol ๐ โจ. The protocol is used to make a key-value store, published by each node, available to all the other nodes. That lets everyone do distributed monitoring and control of a home infrastructure, which is giving smart home energy ๐ซถ. It defines only one additional TLV type: a key=value TLV containing a single key=value assignment for publication ๐.
- Unicast transport: IPv6 TCP on port
EXAMPLE-P1. Only absolute timestamps are used within the key=value data, and the protocol mainly focuses on Linux-based nodes, which support both protocols as well ๐ง. Connections from and to non-link-local addresses are ignored, so this protocol doesn't get exposed outside the secure links ๐. - Multicast transport: IPv6 UDP on port
EXAMPLE-P2, to the link-local scoped multicast addressff02:EXAMPLE. At least one node per link in the home is assumed to facilitate node discovery, without depending on any other infrastructure ๐ฆ. - Security: None. It is to be used only on trusted links (WPA2-x wireless, physically secure wired links) ๐ก๏ธ. Not gonna lie, this one is a little scary, so only use it on links you trust ๐ฌ.
- Additional TLVs to be ignored: None. No DNCP security is specified, and no new TLVs are defined outside of node data ๐ธ.
- Node identifier length (
DNCP_NODE_IDENTIFIER_LENGTH): 32 bits that are randomly generated ๐ฒ. - Node identifier collision handling: Pick a new random node identifier ๐.
- Trickle parameters:
Imin = 200 ms,Imax = 7,k = 1. This means at least one multicast per link in 25 seconds in stable state (0.2 * 2^7) โฑ๏ธโจ. - Hash function
H(x)+ length: SHA-256, with only 128 bits used. It's relatively fast, and 128 bits should be plenty to prevent random conflicts (64 bits would most likely be sufficient, too) ๐ . - No in-protocol keep-alives (Section 6.1): TCP keep-alive is to be used. In practice, TCP keep-alive is seldom encountered anyway, because changes in network state cause packets to be sent on the unicast connections, and connections that fail enough retransmissions get dropped long before the keep-alive would actually fire ๐.
- No support for dense multicast-enabled link optimization (Section 6.2): SHSP is a simple protocol for a few nodes (network-wide, not even to mention on a single link), so this optimization wouldn't provide any benefit ๐.
Acknowledgements ๐ซถ
Thanks to Ole Troan, Pierre Pfister, Mark Baugher, Mark Townsley, Juliusz Chroboczek, Jiazi Yi, Mikael Abrahamsson, Brian Carpenter, Thomas Clausen, DENG Hui, and Margaret Cullen for their contributions to the document ๐ท.
Thanks to Kaiwen Jin and Xavier Bonnetain for their related research work ๐ฌโจ.
Authors' Addresses ๐
Markus Stenberg
Independent
Helsinki 00930
Finland
Email: `markus.stenberg@iki.fi`
Steven Barth
Independent
Halle 06114
Germany
Email: `cyrus@openwrt.org`
That's the whole doc, bestie! ๐๐ Thank you for reading the entire thing with me ๐ฆ๐
๐ฆ where this page comes from
- ietf: rfc7787 2016-04
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms