Internet-Draft | Group Address Allocation Protocol (GAAP) | February 2023 |
Farinacci & McBride | Expires 24 August 2023 | [Page] |
This document describes a design for a lightweight decentralized multicast group address allocation protocol (named GAAP and pronounced "gap" as in "mind the gap"). The protocol requires no configuration setup and no centralized services. The protocol runs among group participants which need a unique group address to send and receive multicast packets.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 24 August 2023.¶
Copyright (c) 2023 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 (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
The Group Address Allocation Protocol (GAAP) is a decentralized multicast protocol used by participating applications which send and receive packets to/from a multicast group. The protocol is relatively lightweight, runs with minimized messaging and state so that it can run within a library a multicast application compiles into its executable binary.¶
Other approaches to multicast group allocation have been proposed in the past, they include mDNS [RFC6762], MADCAP [RFC2730], MASC [RFC2909], and IPv6 Allocation Guidelines [RFC3307]. However, they require configuration, used on a single subnet, and are not decentralized.¶
This document will describe the protocol operation, protocol message formats, the API definition, and how multicast applications use the API.¶
This section will describe the high-level functionality of the GAAP protocol. Each application runs the GAAP protocol by using the API defined in Section 5.¶
At this time, there is a single message called the Claim message with type value 1. Type value of 0 is reserved. The Claim message is sent in a UDP checksummed packet where the source port is ephemeral and chosen by the sender and the destination port is a well-known port allocated by IANA. GAAP can work behind NAT and firewall devices as long as the GAAP destination port is permitted through filters.¶
The GAAP API has the following API calls a multicast application will use. A multicast application imports the library before using it in its code logic. This section documents a python library.¶
gapp.init() is used to initialize the GAAP API with a application callback function. The callback function is called when a group address has changed (due to collision) for a group name the application allocated.¶
import gapp status = gapp.init(app_callback_func) if (status == False): print("error") exit(1) #endif def app_callback_func(group_name, group_address) print("Group name {} changed to group address {}". \ format((group_name, group_address)) #enddef¶
gaap.allocate() is used when the application needs a group address to send or receive on.¶
import gapp group_name = "my-audio-group" group_address = gapp.allocate(group_name) if (group_address == None): print("error") exit(1) #endif print("Name {} allocated address {}".format(group_name, group_address))¶
gaap.release() is used when an application is finished using a group address.¶
import gapp group_address = gapp.allocate("my-audio-group") status = gapp.release(group_address) if (status == False): print("error") exit(1) #endif print("Released address {}".format(group_address))¶
gaap.close() is used when an application is finished using the GAAP protocol.¶
import gapp # # Initialize the GAAP API with no callback function. Return if errored. # if (gapp.init() == False): print("error") exit(1) #endif # # Do multicast work by allocating, sending, and receiving group addresses. # ... # # Application shutting down. No longer need to run GAAP on local node. # gaap.close()¶
When an application needs a group address it provides the GAAP API with a group name, the group name is used as input to a SHA-256 hash function [RFC6234]. Initially, when no group address collision is detected the group name is passed as a string to the hash function and the low-order 32-bits are used for a group address. The following pseudo-code illustrates the functionality:¶
hash = sha256(group_name) low_bits = hash & 0xffffffff if (v4): group_address = 0xe0000000 | (low_bits & 0x007fffff) #endif if (v6): group_address = 0xff02...0000 | low_bits #endif return(group_address)¶
When the hash function is used to resolve a collision, the following pseudo-code will illustrate how 3 more attempts are used to find a unique group address:¶
for append in ["+1", "+2", "+3"]: hash = sha256(group_name + append) group_address = make_group_from_hash(hash) collision = send_claim(group_address) if (collision == False): return #endfor print("Collision limit reached")¶
When a group address collision is detected by 2 GAAP nodes, the node with the earliest timestamp for the group address creation wins the collision and keeps using the address. The node with a later timestamp has the responsibility to allocate a new group address to prevent the collision.¶
When a group address is allocated by a GAAP node it will build and send a Claim message. Included in the Claim message is the group name, group address, and timestamp. If the group address collides with other GAAP nodes already using the address, one of the nodes will send a Claim message to notify the colliding node that it needs to allocate a new group address.¶
A collision is defined to be the same group address allocated to 2 different group names. So if a GAAP node is claiming a group address for its group name and a Claim is received for this group name with the same group address, it is not a collision. It is simply a peer group participant claiming the group address you both agree to be using.¶
Each GAAP node will periodically send Claim messages for all group names for the applications running on the node. It will do this in a multi-record Claim message. The periodic Claim message is sent by setting a rough 1 minute timer. The timer value is set to 1 minute plus a jitter value. The jitter value is a random number in a 10% range of 1 minute (60 to 66 seconds). When the timer expires, a Claim message is sent. Receivers of a Claim message who have their timer running, reset the timer and thereby suppresses sending their own Claim message. This allows only a single GAAP node that is using the group address to keep claiming the group is still in use.¶
There will be network outage situations where all GAAP nodes may not receive Claim messages. During a partition, duplicate group addresses may be allocated and used by nodes on each side of the partition. During this condition, multicast nodes can operate normally and there is no conflict until the partition heals. When the partition heals, duplicate group addresses will be detected and fixed. The group address with the earliest timestamp is used to determine who keeps the collided group address. All others will have to rehash a new group address and have the applications start using the new address (meaning senders will source using the new group address and receivers will leave the collided group and join the new group).¶
When applications are no longer sending to a group address or not joined to a group address, they can inform the GAAP API to release the group. When this happens, the GAAP protocol stops claiming the group address in periodic messages and will not respond to a Claim for this address for a different group name. It is important for receiver applications to leave the group before releasing the group address.¶
It is strongly suggested that the GAAP protocol run over an encrypted multicast channel. The encryption algorithm and key management procedure is not specified in this document. The message Marker is used to indicate if the packet is sent in plaintext or ciphertext. If the Marker is not set to 0xAAAAAAAA and the receiver does not have a shared-key configured, the message MUST be dropped.¶
An open-source GAAP implementation exists where ChaCha20 [RFC7539] is used to encrypt GAAP messages. The implementation's key management procedure is a simple shared key that is configured with the application.¶
At this time there is no dynamic rekeying procedure and is left for future work. Therefore, all nodes must be manually rekeyed when a node is removed from the encrypted channel.¶
The following attack threats may exist with possible mitigation techniques:¶
This document makes several requests for IANA. The first is to allocate a well-known UDP port number for the GAAP protocol. The second is to allocate IPv4 and IPv6 multicast addresses the GAAP protocol uses to send messages to. And the third is to allocate a multicast address block where GAAP allocated group addresses come from.¶
The authors would like to thank the following people for their motivation to start this draft. They include Chris Hopps, Acee Lindem, David Lamparter, Jeff Tantsura, and Nate Karsens.¶