<?xml version="1.0" encoding="UTF-8"?>
<!--  Edited by Dino Farinacci farinacci@gmail.com -->

<!DOCTYPE rfc SYSTEM "rfc2629.dtd">

<rfc category="exp" ipr="trust200902" docName="draft-farinacci-pim-gaap-01">

<?rfc toc="yes" ?>
<?rfc symrefs="yes" ?>
<?rfc sortrefs="yes" ?>
<?rfc iprnotified="no" ?>
<?rfc strict="yes" ?>

<front>

  <title>Group Address Allocation Protocol (GAAP)</title>

  <author initials='D' surname="Farinacci" fullname='Dino Farinacci'>
    <organization>lispers.net</organization>
    <address><postal>
    <street></street>
    <city>San Jose</city> <region>CA</region>
    <code></code>
    <country>USA</country>
    </postal>
    <email>farinacci@gmail.com</email></address>
  </author>

  <author initials='M' surname="McBride" fullname='Mike McBride'>
    <organization>Futurewei</organization>
    <address><postal>
    <street></street>
    <city>Santa Clara</city> <region>CA</region>
    <code></code>
    <country>USA</country>
    </postal>
    <email>mmcbride7@gmail.com</email></address>
  </author>

  <date></date>

  <abstract>
    <t>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.</t>
  </abstract>

</front>

