<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<?rfc toc="yes"?>
<?rfc tocompact="yes"?>
<?rfc tocdepth="3"?>
<?rfc tocindent="yes"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<rfc category="std" docName="draft-ietf-ippm-capacity-protocol-20"
     ipr="trust200902" updates="">
  <front>
    <title abbrev="Test Protocol: IP Capacity Measurement">Test Protocol for
    One-way IP Capacity Measurement</title>

    <author fullname="Len Ciavattone" initials="L." surname="Ciavattone">
      <organization>AT&amp;T Labs</organization>

      <address>
        <postal>
          <street/>

          <city>Middletown</city>

          <region>NJ</region>

          <code/>

          <country>USA</country>
        </postal>

        <phone/>

        <facsimile/>

        <email>lenciavattone@gmail.com</email>

        <uri/>
      </address>
    </author>

    <author fullname="Ruediger Geib" initials="R." surname="Geib">
      <organization>Deutsche Telekom</organization>

      <address>
        <postal>
          <street>Deutsche Telekom Allee 9</street>

          <!-- Reorder these if your country does things differently -->

          <code>64295</code>

          <city>Darmstadt</city>

          <region/>

          <country>Germany</country>
        </postal>

        <phone>+49 6151 5812747</phone>

        <email>Ruediger.Geib@telekom.de</email>

        <!-- uri and facsimile elements may also be added -->
      </address>
    </author>

    <!--   <author fullname="Al Morton" initials="A." surname="Morton">
      <organization>AT&amp;T Labs</organization>

      <address>
        <postal>
          <street/>

          <city>Chicago</city>

          <region>IL</region>

          <code>60660</code>

          <country>USA</country>
        </postal>

        <phone/>

        <facsimile/>

        <email>acmorton@att.com</email>

        <uri/>
      </address>
    </author>