<middle>

  <section title="Introduction">
    <t>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.</t>

    <t>Other approaches to multicast group allocation have been
    proposed in the past, they include mDNS <xref target="RFC6762"/>,
    MADCAP <xref target="RFC2730"/>, MASC <xref target="RFC2909"/>,
    and IPv6 Allocation Guidelines <xref target="RFC3307"/>. However, they
    require configuration, used on a single subnet, and are not decentralized.</t>

    <t>This document will describe the protocol operation, protocol
    message formats, the API definition, and how multicast
    applications use the API.</t>
    <t><vspace blankLines="100"/></t>
  </section>

  <section title="Definition of Terms">
    <t><list style="hanging">
      <t hangText="Group Name:">is an ASCII string used by applications so they can rendezvous on the same group
      address. The application is started using this group name parameter. Applications can use multiple group
      names if they have requirements to use multiple group addresses.</t>

      <t hangText="Group Address:">is a non-link-local IPv4 multicast group address <xref target="RFC1112"/> or an
      IPv6 multicast group address <xref target="RFC4291"/>.</t>      

      <t hangText="GAAP Group Address:">is an IANA assigned non-link-local group address the GAAP protocol sends
      messages to. This address must not come from the GAAP multicast address block allocated by IANA.</t>

      <t hangText="Hash Function:">is a cryptographic hash function which takes the group name as input and produces
      a hash value as output. The GAAP protocol uses SHA-256 <xref target="RFC6234"/>.</t>

      <t hangText="Acceptable Group Hash List:">There are 4 hashed
      values regarded as "acceptable" for a group name. They are
      calculated using the SHA-256 hash function on 1 of 4 character strings:
      &quot;&lt;group-name&gt;&quot;,
      &quot;&lt;group-name&gt;+1&quot;,
      &quot;&lt;group-name&gt;+2&quot;, or
      &quot;&lt;group-name&gt;+3&quot;. No GAAP node should run the hash on any other strings for this group name.</t>
      
      <t hangText="Hashed Value:">is the output of a SHA-256 <xref
      target="RFC6234"/> hash function where the low order 32-bits are
      used to produce a unique network layer multicast group
      address. Achieving a unique 32-bits allows layer-2 switches to
      not have MAC multicast address collisions when mapped from
      multiple network layer multicast group addresses.</t>

      <t hangText="Collided Group Address:">a network layer group address where the low-order 32-bits of one group
      address is the same as the low-order 32-bits of another group address. It is desirable that the the low-order
      32-bits of a mapped IPv6 group address to a MAC group address not be the same so layer-2 switches do not
      leak packets to non-group members. This is also true for IPv4 group addresses where the low-order 23-bits
      must be unique.</t>

      <t hangText="Claim Message:">a GAAP protocol message that allocates a unique group address and claims it among
      other GAAP nodes on the network.</t>
    </list></t>
  </section>

  <section title="Overview of Protocol Operation">
    <t>This section will describe the high-level functionality of the GAAP protocol. Each application runs the GAAP
    protocol by using the API defined in <xref target="API"/>.</t>

    <t><list style="symbols"> 
      <t>An application is started with a group name.</t>

      <t>The group name is used to create a random allocated group address.</t>

      <t>A timestamp is taken when the group address is created.</t>

      <t>A Claim message, see <xref target="CLAIM"/>, is sent with
      group name, group address, and timestamp to determine if the
      group address has been claimed by any other GAAP nodes.</t>

      <t>If no Claim message is sent in response, the application can start using the group address.</t>

      <t>If a Claim message is returned, a collision has occurred and the GAAP node must allocate another group address
      and send a Claim message for the new group address.</t>

      <t>Claim messages are sent periodically. They are sent by a single node using a delay-timer suppression
      mechanism similar to IGMP <xref target="RFC1112"/>. See <xref target="DETAILS"/> for details.</t>

      <t>GAAP nodes are not required to cache information from Claim messages.</t>

      <t>GAAP is designed to be decentralized and stateless. The nodes that participate in the GAAP protocol are
      responsible for allocating and claiming group addresses. No other entities are needed.</t>
	</list></t>
  </section>
  
  <section title="GAAP Message Format" anchor="CLAIM">
    <t>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.</t>

    <figure align="center" title="GAAP Claim Message"> <artwork><![CDATA[
     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=1 |              Reserved                 | Record Count  |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                       0xAAAAAAAA Marker                       |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                  IPv4 Multicast Group Address                 | \
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  \
    |                                                               |    R
    |                        IPv6 Multicast                         |    e
    |                         Group Address                         |    c
    |                                                               |    o
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+    r
    |                          Timestamp                            |    d
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   /
    |                          Group Name ...                       |  /
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ /
    |                             ...                               |/
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    ]]></artwork></figure>

      <t><list style="hanging">                                                                  
        <t hangText="Packet field descriptions:"></t>
        <t><list style="hanging">
          <t hangText="Type=1:">Claim Message</t>
          <t hangText="Reserved:">Set to 0 and ignored on receipt.</t>
          <t hangText="Record Count:">The number of records in this Claim message.</t>
          <t hangText="Marker:">The fixed bit pattern of 0xAAAAAAAA is required to be set by the sender. The receiver
          verifies the marker to be 0xAAAAAAAA. If it is not, the packet is dropped. The Marker field is used to indicate
          to a receiver that the packet may be encrypted. See <xref target="SECURITY"/> for details on encrypting GAAP
          messages.</t>
        </list></t>
        <t hangText="Record field descriptions:"></t>
        <t><list style="hanging">
          <t hangText="IPv4 Multicast Group Address:">a 32-bit multicast address in network byte order
          <xref target="RFC1112"/>. If all bits are set to 0, there is no IPv4 address being allocated and claimed.</t>
          <t hangText="IPv6 Multicast Group Address:">a 128-bit multicast address in network byte order
          <xref target="RFC4291"/>. If all bits are set to 0, there is no IPv6 address being allocated and claimed.</t>
          <t hangText="Timestamp:">Standard epoch UTC timestamp according to <xref target="RFC8536"/>.</t>
          <t hangText="Group Name:">A variable length group name the multicast application uses. It is in ASCII
          format <xref target="RFC0020"/>. The string is terminated with a null character.</t>
        </list></t>
      </list></t>
  </section>

  <section title="GAAP API" anchor="API">
    <t>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.</t>

    <section title="gaap.init()">
      <t>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.</t>
      <figure><artwork><![CDATA[
        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        
        ]]></artwork></figure>
    </section>

    <section title="gaap.allocate()">
      <t>gaap.allocate() is used when the application needs a group address to send or receive on.</t>
      <figure><artwork><![CDATA[
        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))
        ]]></artwork></figure>
    </section>

    <section title="gaap.release()">
      <t>gaap.release() is used when an application is finished using a group address.</t>
      <figure><artwork><![CDATA[
        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))
        ]]></artwork></figure>
    </section>

    <section title="gaap.close()">
      <t>gaap.close() is used when an application is finished using the GAAP protocol.</t>
      <figure><artwork><![CDATA[
        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()
        ]]></artwork></figure>
    </section>

  </section>

  <section title="Detail Protocol Operation" anchor="DETAILS">
    <section title="Allocating Group Addresses">
      <t>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 <xref target="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:</t>

      <figure><artwork><![CDATA[
        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)
        ]]></artwork></figure>

      <t>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:</t>

      <figure><artwork><![CDATA[
        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")
        ]]></artwork></figure>

      <t>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.</t>
    </section>

    <section title="Claiming Group Addresses">
      <t>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.</t>

      <t>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.</t>

      <t>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.</t>
    </section>

    <section title="Partition Repair">
      <t>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).</t>
    </section>

    <section title="Releasing Group Addresses">
      <t>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.</t>
    </section>
  </section>

  <section title="Security Considerations" anchor="SECURITY">
    <t>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.</t>

    <t>An open-source GAAP implementation exists where ChaCha20 <xref
    target="RFC7539"/> is used to encrypt GAAP messages. The
    implementation's key management procedure is a simple shared key
    that is configured with the application.</t>

    <t>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.</t>

    <t>The following attack threats may exist with possible mitigation techniques:</t>
    <t><list style="numbered">
      <t>Even when an encrypted channel is used, a bad actor could be
      claiming a group address not derived from one of the group name
      inputs used for the Acceptable Group Hash List (see
      Definition of Terms section). Cooperating nodes should ignore
      such messages and not try to send Claim messages to correct the
      bad actor node.</t>

      <t>A bad actor could send an invalid timestamp giving it tie-breaking
      priority when a group address collision occurs. If the group address
      has been prior claimed by another node with a timestamp earlier than the
      invalid timestamp, cooperating nodes should put the bad actor node on a
      bad-actor list and ignore future messages from it. If the group name
      has not been claimed yet, the timestamp will be accepted only if
      earlier than the current time for the receiving node.</t>
      
      <t>A bad actor could send messages too often and is not adhering
      to the random delay or periodic timer procedures in this
      document. When this occurs, cooperating nodes should start
      ignoring messages from the bad actor node and not reset or
      cancel timers, or send triggered Claim messages</t>
    </list></t>
  </section>

  <section title="IANA Considerations">
    <t>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.</t>
  </section>

</middle>

<back>

  <references title='Normative References'>
    <?rfc include="reference.RFC.1112'?>
    <?rfc include="reference.RFC.4291'?>
    <?rfc include="reference.RFC.6234'?>
    <?rfc include="reference.RFC.0020'?>
    <?rfc include="reference.RFC.8536'?>
    <!--<?rfc include='http://xml.resource.org/public/rfc/bibxml3/reference.I-D.ietf-xxx.xml'?> -->
  </references>

  <references title='Informative References'>
    <?rfc include="reference.RFC.6762'?>
    <?rfc include="reference.RFC.2730'?>
    <?rfc include="reference.RFC.2909'?>
    <?rfc include="reference.RFC.3307'?>
    <?rfc include="reference.RFC.7539'?>
  </references>

  <section title="Acknowledgments">
    <t>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.</t>
  </section>

  <section title="Document Change Log">

    <section title="Changes to draft-farinacci-pim-gaap-01">
      <t><list style="symbols"> 
        <t>Submitted February 2023.</t>
        <t>Updated spec to reflect implementation.</t>
        <t>Add Marker in message format.</t>
        <t>Add definition for the Acceptable Group Hash List.</t>
        <t>Discuss security threats and possible mitigation methods.</t>
	  </list></t>
    </section>

    <section title="Changes to draft-farinacci-pim-gaap-00">
      <t><list style="symbols"> 
        <t>Initial posting November 2022.</t>
	  </list></t>
    </section>

  </section>

</back>
</rfc>