-->

    <date year="2025"/>

    <abstract>
      <t>This document addresses the problem of protocol support for measuring
      Network Capacity metrics specified by RFC 9097. The Method of
      Measurement discussed there requires a feedback channel from the
      receiver to control the sender's transmission rate in near-real-time.
      This document defines the UDP Speed Test Protocol for conducting RFC
      9097 and other related measurements.</t>
    </abstract>
  </front>

  <middle>
    <section title="Introduction">
      <t>The performance community has seen development of Informative Bulk
      Transport Capacity definitions in <xref target="RFC3148"/> for Framework
      for Bulk Transport Capacity (BTC) <xref target="RFC5136"/> for Network
      Capacity and Maximum IP-layer Capacity, and the Experimental metric
      definitions and methods in <xref target="RFC8337"/>, Model-Based Metrics
      for BTC.</t>

      <t>This document specifies the UDP Speed Test Protocol (UDPSTP) enabling
      the measurement of Network Capacity metrics as defined by <xref
      target="RFC9097"/>. The Method of Measurement discussed there deploys a
      feedback channel from the receiver to control the sender's transmission
      rate in near-real-time.</t>

      <t>This protocol supports measurement features which weren't available
      by TCP based speed tests and standard measurement protocols like One Way
      Active Measurement Protocol (OWAMP) <xref target="RFC4656"/>, Two-Way
      Active Measurement Protocol (TWAMP) <xref target="RFC5357"/> and Simple
      Two-Way Active Measurement Protocol (STAMP) <xref target="RFC8762"/>
      prior to this work. The controlled Bulk Capacity measurement or Speed
      Test, respectively, is based on UDP rather than TCP. The bulk
      measurement load is unidirectional. These specifications did support
      creation of asymmetric traffic in combination with some two-way
      communication, as supported by TWAMP and STAMP, when work on UDPST
      started. Further, two-way communications of TWAMP and STAMP are limited
      to reflection or unidirectional load properties, but lack support for
      closed loop feedback operation. The latter enables limiting congestion
      of a bottleneck, whose capacity is measured, to a short time range.
      Support of such a control loop is the main purpose of the UDPST
      Protocol.</t>

      <t>Apart from measurement functionality, the UDPSTP security features
      have been developed following guidance given by the IETF Security Area
      and the resulting specification is compliant with state-of-the-art
      security implementations. This is a secondary improvement reached by the
      UDPST Protocol and may simplify its reuse for other measurement
      purposes.</t>

      <section title="Terminology">
        <t>Downstream UDP Speed Test: a client initiated Network Capacity
        measurement between a server acting as sender and a client acting as
        receiver.</t>

        <t>Upstream UDP Speed Test: a client initiated measurement of Network
        Capacity measurement between a client acting as a sender and a server
        acting as receiver.</t>
      </section>

      <!--  This statement may be removed by the RFC editor -->

      <section title="Requirements Language">
        <t>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 interpreted as described in BCP
        14 <xref target="RFC2119"/>, <xref target="RFC8174"/> when, and only
        when, they appear in all capitals, as shown here.</t>
      </section>
    </section>

    <section anchor="applicablity" title="Scope, Goals, and Applicability">
      <t>The scope of this document is to define a protocol to measure the
      Maximum IP-Layer Capacity metric according to the Method of Measurement
      standardized by Section 8 of <xref target="RFC9097"/>. Some aspects of
      this protocol and end-host configuration can lead to support of
      additional forms of measurement, such as application emulation enabled
      by creative use of the load rate adjustment algorithm.</t>

      <t>The goal is to harmonize the specified IP-Layer Capacity metric and
      method across the industry, and this protocol supports the
      specifications of IETF and other Standards Development Organizations
      (SDO's; see, e.g., <xref target="TR-471"/>).</t>

      <t>The primary application of the protocol described here is the same as
      in Section 2 of <xref target="RFC7497"/> where:</t>

      <t><list style="symbols">
          <t>The access portion of the network is the focus of this problem
          statement. The user typically subscribes to a service with
          bidirectional access partly described by rates in bits per
          second.</t>
        </list></t>

      <t>UDPSTP is a client-based protocol. It may be applied by consumers to
      measure their own access bandwidth. Consumers may prefer a cross-domain
      measurement architecture for this purpose. UDPSTP may be deployed in
      Large-Scale Measurement of Broadband Performance environments (LMAP, see
      <xref target="RFC7497"/>), another cross-domain deployment. A network
      operator may support operation and maintenance by UDPST, a typical
      intra-domain deployment. All these deployments require or benefit from
      trust into the results, which are ensured by authenticated
      communication. As an option enabling measurements controlled by very
      low-end devices in a lab or limited domain <xref target="RFC8799"/>,
      unauthenticated operation may be implemented (but may be operated in
      exactly that case).</t>
    </section>

    <section title="Protocol Overview">
      <t>All messages defined by this document SHALL use UDP transport.</t>

      <t>The remainder of this section gives an informative overview of the
      communication protocol between two test endpoints (without expressing
      requirements or elaborating on the authentication and encryption
      aspects).</t>

      <t>One endpoint takes the role of server, listening for connection
      requests on a standard UDP Speed Test Protocol port number from the
      other endpoint, the client.</t>

      <t>The client requires configuration of a test direction parameter
      (upstream or downstream test, where the client performs the role of
      sender or receiver, respectively) as well as the hostname or IP
      address(es) of the server(s) in order to begin the setup and
      configuration exchanges with the server(s). By default, the client uses
      the single, standard UDPSTP port number per connection (see <xref
      target="Test-Setup"/>). If the default port number is not used, the
      client may require configuration of the control port number used by each
      server. This would be the case, if multiple server instances (processes)
      operate on one or more machines.</t>

      <t>Additionally, multi-connection (multi-flow) testing is supported by
      the protocol. Each connection is independent and attempts to maximize
      its own individual traffic rate. For multi-connection tests, a single
      client process would replicate the connection setup and test procedure
      multiple times (once for each flow) to one or more server instances. The
      server instance(s) would process each connection independently, as if
      they were coming from separate clients. It shall be the responsibility
      of the client process to manage the inter-related connections: handling
      the individual connection setup successes and failures, cleaning up
      connections during a test (should some fail) as well as aggregate the
      individual test results into an overall set of performance statistics.
      Fields in the Setup Request (mcIndex, mcCount, and mcIdent, see <xref
      target="Client-Gen-Activation"/>) are used to both differentiate and
      associate the multiple connections that comprise a single test.</t>

      <t>The protocol uses UDP transport <xref target="RFC0768"/> with two
      connection phases (Control and Data). The exchanges 1 and 2 (see below)
      constitute the Control phase, while exchanges 3 and 4 constitute the
      Data phase. In this document, the term message and the term Protocol
      Data Unit, or PDU (<xref target="RFC5044"/>) are used
      interchangeably.</t>

      <t><list style="numbers">
          <t>Test Setup Request and Response: If a server instance is
          identified with a host name that resolves to both IPv4/IPv6
          addresses, it is recommended to use the first address returned in
          the name resolution response - regardless, whether it's IPv4 or
          IPv6. Thus, the decision on the preferred IP address family is left
          to the DNS operator. Support for separate IPv4 and IPv6 measurements
          or an IPv4 and IPv6 multi connection setup are left for future
          improvement. The client then requests to begin a test by
          communicating its protocol version, intended security mode, and
          datagram size support. The server either confirms matching a
          configuration or rejects the connection request. If the request is
          accepted, the server provides a unique ephemeral port number for
          each test connection, allowing further communication. In a
          multi-connection setup, distinct UDP port numbers may be assigned
          with each Setup Response from a server instance. Distinct UDP port
          numbers are assigned, if all Setup Response messages originate from
          the same server in that case.</t>

          <t>Test Activation Request and Response: after having received a
          confirmation of the configuration by a server, the client composes a
          request conveying parameters such as the testing direction, the
          duration of the test interval and test sub-intervals, and various
          thresholds (for a detailed discussion, see <xref target="RFC9097"/>
          and <xref target="TR-471"/>). The server then chooses to accept,
          ignore or modify any of the test parameters, and communicates the
          set that will be used unless the client rejects the modifications.
          Note that the client assumes that the Test Activation exchange has
          opened any co-located firewalls and network address/port translators
          for the test connection (in response to the Request packet on the
          ephemeral port number) and the traffic that follows. See <xref
          target="RFC9097"/> for a more detailed discussion of firewall and
          NAT related features. If the Test Activation Request is rejected or
          fails, the client assumes that the firewall will close the
          address/port number pinhole entry after the firewall's configured
          idle traffic timeout.</t>

          <t>Test Stream Transmission and Measurement Feedback Messages:
          Testing proceeds with one endpoint sending Load PDUs and the other
          endpoint receiving the Load PDUs and sending frequent status
          messages to communicate status and transmission conditions there.
          The data in the feedback messages, whether received from the client
          or when being sent to the client, is input to a load rate adjustment
          algorithm at the server which controls future sending rates at
          either end. The choice to locate the load rate adjustment algorithm
          at the server, regardless of transmission direction, means that the
          algorithm can be updated more easily at a host within the network,
          and at a fewer number of hosts than the number of clients. Note,
          that this mode of operation also helps to keep the pinhole (or
          mapping, respecitvely) active at on-path stateful devices. UDPSTP is
          at least partially compliant to section 3.1 of <xref
          target="RFC8085"/>: the bottleneck is congested, but pending
          congestion is avoided by limiting the duration of that congestion to
          the minimum required to determine the bottleneck capacity.</t>

          <t>Stopping the Test: When the specified test duration has been
          reached, the server initiates the exchange to stop the test by
          setting a STOP indication in its outgoing Load PDUs or Status
          Feedback messages. After being received, the client acknowledges it
          by also setting a STOP indication in its outgoing Load PDUs or
          Status Feedback messages. A graceful connection termination at each
          end then follows. Since the Load PDUs and Status Feedback messages
          are used, this exchange is considered a sub-exchange of 3. If the
          Test traffic stops or the communication path fails, the client
          assumes that the firewall will close the address/port number
          combination after the firewall's configured idle traffic
          timeout.</t>

          <t>Both the client and server react to unexpected interruptions in
          the Control or Data phase, respectively. Watchdog timers limit the
          time a server or client will wait before stopping all traffic and
          terminating a test.</t>
        </list></t>

      <t><xref target="MessageExchange"/> provides an example exchange of
      control and measurement PDUs for both a downstream and upstream UDP
      Speed Tests (always client initiated):</t>

      <t><figure anchor="MessageExchange"
          title="Successful UDPSTP Message Exchanges">
          <artwork>
             =========== Downstream Test ===========
+---------+                                           +---------+
| Client  |          Test Setup Request -----&gt;        |  Server |
+---------+                                           +---------+
            &lt;----- Test Setup Response (Accept)
            &lt;----- Null Request PDU

                   Test Activation Request -----&gt;

            &lt;----- Test Activation Response (Accept)

            &lt;----- Load PDUs

                      Status Feedback PDUs -----&gt;

          After expiry of server's test duration timer...

            &lt;----- Load PDU (TEST_ACT_STOP)

           Status Feedback PDU (TEST_ACT_STOP) -----&gt;


             ============ Upstream Test ============
+---------+                                           +---------+
| Client  |          Test Setup Request -----&gt;        |  Server |
+---------+                                           +---------+
            &lt;----- Test Setup Response (Accept)
            &lt;----- Null Request PDU

                   Test Activation Request -----&gt;

            &lt;----- Test Activation Response (Accept)

                      Load PDUs -----&gt;

            &lt;----- Status Feedback PDUs

          After expiry of server's test duration timer...

            &lt;----- Status Feedback PDU (TEST_ACT_STOP)
            
                    Load PDU (TEST_ACT_STOP) -----&gt;
        </artwork>

          <postamble/>
        </figure></t>
    </section>

    <section anchor="Security-Checksum"
             title="Parameters, Security Operations, and Optional Checksum">
      <t>Security and checksum operation aren't covered by <xref
      target="RFC9097"/>, which only defines the Method of Measurement. This
      section adds the operational specification related to security and
      optional checksum. Due to the additional complexities, and loss of the
      direct Layer 3 to Layer 4 mapping of packets to datagrams, it is
      recommended that Layer 3 fragmentation be avoided. A simplified approach
      is to choose the default datagram size small enough to prevent
      fragmentation. MTU size detection prior to a test is out of scope of
      this document. A method for a path MTU size discovery, as for example
      proposed by <xref target="RFC8899"/>, is left for future design and
      implementation. Unless IP fragmentation is expected and is one of the
      attributes being measured, the IPv4 DF bit SHOULD be set for all
      tests.</t>

      <section title="Parameters and Definitions">
        <t>Please refer to Section 4 of <xref target="RFC9097"/> for an
        overview of Parameters related to the Maximum IP-Layer Capacity Metric
        and Method. A set of error-codes to support debugging are provided in
        <xref target="Error-codes"/>.</t>
      </section>

      <section anchor="SecurityModes" title="Security Mode Operations">
        <t>There are four security modes of operation, one unauthenticated
        mode, two authenticated modes and a fourth adding encryption.
        Operational support of unauthenticated and authenticated modes MUST be
        mutually exclusive. Once the modes requiring or optionally adding
        authentication or encryption are implemented and configured locally,
        the unauthenticated mode must be disabled. The four modes are:</t>

        <t><list style="numbers">
            <t>An OPTIONAL Unauthenticated mode for all messages shall only be
            allowed when all other modes requiring authentication (or Partial
            Encryption) are unavailable for use. This mode is only intended
            for a lab or limited domain <xref target="RFC8799"/> hosting very
            low-end devices lacking accurate clock synchronization (see <xref
            target="applicablity"/>).</t>

            <t>A REQUIRED mode with authentication during the Control phase
            (Test Setup and Test Activation exchanges). This mode may be
            preferred to perform infrequent reliable measurements, typically
            initiated by consumers or for operator OAM purposes (see <xref
            target="applicablity"/>).</t>

            <t>An OPTIONAL mode with the additional authentication of the
            Status Feedback messages during the Data phase. This mode may be
            preferred to perform infrequent reliable measurements, typically
            initiated by consumers or for operator OAM purposes (see <xref
            target="applicablity"/>).</t>

            <t>An OPTIONAL mode that adds encryption, prior to authentication,
            of the Control phase exchanges and the Status Feedback messages.
            This mode is optional, as Performance measurements don't transport
            application data and encryption has impact on or at least may
            impact performance measurements (especially on very low-end
            devices). Encryption preserves privacy, and may be of interest for
            Large-Scale Measurement of Broadband Performance environments
            (LMAP, see <xref target="applicablity"/>).</t>
          </list></t>

        <t>The requirements discussed hereafter refer to the PDUs in sections
        5 and 6 below, primarily the authMode, keyId, authUnixTime,
        initVector, and authDigest fields. The roles in this section have been
        generalized so that the requirements for the PDU sender and receiver
        can be re-used and referred to by other sections within this document.
        Each successive mode increases security, but comes with additional
        performance impacts and complexity. The protocol is used with
        unsubstantial payload and it may operate on very low-end devices.
        Offering the flexibility of various security operation modes allows
        for adoption of available end-device resources. In general, an active
        measurement technique as the one defined by this document is better
        suited to protect the privacy of those involved in measurements <xref
        target="RFC7594"/>.</t>

        <section anchor="Auth-Mode-0"
                 title="Mode 0: Optional Unauthenticated Mode">
          <t>In this mode, all PDU senders SHALL set the keyId, authUnixTime,
          the initVector, and the authDigest fields of all related packets to
          zero.</t>

          <t>Any errors (configuration miss-match between client and server)
          found in the Test Setup exchange or the Test Activation exchange
          SHOULD result in silent rejection (no further packets sent on the
          address/port pairs). The exception is when the testing hosts have
          been configured for troubleshooting control phase failures and
          rejection messages will aid in the process.</t>
        </section>

        <section anchor="Auth-Mode-1"
                 title="Mode 1: Required Authenticated Mode">
          <t>In this mode, the client and the server SHALL be configured to
          use one of a number of shared secret keys, designated via the
          numeric keyId field (see <xref target="key-management"/>). This key
          SHALL be used as input to the KDF (Key Derivation Function), as
          specified in <xref target="kdf"/>, to obtain the actual keys used by
          the client and server for authentication.</t>

          <t>During the Control phase, the sender SHALL read the current
          system (wall-clock) time and populate the authUnixTime field and
          next calculate the 32-octet HMAC-SHA-256 hash of the entire PDU
          according to section 6 of <xref target="RFC6234"/> (with initVector
          and authDigest preset to all zeroes). The authDigest field is filled
          by the result, then the packet is sent to the receiver. The value in
          the authUnixTime field is a 32-bit time stamp and a 10-second
          tolerance window (+/- 5 seconds) SHALL be used by the receiver to
          distinguish a subsequent replay of a PDU. See Table 2 of <xref
          target="TR-471"/> for a recommended timestamp resolution.</t>

          <t>Upon reception, the receiver SHALL validate the message PDU for
          correct length, validity of authDigest, immediacy of authUnixTime,
          and expected formatting (PDU-specific fields are also checked, such
          as protocol version). Validation of the authDigest requires that it
          will be extracted from the PDU and the field zeroed prior to the
          HMAC calculation used for comparison (see section 7.2 of <xref
          target="RFC9145"/>).</t>

          <t>If the validation fails, the receiver SHOULD NOT continue with
          the Control phase and implement silent rejection (no further packets
          sent on the address/port pairs). The exception is when the testing
          hosts have been configured for troubleshooting Control phase
          failures and rejection messages will aid in the process.</t>

          <t>If the validation succeeds, the receiver SHALL continue with the
          Control phase and compose a successful response or a response
          indicating the error conditions identified (if any).</t>

          <t>This process SHALL be executed for the request and response in
          the Test Setup exchange, including the Null Request (<xref
          target="Test-Setup"/>) and the Test Activation exchange (<xref
          target="Test-Activation"/>).</t>
        </section>

        <section anchor="Auth-Mode-2"
                 title="Mode 2: Optional Authenticated Mode for Data Phase">
          <t>This mode incorporates Authenticated mode 1. When using the
          optional authentication during the Data phase, authentication SHALL
          also be applied to the Status Feedback PDU (see <xref
          target="Status-PDU"/>). The client sends the Status PDU in a
          downstream test, and the server sends it in an upstream test.</t>

          <t>The Status PDU sender SHALL read the current system (wall-clock)
          time and populate the authUnixTime field, then calculate the
          authDigest field of the entire Status PDU (with the initVector and
          authDigest field set to all zeroes) and send the packet to the
          receiver. The values of authUnixTime field and authDigest field are
          determined as defined by <xref target="Auth-Mode-1"/>.</t>

          <t>Upon reception, the receiver SHALL validate the message PDU for
          correct length, validity of authDigest, immediacy of authUnixTime,
          and expected formatting (PDU-specific fields are also checked, such
          as protocol version). Validation of the authDigest will require that
          it be extracted from the PDU and the field zeroed prior to the HMAC
          calculation used for comparison.</t>

          <t>If the authentication validation fails, the receiver SHALL ignore
          the message. If the watchdog timer expires (due to successive failed
          validations), the test session will prematurely terminate (no
          further load traffic SHALL be transmitted).</t>

          <t>If this optional mode has not been selected, then the keyId,
          authUnixTime, initVector, and authDigest fields of the Status PDU
          (see <xref target="Status-PDU"/>) SHALL be set to all zeroes.</t>
        </section>

        <section anchor="Auth-Mode-3"
                 title="Mode 3: Optional Encryption of Control and Status">
          <t>This mode incorporates authentication mode 2 after encryption of
          all fields prior to the authMode field. This is done for all Control
          and Status Feedback messages. The encryption algorithm only provides
          encryption and relies on the existing authentication mechanism to
          provide integrity protection. Adding encryption to prior
          authentication allows re-using code of optional authentication mode,
          and additionally allows re-using several protocol fields. Still,
          both authentication and encryption are provided. See sections <xref
          format="counter" target="Test-Setup"/> to <xref format="counter"
          target="Test-Measurement"/> for the field format.</t>

          <t>When using the optional Encryption, the process SHALL be applied
          to the Test Setup Request, the Test Setup Response, the Null Request
          (if applicable), the Test Activation Request, the Test Activation
          Response, and the Status PDU. The client sends the Status PDU in a
          downstream test and the server sends it in an upstream test.</t>

          <t>In the OPTIONAL Encryption mode, the client and the server SHALL
          be configured to use one of a number of shared secret keys (see
          keyId). This key SHALL be used as input to the KDF, as specified in
          <xref target="kdf"/>, to obtain the actual keys used by the client
          and server for encryption.</t>

          <t>The following encryption specifications SHALL be used for
          this:</t>

          <t><list style="numbers">
              <t>Advanced Encryption Standard, AES, according to Federal
              Information Processing Standards Publication 197 <xref
              target="FIPS-197"/></t>

              <t>Cipher Block Chaining (CBC) <xref target="CBC"/></t>

              <t>Key size of 128 bits (fixed block size of 128 bits)</t>
            </list></t>

          <t>The encrypted portion of each PDU SHALL contain the padding
          required to maintain a multiple of the AES CBC block size of 16
          octets. As such, any library functions used for encryption and
          decryption SHALL have padding disabled (to maintain an equal
          encrypted and unencrypted length). In OpenSSL for example, this can
          be accomplished via "EVP_CIPHER_CTX_set_padding(ctx,0)".</t>

          <t>The sender SHALL populate the initVector field with a
          cryptographically random 16-octet Initialization Vector (IV), see
          <xref target="RFC4086"/>. The IV, in conjunction with the KDF
          encryption key (derived from the shared secret key), SHALL be used
          to encrypt the header up to, but not including, the authMode field.
          The shared secret key is designated via the keyId field. The sender
          SHALL then read the current system (wall-clock) time and populate
          the authUnixTime field and then calculate (and populate) the
          authDigest, for the entire PDU, in the same manner as specified with
          Authentication modes 1 and 2. Finally, the sender SHALL send the
          packet with partially encrypted PDU to the receiver.</t>

          <t>Upon reception, the receiver SHALL validate the message PDU for
          correct length, validity of authDigest, and immediacy of
          authUnixTime. Validation of the authDigest will require that it be
          extracted from the PDU and the field zeroed prior to the HMAC
          calculation used for comparison. If the PDU validation succeeds, the
          receiver SHALL then decrypt the initial portion of the PDU using the
          included IV and KDF encryption key derived from the shared secret
          key (designated by the keyId). Finally, the PDU-specific fields that
          control the test are validated and processed.</t>

          <t>If the PDU validation fails in the Control phase, the receiver
          SHOULD NOT continue with current exchange and implement silent
          rejection (no further packets sent on the address/port pairs). The
          exception is when the testing hosts have been configured for
          troubleshooting Control phase failures and rejection messages will
          aid in the process.</t>

          <t>If the validation succeeds in the Control phase, the receiver
          SHALL continue with the current exchange and compose a successful
          response or a response indicating the error conditions identified.
          The response PDU SHALL be encrypted and authenticated as described
          above using a new random 16-octet IV. The packet with partially
          encrypted PDU SHALL be sent back to the originator.</t>

          <t>This process SHALL be executed for the request and response in
          the Test Setup exchange, including the Null Request (<xref
          target="Test-Setup"/>) and the Test Activation exchange (<xref
          target="Test-Activation"/>).</t>

          <t>If the PDU validation fails for a Status PDU, the receiver SHALL
          ignore the message. If the watchdog timer expires (due to successive
          failed validations), the test session will prematurely terminate (no
          further load traffic SHALL be transmitted).</t>
        </section>
      </section>

      <section anchor="key-management" title="Key Management">
        <t>Section 2 of <xref target="RFC7210"/> specifies a conceptual
        database for long-lived cryptographic keys. The key table SHALL be
        used with the REQUIRED authentication mode and the OPTIONAL
        authentication mode (using the same key). The same key table and key
        SHALL also be used with the OPTIONAL Encryption mode, when utilized.
        For both authentication and encryption, this key SHALL only be used as
        input to the KDF, specified in <xref target="kdf"/>, to derive the
        actual keys used for authentication and encryption processing. Key
        rotation and related management specifics are beyond the scope of this
        document.</t>

        <t>The key table SHALL have (at least) the following fields, referring
        to Section 2 of <xref target="RFC7210"/>:</t>

        <t><list style="symbols">
            <t>AdminKeyName</t>

            <t>LocalKeyName</t>

            <t>KDF</t>

            <t>AlgID</t>

            <t>Key</t>

            <t>SendLifetimeStart</t>

            <t>SendLifetimeEnd</t>

            <t>AcceptLifetimeStart</t>

            <t>AcceptLifetimeEnd</t>
          </list></t>

        <t>The LocalKeyName SHALL be determined from the corresponding keyId
        field in the PDUs that follow.</t>

        <section anchor="kdf" title="Key Derivation Function (KDF)">
          <t>A Key Derivation Function (KDF) is a one-way function that
          provides cryptographic separation of key material. The protocol
          requires a KDF to securely derive cryptographic keys used for
          authentication and encryption of protocol messages. The inclusion of
          a KDF ensures that keys are generated in a standardized,
          cryptographically secure manner, reducing the risk of key compromise
          and enabling interoperability across implementations. The benefits
          of using a KDF include:</t>

          <t><list style="symbols">
              <t>Security: A KDF produces keys with high entropy, resistant to
              brute-force and related-key attacks, ensuring robust protection
              for protocol communications.</t>

              <t>Flexibility: The KDF allows derivation of multiple keys from
              a single shared secret, supporting distinct keys for client and
              server authentication and encryption.</t>

              <t>Standardization: By adhering to established cryptographic
              standards, the KDF ensures compatibility with existing security
              frameworks and facilitates implementation audits.</t>

              <t>Efficiency: The KDF enables efficient key generation without
              requiring additional key exchange mechanisms, minimizing
              protocol overhead.</t>
            </list></t>

          <t>The KDF algorithm SHALL be a Key Derivation Function in Counter
          Mode, as specified in Section 4.1 of <xref target="NIST800-108"/>. 
		  This algorithm uses a counter-based mechanism to generate key material
		  from a shared secret, ensuring deterministic and secure key derivation.
		  The Pseudorandom Function (PRF) used in the KDF SHALL be HMAC-SHA-256,
          as defined in section 6 of <xref target="RFC6234"/>. IANA is asked 
		  to assign &ldquo;HMAC-SHA-256&rdquo; as a new KeyTable KDF (<xref
          target="kdf-HMAC-SHA-256"/>).</t>

          <t>The KDF SHALL use the following parameters:</t>

          <t><list style="symbols">
              <t>Kin (Key-derivation key): The shared key as identified by the
              keyId field in the PDU.</t>

              <t>Label: The fixed string "UDPSTP" (without quotes), encoded as
              a UTF-8 string, used to bind the derived keys to this specific
              protocol.</t>

              <t>Context: The UTF-8 string representation of the authUnixTime
              field received in the very first Setup Request PDU sent from the
              client to the server. This ensures that the derived keys are
              unique to the session and tied to the temporal context of the
              initial setup exchange. The authUnixTime field serves as a nonce
              and is protected from modification by the HMAC-SHA-256 hash
              present in the authDigest field.</t>

              <t>r: The length of the binary encoding of the counter SHALL be
              32 (bits).</t>
            </list></t>

          <t>The total derived key material SHALL be 96 octets (768 bits) in
          length. The key material SHALL be structured as follows, from most
          significant bit (MSB) to least significant bit (LSB):</t>

          <t><list style="symbols">
              <t>Client Authentication Key: 256 bits (32 octets), used for
              authenticating messages sent by the client.</t>

              <t>Server Authentication Key: 256 bits (32 octets), used for
              authenticating messages sent by the server.</t>

              <t>Client Encryption Key: 128 bits (16 octets), used for
              encrypting messages sent by the client.</t>

              <t>Server Encryption Key: 128 bits (16 octets), used for
              encrypting messages sent by the server.</t>
            </list></t>

          <t>This structure ensures that the derived keys are sufficient for
          securing both authentication and encryption operations within the
          protocol, while maintaining clear separation of function and
          directionality.</t>

          <t>If authentication of the initial Setup Request PDU received by
          the server fails, due to an invalid authDigest field, any and all
          derived keying material and keys SHALL be considered invalid.</t>

          <t>The key material derived from the initial Setup Request PDU,
          either at the client prior to transmission or at the server upon
          reception, SHALL be used for all subsequent PDUs sent between them
          for that test connection. As such, the KDF is only required to be
          executed once by the client and server for each test connection.</t>

          <t><xref target="KDF-Example"/>, <xref target="KDFfigure"/> 
		  provides a code snippet demonstrating derivation of the specified 
		  keys from key material using the OpenSSL cryptographic library.
		  Specifically, the high-level Key-Based EVP_KDF implementation 
		  (EVP_KDF-KB, Key-Based Envelope Key-Distribution Function), 
		  see <xref target="EVP_KDF-KB"/> for details.</t>
        </section>
      </section>

      <section title="Configuration of Network Functions with Stateful Filtering">
        <t>Successful interaction with a local firewall assumes the firewall
        to be configured allowing a host to open a bidirectional connection
        using unique source and destination addresses as well as port numbers
        by sending a packet using that 4-tuple for a given transport protocol.
        The client's interaction with its firewall depends on this
        configuration.</t>

        <t>The firewall at the server MUST be configured with an open pinhole
        for the server IP address and standard UDP port of the server. All
        messages sent by the client to the server use this standard UDP
        port.</t>

        <t>The server uses one ephemeral UDP port per test connection.
        Assuming that the firewall administration at the server does not allow
        an open UDP ephemeral port range, then the server MUST send a Null
        Request to the client from the ephemeral port communicated to the
        client in the Test Setup Response. The Null Request may not reach the
        client: it may be discarded by the client's firewall.</t>

        <t>If the server firewall administration allows an open UDP ephemeral
        port range, then the Null Request is not strictly necessary. However,
        the availability of an open port range policy cannot be assumed.</t>

        <t>Network Address Translators (NATs) are expected to offer support of
        a wider set of operational configurations as compared to Firewalls.
        Specifications covering NAT behaviour apart from the above are out of
        scope of this document, as are combined implementations of NAT and
        Firewalls too.</t>
      </section>

      <section anchor="Checksum" title="Optional Checksum">
        <t>All of the PDUs exchanged between the client and server support a
        header checksum that covers the various fields in the UDPST PDU
        (excluding the Payload Content of the Load PDU and, to be clear, also
        the IP- and UDP-header). This checksum is intended for environments
        where UDP data integrity may be uncertain. This includes situations
        where the standard UDP checksum is disabled or a nonstandard network
        API is in use (things typically done to improve performance on low-end
        devices). The calculation is the same as the 16-bit one's complement
        Internet checksum used in the IPv4 packet header (see section 3.1 of
        <xref target="RFC0791"/>).</t>

        <t>If a PDU sender is populating the checkSum field, it SHALL do so
        after the PDU is built but prior to any authentication or encryption
        processing (i.e., all fields starting with authMode are zeroed). The
        PDU receiver SHALL subsequently verify the PDU checksum whenever
        checksum processing has been configured. Verification requires that
        all fields starting with authMode are zeroed prior to the checksum
        calculation used to verify the PDU.</t>

        <t>Because of its redundancy when authentication is being used, it is
        OPTIONAL for a PDU sender to utilize the checkSum field whenever the
        authDigest field is also utilized. However, because authentication is
        not applicable to the Load PDU, the checkSum field SHALL be utilized
        by the sender whenever UDP data integrity may be uncertain (as
        outlined above).</t>
      </section>
    </section>

    <section anchor="Test-Setup" title="Test Setup Request and Response">
      <section title="Client Generates Test Setup Request">
        <t>The client SHALL begin the Control phase exchanges by sending a
        Test Setup Request message to the server's (standard) control port.
        This standard UDPSTP port number is utilized for each connection of a
        multi-connection test (assuming each server to have a distinct IP
        address and/or a client to have one or more distinct IP adresses,
        respectively).</t>

        <t>The client SHALL simultaneously start a test initiation timer so
        that if the Control phase fails to complete Test Setup and Test
        Activation exchanges in the allocated time, the client software SHALL
        exit (close the UDP socket and indicate an error message to the user).
        Lost messages result in a Test Setup and Test Activation failure. The
        test initiation timer MAY reuse the test termination timeout
        value.</t>

        <t>The watchdog timeout is configured as a 1-second interval to
        trigger a warning message that the received traffic has stopped. The
        test termination timeout is based on the watchdog interval, and
        implements a wait time of 2 additional seconds before triggering a
        non-graceful termination.</t>

        <t>The UDP PDU format layout SHALL be as follows (big-endian AB,
        starting by most significant byte ending by least significant
        byte):</t>

        <t><figure anchor="Setup-PDU" title="Test Setup PDU Layout">
            <artwork>
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            pduId              |          protocolVer          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    mcIndex    |    mcCount    |            mcIdent            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  cmdRequest   | cmdResponse   |         maxBandwidth          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           testPort            |modifierBitmap |   reserved1   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           checkSum            |           reserved2           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                      padding (12 octets)                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   authMode    |     keyId     |        reserved-auth1         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         authUnixTime                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                     initVector (16-octet)                    .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                     authDigest (32-octet)                    .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        </artwork>

            <postamble/>
          </figure></t>

        <t>Additional details regarding the Setup Request and Response fields
        are as follows:</t>

        <t>pduId: A two-octet field. IANA is asked to assign the value hex
        0xACE1 (<xref target="pduId"/>).</t>

        <t>protocolVer: A two-octet field, identifying the actual protocol
        version. IANA is asked to assign only one initial value, 20 (<xref
        target="protocolVer"/>).</t>

        <t>mcIndex: The index of a connection relative to all connections that
        make up a single test (starting at 0, incremented by 1 per
        connection). It is used to differentiate separate connections within a
        multi-connection test. An implementation may restrict the number of
        connections supported for a single test to a value smaller or equal to
        255.</t>

        <t>mcCount: The total count of attempted connections.</t>

        <t>mcIdent: A pseudorandom non-zero identifier (via a Random Number
        Generator, source port number,...) that is common to all connections
        of a single test. It is used by clients/servers to associate separate
        connections within a multi-connection test.</t>

        <t>cmdRequest: Is set to CHSR_CREQ_SETUPREQ to indicate a Setup
        request message. Note that CHSR_CREQ_NONE remains unused.</t>

        <t>cmdResponse: All Request PDUs always have a Command Response of
        XXXX_CRSP_NONE.</t>

        <t>maxBandwith: When this field is non-zero, it is a specification of
        the maximum bit rate the client expects to send or receive during the
        requested test in Mbps. The server compares this value to its
        currently available configured limit for test admission control. This
        field MAY be used for rate-limiting the maximum rate the server should
        attempt. The maxBandwidth field's most significant bit, the
        CHSR_USDIR_BIT, is set to 0 by default to indicate "downstream" and
        has to be set to 1 to indicate "upstream".</t>

        <t>testPort: Set to zero in the Test Setup Request and populated by
        the server in the Test Setup Response. It contains the UDP ephemeral
        port number on the server that the client has to use for the Test
        Activation Request and subsequent Load or Status PDUs.</t>

        <t>modifierBitmap: this document only assigns two bits in this bitmap,
        see <xref target="Setup-modifierBitmap"/>:</t>

        <t><list style="hanging">
            <t hangText="CHSR_JUMBO_STATUS">Above a sending rate of 1Gbps,
            allow datagram sizes that result in Jumbo Frames (with a max IP
            packet size of 9000 bytes). Up to a sending rate of 1Gbps, or for
            all sending rates if CHSR_JUMBO_STATUS is not set, datagram sizes
            SHALL NOT produce an IP packet size greater than 1250 bytes
            (unless CHSR_TRADITIONAL_MTU is also set).</t>

            <t hangText="CHSR_TRADITIONAL_MTU">Allow datagram sizes, at any
            sending rate, that can result in a Traditional IP packet size of
            1500 bytes. Effectively increasing the default non-Jumbo maximum
            from 1250 bytes to 1500 bytes.</t>
          </list>Other bit positions are left unassigned by this document.</t>

        <t>reserved1: This field MUST be set to 0 and it MUST be ignored on
        receipt.</t>

        <t>checkSum: An optional checksum of the entire PDU (see <xref
        target="Checksum"/> for guidance). The calculation is done with the
        fields checksum, authMode and those following after authMode set to
        zero.</t>

        <t>reserved2: This field MUST be set to 0 and it MUST be ignored on
        receipt.</t>

        <t>authMode: The authMode field currently has four values assigned
        (see <xref target="Setup-authMode"/>). One of these has to be set (see
        <xref target="SecurityModes"/> for requirements and details of
        operation): <list style="hanging">
            <t hangText="AUTHMODE_0:">Optional Unauthenticated mode</t>

            <t hangText="AUTHMODE_1:">Required Authentication for Control
            phase</t>

            <t hangText="AUTHMODE_2:">Optional Authentication for Control and
            Data phase (Status Feedback PDU only)</t>

            <t hangText="AUTHMODE_3:">Optional Encrypted mode</t>
          </list>A range of 60 through 63 is reserved for experimentation.
        IANA is asked to create a registry for the assigned values; see the
        IANA Considerations Section.</t>

        <t>keyId: This is a localKeyName, the numeric key identifier for a key
        in the shared key table.</t>

        <t>reserved-auth1: This field MUST be set to 0 and it MUST be ignored
        on receipt. Identical usage of reserved-auth1 field across all PDUs in
        a future UDPSTP version allows it to keep the security functionality
        identical in each PDU.</t>

        <t>authUnixTime: A 32-bit time stamp of the current system
        (wall-clock) time since the Unix Epoch on January 1st, 1970 at
        UTC.</t>

        <t>initVector: This field contains the 16-octet random IV used for
        Encryption mode. A new random 16-octet IV SHALL be used each time
        encryption is performed.</t>

        <t>authDigest: This field contains the 32-octet HMAC-SHA-256 hash that
        covers the entire PDU.</t>
      </section>

      <section title="Server Test Setup Request Processing and Response Generation">
        <t>This section describes the processes at the server to evaluate the
        Test Setup Request and determine the next steps.</t>

        <section title="Test Setup Request Processing - Rejection">
          <t>When the server receives the Setup Request, it SHALL:</t>

          <t><list style="symbols">
              <t>verify the size of the Setup Request message and if correct
              evaluate the authMode field,</t>

              <t>if operating in one of the Authenticated modes, validate the
              Setup Request message by checking the authDigest as prescribed
              in <xref target="Auth-Mode-1"/>, and</t>

              <t>if operating in the Encryption mode, use the client
              encryption key from the KDF (derived from the keyId designated
              key) and the IV to decrypt the Setup Request message up to the
              authMode field using the method prescribed in <xref
              target="Auth-Mode-3"/></t>
            </list></t>

          <t>Then, the server evaluates the other fields in the protocol
          header, such as the protocol version, the PDU ID (to validate the
          type of message), the maximum Bandwidth requested for the test, and
          the modifierBitmap for use of options such as Jumbo datagram status
          and Traditional MTU (1500 bytes).</t>

          <t>If the client has selected options for:<list style="symbols">
              <t>Jumbo datagram support (modifierBitmap),</t>

              <t>Traditional MTU (modifierBitmap),</t>

              <t>Authentication mode (authMode)</t>
            </list></t>

          <t>that do not match the server configuration, the server MUST
          reject the Setup Request.</t>

          <t>If the Setup Request must be rejected, the conditions below
          determine whether the server sends a response:</t>

          <t><list style="symbols">
              <t>In Authenticated modes, if the authDigest is valid, a Test
              Setup Response SHALL be sent back to the client with a
              corresponding command response value indicating the reason for
              the rejection. If operating in the Encryption mode, the server
              SHALL proceed per <xref target="Auth-Mode-3"/>, else the server
              SHALL proceed per <xref target="Auth-Mode-1"/>.</t>

              <t>In Authenticated modes, if the authDigest is invalid, then
              the Test Setup Request SHOULD fail silently. The exception is
              for operations support: server administrators using
              authentication are permitted to send a Setup Response to support
              operations and troubleshooting.</t>

              <t>If Unauthenticated mode is selected, the Test Setup Request
              SHALL fail silently.</t>
            </list>The additional, non-authentication circumstances when a
          server SHALL NOT communicate the appropriate Command Response code
          for an error condition (fail silently) are when: <list
              style="numbers">
              <t>the Setup Request PDU size is not equal to the 'struct
              controlHdrSR' size shown in <xref target="CHSR"/>,</t>

              <t>the PDU ID is not 0xACE1 (Test Setup PDU), or</t>

              <t>a directed attack has been detected,</t>
            </list>in which case the server will allow setup attempts to
          terminate silently. Attack detection is beyond the scope of this
          specification.</t>

          <t>When the server replies to a Test Setup Request message, the Test
          Setup Response PDU is structured identically to the Request PDU and
          SHALL retain the original values received in it, with the following
          exceptions:</t>

          <t><list style="symbols">
              <t>The cmdRequest field is set to CHSR_CREQ_SETUPRSP, indicating
              a response.</t>

              <t>The cmdResponse field is set to an error code (starting at
              cmdResponse 2, Bad Protocol Version, see <xref
              target="Error-codes"/>), indicating the reason for rejection. If
              cmdResponse indicates a bad protocol version (CHSR_CRSP_BADVER),
              the protocolVer field is also updated to indicate the current
              expected version.</t>

              <t>The PDU is encrypted up to the authMode field using a new
              random IV, if doing encryption.</t>

              <t>The authUnixTime field is updated to the current system
              (wall-clock) time and the authDigest is recalculated, if doing
              authentication.</t>
            </list></t>

          <t>The Setup Request/Response message PDU SHALL be organized as
          follows:</t>

          <t><figure anchor="CHSR" title="Test Setup PDU">
              <artwork>
&lt;CODE BEGINS&gt;
//
// Control header for UDP payload of Setup Request/Response PDUs
//
struct controlHdrSR {
#define CHSR_ID 0xACE1
        uint16_t pduId;   // PDU ID
#define PROTOCOL_VER 20
        uint16_t protocolVer; // Protocol version
        uint8_t mcIndex;      // Multi-connection index
        uint8_t mcCount;      // Multi-connection count
        uint16_t mcIdent;     // Multi-connection identifier
#define CHSR_CREQ_NONE     0
#define CHSR_CREQ_SETUPREQ 1   // Setup request
#define CHSR_CREQ_SETUPRSP 2   // Setup response
        uint8_t cmdRequest;    // Command request
#define CHSR_CRSP_NONE     0   // (used with request)
#define CHSR_CRSP_ACKOK    1   // Acknowledgment
#define CHSR_CRSP_BADVER   2   // Bad version
#define CHSR_CRSP_BADJS    3   // Jumbo setting mismatch
#define CHSR_CRSP_AUTHNC   4   // Auth. not configured
#define CHSR_CRSP_AUTHREQ  5   // Auth. required
#define CHSR_CRSP_AUTHINV  6   // Auth. (mode) invalid
#define CHSR_CRSP_AUTHFAIL 7   // Auth. failure
#define CHSR_CRSP_AUTHTIME 8   // Auth. time invalid
#define CHSR_CRSP_NOMAXBW  9   // Max bandwidth required
#define CHSR_CRSP_CAPEXC   10  // Capacity exceeded
#define CHSR_CRSP_BADTMTU  11  // Trad. MTU mismatch
#define CHSR_CRSP_MCINVPAR 12  // Multi-conn. invalid params
#define CHSR_CRSP_CONNFAIL 13  // Conn. allocation failure
        uint8_t cmdResponse;   // Command response
#define CHSR_USDIR_BIT 0x8000  // Upstream direction bit
        uint16_t maxBandwidth; // Required bandwidth in Mbps
        uint16_t testPort;     // Test port on server
#define CHSR_JUMBO_STATUS    0x01
#define CHSR_TRADITIONAL_MTU 0x02
        uint8_t modifierBitmap; // Modifier bitmap
        uint8_t reserved1;      // (reserved for alignment)
        uint16_t checkSum;      // Header checksum
        uint16_t reserved2;     // (reserved for alignment)
        //
        uint8_t padding[12]; // Padding for encryption
        // ========== Encryption ends here ==========
#define AUTHMODE_0 0 // Mode 0: Unauthenticated
#define AUTHMODE_1 1 // Mode 1: Authenticated Control
#define AUTHMODE_2 2 // Mode 2: Authenticated Control+Status
#define AUTHMODE_3 3 // Mode 3: Encrypted+Auth Control+Status
        uint8_t authMode;        // Authentication mode
        uint8_t keyId;           // Key ID in shared table
        uint16_t reserved-auth1; // (reserved for alignment)
        uint32_t authUnixTime;   // Authentication time stamp
#define AUTH_IV_LENGTH 16        // Initialization Vector length
        uint8_t initVector[AUTH_IV_LENGTH]     // IV
#define AUTH_DIGEST_LENGTH 32    // SHA-256 digest length
        uint8_t authDigest[AUTH_DIGEST_LENGTH] // HMAC
};
#define SHA256_KEY_LEN 32 // Authentication key length
#define AES128_KEY_LEN 16 // Encryption key length
&lt;CODE ENDS&gt;
        </artwork>

              <postamble/>
            </figure></t>
        </section>

        <section title="Test Setup Request Processing - Acceptance">
          <t>If the server finds that the Setup Request matches its
          configuration and is otherwise acceptable, the server SHALL initiate
          a new connection to receive the Test Activation Request from the
          client, using a new UDP socket allocated from the UDP ephemeral port
          range. This new socket will also be used for the subsequent Load and
          Status PDUs that are part of testing (with the port number
          communicated back to the client in testPort field of the Test Setup
          Response). Then, the server SHALL start a watchdog timer (to
          terminate the new connection if the client goes silent) and SHALL
          send the Test Setup Response back to the client. The watchdog timer
          is set to the same values as on the Client side (see <xref
          target="Test-Setup"/>)</t>

          <t>When the server replies to the Test Setup Request message, the
          Test Setup Response PDU is structured identically to the Request PDU
          and SHALL retain the original values received in it, with the
          following exceptions:</t>

          <t><list style="symbols">
              <t>The cmdRequest field is set to CHSR_CREQ_SETUPRSP, indicating
              a response.</t>

              <t>The cmdResponse field is set to CHSR_CRSP_ACKOK, indicating
              an acknowledgment.</t>

              <t>The testPort field is set to the ephemeral port number to be
              used for the client's Test Activation Request and all subsequent
              communication.</t>

              <t>The PDU is encrypted up to the authMode field using a new
              random IV, if doing encryption.</t>

              <t>The authUnixTime field is updated to the current system
              (wall-clock) time and the authDigest is recalculated, if doing
              authentication.</t>
            </list></t>

          <t>Finally, the new UDP connection associated with the new socket
          and port are made ready, and the server awaits further communication
          there.</t>

          <t>To ensure that a server's local firewall will successfully allow
          packets received for the new ephemeral port, the server SHALL
          immediately send a Null Request with the corresponding values
          including the source and destination IP addresses and port numbers.
          The source port SHALL be the new ephemeral port. This operation
          allows communication to the server even when the server's local
          firewall prohibits open ranges of ephemeral ports. The packet is not
          expected to arrive successfully at the client if the client-side
          firewall blocks unexpected traffic. If the Null Request arrives at
          the client, it is a confirmation that further exchanges are possible
          on the new port-pair (but this is not strictly necessary). Note that
          there is no response to a Null Request.</t>

          <t>The UDP PDU format layout SHALL be as follows (big-endian
          AB):</t>

          <t><figure anchor="Null-Request" title="Null Request PDU Layout">
              <artwork>
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            pduId              |          protocolVer          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  cmdRequest   |  cmdResponse  |           checkSum            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      padding (8 octets)                       |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   authMode    |     keyId     |          reserved1a           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         authUnixTime                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                     initVector (16-octet)                    .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                     authDigest (32-octet)                    .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        </artwork>

              <postamble/>
            </figure></t>

          <t>Additional details regarding the Null Request fields are as
          follows:</t>

          <t>pduId: A two-octet field. IANA is asked to assign the value hex
          0xDEAD (<xref target="pduId"/>).</t>

          <t>cmdRequest: Is set to CHNR_CREQ_NULLREQ indicating a Null Request
          message.</t>

          <t>cmdResponse: Is set to CHNR_CRSP_NONE.</t>

          <t>checkSum: An optional checksum of the PDU (see <xref
          target="Checksum"/> for guidance). The calculation is done with the
          checkSum field, and all fields starting with authMode, set to
          zero.</t>

          <t>If a Test Activation Request is not subsequently received from
          the client on the new ephemeral port number before the watchdog
          timer expires, the server SHALL close the socket and deallocate the
          associated resources.</t>

          <t>The Null Request message PDU SHALL be organized as follows:</t>

          <t><figure anchor="CHNR" title="Null Request PDU">
              <artwork>
&lt;CODE BEGINS&gt;  
//
// Control header for UDP payload of Null Request PDU
//
struct controlHdrNR {
#define CHNR_ID 0xDEAD
        uint16_t pduId;       // PDU ID
        uint16_t protocolVer; // Protocol version
#define CHNR_CREQ_NONE    0
#define CHNR_CREQ_NULLREQ 1  // Null request
        uint8_t cmdRequest;  // Command request
#define CHNR_CRSP_NONE 0     // (used with request)
        uint8_t cmdResponse; // Command response
        uint16_t checkSum;   // Header checksum
        //
        uint8_t padding[8];  // Padding for encryption
        // ========== Encryption ends here ==========
        uint8_t authMode;        // Authentication mode
        uint8_t keyId;           // Key ID in shared table
        uint16_t reserved-auth1; // (reserved for alignment)
        uint32_t authUnixTime;   // Authentication time stamp
        uint8_t initVector[AUTH_IV_LENGTH]     // IV
        uint8_t authDigest[AUTH_DIGEST_LENGTH] // HMAC
};
&lt;CODE ENDS&gt;
        </artwork>

              <postamble/>
            </figure></t>
        </section>
      </section>

      <section title="Setup Response Processing at the Client">
        <t>When the client receives the Test Setup Response message, it
        SHALL:</t>

        <t><list style="symbols">
            <t>verify the size of the Setup Response message and if correct
            interrogate the authMode field,</t>

            <t>if operating in one of the Authenticated modes, validate the
            Setup Response message by checking the authDigest as prescribed in
            <xref target="Auth-Mode-1"/>,</t>

            <t>if operating in the Encryption mode, use the server encryption
            key from the KDF (derived from the keyId designated key) and the
            IV to decrypt the Setup Response message up to the authMode field
            using the method prescribed in <xref target="Auth-Mode-3"/>,</t>
          </list></t>

        <t>and then proceed to evaluate the other fields in the protocol,
        beginning with the protocol version, PDU ID (to validate the type of
        message), and cmdRequest for the role of the message, which MUST be
        Test Setup Response, CHSR_CREQ_SETUPRSP, as indicated by <xref
        target="CHSR"/>.</t>

        <t>If the cmdResponse value indicates an error (values greater than
        CHSR_CRSP_ACKOK) the client SHALL display/report a relevant message to
        the user or management process and exit. If the client receives a
        Command Response code that is not equal to one of the codes defined,
        the client MUST terminate the connection and terminate operation of
        the current Setup Request. If the Command Server Response code value
        indicates success (CHSR_CRSP_ACKOK), the client SHALL compose a Test
        Activation Request with all the test parameters it desires, such as
        the test direction, the test duration, etc., as described below.</t>
      </section>
    </section>

    <section anchor="Test-Activation"
             title="Test Activation Request and Response">
      <t>This section is divided according to the sending and processing of
      the client, server, and again at the client.</t>

      <section anchor="Client-Gen-Activation"
               title="Client Generates Test Activation Request">
        <t>Upon a successful setup exchange, the client SHALL compose and send
        the Test Activation Request to the UDP port number the server
        communicated in the Test Setup Response (the new ephemeral port, and
        not the standard UDPSTP port).</t>

        <t>The UDP PDU format layout is as follows (big-endian AB):</t>

        <t><figure anchor="Test-Activation-PDU"
            title="Test Activation PDU Layout">
            <artwork>
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          txInterval1                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          udpPayload1                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          burstSize1                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          txInterval2                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          udpPayload2                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          burstSize2                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           udpAddon2                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            pduId              |          protocolVer          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  cmdRequest   | cmdResponse   |           lowThresh           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         upperThresh           |           trialInt            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         testIntTime           |   reserved1   |   dscpEcn     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         srIndexConf           |  useOwDelVar  |highSpeedDelta |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         slowAdjThresh         |         seqErrThresh          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ignoreOooDup  |modifierBitmap |  rateAdjAlgo  |   reserved2   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                      srStruct (28 octets)                     .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|        subIntPeriod           |           checkSum            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      padding (4 octets)                       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   authMode    |     keyId     |        reserved-auth1         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         authUnixTime                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                     initVector (16-octet)                    .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                     authDigest (32-octet)                    .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        </artwork>

            <postamble/>
          </figure></t>

        <t>Fields are populated based on default values or command-line
        options. Authentication and encryption modes follow the same
        methodology as with the Setup Request and Response.</t>

        <t>pduId: A two-octet field. IANA is asked to assign the value hex
        0xACE2 (<xref target="pduId"/>).</t>

        <t>cmdRequest: Is set to CHTA_CREQ_TESTACTUS to indicate an upstream
        test activation or alternatively to CHTA_CREQ_TESTACTDS to indicate a
        downstream test activation. Note that CHTA_CREQ_NONE remains unused.
        See <xref target="ActivationCmdRequest"/>.</t>

        <t>cmdResponse: three CHTA_CRSP_&lt;Indication&gt; values are defined,
        see <xref target="CHTA"/>.</t>

        <t>lowThresh, upperThresh: see Table 3 of <xref target="TR-471"/>.</t>

        <t>trialInt: Status Feedback / trial interval [ms]. The test interval
        Delta_t is subdivided into a number of sub-intervals dt, and each
        sub-interval is further divided into a number of trial intervals (see
        <xref target="TR-471"/>). Starts by 1 and is continuosly incremented
        during a single test interval (testIntTime).</t>

        <t>testIntTime: see TestInterval, Table 3 of <xref
        target="TR-471"/>.</t>

        <t>dscpEcn: The Load PDU Differentiated Services and ECN Fields as
        specified by section 5 of <xref target="RFC3168"/>. Note that the
        DiffServ Codepoint (DSCP) is denoted by the 6 most significant bits.
        The DSCP field specified by <xref target="TR-471"/> is a subset of the
        dscpEcn field.</t>

        <t>useOwDelVar: Boolean, see EnableIPDV in Table 1 of <xref
        target="TR-471"/>.</t>

        <t>highSpeedDelta, slowAdjThresh, seqErrThresh: see Appendix A of
        <xref target="RFC9097"/>.</t>

        <t>ignoreOooDup: Boolean, see ReordDupIgnoreEnable in Table 3 of <xref
        target="TR-471"/>.</t>

        <t>srIndexConf: The requested Configured Sending Rate Table index,
        used in a Test Activation Request, of the desired fixed or starting
        sending rate (depending on whether CHTA_SRIDX_ISSTART is cleared or
        set respectively). Because a value of zero is a valid fixed or
        starting sending rate index, the field SHALL be set to its maximum
        (CHTA_SRIDX_DEF) when requesting the default behavior of the server
        (starting the selected load rate adjustment algorithm at its
        minimum/zero index). This SHALL be equivalent to setting srIndexConf
        to zero and setting the CHTA_SRIDX_ISSTART bit.</t>

        <t>rateAdjAlgo: The applied Load Rate Adjustment Algorithm, see <xref
        target="Activation-rateAdjAlgo"/>.</t>

        <t>modifierBitmap: this document only assigns two bits in this bitmap,
        see <xref target="Activation-modifierBitmap"/>:</t>

        <t><list style="hanging">
            <t hangText="CHTA_SRIDX_ISSTART">Treat srIndexConf as the starting
            sending rate to be used by the load rate adjustment algorithm</t>

            <t hangText="CHTA_RAND_PAYLOAD">Randomize the Payload Content
            beyond the Load PDU header</t>
          </list>Other bit positions are left unassigned by this document.</t>

        <t>Sending Rate structure (srStruct), used by the server in a Test
        Activation Response for an upstream test, to communicate the (initial)
        Load PDU transmission parameters the client SHALL use. For a Test
        Activation Request or a downstream test, this structure SHALL be
        zeroed. Two sets of periodic transmission parameters are available,
        allowing for dual independent transmitters (to support a high degree
        of rate granularity). The fields are defined as follows:</t>

        <t>txInterval1 and txInterval2: load rate transmit interval in [us]. A
        100 us granularity is recommended for optimal rate selection.</t>

        <t>udpPayload1 and udpPayload2: load rate UDP payload in [byte].</t>

        <t>burstSize1 and burstSize2: load rate burst size by a dimensionless
        number (of datagrams).</t>

        <t>udpAddon2: the size of a single Load PDU to be sent at the end of
        the txInterval2 send sequence, even when udpPayload2 or burstSize2 are
        zero and result in no transmission of their own.</t>

        <t>subIntPeriod: Test Sub-interval period in [ms], see dt
        (TestSubInterval) in Table 1 of <xref target="TR-471"/>, default 1000
        ms.</t>

        <t>checkSum: An optional checksum of the entire PDU ( see <xref
        target="Checksum"/> for guidance). The calculation is done with the
        checkSum field, and all fields starting with authMode, set to
        zero.</t>

        <t>The Test Activation Request/Response message PDU (as well as the
        included Sending Rate structure) SHALL be organized as follows:</t>

        <t><figure anchor="CHTA" title="Test Activation PDU">
            <artwork>
&lt;CODE BEGINS&gt;
//
// Sending rate structure for a single row of transmission parameters
//
struct sendingRate {
        uint32_t txInterval1; // Transmit interval (us)
        uint32_t udpPayload1; // UDP payload (bytes)
        uint32_t burstSize1;  // UDP burst size per interval
        uint32_t txInterval2; // Transmit interval (us)
        uint32_t udpPayload2; // UDP payload (bytes)
        uint32_t burstSize2;  // UDP burst size per interval
        uint32_t udpAddon2;   // UDP add-on (bytes)
};
//
// Control header for UDP payload of Test Act. Request/Response PDUs
//
struct controlHdrTA {
#define CHTA_ID 0xACE2
        uint16_t pduId;       // PDU ID
        uint16_t protocolVer; // Protocol version
#define CHTA_CREQ_NONE      0
#define CHTA_CREQ_TESTACTUS 1 // Test activation upstream
#define CHTA_CREQ_TESTACTDS 2 // Test activation downstream
        uint8_t cmdRequest;   // Command request
#define CHTA_CRSP_NONE     0  // (used with request)
#define CHTA_CRSP_ACKOK    1  // Acknowledgment
#define CHTA_CRSP_BADPARAM 2  // Bad/invalid test params
        uint8_t cmdResponse;  // Command response
        uint16_t lowThresh;   // Low delay variation threshold (ms)
        uint16_t upperThresh; // Upper delay variation threshold (ms)
        uint16_t trialInt;    // Status Feedback/trial interval (ms)
        uint16_t testIntTime; // Test interval time (sec)
        uint8_t reserved1;    // (reserved for alignment)
        uint8_t dscpEcn;      // DiffServ and ECN field for testing
#define CHTA_SRIDX_DEF UINT16_MAX // Request default server search
        uint16_t srIndexConf; // Configured Sending Rate Table index
        uint8_t useOwDelVar;  // Use one-way delay, not RTT (BOOL)
        uint8_t highSpeedDelta; // High-speed row adjustment delta
        uint16_t slowAdjThresh; // Slow rate adjustment threshold
        uint16_t seqErrThresh;  // Sequence error threshold
        uint8_t ignoreOooDup;   // Ignore Out-of-Order/Dup (BOOL)
#define CHTA_SRIDX_ISSTART 0x01 // Use srIndexConf as starting index
#define CHTA_RAND_PAYLOAD  0x02 // Randomize payload
        uint8_t modifierBitmap; // Modifier bitmap
#define CHTA_RA_ALGO_B   0   // Algorithm B
#define CHTA_RA_ALGO_C   1   // Algorithm C
        uint8_t rateAdjAlgo; // Rate adjust. algorithm
        uint8_t reserved2;   // (reserved for alignment)
        struct sendingRate srStruct; // Sending rate structure
        uint16_t subIntPeriod;       // Sub-interval period (msec)
        uint16_t checkSum;   // Header checksum
        //
        uint8_t padding[4];  // Padding for encryption
        // ========== Encryption ends here ==========
        uint8_t authMode;        // Authentication mode
        uint8_t keyId;           // Key ID in shared table
        uint16_t reserved-auth1; // (reserved for alignment)
        uint32_t authUnixTime;   // Authentication time stamp
        uint8_t initVector[AUTH_IV_LENGTH]     // IV
        uint8_t authDigest[AUTH_DIGEST_LENGTH] // HMAC
};
&lt;CODE ENDS&gt;
        </artwork>

            <postamble/>
          </figure></t>
      </section>

      <section title="Server Processes Test Activation Request and Generates Response">
        <t>After the server receives the Test Activation Request on the new
        connection, it MUST choose to accept, ignore or modify any of the test
        parameters. When the server replies to the Test Activation Request
        message, the Test Activation Response PDU is structured identically to
        the Request PDU and SHALL retain the original values received in it
        unless they are explicitly coerced to a server acceptable value.</t>

        <section title="Server Rejects or Modifies Request">
          <t>When evaluating the Test Activation Request, the server MAY allow
          the client to specify its own fixed or starting send rate via
          srIndexConf.</t>

          <t>Alternatively, the server MAY enforce a maximum limit of the
          fixed or starting send rate which the client can successfully
          request. If the client's Test Activation Request exceeds the
          server's configured maximum, the server MUST either reject the
          request or coerce the value to the configured maximum bit rate, and
          communicate that maximum to the client in the Test Activation
          Response. The client can of course choose to end the test, as
          appropriate.</t>

          <t>Other parameters where the server has the OPTION to coerce the
          client to use values other than those in the Test Activation Request
          are (grouped by role):</t>

          <t><list style="symbols">
              <t>Load rate adjustment algorithm: lowThresh, upperThresh,
              useOwDelayVar, highSpeedDelta, slowAdjThresh, seqErrThresh,
              highSpeedDelta, ignoreOooDup, rateAdjAlgo.</t>

              <t>Test duration/intervals: trialInt, testIntTime,
              subIntPeriod</t>

              <t>Packet marking: dscpEcn</t>
            </list>Coercion is a step towards performing a test with the
          server-configured values; even though the client might prefer
          certain values, the server gives the client an opportunity to run a
          test with different values than the preferred set. In these cases,
          the Command Response value SHALL be CHTA_CRSP_ACKOK.</t>

          <t>Note that the server also has the option of completely rejecting
          the request and sending back an appropriate cmdResponse field value
          (currently only CHTA_CRSP_BADPARAM, see <xref
          target="Activation-cmdResponse"/>).</t>

          <t>Whether this error response is sent or not depends on the
          Security mode of operation and the outcome of authDigest
          validation.</t>

          <t>If the Test Activation Request must be rejected (due to the
          Command Response value being CHTA_CRSP_BADPARAM), and</t>

          <t><list style="symbols">
              <t>In Authenticated modes, if the authDigest is valid, a Test
              Activation Response SHALL be sent back to the client with a
              corresponding command response value indicating the reason for
              the rejection. If operating in the Encryption mode, the server
              SHALL follow the requirements of <xref target="Auth-Mode-3"/>,
              else the server SHALL follow the requirements of <xref
              target="Auth-Mode-1"/>.</t>

              <t>In Authenticated modes, if the authDigest is invalid, then
              the Test Activation Request SHOULD fail silently. The exception
              is for operations support: server administrators using
              Authentication are permitted to send a Setup Response to support
              operations and troubleshooting.</t>

              <t>If Unauthenticated mode is selected, the Test Activation
              Request SHALL fail silently.</t>
            </list></t>

          <t>The additional, non-authentication circumstances when a server
          SHALL NOT communicate the appropriate Command Response code for an
          error condition (fail silently) are when: <list style="numbers">
              <t>the Test Activation Request PDU size is not equal to the
              'struct controlHdrTA' size shown in <xref target="CHTA"/>,</t>

              <t>the PDU ID is not 0xACE2 (Test Activation PDU), or</t>

              <t>a directed attack has been detected,</t>
            </list>in which case the server will allow Test Activation
          Requests to terminate silently. Attack detection is beyond the scope
          of this specification.</t>
        </section>

        <section title="Server Accepts Request and Generates Response">
          <t>When the server sends the Test Activation Response, it SHALL set
          the cmdResponse field to CHTA_CRSP_ACKOK (see <xref
          target="Activation-cmdResponse"/>)</t>

          <t>If the client has requested an upstream test, the server
          SHALL:</t>

          <t><list style="symbols">
              <t>include the transmission parameters from the first row of the
              Sending Rate Table in the Sending Rate structure (if requested
              by srIndexConf having been set to CHTA_SRIDX_DEF), or</t>

              <t>include the transmission parameters from the designated
              Configured Sending Rate Table index (srIndexConf) of the Sending
              Rate Table where, if CHTA_SRIDX_ISSTART is set in
              modifierBitmap, this will be used as the starting rate for the
              load rate adjustment algorithm, else it will be considered a
              fixed rate test.</t>
            </list></t>

          <t>When generating the Test Activation Response (acceptance) for a
          downstream test, the server SHALL set all octets of the Sending Rate
          structure to zero.</t>

          <t>If activation continues, the server prepares the new connection
          for an upstream OR downstream test.</t>

          <t>In the case of an upstream test, the server SHALL prepare to use
          a single timer to send Status PDUs at the specified interval. For a
          downstream test, the server SHALL prepare to utilize dual timers to
          send Load PDUs based on</t>

          <t><list style="symbols">
              <t>the transmission parameters directly from the first row of
              the Sending Rate Table (if requested by srIndexConf having been
              set to CHTA_SRIDX_DEF), or</t>

              <t>the transmission parameters from the designated Configured
              Sending Rate Table index (srIndexConf) of the Sending Rate Table
              where, if CHTA_SRIDX_ISSTART is set in modifierBitmap, this will
              be used as the starting rate for the load rate adjustment
              algorithm, else it will be considered a fixed rate test.</t>
            </list></t>

          <t>The server SHALL then send the Test Activation Response back to
          the client, update the watchdog timer with a new timeout value, and
          set a test duration timer to eventually stop the test.</t>
        </section>
      </section>

      <section title="Client Processes Test Activation Response">
        <t>When the client receives the Test Activation Response, it
        SHALL:</t>

        <t><list style="symbols">
            <t>If operating in an Authenticated mode, check the message PDU
            for validity via the authDigest field and acceptable immediacy via
            the authUnixTime field. If validated, and if operating in the
            Encryption mode, decrypt the PDU using the included IV and the
            server encryption key from the KDF (derived from the keyId
            designated shared key). Finally, check the PDU for general
            formatting, such as protocol version, and any PDU-specific fields
            that control the test.</t>
          </list></t>

        <t>When the client receives the (vetted) Test Activation Response, it
        first checks the command response value.</t>

        <t>If the client receives a Test Activation cmdResponse field value
        that indicates an error, the client SHALL display/report a relevant
        message to the user or management process and exit.</t>

        <t>If the client receives a Test Activation cmdResponse field value
        that is not equal to one of the codes defined in <xref
        target="Activation-cmdResponse"/>, the client MUST terminate the
        connection and terminate operation of the current setup procedure.</t>

        <t>If the client receives a Test Activation Command Response value
        that indicates success (CHTA_CRSP_ACKOK, see <xref
        target="Activation-cmdResponse"/>), the client SHALL update its
        configuration to use any test parameters modified by the server. If
        the setup parameters coerced by the server are not acceptable to the
        client, the client ends the test.</t>

        <t>To finalize an accepted test activation, the client SHALL prepare
        its connection for either an upstream test with dual timers set to
        send Load PDUs (based on the starting transmission parameters sent by
        the server), OR a downstream test with a single timer to send Status
        PDUs at the specified interval.</t>

        <t>Then, the client SHALL stop the test initiation timer and start a
        watchdog timer to detect if the server goes quiet.</t>

        <t>The connection is now ready for testing.</t>
      </section>
    </section>

    <section anchor="Test-Measurement"
             title="Test Stream Transmission and Measurement Feedback Messages">
      <t>This section describes the data phase of the protocol. The roles of
      sender and receiver vary depending on whether the direction of testing
      is from server to client, or the reverse.</t>

      <section title="Test Packet PDU and Roles">
        <t>Testing proceeds with one endpoint sending Load PDUs, based on
        transmission parameters from the Sending Rate Table, and the other
        endpoint sending Status Feedback messages to communicate the traffic
        conditions at the receiver. When the server is sending Status Feedback
        messages, they will also contain the latest transmission parameters
        from the Sending Rate Table that the client SHALL use.</t>

        <t>The watchdog timer at the receiver SHALL be reset each time a PDU
        is received. See non-graceful test stop in <xref target="Test-Stop"/>
        for handling the watchdog timeout expiration at each endpoint.</t>

        <t>When the server is sending Load PDUs in the role of sender, it
        SHALL use the transmission parameters directly from the Sending Rate
        Table via the index that is currently selected (which was indirectly
        based on the feedback in its received Status Feedback messages).</t>

        <t>However, when the client is sending Load PDUs in the role of
        sender, it SHALL use the discreet transmission parameters that were
        communicated by the server in its periodic Status Feedback messages
        (and not referencing a Sending Rate Table directly). This approach
        allows the server to control the individual sending rates as well as
        the algorithm used to decide when and how to adjust the rate.</t>

        <t>The server uses a load rate adjustment algorithm which evaluates
        measurements taken locally at the Load PDU receiver. When the client
        is the receiver, the information is communicated to the server via the
        periodic Status Feedback messages. When the server is the receiver,
        the information is used directly (although it is also communicated to
        the client via its periodic Status Feedback messages). This approach
        is unique to this protocol; it provides the ability to search for the
        Maximum IP Capacity and specify specific sender behaviors that is
        absent from other testing tools. Although the algorithm depends on the
        protocol, it is not part of the protocol per se.</t>

        <t>The default algorithm (B, see <xref target="Y.1540"/>) has three
        paths to its decision on the next sending rate:<list style="numbers">
            <t>When there are no impairments present (no sequence errors and
            low delay variation), resulting in a sending rate increase.</t>

            <t>When there are low impairments present (no sequence errors but
            higher levels of delay variation), the same sending rate is
            maintained.</t>

            <t>When the impairment levels are above the thresholds set for
            this purpose and "congestion" is inferred, resulting in a sending
            rate decrease.</t>
          </list></t>

        <t>Algorithm B also has two modes for increasing/decreasing the
        sending rate:<list style="symbols">
            <t>A high-speed mode (fast) to achieve high sending rates quickly,
            but also back-off quickly when "congestion" is inferred from the
            measurements. Consecutive feedback intervals that have a
            supra-threshold count of sequence number anomalies and/or contain
            an upper delay variation threshold exception in all of the
            consecutive intervals are sufficient to declare "congestion"
            within a test. The threshold of consecutive feedback intervals
            SHALL be configurable with a default of 3 intervals.</t>

            <t>A single-step (slow) mode where all rate adjustments use the
            minimum increase or decrease of one step in the sending rate
            table. The single step mode continues after the first inference of
            "congestion" from measured impairments.</t>
          </list></t>

        <t>An OPTIONAL load rate adjustment algorithm (designated C) has been
        defined in <xref target="TR-471"/>. Algorithm C operation and modes
        are similar to B, but C uses multiplicative increases in the fast mode
        to reach the Gigabit range quickly and adds the possibility to re-try
        the fast mode during a test (which improves the measurement accuracy
        in dynamic or error-prone access, such as radio access).</t>

        <t>On the other hand, the test configuration MAY use a fixed sending
        rate requested by the client, using the field srIndexConf.</t>

        <t>The client MAY communicate the desired fixed rate in its test
        activation request. The reasons to conduct a fixed-rate test include
        stable measurement at the maximum determined by the load rate
        adjustment algorithm, or the desire to test at a known subscribed rate
        without searching.</t>

        <t>The UDP PDU format layout SHALL be as follows (big-endian AB):</t>

        <t><figure anchor="Load-PDU" title="Load PDU Layout">
            <artwork>   
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            pduId              |   testAction  |   rxStopped   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           lpduSeqNo                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           udpPayload          |           spduSeqErr          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          spduTime_sec                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         spduTime_nsec                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          lpduTime_sec                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         lpduTime_nsec                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         rttRespDelay          |           checkSum            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                       Payload Content...                      .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        </artwork>

            <postamble/>
          </figure></t>

        <t>Specific details regarding Load PDU fields are as follows:</t>

        <t>pduId: A two-octet field. IANA is asked to assign the value hex
        0xBEEF (<xref target="pduId"/>).</t>

        <t>testAction: Designates the current test action as either
        TEST_ACT_TEST (testing in progress), TEST_ACT_STOP1 (first phase of
        graceful termination, used locally by server), or TEST_ACT_STOP2
        (second phase of graceful termination, sent by server and reciprocated
        by client). See <xref target="Test-Stop"/> for additional information
        on test termination.</t>

        <t>rxStopped: A boolean (0 or 1) used to indicate to the remote
        endpoint that local receive traffic (either Load or Status PDUs) has
        stopped. All outgoing Load or Status PDUs SHALL continue to assert
        this indication until traffic is received again, or the test is
        terminated. The time threshold to trigger this condition is expected
        to be a reasonable fraction of the watchdog timeout (a default of one
        second is recommended).</t>

        <t>lpduSeqNo: Load PDU sequence number (starting at 1). Used to
        determine loss, out-of-order, and duplicates.</t>

        <t>udpPayload: The total payload size of the UDP datagram including
        the Load PDU message header and Payload Content (i.e., what the UDP
        socket read function would return). This field allows the Load PDU
        receiver to maintain accurate receive statistics if utilizing receive
        truncation (only requesting the Load PDU message header octets from
        the protocol stack).</t>

        <t>spduSeqErr: Status PDU loss count, as seen by the Load PDU sender.
        This is determined by the Status PDU sequence number (spduSeqNo) in
        the most recently received Status PDU. Used to communicate to the Load
        PDU receiver that return traffic (in the unloaded direction) is being
        lost.</t>

        <t>spduTime_sec/spduTime_nsec: A copy of the most recent
        spduTime_sec/spduTime_nsec from the last Status PDU received. Used for
        RTT measurements made by the Load PDU receiver.</t>

        <t>lpduTime_sec/lpduTime_nsec: The local send time of the Load PDU.
        Used for one-way delay variation measurements made by the Load PDU
        receiver.</t>

        <t>rttRespDelay: RTT response delay, used to "adjust" raw RTT. On the
        Load PDU sender, it is the number of milliseconds from reception of
        the most recent Status PDU (when the latest spduTime_sec/spduTime_nsec
        was obtained) to the transmission of the Load PDU (where the
        previously obtained spduTime_sec/spduTime_nsec is returned). When the
        Load PDU receiver is calculating RTT, by subtracting the copied Status
        PDU send time (in the Load PDU) from the local Load PDU receive time,
        this value is subtracted from the raw RTT to correct for any response
        delay due to Load PDU scheduling.</t>

        <t>checkSum: An optional checksum of only the Load PDU header (see
        <xref target="Checksum"/> for guidance). The checksum does not cover
        the Payload Content. The calculation is done with the checkSum field
        set to zero.</t>

        <t>Payload Content: All zeroes, all ones, or a pseudorandom binary
        sequence.</t>

        <t>The Load PDU SHALL be organized as follows (followed by any payload
        content):</t>

        <t><figure anchor="TEST_ACT" title="Load PDU">
            <artwork>        
&lt;CODE BEGINS&gt;
//
// Load header for UDP payload of Load PDUs
//
struct loadHdr {
#define LOAD_ID 0xBEEF
        uint16_t pduId;  // PDU ID
#define TEST_ACT_TEST  0 // Test active
#define TEST_ACT_STOP1 1 // Stop indication used locally by server
#define TEST_ACT_STOP2 2 // Stop indication exchanged with client
        uint8_t testAction;  // Test action
        uint8_t rxStopped;   // Receive traffic stopped (BOOL)
        uint32_t lpduSeqNo;  // Load PDU sequence number
        uint16_t udpPayload; // UDP payload (bytes)
        uint16_t spduSeqErr; // Status PDU sequence error count
        uint32_t spduTime_sec;  // Send time in last rx'd status PDU
        uint32_t spduTime_nsec; // Send time in last rx'd status PDU
        uint32_t lpduTime_sec;  // Send time of this load PDU
        uint32_t lpduTime_nsec; // Send time of this load PDU
        uint16_t rttRespDelay;  // Response delay for RTT (ms)
        uint16_t checkSum;      // Header checksum
};
&lt;CODE ENDS&gt;
        </artwork>

            <postamble/>
          </figure></t>
      </section>

      <section anchor="Status-PDU" title="Status PDU">
        <t>The Load PDU receiver SHALL send a Status PDU to the sender during
        a test at the configured feedback interval, after at least one Load
        PDU has been received (when there is something to provide status on).
        In test scenarios with long delays between client and server, it is
        possible for the Status PDU send timer to fire before the first Load
        PDU arrives. In these cases, the Status PDU SHALL NOT be sent.</t>

        <t>The watchdog timer at the Load PDU sender SHALL be reset each time
        a Status PDU is received. See non-graceful test stop in <xref
        target="Test-Stop"/> for handling the watchdog timeout expiration at
        each endpoint.</t>

        <t>The UDP PDU format layout SHALL be as follows (big-endian AB):</t>

        <t><figure anchor="StatPDU" title="Status PDU Layout">
            <artwork>   
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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          rxDatagrams                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            rxBytes                            |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           deltaTime                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           seqErrLoss                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           seqErrOoo                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           seqErrDup                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          delayVarMin                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          delayVarMax                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          delayVarSum                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          delayVarCnt                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         rttVarMinimum                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         rttVarMaximum                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           accumTime                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|             pduId             |   testAction  |   rxStopped   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           spduSeqNo                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                      srStruct (28 octets)                     .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          subIntSeqNo                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                      sisSav (56 octets)                       .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           seqErrLoss                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           seqErrOoo                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           seqErrDup                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         clockDeltaMin                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          delayVarMin                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          delayVarMax                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          delayVarSum                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          delayVarCnt                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          rttMinimum                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         rttVarSample                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  delayMinUpd  |   reserved1   |           checkSum            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          tiDeltaTime                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         tiRxDatagrams                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           tiRxBytes                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         spduTime_sec                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         spduTime_nsec                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   authMode    |     keyId     |        reserved-auth1         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         authUnixTime                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                     initVector (16-octet)                    .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                     authDigest (32-octet)                    .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        </artwork>

            <postamble/>
          </figure></t>

        <t>Note that the Sending Rate structure is defined in <xref
        target="Test-Activation"/>.</t>

        <t>The primary role of the Status Feedback message is to communicate
        to the Load PDU sender the traffic conditions at the Load PDU
        receiver. While the Sub-Interval Statistics structure (sisSav) covers
        the most recently saved (completed) sub-interval, similar fields
        directly in the Status PDU itself cover the most recent trial interval
        (the time period between Status Feedback messages, completed by this
        Status PDU). Both sets of statistics SHALL always be populated by the
        Load PDU receiver, regardless of role (client or server).</t>

        <t>Details on the Status PDU measurement fields are provided in <xref
        target="RFC9097"/>. Additional information regarding fields not
        defined previously are as follows:</t>

        <t>pduId: A two-octet field. IANA is asked to assign the value hex
        0xFEED (<xref target="pduId"/>).</t>

        <t>spduSeqNo: Status PDU sequence number (starting at 1). Used by the
        Load PDU sender to detect Status PDU loss (in the unloaded direction).
        The loss count is communicated back to the Load PDU receiver via
        spduSeqErr in subsequent Load PDUs.</t>

        <t>subIntSeqNo: Sub-interval sequence number (starting at 1) that
        corresponds to the statistics provided in sisSav, for the last saved
        (completed) sub-interval.</t>

        <t>sisSav: Sub-interval statistics saved (completed) for the most
        recent sub-interval (as designated by the subIntSeqNo). These consist
        of the following fields:</t>

        <t>rxDatagrams/rxBytes/deltaTime: Sub-interval received datagram and
        byte counts as well as the exact duration of the sub-interval in
        microseconds. Used to calculate the received traffic rate for the
        sub-interval. The rxBytes field is a 64-bit value to prevent overflow
        at high speeds.</t>

        <t>seqErrLoss/seqErrOoo/seqErrDup: Loss, out-of-order, and duplicate
        totals. Available for both the sub-interval and trial interval, it is
        a breakout of the SeqErrors count in Table 3 of <xref
        target="TR-471"/>. seqErrOoo and seqErrDup are realized by comparing
        sequence numbers. A lookback list of the last n sequence numbers
        received is used as the basis. Each Load PDU sequence number is
        checked against this lookback. The number n may depend on the
        implementation and on typical characteristics of environments, where
        UDPST is deployed (like mobile networks or Wi-Fi). Currently, a
        default sequence number interval of n=32 has been chosen. Specifically
        for seqErrOoo, each successively received higher seqno sets the
        next-expected-seqno to seqno+1 and anything below that is considered
        out-of-order (i.e., delayed). For example, given the sequence 93, 94,
        95, 100, 96, 97, 101, 98, 99, 102, 103, ... reception of 96, 97, 98,
        and 99 would not increment the next-expected-seqno and would all be
        considered out-of-order.</t>

        <t>delayVarMin/delayVarMax/delayVarSum/delayVarCnt: The one-way delay
        variation measurements of all received Load PDUs (where avg =
        sum/cnt). For each Load PDU received, the send time
        (lpduTime_sec/lpduTime_nsec) is subtracted from the local receive
        time, which is then normalized by subtracting the current
        clockDeltaMin. Available for both the sub-interval and trial
        interval.</t>

        <t>rttVarMinimum/rttVarMaximum (in sisSav): The minimum and maximum
        RTT delay variation (rttVarSample) in the sub-interval designated by
        the subIntSeqNo.</t>

        <t>accumTime: The accumulated time of the test in milliseconds, based
        on the duration of each sub-interval. Equivalent to the sum of each
        deltaTime (although in ms) sent in each Status PDU during the
        test.</t>

        <t>clockDeltaMin: The minimum clock delta (difference) since the
        beginning of the test. Obtained by subtracting the send time of each
        Load PDU (lpduTime_sec/lpduTime_nsec) from the local time that it was
        received. This value is initialized with the first Load PDU received
        and is updated with each subsequent one to maintain a current (and
        continuously updated) minimum. If the endpoint clocks are sufficiently
        synchronized, this will be the minimum one-way delay in milliseconds.
        Otherwise, this value may be negative, but still valid for one-way
        delay variation measurements for the default test duration (default is
        10 [s]). If the test duration is extended to a range of minutes, where
        significant clock drift can occur, synchronized (or at least
        well-disciplined) clocks may be required.</t>

        <t>rttMinimum (in Status PDU): The minimum "adjusted" RTT measured
        since the beginning of the test. See rttRespDelay regarding "adjusted"
        measurements. RTT is obtained by subtracting the copied
        spduTime_sec/spduTime_nsec in the received Load PDU from the local
        time at which it was received. This minimum SHALL be kept current (and
        continuously updated) via each Load PDU received with an updated
        spduTime_sec/spduTime_nsec. This value MUST be positive. Before an
        initial value can be established, and because zero is itself valid, it
        SHALL be set to STATUS_NORTT when communicated in the Status PDU.</t>

        <t>rttVarSample: The most recent "adjusted" RTT delay variation
        measurement. See rttRespDelay regarding "adjusted" measurements. RTT
        delay variation is obtained by subtracting the current (and
        continuously updated) "adjusted" RTT minimum, communicated as
        rttMinimum (in Status PDU), from each "adjusted" RTT measurement
        (which is itself obtained by subtracting the copied
        spduTime_sec/spduTime_nsec in the received Load PDU from the local
        time at which it was received). Note that while one-way delay
        variation is measured for every Load PDU received, RTT delay variation
        is only sampled via the Status PDU sent and the very next Load PDU
        received with the corresponding updated spduTime_sec/spduTime_nsec.
        When a new value is unavailable (possibly due to packet loss), and
        because zero is itself valid, it SHALL be set to STATUS_NORTT when
        communicated in the Status PDU.</t>

        <t>delayMinUpd: Boolean (0 or 1) indicating that the clockDeltaMin
        and/or rttMinimum (in Status PDU), as measured by the Load PDU
        receiver, has been updated.</t>

        <t>checkSum: An optional checksum of the entire PDU (see <xref
        target="Checksum"/> for guidance). The calculation is done with the
        checkSum field, and all fields starting with authMode, set to
        zero.</t>

        <t>tiDeltaTime/tiRxDatagrams/tiRxBytes: The trial interval time in
        microseconds, along with the received datagram and byte counts. Used
        to calculate the received traffic rate for the trial interval.</t>

        <t>spduTime_sec/spduTime_nsec: The local transmit time of the Status
        PDU. Expected to be copied into spduTime_sec/spduTime_nsec in
        subsequent Load PDUs after being received by the Load PDU sender. Used
        for RTT measurements.</t>

        <t>The authentication, encryption, and checksum fields and their
        operation are as defined previously in <xref
        target="Security-Checksum"/>.</t>

        <t>The Status Feedback message PDU (as well as the included
        Sub-Interval Statistics structure) SHALL be organized as follows:</t>

        <t><figure anchor="STATUS" title="Status PDU">
            <artwork>
&lt;CODE BEGINS&gt;
//
// Sub-interval statistics structure for received traffic information
//
struct subIntStats {
        uint32_t rxDatagrams; // Received datagrams
        uint64_t rxBytes;     // Received bytes (64 bits)
        uint32_t deltaTime;   // Time delta (us)
        uint32_t seqErrLoss;  // Loss sum
        uint32_t seqErrOoo;   // Out-of-Order sum
        uint32_t seqErrDup;   // Duplicate sum
        uint32_t delayVarMin; // Delay variation minimum (ms)
        uint32_t delayVarMax; // Delay variation maximum (ms)
        uint32_t delayVarSum; // Delay variation sum (ms)
        uint32_t delayVarCnt; // Delay variation count
        uint32_t rttMinimum;  // Minimum round-trip time (ms)
        uint32_t rttMaximum;  // Maximum round-trip time (ms)
        uint32_t accumTime;   // Accumulated time (ms)
};
//
// Status feedback header for UDP payload of status PDUs
//
struct statusHdr {
#define STATUS_ID 0xFEED
        uint16_t pduId;     // PDU ID
        uint8_t testAction; // Test action
        uint8_t rxStopped;  // Receive traffic stopped (BOOL)
        uint32_t spduSeqNo; // Status PDU sequence number
        struct sendingRate srStruct; // Sending rate structure
        uint32_t subIntSeqNo;        // Sub-interval sequence number
        struct subIntStats sisSav;   // Sub-interval saved stats
        uint32_t seqErrLoss;    // Loss sum
        uint32_t seqErrOoo;     // Out-of-Order sum
        uint32_t seqErrDup;     // Duplicate sum
        uint32_t clockDeltaMin; // Clock delta minimum (ms)
        uint32_t delayVarMin;   // Delay variation minimum (ms)
        uint32_t delayVarMax;   // Delay variation maximum (ms)
        uint32_t delayVarSum;   // Delay variation sum (ms)
        uint32_t delayVarCnt;   // Delay variation count
#define STATUS_NORTT UINT32_MAX // No RTT data/value
        uint32_t rttMinimum;    // Min round-trip time sampled (ms)
        uint32_t rttVarSample;  // Last round-trip time sample (ms)
        uint8_t delayMinUpd;    // Delay minimum(s) updated (BOOL)
        uint8_t reserved1;      // (reserved for alignment)
        uint16_t checkSum;      // Header checksum
        uint32_t tiDeltaTime;   // Trial interval delta time (us)
        uint32_t tiRxDatagrams; // Trial interval receive datagrams
        uint32_t tiRxBytes;     // Trial interval receive bytes
        uint32_t spduTime_sec;  // Send time of this status PDU
        uint32_t spduTime_nsec; // Send time of this status PDU
        //
        // ========== Encryption ends here ==========
        uint8_t authMode;        // Authentication mode
        uint8_t keyId;           // Key ID in shared table
        uint16_t reserved-auth1; // (reserved for alignment)
        uint32_t authUnixTime;   // Authentication time stamp
        uint8_t initVector[AUTH_IV_LENGTH]     // IV
        uint8_t authDigest[AUTH_DIGEST_LENGTH] // HMAC
};
&lt;CODE ENDS&gt;
        </artwork>

            <postamble/>
          </figure></t>
      </section>
    </section>

    <section anchor="Test-Stop" title="Stopping a Test">
      <t>When the test duration timer (testIntTime) on the server expires, it
      SHALL set the local connection test action to TEST_ACT_STOP1 (phase 1 of
      graceful termination). This is simply a non-reversible state awaiting
      the next message(s) to be sent from the server. During this time, any
      received Load or Status PDUs are processed normally.</t>

      <t>Upon transmission of the next Load or Status PDUs, the server SHALL
      set the local connection test action to TEST_ACT_STOP2 (phase 2 of
      graceful termination) and mark any outgoing PDUs with a testAction value
      of TEST_ACT_STOP2. While in this state, the server MAY reduce any Load
      PDU bursts to a size of one.</t>

      <t>When the client receives a Load or Status PDU with the TEST_ACT_STOP2
      indication, it SHALL finalize testing, display the test results, and
      also mark its local connection with a test action of TEST_ACT_STOP2 (so
      that any PDUs subsequently received can be ignored).</t>

      <t>With the test action of the client's connection set to
      TEST_ACT_STOP2, the very next expiry of a send timer, for either a Load
      or Status PDU, SHALL result in it and any subsequent PDUs to be sent
      with a testAction value of TEST_ACT_STOP2 (as confirmation to the
      server). While in this state, the client MAY reduce any Load PDU bursts
      to a size of one. The client SHALL then schedule an immediate end time
      for the connection.</t>

      <t>When the server receives the TEST_ACT_STOP2 confirmation in the Load
      or Status PDU, the server SHALL schedule an immediate end time for the
      connection which closes the socket and deallocates the associated
      resources. The TEST_ACT_STOP2 exchange constitutes a graceful
      termination of the test.</t>

      <t>In a non-graceful test stop due to path failure, the watchdog
      timeouts at each endpoint will expire (sometimes at one endpoint first),
      notifications in logs, STDOUT, and/or formatted output SHALL be made,
      and the endpoint SHALL schedule an immediate end time for the
      connection.</t>

      <t>If an attacker clears the TEST_ACT_STOP2 indication, then the
      configured test duration timer (testIntTime) at the server and client
      SHALL take precedence and the endpoint SHALL schedule an immediate end
      time for the connection.</t>
    </section>

    <section title="Operational considerations for the Measurement Method">
      <t>The architecture of the method requires two cooperating hosts
      operating in the roles of Src (test packet sender) and Dst (receiver),
      with a measured path and return path between them.</t>

      <t>The nominal duration of a measurement interval at the Destination,
      parameter testIntTime, MUST be constrained in a production network,
      since this is an active test method and it will likely cause congestion
      on the Src to Dst host path during a test.</t>

      <t>It is RECOMMENDED to locate test endpoints as close to the intended
      measured link(s) as practical. The testing operator MUST set a value for
      the MaxHops Parameter, based on the expected path length. This Parameter
      can keep measurement traffic from straying too far beyond the intended
      path.</t>

      <t>It is obviously counterproductive to run more than one independent
      and concurrent test (regardless of the number of flows in the test
      stream) attempting to measure the maximum capacity on a single path. The
      number of concurrent, independent tests of a path SHALL be limited to
      one.</t>

      <t>The load rate adjustment algorithm's scope is limited to helping
      determine the Maximum IP-Layer Capacity in the context of an infrequent,
      diagnostic, short-term measurement. It is RECOMMENDED to discontinue
      non-measurement traffic that shares a subscriber's dedicated resources
      while testing: measurements may not be accurate, and throughput of
      competing elastic traffic may be greatly reduced.</t>

      <t>See section 8 of <xref target="RFC9097"/> for a discussion of the
      method of measurement beyond purely operational aspects.</t>

      <section title="Notes on Interface Measurements">
        <t>Additional measurements may be useful in specific circumstances.
        For example, interface byte counters measured by a client at a
        residential gateway are possible when the client application has
        access to an interface that sees all traffic to/from a service
        subscriber's location. Adding a byte counter at the client for
        download or upload directions could be used to measure total traffic
        and possibly detect when non-test traffic is present (and using
        capacity). The client may not have the CPU cycles available to count
        both the interface traffic and IP-layer Capacity simultaneously, so
        this form of diagnostic measurement may not be possible.</t>
      </section>
    </section>

    <section title="Security Considerations">
      <t>Active metrics and measurements have a long history of security
      considerations. The security considerations that apply to any active
      measurement of live paths are relevant here. See <xref
      target="RFC4656"/> and <xref target="RFC5357"/>.</t>

      <t>When considering privacy of those involved in measurement or those
      whose traffic is measured, the sensitive information available to
      potential observers is greatly reduced when using active techniques
      which are within this scope of work. Passive observations of user
      traffic for measurement purposes raise many privacy issues. We refer the
      reader to the privacy considerations described in the Large Scale
      Measurement of Broadband Performance (LMAP) Framework <xref
      target="RFC7594"/>, which covers active and passive techniques.</t>

      <t>There are some new considerations for Capacity measurement as
      described in this document.</t>

      <t><list style="numbers">
          <t>Cooperating client and server hosts and agreements to test the
          path between the hosts are REQUIRED. Hosts perform in either the
          server or client roles. One way to assure a cooperative agreement
          employs the optional Authorization mode through the use of the
          authDigest field and the known identity associated with the shared
          key used to create the authDigest field via the KDF. Other means are
          also possible, such as access control lists at the server.</t>

          <t>It is REQUIRED to have a user client-initiated setup handshake
          between cooperating hosts that allows firewalls to control inbound
          unsolicited UDP traffic which either goes to a control port or to
          ephemeral ports that are only created as needed. Firewalls
          protecting each host can both continue to do their job normally.</t>

          <t>Client-server authentication and integrity protection for
          feedback messages conveying measurements is RECOMMENDED. To
          accommodate different host limitations and testing circumstances,
          different modes of operation are available, as described in <xref
          target="Security-Checksum"/> above.</t>

          <t>Hosts MUST limit the number of simultaneous tests to avoid
          resource exhaustion and inaccurate results.</t>

          <t>Senders MUST be rate-limited. This can be accomplished using a
          pre-built table defining all the offered sending rates that will be
          supported. The default and optional load rate adjustment algorithm
          results in "ramp up" from the lowest rate in the table. Optionally,
          the server could utilize the maxBandwidth field (and CHSR_USDIR_BIT
          bit) in the Setup Request from the client to limit the maximum that
          it will attempt to achieve.</t>

          <t>Service subscribers with limited data volumes who conduct
          extensive capacity testing might experience the effects of Service
          Provider controls on their service. Testing with the Service
          Provider's measurement hosts SHOULD be limited in frequency and/or
          overall volume of test traffic (for example, the range of test
          interval duration values should be limited).</t>
        </list></t>

      <t>One specific attack that has been recognized is an on-path attack on
      the testAction field where the attacker would set or clear the STOP
      indication. Setting the indication in successive packets terminates the
      test prematurely, with no threat to the Internet but annoyance for the
      testers. If an attacker clears the STOP indication, the mitigation
      relies on knowledge of the test duration at the client and server, where
      these hosts cease all traffic when the specified test duration is
      complete.</t>

      <t>Authentication and encryption methods and requirements steadily
      evolve. Alternate encryption and/or authentication modes provide for
      algorithm agility by defining a new Mode, whose support is indicated by
      an assigning a suitable "Test Setup PDU Authentication Mode Registry"
      value (see <xref target="Setup-authMode"/> ).</t>
    </section>

    <section anchor="IANA" title="IANA Considerations">
      <t>This document requests IANA to assign a User/Registered UDP port for
      the Test Setup exchange in the Control phase of protocol operation, and
      to create a new registry group for the UDP Speed Test Protocol
      (UDPSTP).</t>

      <section title="New System Port Number Assignment">
        <t>IANA will allocate the following service name to the "Service Name
        and Transport Protocol Port Number Registry" registry:</t>

        <t><list style="hanging">
            <t hangText="Service:">udpst-control</t>

            <t hangText="Transport Protocol:">UDP</t>

            <t hangText="Assignee:">IESG &lt;iesg@ietf.org&gt;</t>

            <t hangText="Contact:">IETF Chair &lt;chair@ietf.org&gt;</t>

            <t hangText="Description:">UDP-based IP-Layer Capacity and
            performance measurement protocol</t>

            <t hangText="Reference:">This RFC, RFCYYYY. The protocol uses
            IP-Layer Unicast. The assignment of a single port number is
            requested to help configure firewalls and other port-based systems
            for access control prior to negotiating dynamic ports between
            client and server.</t>

            <t hangText="Port Number:">&lt;PORTNUM&gt; of the IANA User Port
            range (1024-49151)</t>
          </list></t>
      </section>

      <section anchor="kdf-HMAC-SHA-256" title="New KeyTable KDF">
        <t>IANA will allocate the following KDF to the existing list of
        KeyTable KDFs (see
        https://www.iana.org/assignments/keytable/keytable.xhtml#kdf).</t>

        <t><figure>
            <artwork>
KDF             Description                    Reference
===============================================================
HMAC-SHA-256    HMAC using the SHA-256 hash    [RFC6234]
</artwork>
          </figure></t>
      </section>

      <section title="New UDPSTP Registry Group">
        <t>IANA will create the following registry in a new registry group
        called "UDP Speed Test Protocol (UDPSTP)":</t>

        <t>Registration Procedure: see below</t>

        <t>Reference: &lt;This RFC&gt;</t>

        <t>Experts: &lt;To be set at publication&gt;</t>

        <section anchor="pduId" title="PDU Identifier Registry">
          <t>IANA will create the "PDU Identifier" registry under the "UDP
          Speed Test Protocol (UDPSTP)" registry group. Every UDPSTP PDU
          contains a two octet pduId field identifying the role and format of
          the PDU that follows. The code points in this registry are allocated
          according to the registration procedures <xref target="RFC8126"/>
          described in Table 1.</t>

          <t><figure>
              <artwork>Range(Hex)             Registration Procedures
===============================================================
0xFFFF and 0x0000      Reserved

0x8000-0xFFFE          Expert Review

0x0001-0x7F00          First Come, First Served     

0x7F01-0x7FE0          Experimental  

0x7FE1-0x7FFF          Private Use

</artwork>
            </figure>Table 1: Registration procedures for the PDU Identifier
          registry</t>

          <t>Initially, IANA will assign the "PDU Identifier" registry with
          the values in Table 2:</t>

          <t><figure>
              <artwork>Value    Description           Reference                          
===================================================
0xACE1   Test Setup PDU        &lt;this RFC&gt;
                               
0xACE2   Test Activation PDU   &lt;this RFC&gt;
                               
0xDEAD   Null PDU              &lt;this RFC&gt;
                               
0xBEEF   Load PDU              &lt;this RFC&gt;
                               
0xFEED   Status Feedback PDU   &lt;this RFC&gt;


</artwork>
            </figure>Table 2: Initial PDU Identifier Values</t>
        </section>

        <section anchor="protocolVer" title="Protocol Version Registry">
          <t>IANA will create the "Protocol Version" registry under the "UDP
          Speed Test Protocol (UDPSTP)" registry group. UDPST Protocol Test
          Setup Request, Test Setup Response and Test Activation Request PDUs
          contain a two octet protocolVer field, identifying the version of
          the protocol in use. The code points in this registry are allocated
          according to the registration procedures <xref target="RFC8126"/>
          described in Table 3.</t>

          <t><figure>
              <artwork>Range(Decimal)         Registration Procedures
===============================================================
0-19                   Reserved

20-40960               IETF Review

40961-53248            First Come, First Served     

53249-65534            Experimental  

65535                  Reserved

</artwork>
            </figure>Table 3: Registration procedures for the Protocol Version
          registry</t>

          <t>Initially, IANA will assign the decimal value 20 listed in Table
          4 in the "Protocol Version" registry:</t>

          <t><figure>
              <artwork>Value  Description            Reference                          
================================================
20     Protocol version 20    &lt;this RFC&gt;

</artwork>
            </figure>Table 4: Initial Protocol Version value</t>
        </section>

        <section anchor="Setup-modifierBitmap"
                 title="Test Setup PDU    Modifier Bitmap Registry">
          <t>IANA will create the "Test Setup PDU Modifier Bitmap" registry
          under the "UDP Speed Test Protocol (UDPSTP)" registry group. The
          Test Setup PDU layout contains a modifierBitmap field. The bitmaps
          in this registry are allocated according to the registration
          procedures <xref target="RFC8126"/> described in Table 5.</t>

          <t><figure>
              <artwork>Range(Bitmap)          Registration Procedures
===============================================================
00000000-01111111      IETF Review

10000000               Reserved

</artwork>
            </figure>Table 5: Registration procedures for the Test Setup PDU
          Modifier Bitmap Registry</t>

          <t>Initially, IANA will assign the bitmap values defined by Table 6
          in the "Test Setup PDU Modifier Bitmap" registry.</t>

          <t><figure>
              <artwork>Value  Description             Reference
===============================================================
0x00   No modifications        &lt;this RFC&gt;
                                             
0x01   Allow Jumbo datagram    &lt;this RFC&gt;
       sizes above sending             
       rates of 1Gbps                    
                                             
0x02   Use Traditional MTU     &lt;this RFC&gt; 
       (1500 bytes with                                  
       IP-header)                                        

</artwork>
            </figure>Table 6: Initial Test Setup PDU Modifier Bitmap
          values</t>
        </section>

        <section anchor="Setup-authMode"
                 title="Test Setup PDU    Authentication Mode Registry">
          <t>IANA will create the "Test Setup PDU Authentication Mode"
          registry under the "UDP Speed Test Protocol (UDPSTP)" registry
          group. The Test Setup PDU layout contains an authMode field. The
          code points in this registry are allocated according to the
          registration procedures <xref target="RFC8126"/> described in Table
          7.</t>

          <t><figure>
              <artwork>Range(Decimal)         Registration Procedures
===============================================================
0-59                   IETF Review

60-63                  Experimental  

64-255                 Reserved

</artwork>
            </figure>Table 7: Registration procedures for the Test Setup PDU
          Authentication Mode registry</t>

          <t>Initially, IANA will assign the decimal values defined by Table 8
          in the "Test Setup PDU Authentication Mode" registry.</t>

          <t><figure>
              <artwork>Value   Description                    Reference
===============================================================
0       Optional Unauthenticated mode  &lt;this RFC&gt;    
                                          
1       Required authentication        &lt;this RFC&gt;
        for the Control phase                                
                                          
2       Optional authentication for    &lt;this RFC&gt;
        the Data phase, in addition                       
        to the Control phase                        
                                          
3       Optional encrypted mode        &lt;this RFC&gt;

</artwork>
            </figure>Table 8: Initial Test Setup PDU Authentication Mode
          values</t>
        </section>

        <section anchor="Error-codes"
                 title="Test Setup PDU Command Response Field Registry">
          <t>IANA will create the "Test Setup PDU Command Response Field"
          registry under the "UDP Speed Test Protocol (UDPSTP)" registry
          group. The Test Setup PDU layout contains a cmdResponse field. The
          code points in this registry are allocated according to the
          registration procedures <xref target="RFC8126"/> described in Table
          9.</t>

          <t><figure>
              <artwork>Range(Decimal)         Registration Procedures
===============================================================
0-127                  IETF Review

128-239                First Come, First Served     

240-249                Experimental

250-254                Private Use  

255                    Reserved

</artwork>
            </figure>Table 9: Registration procedures for the Test Setup PDU
          Command Response Field Registry</t>

          <t>Initially, IANA will assign the decimal values defined by Table
          10 in the "Test Setup PDU Command Response Field" registry.</t>

          <t><figure>
              <artwork>Value   Description                    Reference
===============================================================
0       None (used by                  &lt;this RFC&gt;
        client in Request)                                   

1       Acknowledgment                 &lt;this RFC&gt;
                                                        
2       Bad Protocol Version           &lt;this RFC&gt;
                                                        
3       Invalid Jumbo datagram         &lt;this RFC&gt;
        option                                               

4       Unexpected Authentication      &lt;this RFC&gt;
        in Setup Request                                     

5       Authentication missing         &lt;this RFC&gt;
        in Setup Request                                        

6       Invalid authentication         &lt;this RFC&gt;
        method                                               

7       Authentication failure         &lt;this RFC&gt;

8       Authentication time is         &lt;this RFC&gt;
        invalid in Setup Request                             

9       No Maximum test Bit rate       &lt;this RFC&gt;
        specified                                            

10      Server Maximum Bit rate        &lt;this RFC&gt;
        exceeded                                             

11      MTU option does not match      &lt;this RFC&gt;
        server                                               

12      Multi-connection parameters    &lt;this RFC&gt;
        rejected by server                                   

13      Connection allocation          &lt;this RFC&gt;
        failure on server                              

</artwork>
            </figure>Table 10: Initial Test Setup PDU Command Response Field
          values</t>
        </section>

        <section anchor="ActivationCmdRequest"
                 title="Test Activation PDU Command Request Registry">
          <t>IANA will create the "Test Activation PDU Command Request"
          registry under the "UDP Speed Test Protocol (UDPSTP)" registry
          group. The Test Setup PDU layout contains a cmdRequest field. The
          code points in this registry are allocated according to the
          registration procedures <xref target="RFC8126"/> described in Table
          11.</t>

          <t><figure>
              <artwork>Range(Decimal)         Registration Procedures
===============================================================
0-127                  IETF Review

128-239                First Come, First Served     

240-249                Experimental

250-254                Private Use 

255                    Reserved

</artwork>
            </figure>Table 11: Registration procedures for the Test Activation
          PDU Command Request registry</t>

          <t>Initially, IANA will assign the decimal values defined by Table
          12 in the "Test Activation PDU Command Request" registry.</t>

          <t><figure>
              <artwork>Value   Description                   Reference
===============================================================
0       No Request                    &lt;this RFC&gt;
                                     
1       Request test in Upstream      &lt;this RFC&gt;
        direction (client to server)                        
                                     
2       Request test in Downstream    &lt;this RFC&gt;
        direction (server to client)                        

</artwork>
            </figure>Table 12: Initial Test Activation PDU Command Request
          values</t>
        </section>

        <section anchor="Activation-modifierBitmap"
                 title="Test Activation    PDU Modifier Bitmap Registry">
          <t>IANA will create the "Test Activation PDU Modifier Bitmap"
          registry under the "UDP Speed Test Protocol (UDPSTP)" registry
          group. The Test Activation PDU layout (also) contains a
          modifierBitmap field. The bitmaps in this registry are allocated
          according to the registration procedures <xref target="RFC8126"/>
          described in Table 13.</t>

          <t><figure>
              <artwork>Range(Bitmap)          Registration Procedures
===============================================================
00000000-01111111      IETF Review

10000000               Reserved

</artwork>
            </figure>Table 13: Registration procedures for the Test Activation
          PDU Modifier Bitmap registry</t>

          <t>Initially, IANA will assign the bitmap values defined by Table 14
          in the "Test Activation PDU Modifier Bitmap" registry.</t>

          <t><figure>
              <artwork>Value    Description               Reference
===============================================================
0x00     No modifications          &lt;this RFC&gt;
                                   
0x01     Set when srIndexConf is   &lt;this RFC&gt;
         start rate for search                           
                                   
0x02     Set for randomized        &lt;this RFC&gt;
         UDP payload                                     

</artwork>
            </figure>Table 14: Initial Test Activation PDU Modifier Bitmap
          values</t>
        </section>

        <section anchor="Activation-rateAdjAlgo"
                 title="Test Activation    PDU Rate Adjustment Algo. Registry">
          <t>The Test Activation PDU layout contains a rateAdjAlgo field. The
          table below defines the assigned Capitalized alphabetic UTF-8 values
          in the registry.</t>

          <t>IANA will create the "Test Activation PDU Rate Adjustment Algo."
          registry under the "UDP Speed Test Protocol (UDPSTP)" registry
          group. The Test Activation PDU layout contains a rateAdjAlgo field.
          The code points in this registry are allocated according to the
          registration procedures <xref target="RFC8126"/> described in Table
          15.</t>

          <t><figure>
              <artwork>Range(Capital alphabet. UTF-8)     Registration Procedures
==========================================================
A-Q                                IETF review

R-V                                Experimental

W-Y                                Private use

Z                                  Reserved
</artwork>
            </figure>Table 15: Registration procedures for the Test Activation
          PDU Rate Adjustment Algo. registry</t>

          <t>Initially, IANA will assign the Capitalized alphabetic UTF-8
          values, as well as the corresponding incremental numeric, defined by
          Table 16 in the "Test Activation PDU Rate Adjustment Algo."
          registry.</t>

          <t><figure>
              <artwork>Value(Numeric)   Description             Reference        
========================================================
A(n/a)           Not used                &lt;this RFC&gt; 
                                 
B(0)             Rate algorithm Type B   &lt;this RFC&gt; 
                                                 
C(1)             Rate algorithm Type C   &lt;this RFC&gt;

</artwork>
            </figure>Table 16: Initial Test Activation PDU Rate Adjustment
          Algo. values</t>
        </section>

        <section anchor="Activation-cmdResponse"
                 title="Test Activation    PDU Command Response Field Registry">
          <t>IANA will create the "Test Activation PDU Command Response Field"
          registry under the "UDP Speed Test Protocol (UDPSTP)" registry
          group. The Test Activation PDU layout (also) contains a cmdResponse
          field. The code points in this registry are allocated according to
          the registration procedures <xref target="RFC8126"/> described in
          Table 17.</t>

          <t><figure>
              <artwork>Range(Decimal)         Registration Procedures
===============================================================
0-127                  IETF Review

128-239                First Come, First Served

240-249                Experimental

250-254                Private Use  

255                    Reserved

</artwork>
            </figure>Table 17: Registration procedures for the Test Activation
          PDU Command Response Field registry</t>

          <t>Initially, IANA will assign the decimal values defined by Table
          18 in the "Test Activation PDU Command Response Field" registry.</t>

          <t><figure>
              <artwork>Value   Description                 Reference
===============================================================
0       None (used by               &lt;this RFC&gt;
        client in Request)                                
                                      
1       Server Acknowledgment       &lt;this RFC&gt;
                                                        
2       Server indicates an error   &lt;this RFC&gt;

</artwork>
            </figure>Table 18: Initial Test Activation PDU Command Response
          Field values</t>
        </section>
      </section>

      <section  title="Guidelines for the Designated Experts">
        <t>It is suggested that multiple designated experts be appointed for
        registry change requests.</t>

        <t>Criteria that should be applied by the designated experts include
        determining whether the proposed registration duplicates existing
        entries and whether the registration description is clear and fits the
        purpose of this registry.</t>

        <t>Registration requests are evaluated within a two-week review period
        on the advice of one or more designated experts. Within the review
        period, the designated experts will either approve or deny the
        registration request, communicating this decision to IANA. Denials
        should include an explanation and, if applicable, suggestions as to
        how to make the request successful.</t>
      </section>
    </section>

    <section title="Acknowledgments">
      <t>This document was edited by Al Morton, who passed away before being
      able to finalize this work. Ruediger Geib only joined later to help
      finalize this draft.</t>

      <t>Thanks to Lincoln Lavoie, Can Desem, Greg Mirsky, Bjoern Ivar Teigen,
      Ken Kerpez and Chen Li for reviewing this draft and providing helpful
      suggestions and areas for further development. Mohamed Boucadair's AD
      review improved comprehensability of the document. David Dong and Amanda
      Baber provided early reviews of the IANA Considerations section.</t>

      <t>Brian Weis provided an early SEC-DIR review; version 02 captures
      clarifications and version 03-09 took up on the protocol changes which
      Brian suggested. Tommy Pauly sheperded this document.</t>
    </section>
	
  </middle>

  <back>
    <references title="Normative References">
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.0768.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.0791.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3168.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4086.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5044.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6234.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7210.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8085.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8126.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8899.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9097.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <reference anchor="FIPS-197"
                 target="https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.197.pdf">
        <front>
          <title>Federal Information Processing Standards Publication 197
          (FIPS-197), ADVANCED ENCRYPTION STANDARD (AES)</title>

          <author fullname="National Institute of Standards and Technology (NIST)"
                  initials="NIST"
                  surname="National Institute of Standards and Technology">
            <organization>NIST</organization>
          </author>

          <date day="26" month="November" year="2001"/>
        </front>
      </reference>

      <reference anchor="TR-471"
                 target="https://www.broadband-forum.org/technical/download/TR-471.pdf">
        <front>
          <title>Broadband Forum TR-471: IP Layer Capacity Metrics and
          Measurement, Issue 4</title>

          <author fullname="" initials="Editor" surname="Morton, A,">
            <organization>AT&amp;T Labs</organization>
          </author>

          <date day="" month="September" year="2024"/>
        </front>
      </reference>

      <reference anchor="Y.1540" derivedAnchor="Y.1540" quoteTitle="true"
                 target="https://www.itu.int/rec/T-REC-Y.1540-201912-I/en">
        <front>
          <title>Internet protocol data communication service - IP packet
          transfer and availability performance parameters</title>

          <author>
            <organization showOnFrontPage="true">ITU-T</organization>
          </author>

          <date month="December" year="2019"/>
        </front>

        <refcontent>ITU-T Recommendation Y.1540</refcontent>
      </reference>

      <reference anchor="NIST800-108"
                 target="https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-108r1-upd1.pdf">
        <front>
          <title>Recommendation for Key Derivation Using Pseudorandom
          Functions (Revised, Update 1)</title>

          <author fullname="Lily Chen" initials="LC" surname="Chen">
            <organization>National Institute of Standards and
            Technology</organization>
          </author>

          <date month="August" year="2022"/>
        </front>
      </reference>
	  
    </references>

    <references title="Informative References">
      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.3148.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4656.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5136.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.5357.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7497.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7594.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8337.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8762.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8799.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

      <xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.9145.xml"
                  xmlns:xi="http://www.w3.org/2001/XInclude"/>

	  <reference anchor="EVP_KDF-KB" target="https://docs.openssl.org/master/man7/EVP_KDF-KB/">
        <front>
          <title>The Key-Based EVP_KDF implementation</title>
        <author/>
        </front>
      </reference>

      <reference anchor="CBC"
                 target="https://csrc.nist.gov/pubs/sp/800/38/a/final">
        <front>
          <title>NIST Special Publication 800-38A: Recommendation for Block
          Cipher Modes of Operation: Methods and Techniques, U.S. National
          Institute of Standards and Technology</title>

          <author fullname="M. Dworkin" initials="M." surname="Dworkin">
            <organization>NIST</organization>
          </author>

          <date month="December" year="2001"/>
        </front>
      </reference>

    </references>
	
	<section anchor="KDF-Example" title="KDF Example (OpenSSL)">
      <figure anchor="KDFfigure" title="KDF Example Code Snippet">
        <artwork>
&lt;CODE BEGINS&gt;
/*
 * Output individual authentication and encryption keys, of length
 * SHA256_KEY_LEN and AES128_KEY_LEN respectively, from derived key
 * material.
 * Return Values: 0 = Failure, 1 = Success
 */
int kdf_hmac_sha256(char *Kin, uint32_t authUnixTime,
  unsigned char *cAuthKey, unsigned char *cEncKey,   /* Client */
  unsigned char *sAuthKey, unsigned char *sEncKey) { /* Server */

  int var, keylen = (SHA256_KEY_LEN * 2) + (AES128_KEY_LEN * 2);
  char context[16];
  unsigned char *keyptr, keybuf[keylen];
  EVP_KDF *kdf = NULL;
  EVP_KDF_CTX *kctx = NULL;
  OSSL_PARAM params[16], *p = params;

  /*
   * Fetch KDF algorithm and create context
   */
  if ((kdf = EVP_KDF_fetch(NULL, "KBKDF", NULL)) == NULL) {
    return 0;
  }
  if ((kctx = EVP_KDF_CTX_new(kdf)) == NULL) {
    EVP_KDF_free(kdf);
    return 0;
  }

  /*
   * Set parameters for KBKDF
   */
  *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MODE, "COUNTER", 0);
  *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC, "HMAC", 0);
  *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, "SHA256", 0);
  *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, Kin, strlen(Kin));
  *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, "UDPSTP", 6);
  var = snprintf(context, sizeof(context), "%u", authUnixTime);
  *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, context, var);
  /* Confirm the following are enabled */
  var = 1;
  *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_KBKDF_USE_L, &amp;var);
  *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_KBKDF_USE_SEPARATOR, &amp;var);
  /* Set counter length in bits (available as of OpenSSL 3.1) */
  var = 32; /* 32 is backward compatible with OpenSSL 3.0 */
  *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_KBKDF_R, &amp;var);
  *p++ = OSSL_PARAM_construct_end();
  
  /*
   * Derive key material
   */
  if (EVP_KDF_derive(kctx, keybuf, keylen, params) &lt; 1) {
    EVP_KDF_CTX_free(kctx);
    EVP_KDF_free(kdf);
    return 0;
  }

  /*
   * Output individual keys
   */
  keyptr = keybuf;
  memcpy(cAuthKey, keyptr, SHA256_KEY_LEN);
  keyptr += SHA256_KEY_LEN;
  memcpy(sAuthKey, keyptr, SHA256_KEY_LEN);
  keyptr += SHA256_KEY_LEN;
  memcpy(cEncKey, keyptr, AES128_KEY_LEN);
  keyptr += AES128_KEY_LEN;
  memcpy(sEncKey, keyptr, AES128_KEY_LEN);

  /*
   * Cleanup
   */
  EVP_KDF_CTX_free(kctx);
  EVP_KDF_free(kdf);
  return 1;
}
&lt;CODE ENDS&gt;
        </artwork>
      </figure>
    </section>
	
  </back>
</rfc>
