Internet-Draft Test Protocol: IP Capacity Measurement September 2024
Ciavattone & Geib Expires 3 April 2025 [Page]
Workgroup:
Network Working Group
Internet-Draft:
draft-ietf-ippm-capacity-protocol-10
Published:
Intended Status:
Standards Track
Expires:
Authors:
L. Ciavattone
AT&T Labs
R. Geib
Deutsche Telekom

Test Protocol for One-way IP Capacity Measurement

Abstract

This memo addresses the problem of protocol support for measuring Network Capacity metrics in RFC 9097, where the method deploys a feedback channel from the receiver to control the sender's transmission rate in near-real-time. This memo defines a simple protocol to perform the RFC 9097 (and other) measurements.

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 3 April 2025.

Table of Contents

1. Introduction

The IETF's efforts to define Network and Bulk Transport Capacity have been chartered and finally progressed after over twenty years.

In that time, the performance community has seen development of Informative definitions in [RFC3148] for Framework for Bulk Transport Capacity (BTC), RFC 5136 for Network Capacity and Maximum IP-layer Capacity, and the Experimental metric definitions and methods in [RFC8337], Model-Based Metrics for BTC.

This memo looks at the problem of measuring Network Capacity metrics defined in [RFC9097] where the method deploys a feedback channel from the receiver to control the sender's transmission rate in near-real-time.

Although there are several test protocols already available for support and management of active measurements, this protocol is a major departure from their operation:

  1. UDP transport, not TCP, is used for Control phase messages (e.g., Test Setup, Test Activation) and Data phase messages (e.g., Load, Status Feedback).

  2. TWAMP [RFC5357] and STAMP [RFC8762] use the philosophy that one host is a Session-Reflector, sending test packets every time they receive a test packet. This protocol supports a one-way test with periodic Status Feedback messages returned to the sender. These messages are also a basis for on-path round-trip delay measurements, which are a key input to the load rate adjustment algorithm.

  3. OWAMP [RFC4656] supports one-way testing with results Fetch at the end of the test session. This protocol supports a one-way test and requires periodic Status Feedback messages returned to the sender to support the load rate adjustment algorithm.

  4. The security features of OWAMP [RFC4656] and TWAMP [RFC5357] have been described as "unusual", to the point that IESG approved their use while also asking that these methods not be used again. Further, the common OWAMP [RFC4656] and TWAMP [RFC5357] approach to security is over 15 years old at this time.

Ruediger Geib joined the team of authors to help completing this draft. He's not replacing Al Morton, as Al can't be replaced.

1.1. Requirements Language

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[RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

2. Scope, Goals, and Applicability

The scope of this memo is to define a protocol to measure the Maximum IP-Layer Capacity metric and according to the standardized method. We note that 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.

The continued 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.

All active testing protocols currently defined by the IPPM WG are UDP-based, but this protocol specifies both control and test protocols using UDP transport. Also, a feedback message stream continues operating during testing to convey results and dynamic configurations.

The primary application of the protocol described here is the same as in Section 2 of [RFC7497] where:

3. Protocol Overview

This section gives an informative overview of the communication protocol between two test end-points (without expressing requirements or describing the authentication and encryption aspects; later sections provide these details and requirements).

One end-point takes the role of server, listening for connection requests on a well-known destination port from the other end-point, the client.

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 of the server in order to begin the setup and configuration exchanges with the server.

Additionally, multi-connection (multi-flow) testing is inherently supported by the protocol. Each connection is essentially 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 logistically as well as aggregate the individual test results into an overall set of performance statistics. Fields in the Setup Request (mcIndex, mcCount, and mcIdent) exist to both differentiate and associate the multiple connections that comprise a single test.

The protocol uses UDP transport and has four types of exchanges in two phases. Exchanges 1 and 2 constitute the Control phase, while exchanges 3 and 4 constitute the Data phase.

  1. Setup Request and Response Exchange: The client 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. The server also communicates the ephemeral port for further communication when accepting the client's request.

  2. Test Activation Request and Response: 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. 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) and the traffic that follows. If the Test Activation Request is rejected or fails, the client assumes that the firewall will close the address/port combination after the firewall's configured idle traffic timeout.

  3. Test Stream Transmission and Measurement Feedback Messages: Testing proceeds with one end-point sending Load PDUs and the other end-point 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.

  4. 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 combination after the firewall's configured idle traffic timeout.

  5. Both the client and server react to unexpected interruptions in the Control and Data phase. Watchdog timers limit the time a server or client will wait before stopping all traffic and terminating a test.

4. Parameters, Security Operations, and Optional Checksum

4.1. Parameters and Definitions

For Parameters related to the Maximum IP-Layer Capacity Metric and Method, please see Section 4 of [RFC9097].

4.2. Security Mode Operations

There are four security modes of operation:

  1. An OPTIONAL Unauthenticated mode for all messages. This mode, intended for a lab or secured environment, SHALL only be allowed when all other modes requiring authentication (or Partial Encryption) are blocked or unavailable for use.

  2. A REQUIRED mode with authentication during the Control phase: Test Setup and Test Activation exchanges. When this mode is available, the OPTIONAL unauthenticated mode SHALL NOT be simultaneously available.

  3. An OPTIONAL mode with the additional authentication of the Status Feedback messages during the Data phase. When this mode is available, the OPTIONAL unauthenticated mode SHALL NOT be simultaneously available.

  4. An OPTIONAL mode that adds encryption, prior to authentication, of the Control phase exchanges and the Status Feedback messages. When this mode is available, the OPTIONAL unauthenticated mode SHALL NOT be simultaneously available.

The requirements below refer to the PDUs in the sections that follow, 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 elsewhere.

4.2.1. Mode 0: OPTIONAL Unauthenticated mode

In the OPTIONAL Unauthenticated mode, all PDU senders SHALL set the keyId field, authUnixTime field, the initVector field, and the authDigest field of all packets to zero.

When the OPTIONAL Unauthenticated mode of operation is available, all other modes requiring authentication (or Partial Encryption) SHALL be blocked or unavailable for use. The availability of unauthenticated and authenticated modes SHALL be considered mutually exclusive.

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.

4.2.2. Mode 1: REQUIRED Authenticated mode

In the REQUIRED Authenticated mode, the client and the server SHALL be configured to use one of a number of shared secret keys, designated via the keyId field.

During the Control phase, the sender SHALL read the current time and populate the authUnixTime field, then calculate the authDigest field of the entire PDU (with the initVector and authDigest fields set to all zeroes) according to [RFC6234] and send the packet 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.

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.

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.

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.

This process SHALL be executed for the request and response in the Test Setup exchange, including the Null Request, (Section 5) and the Test Activation exchange (Section 6).

4.2.3. Mode 2: OPTIONAL Authenticated mode for Data phase

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. The client sends the Status PDU in a downstream test, and the server sends it in an upstream test.

The Status PDU sender SHALL read the current 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.

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.

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).

If this optional mode has not been selected, then the keyId field, authUnixTime field, initVector field, and authDigest field of the Status PDU (see Section 7.2) SHALL be populated with all zeroes.

4.2.4. Mode 3: OPTIONAL Partial Encryption of Control and Status

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. This mode re-uses several protocol fields, which is reasonable since both authentication and encryption are provided (the field format is presented in later sections).

When using the OPTIONAL Partial 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.

In the OPTIONAL Partial Encryption mode, the client and the server SHALL be configured to use one of a number of shared secret keys (see keyId).

The following encryption specifications SHALL be used:

  1. Advanced Encryption Standard, AES, according to Federal Information Processing Standards Publication 197 [FIPS-197]

  2. Cipher Block Chaining (CBC) [CBC]

  3. Key size of 128 bits (fixed block size of 128 bits)

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)".

The sender SHALL populate the initVector field with a random 16 octet Initialization Vector (IV). The IV, in conjunction with 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 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 mode 1 and 2. Finally, the sender SHALL send the packet with partially encrypted PDU to the receiver.

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 shared key designated by the keyId. Finally, the PDU-specific fields that control the test are validated and processed.

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.

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 Initialization Vector (IV). The packet with partially encrypted PDU SHALL be sent back to the originator.

This process SHALL be executed for the request and response in the Test Setup exchange, including the Null Request, (Section 5) and the Test Activation exchange (Section 6).

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).

4.3. Key Management

Section 2 of [RFC7210] specifies a conceptual database for long-lived cryptographic keys. The database is implemented as a plaintext table, to allow text editor maintenance of the key table. 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 Partial Encryption mode, when utilized.

The Key table SHALL have (at least) the following fields, referring to Section 2 of [RFC7210]:

  • AdminKeyName

  • LocalKeyName

  • AlgID

  • Key

  • SendLifetimeStart

  • SendLifetimeEnd

  • AcceptLifetimeStart

  • AcceptLifetimeEnd

The LocalKeyName SHALL be determined from the corresponding keyId field in the PDUs that follow.

4.4. Firewall Configuration

Normal firewall configuration allows a host to open a bidirectional connection using unique source and destination addresses and port numbers by sending a packet using that set of 4-tuple values. The client's interaction with its firewall depends on this configuration.

The firewall at the server MUST be configured with an open pinhole for the server IP address and well-known UDP port of the server.

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.

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.

4.5. Optional Checksum

All of the PDUs exchanged between the client and server support a header checksum that covers the various fields in the PDU (excluding the Payload Content of the Load PDU). 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.

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.

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 will also be 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).

5. Test Setup Request and Response

All messages defined in this section SHALL use UDP transport.

5.1. Client Generates Test Setup Request

The client SHALL begin the Control phase exchanges by sending a Test Setup Request message to the server's (well-known) control port.

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 SHALL NOT be retransmitted. The test initiation timer MAY reuse the test termination timeout value.

As of version 9, 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.

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

//
// Control header for UDP payload of Setup Request/Response PDUs
//
struct controlHdrSR {
#define CHSR_ID 0xACE1
        uint16_t controlId;   // Control 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
        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 reserved1a;   // (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
};

Figure 1: Test Setup PDU

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

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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          controlId            |          protocolVer          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|    mcIndex    |    mcCount    |            mcIdent            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  cmdRequest   | cmdResponse   |         maxBandwidth          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           testPort            |modifierBitmap |   reserved1   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           checkSum            |           reserved2           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                      padding (12 octets)                      |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   authMode    |     keyId     |          reserved1a           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         authUnixTime                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                     initVector (16 octets)                    .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                     authDigest (32 octets)                    .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 2: Test Setup PDU Layout

Additional details regarding the Setup Request and Response fields are as follows:

mcIndex: The index (0,1,2,...) of a connection relative to all connections that make up a single test. It is used to differentiate separate connections within a multi-connection test.

mcCount: The total count of attempted connections.

mcIdent: A pseudorandom non-zero identifier (via RNG, source port number,...) that is common to all connections of a single test. It is used to associate separate connections within a multi-connection test.

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. The server compares this value to its currently available configured limit for test admission control. This field MAY optionally be used for rate-limiting the maximum rate the server should attempt. The CHSR_USDIR_BIT bit is set to 0 by default to indicate "downstream" and has to be set to 1 to indicate "upstream".

testPort: The UDP ephemeral port number on the server that the client SHALL use for the Test Activation Request and subsequent Load or Status PDUs.

modifierBitmap: There are two bits currently assigned in this bitmap:

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).
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.

Other bit positions are currently undefined. A new registry will be needed for modifierBitmap assignments; see the IANA Considerations section.

checkSum: An OPTIONAL checksum of the entire PDU. The calculation is done with the checkSum field, and all fields starting with authMode, set to zero.

authMode: The authMode field currently has four values assigned:

AUTHMODE_0:
OPTIONAL Unauthenticated mode
AUTHMODE_1:
REQUIRED Authentication for Control phase
AUTHMODE_2:
OPTIONAL Authentication for Control and Data phase (Status Feedback PDU only)
AUTHMODE_3:
OPTIONAL Partial Encrypted mode

plus, a range of values for experimentation: 60 through 63. A new registry will be needed for mode values; see the IANA Considerations section.

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

authUnixTime: A 32-bit time stamp of the current time since the Unix Epoch on January 1st, 1970 at UTC.

initVector: This field contains the 16 octet random Initialization Vector (IV) used for Partial Encryption mode. A new random 16 octet IV SHALL be used each time encryption is performed.

authDigest: This field contains the 32 octet HMAC-SHA256 hash that covers the entire PDU.

5.2. Server Processes Test Setup Request and Generates Response

This section describes the processes at the server to evaluate the Test Setup Request and determine the next steps.

5.2.1. Test Setup Request Processing - Rejection

When the server receives the Setup Request, it SHALL:

  • verify the size of the Setup Request message and if correct interrogate the authMode field

  • if operating in one of the Authenticated modes, validate the Setup Request message by checking the authDigest as prescribed in Section 4.2.2

  • if operating in the Partial Encryption mode, use the available keyId and IV to decrypt the Setup Request message up to the authMode field using the method prescribed in Section 4.2.4

and then proceed to evaluate the other fields in the protocol header, such as the protocol version, the Control 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).

If the client has selected options for:

  • Jumbo datagram support (modifierBitmap),

  • Traditional MTU (modifierBitmap),

  • Authentication mode (authMode)

that do not match the server configuration, the server MUST reject the Setup Request.

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

  • 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 Partial Encryption mode, the server SHALL follow the requirements of Section 4.2.4, else the server SHALL follow the requirements of Section 4.2.2.

  • 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.

  • If Unauthenticated mode is selected, the Test Setup Request SHALL fail silently.

The additional, non-authentication circumstances when a server SHALL NOT communicate the appropriate Command Response code for an error condition (fail silently) are when:

  1. the Setup Request PDU size is not correct,

  2. the Control ID is invalid, or

  3. a directed attack has been detected,

in which case the server will allow setup attempts to terminate silently. Attack detection is beyond the scope of this specification.

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:

  • The cmdRequest field is set to CHSR_CREQ_SETUPRSP, indicating a response.

  • The cmdResponse field is set to an error code (starting at CHSR_CRSP_BADVER), 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.

  • The PDU is encrypted up to the authMode field using a new random IV, if doing encryption.

  • The authUnixTime field is updated to the current time and the authDigest is recalculated, if doing authentication.

5.2.2. Test Setup Request Processing - Acceptance

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

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:

  • The cmdRequest field is set to CHSR_CREQ_SETUPRSP, indicating a response.

  • The cmdResponse field is set to CHSR_CRSP_ACKOK, indicating an acknowledgment.

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

  • The PDU is encrypted up to the authMode field using a new random IV, if doing encryption.

  • The authUnixTime field is updated to the current time and the authDigest is recalculated, if doing authentication.

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

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.

The Null Request message PDU SHALL be organized as follows:

//
// Control header for UDP payload of Null Request PDU
//
struct controlHdrNR {
#define CHNR_ID 0xDEAD
        uint16_t controlId;   // Control 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 reserved1a;   // (reserved for alignment)
        uint32_t authUnixTime; // Authentication time stamp
        uint8_t initVector[AUTH_IV_LENGTH]     // IV
        uint8_t authDigest[AUTH_DIGEST_LENGTH] // HMAC
};

Figure 3: Null Request PDU

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

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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          controlId            |          protocolVer          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  cmdRequest   |  cmdResponse  |           checkSum            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      padding (8 octets)                       |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   authMode    |     keyId     |          reserved1a           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         authUnixTime                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                     initVector (16 octets)                    .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                     authDigest (32 octets)                    .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 4: Null Request PDU Layout

Additional details regarding the Null Request fields are as follows:

checkSum: An OPTIONAL checksum of the entire PDU. The calculation is done with the checkSum field, and all fields starting with authMode, set to zero.

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.

5.3. Setup Response Processing at the Client

When the client receives the Test Setup Response message, it SHALL:

  • verify the size of the Setup Response message and if correct interrogate the authMode field

  • if operating in one of the Authenticated modes, validate the Setup Response message by checking the authDigest as prescribed in Section 4.2.2

  • if operating in the Partial Encryption mode, use the available keyId and IV to decrypt the Setup Response message up to the authMode using the method prescribed in Section 4.2.4

and then proceed to evaluate the other fields in the protocol, beginning with the protocol version, Control ID (to validate the type of message), and cmdRequest for the role of the message (SHOULD be Test Setup Response).

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.

6. Test Activation Request and Response

This section is divided according to the sending and processing of the client, server, and again at the client. All messages defined in this section SHALL use UDP transport.

6.1. Client Generates Test Activation Request

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 well-known port).

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

//
// 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 controlId;   // Control 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 subIntPeriod; // Sub-interval period (sec)
        uint8_t ipTosByte;    // IP ToS byte for testing
#define CHTA_SRIDX_DEF UINT16_MAX // Request default server rate 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/Duplicates (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 reserved1;   // (reserved for alignment)
        struct sendingRate srStruct; // Sending rate structure
        uint16_t reserved2; // (reserved for alignment)
        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 reserved1a;   // (reserved for alignment)
        uint32_t authUnixTime; // Authentication time stamp
        uint8_t initVector[AUTH_IV_LENGTH]     // IV
        uint8_t authDigest[AUTH_DIGEST_LENGTH] // HMAC
};

Figure 5: Test Activation PDU

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

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

Figure 6: Test Activation PDU Layout

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.

The content of many of the unique fields in Figures 5 and 6 are defined in Section 4 of [RFC9097] and Appendix A of [RFC9097]. Additional details are given below.

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.

modifierBitmap: There are two bits currently assigned in this bitmap:

CHTA_SRIDX_ISSTART
Treat srIndexConf as the starting sending rate to be used by the load rate adjustment algorithm
CHTA_RAND_PAYLOAD
Randomize the Payload Content beyond the Load PDU header

Other bit positions are currently undefined. A new registry will be needed for modifierBitmap assignments; see the IANA Considerations section.

srStruct: Sending Rate structure, used by the server in a Test Activation Response for an upstream test, to communicate the (initial) Load PDU transmisstion 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 udpAddon2 field specifies 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.

checkSum: An OPTIONAL checksum of the entire PDU. The calculation is done with the checkSum field, and all fields starting with authMode, set to zero.

6.2. Server Processes Test Activation Request and Generates Response

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.

6.2.1. Server Rejects or Modifies Request

When evaluating the Test Activation Request, the server MAY allow the client to specify its own fixed or starting send rate via srIndexConf.

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.

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):

  • Load rate adjustment algorithm: lowThresh, upperThresh, useOwDelayVar, highSpeedDelta, slowAdjThresh, seqErrThresh, highSpeedDelta, ignoreOooDup, rateAdjAlgo.

  • Test duration/intervals: trialInt, testIntTime, subIntPeriod

  • Packet marking: ipTosByte

Coercion is a step toward 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.

Note that the server also has the option of completely rejecting the request and sending back an appropriate Command Response value (only CHTA_CRSP_BADPARAM currently).

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

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

  • 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 Partial Encryption mode, the server SHALL follow the requirements of Section 4.2.4, else the server SHALL follow the requirements of Section 4.2.2.

  • 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.

  • If Unauthenticated mode is selected, the Test Activation Request SHALL fail silently.

The additional, non-authentication circumstances when a server SHALL NOT communicate the appropriate Command Response code for an error condition (fail silently) are when:

  1. the Test Activation Request PDU size is not correct,

  2. the Control ID is invalid, or

  3. a directed attack has been detected,

in which case the server will allow Test Activation Requests to terminate silently. Attack detection is beyond the scope of this specification.

6.2.2. Server Accepts Request and Generates Response

When the server sends the Test Activation Response, it SHALL set the Command Response field to CHTA_CRSP_ACKOK

If the client has requested an upstream test, the server SHALL:

  • 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

  • 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.

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

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

In the case of a 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

  • 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

  • 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.

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.

6.3. Client Processes Test Activation Response

When the client receives the Test Activation Response, it SHALL:

  • 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 Partial Encryption mode, decrypt the PDU using the included IV and shared key designated via keyId. Finally, check the PDU for general formatting, such as protocol version, and any PDU-specific fields that control the test.

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

If the client receives a Test Activation Command Response value that indicates an error, the client SHALL display/report a relevant message to the user or management process and exit.

If the client receives a Test Activation Command Response value that is not equal to one of the codes defined, the client MUST terminate the connection and terminate operation of the current setup procedure.

If the client receives a Test Activation Command Response value that indicates success (CHTA_CRSP_ACKOK) the client SHALL update its configuration to use any test parameters modified by the server.

Next, 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.

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

The connection is now ready for testing.

7. Test Stream Transmission and Measurement Feedback Messages

This section describes the data phase of the protocol. The roles of sender and receiver vary depending whether the direction of testing is from server to client, or the reverse. All messages defined in this section SHALL use UDP transport.

7.1. Test Packet PDU and Roles

Testing proceeds with one end-point sending Load PDUs, based on transmission parameters from the Sending Rate Table, and the other end-point 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.

The watchdog timer at the receiver SHALL be reset each time a PDU is received. See non-graceful test stop in Section 8 for handling the watchdog timeout expiration at each end-point.

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).

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.

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.

The default algorithm (B) has three paths to its decision on the next sending rate:

  1. When there are no impairments present (no sequence errors and low delay variation), resulting in a sending rate increase.

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

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

Algorithm B also has two modes for increasing/decreasing the sending rate:

An OPTIONAL load rate adjustment algorithm (designated C) has been defined in [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).

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

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.

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

//
// Load header for UDP payload of Load PDUs
//
struct loadHdr {
#define LOAD_ID 0xBEEF
        uint16_t loadId; // Load 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 indicator (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 received status PDU
        uint32_t spduTime_nsec; // Send time in last received 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
};

Figure 7: Load PDU

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

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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           loadId              |   testAction  |   rxStopped   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           lpduSeqNo                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           udpPayload          |           spduSeqErr          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          spduTime_sec                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         spduTime_nsec                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          lpduTime_sec                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         lpduTime_nsec                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|         rttRespDelay          |           checkSum            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.                       Payload Content...                      .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 8: Load PDU Layout

Specific details regarding Load PDU fields are as follows:

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 Section 8 for additional information on test termination.

rxStopped: A boolean (0 or 1) used to indicate to the remote end-point 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).

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

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).

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.

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.

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.

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.

checkSum: An OPTIONAL checksum of only the Load PDU header. The checksum does not cover the Payload Content. The calculation is done with the checkSum field set to zero.

Payload Content: All zeroes, all ones, or a pseudorandom binary sequence.

7.2. Status PDU

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.

The watchdog timer at the Load PDU sender SHALL be reset each time a Status PDU is received. See non-graceful test stop in Section 8 for handling the watchdog timeout expiration at each end-point.

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

//
// 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 statusId;  // Status ID
        uint8_t testAction; // Test action
        uint8_t rxStopped;  // Receive traffic stopped indicator (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;    // Minimum round-trip time sampled (ms)
        uint32_t rttSample;     // 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 reserved1a;   // (reserved for alignment)
        uint32_t authUnixTime; // Authentication time stamp
        uint8_t initVector[AUTH_IV_LENGTH]     // IV
        uint8_t authDigest[AUTH_DIGEST_LENGTH] // HMAC
};

Figure 9: Status PDU

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

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

Figure 10: Status PDU Layout

Note that the Sending Rate structure is defined in Section 6.

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).

Details on the Status PDU measurement fields are provided in [RFC9097]. Additional information regarding fields not defined previously are as follows:

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.

seqErrLoss/seqErrOoo/seqErrDup: Loss, out-of-order, and duplicate totals. Available for both the sub-interval and trial interval.

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.

rttMinimum/rttMaximum (in sisSav): The minimum and maximum RTT delay variation (rttSample) in the sub-interval designated by the subIntSeqNo.

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.

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.

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

sisSav: Sub-interval statistics saved (completed) for the most recent sub-interval (as designated by the subIntSeqNo).

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 end-point clocks are sufficiently synchronized, this will be the minimum one-way delay in milliseconds. Otherwise, this value may be negative (but still completely valid for one-way delay variation measurements).

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.

rttSample: 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.

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.

checkSum: An OPTIONAL checksum of the entire PDU. The calculation is done with the checkSum field, and all fields starting with authMode, set to zero.

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.

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.

The authentication, encryption, and checksum fields and their operation are as defined previously in Section 4.

8. Stopping the Test

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.

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.

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).

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.

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.

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

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 end-point SHALL schedule an immediate end time for the connection.

9. Method of Measurement

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.

The duration of a test, parameter I, 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.

9.1. Notes on Interface Measurements

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.

10. Security Considerations

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 [RFC4656] and [RFC5357].

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 [RFC7594], which covers active and passive techniques.

There are some new considerations for Capacity measurement as described in this memo.

  1. 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 key used to create the authDigest field. Other means are also possible, such as access control lists at the server.

  2. 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.

  3. Client-server authentication and integrity protection for feedback messages conveying measurements is REQUIRED. To accommodate different host limitations and testing circumstances, different modes of operation are recommended, as described in Section 4 above.

  4. Hosts MUST limit the number of simultaneous tests to avoid resource exhaustion and inaccurate results.

  5. 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.

  6. 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).

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.

11. IANA Considerations

This memo requests IANA to assign a "well-known" 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 (UDPST) protocol.

11.1. New System Port Assignment

IANA will allocate the following service name to the "Service Name and Transport Protocol Port Number Registry" registry:

Service:
udpst-control
Transport Protocol:
UDP
Assignee:
IESG <[email protected]>
Contact:
IETF Chair <[email protected]>
Description:
UDP-based IP-Layer Capacity and performance measurement protocol
Reference:
This RFC, RFCYYYY. The protocol uses IP-Layer Unicast.
Port Number:
<left blank, as instructed>

11.2. New UDPST Registry Group

This section describes the design of the UDP Speed Test (UDPST) registry group.

The new registry group SHALL be named, "UDPST Registry".

The following applies to each registry in the sub-sections below:

Registration Procedure: Specification Required

Reference: <This RFC>

Experts: Performance Metrics Experts

Note: TBD

11.2.1. PDU Identifier Registry

The first two octets of the PDUs used in the UDPST protocol identify the role and format of PDU that follows.

Identifier  Value  Reference   Change     Description
Name                           Controller
===================================================================
controlId   0xACE1 <this RFC>  IETF       Test Setup PDU

controlId   0xACE2 <this RFC>  IETF       Test Activation PDU

controlId   0xDEAD <this RFC>  IETF       Null PDU

loadId      0xBEEF <this RFC>  IETF       Load PDU

statusId    0xFEED <this RFC>  IETF       Status Feedback PDU


Other values are unassigned.

11.2.2. Protocol Number Registry

The second two octets of the PDUs used in the UDPST protocol identify the version of the protocol in use. The table below defines the assigned decimal values in the registry.

Field          Value  Reference   Change     Description
Name                              Controller
===================================================================
protocolVer    0-7    <this RFC>  IETF       Reserved

protocolVer    8      <this RFC>  IETF       Protocol version 8

protocolVer    9      <this RFC>  IETF       Protocol version 9

protocolVer    10     <this RFC>  IETF       Protocol version 10

protocolVer    20     <this RFC>  IETF       Protocol version 20


Other values are unassigned, with an upper value of 65535.

11.2.3. Test Setup PDU Modifier Bitmap Registry

The Test Setup PDU layout contains a modifierBitmap field. The table below defines the initial bit assignments in the registry.

Field           Value  Reference   Change     Description
Name                                Controller
===================================================================
modifierBitmap   0x00   <this RFC>  IETF      No modifications

modifierBitmap   0x01   <this RFC>  IETF      Allow Jumbo
                                              datagram sizes above
                                              sending rates of 1Gbps

modifierBitmap   0x02   <this RFC>  IETF      Use Traditional MTU
                                              (1500 bytes with
                                              IP-header)

modifierBitmap   0x03-0xFF          IETF      Unassigned

11.2.4. Test Setup PDU Authentication Mode Registry

The Test Setup PDU layout contains an authMode field. The table below defines the assigned decimal values in the registry, and a range for experimentation.

Field     Value  Reference   Change     Description
Name                         Controller
=====================================================================
authMode  0      <this RFC>  IETF       OPTIONAL Unauthenticated mode

authMode  1      <this RFC>  IETF       REQUIRED authentication
                                        for the Control phase

authMode  2      <this RFC>  IETF       OPTIONAL authentication
                                        for the Data phase, in
                                        addition to the Control phase

authMode  3      <this RFC>  IETF       OPTIONAL partial encrypted
                                        mode

authMode  60-63  <this RFC>  IETF       Range for experimentation

Other values are unassigned, with the upper boundary of 255.

11.2.5. Test Setup PDU Command Response Field Registry

The Test Setup PDU layout contains an cmdResponse field. The table below defines the assigned decimal values in the registry.

Field        Value  Reference   Change     Description
Name                            Controller
===================================================================
cmdResponse  0      <this RFC>  IETF       None (used by
                                           client in Request)

cmdResponse  1      <this RFC>  IETF       Acknowledgment

cmdResponse  2      <this RFC>  IETF       Bad Protocol Version

cmdResponse  3      <this RFC>  IETF       Invalid Jumbo datagram
                                           option

cmdResponse  4      <this RFC>  IETF       Unexpected Authentication
                                           in Setup Request

cmdResponse  5      <this RFC>  IETF       Authentication missing in
                                           Setup Request

cmdResponse  6      <this RFC>  IETF       Invalid authentication
                                           method

cmdResponse  7      <this RFC>  IETF       Authentication failure

cmdResponse  8      <this RFC>  IETF       Authentication time is
                                           invalid in Setup Request

cmdResponse  9      <this RFC>  IETF       No Maximum test Bit rate
                                           specified

cmdResponse  10     <this RFC>  IETF       Server Maximum Bit rate
                                           exceeded

cmdResponse  11     <this RFC>  IETF       MTU option does not match
                                           server

cmdResponse  12     <this RFC>  IETF       Multi-connection parameters
                                           rejected by server

cmdResponse  13     <this RFC>  IETF       Connection allocation
                                           failure on server

Other values are unassigned, with the upper boundary of 255.

11.2.6. Test Activation PDU Modifier Bitmap Registry

The Test Activation PDU layout (also) contains a modifierBitmap field. The table below defines the initial bit assignments in the registry.

Field           Value  Reference   Change     Description
Name                               Controller
===================================================================
modifierBitmap   0x00   <this RFC>  IETF      No modifications

modifierBitmap   0x01   <this RFC>  IETF      Set when srIndexConf is
                                              start rate for search

modifierBitmap   0x02   <this RFC>  IETF      Set for randomized
                                              UDP payload

modifierBitmap   0x03-0xFF          IETF      Unassigned

11.2.7. Test Activation PDU Command Request Registry

The Test Activation PDU layout contains a cmdRequest field. The table below defines the assigned decimal values in the registry.

Field      Value    Reference  Change    Description
Name                           Controller
===================================================================
cmdRequest  0      <this RFC>  IETF      No Request

cmdRequest  1      <this RFC>  IETF      Request test in Upstream
                                         direction (client to server)

cmdRequest  2      <this RFC>  IETF      Request test in Downstream
                                         direction (server to client)

Other values are unassigned, with the upper boundary of 255.

11.2.8. Test Activation PDU Rate Adjustment Algo. Registry

The Test Activation PDU layout contains a rateAdjAlgo field. The table below defines the assigned Capitalized alphabetic UTF-8 values in the registry.

Field      Value    Reference  Change    Description
Name                           Controller
===================================================================
rateAdjAlgo  A      <this RFC>  IETF      Not used

rateAdjAlgo  B      <this RFC>  IETF      Rate algorithm Type B

rateAdjAlgo  C      <this RFC>  IETF      Rate algorithm Type C

Other values are unassigned, with the upper boundary of Z.

11.2.9. Test Activation PDU Command Response Field Registry

The Test Activation PDU layout (also) contains a cmdResponse field. The table below defines the assigned decimal values in the registry.

Field        Value  Reference   Change     Description
Name                            Controller
===================================================================
cmdResponse  0      <this RFC>  IETF       None (used by
                                           client in Request)

cmdResponse  1      <this RFC>  IETF       Server Acknowledgment

cmdResponse  2      <this RFC>  IETF       Server indicates an error


Other values are unassigned, with the upper boundary of 255.

12. Acknowledgments

This specification has been edited by Al Morton. Al Morton died before he was able to finalise this work. As Al can't complete author tasks during the IETF standardisation process anymore, it was decided not to keep him as an author in the proper section. Respecting, that almost all of the content here has been edited or created by Al, it seems fair not just to give him credit for his work, but also list him as editor, if this document reaches RFC status.

Thanks to Lincoln Lavoie, Can Desem, and Greg Mirsky for reviewing this draft and providing helpful suggestions and areas for further development. Ken Kerpez and Chen Li have provided helpful reviews. Amanda Baber provided early reviews of the IANA Considerations section.

Brian Weis provided an early SEC-DIR review; version 02 captures clarifications and version 03-07 took up on the protocol changes which Brian suggested.

13. References

13.1. Normative References

[FIPS-197]
National Institute of Standards and Technology, NIST., "Federal Information Processing Standards Publication 197 (FIPS-197), ADVANCED ENCRYPTION STANDARD (AES)", , <https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.197.pdf>.
[I-D.ietf-ippm-capacity-metric-method]
Morton, A. C., Geib, R., and L. Ciavattone, "Metrics and Methods for One-Way IP Capacity", Work in Progress, Internet-Draft, draft-ietf-ippm-capacity-metric-method-12, , <https://datatracker.ietf.org/doc/html/draft-ietf-ippm-capacity-metric-method-12>.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC2330]
Paxson, V., Almes, G., Mahdavi, J., and M. Mathis, "Framework for IP Performance Metrics", RFC 2330, DOI 10.17487/RFC2330, , <https://www.rfc-editor.org/info/rfc2330>.
[RFC2681]
Almes, G., Kalidindi, S., and M. Zekauskas, "A Round-trip Delay Metric for IPPM", RFC 2681, DOI 10.17487/RFC2681, , <https://www.rfc-editor.org/info/rfc2681>.
[RFC6071]
Frankel, S. and S. Krishnan, "IP Security (IPsec) and Internet Key Exchange (IKE) Document Roadmap", RFC 6071, DOI 10.17487/RFC6071, , <https://www.rfc-editor.org/info/rfc6071>.
[RFC6234]
Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)", RFC 6234, DOI 10.17487/RFC6234, , <https://www.rfc-editor.org/info/rfc6234>.
[RFC6438]
Carpenter, B. and S. Amante, "Using the IPv6 Flow Label for Equal Cost Multipath Routing and Link Aggregation in Tunnels", RFC 6438, DOI 10.17487/RFC6438, , <https://www.rfc-editor.org/info/rfc6438>.
[RFC7210]
Housley, R., Polk, T., Hartman, S., and D. Zhang, "Database of Long-Lived Symmetric Cryptographic Keys", RFC 7210, DOI 10.17487/RFC7210, , <https://www.rfc-editor.org/info/rfc7210>.
[RFC7497]
Morton, A., "Rate Measurement Test Protocol Problem Statement and Requirements", RFC 7497, DOI 10.17487/RFC7497, , <https://www.rfc-editor.org/info/rfc7497>.
[RFC7680]
Almes, G., Kalidindi, S., Zekauskas, M., and A. Morton, Ed., "A One-Way Loss Metric for IP Performance Metrics (IPPM)", STD 82, RFC 7680, DOI 10.17487/RFC7680, , <https://www.rfc-editor.org/info/rfc7680>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/info/rfc8174>.
[RFC8446]
Rescorla, E., "The Transport Layer Security (TLS) Protocol Version 1.3", RFC 8446, DOI 10.17487/RFC8446, , <https://www.rfc-editor.org/info/rfc8446>.
[RFC8468]
Morton, A., Fabini, J., Elkins, N., Ackermann, M., and V. Hegde, "IPv4, IPv6, and IPv4-IPv6 Coexistence: Updates for the IP Performance Metrics (IPPM) Framework", RFC 8468, DOI 10.17487/RFC8468, , <https://www.rfc-editor.org/info/rfc8468>.
[RFC9097]
Morton, A., Geib, R., and L. Ciavattone, "Metrics and Methods for One-Way IP Capacity", RFC 9097, DOI 10.17487/RFC9097, , <https://www.rfc-editor.org/info/rfc9097>.
[RFC9147]
Rescorla, E., Tschofenig, H., and N. Modadugu, "The Datagram Transport Layer Security (DTLS) Protocol Version 1.3", RFC 9147, DOI 10.17487/RFC9147, , <https://www.rfc-editor.org/info/rfc9147>.

13.2. Informative References

[CBC]
Dworkin, M., "NIST Special Publication 800-38A: Recommendation for Block Cipher Modes of Operation: Methods and Techniques, U.S. National Institute of Standards and Technology", , <csrc.nist.gov/publications/detail/sp/800-38a/final>.
[copycat]
Edleine, K., Kuhlewind, K., Trammell, B., and B. Donnet, "copycat: Testing Differential Treatment of New Transport Protocols in the Wild (ANRW '17)", , <https://irtf.org/anrw/2017/anrw17-final5.pdf>.
[LS-SG12-A]
12, I. S., "LS - Harmonization of IP Capacity and Latency Parameters: Revision of Draft Rec. Y.1540 on IP packet transfer performance parameters and New Annex A with Lab Evaluation Plan", , <https://datatracker.ietf.org/liaison/1632/>.
[LS-SG12-B]
12, I. S., "LS on harmonization of IP Capacity and Latency Parameters: Consent of Draft Rec. Y.1540 on IP packet transfer performance parameters and New Annex A with Lab & Field Evaluation Plans", , <https://datatracker.ietf.org/liaison/1645/>.
[RFC2544]
Bradner, S. and J. McQuaid, "Benchmarking Methodology for Network Interconnect Devices", RFC 2544, DOI 10.17487/RFC2544, , <https://www.rfc-editor.org/info/rfc2544>.
[RFC3148]
Mathis, M. and M. Allman, "A Framework for Defining Empirical Bulk Transfer Capacity Metrics", RFC 3148, DOI 10.17487/RFC3148, , <https://www.rfc-editor.org/info/rfc3148>.
[RFC3610]
Whiting, D., Housley, R., and N. Ferguson, "Counter with CBC-MAC (CCM)", RFC 3610, DOI 10.17487/RFC3610, , <https://www.rfc-editor.org/info/rfc3610>.
[RFC4656]
Shalunov, S., Teitelbaum, B., Karp, A., Boote, J., and M. Zekauskas, "A One-way Active Measurement Protocol (OWAMP)", RFC 4656, DOI 10.17487/RFC4656, , <https://www.rfc-editor.org/info/rfc4656>.
[RFC5136]
Chimento, P. and J. Ishac, "Defining Network Capacity", RFC 5136, DOI 10.17487/RFC5136, , <https://www.rfc-editor.org/info/rfc5136>.
[RFC5357]
Hedayat, K., Krzanowski, R., Morton, A., Yum, K., and J. Babiarz, "A Two-Way Active Measurement Protocol (TWAMP)", RFC 5357, DOI 10.17487/RFC5357, , <https://www.rfc-editor.org/info/rfc5357>.
[RFC6815]
Bradner, S., Dubray, K., McQuaid, J., and A. Morton, "Applicability Statement for RFC 2544: Use on Production Networks Considered Harmful", RFC 6815, DOI 10.17487/RFC6815, , <https://www.rfc-editor.org/info/rfc6815>.
[RFC7312]
Fabini, J. and A. Morton, "Advanced Stream and Sampling Framework for IP Performance Metrics (IPPM)", RFC 7312, DOI 10.17487/RFC7312, , <https://www.rfc-editor.org/info/rfc7312>.
[RFC7594]
Eardley, P., Morton, A., Bagnulo, M., Burbridge, T., Aitken, P., and A. Akhter, "A Framework for Large-Scale Measurement of Broadband Performance (LMAP)", RFC 7594, DOI 10.17487/RFC7594, , <https://www.rfc-editor.org/info/rfc7594>.
[RFC7799]
Morton, A., "Active and Passive Metrics and Methods (with Hybrid Types In-Between)", RFC 7799, DOI 10.17487/RFC7799, , <https://www.rfc-editor.org/info/rfc7799>.
[RFC8337]
Mathis, M. and A. Morton, "Model-Based Metrics for Bulk Transport Capacity", RFC 8337, DOI 10.17487/RFC8337, , <https://www.rfc-editor.org/info/rfc8337>.
[RFC8762]
Mirsky, G., Jun, G., Nydell, H., and R. Foote, "Simple Two-Way Active Measurement Protocol", RFC 8762, DOI 10.17487/RFC8762, , <https://www.rfc-editor.org/info/rfc8762>.
[RFC8972]
Mirsky, G., Min, X., Nydell, H., Foote, R., Masputra, A., and E. Ruffini, "Simple Two-Way Active Measurement Protocol Optional Extensions", RFC 8972, DOI 10.17487/RFC8972, , <https://www.rfc-editor.org/info/rfc8972>.
[TR-471]
Morton, A,, Editor., "Broadband Forum TR-471: IP Layer Capacity Metrics and Measurement, Issue 3", , <https://www.broadband-forum.org/technical/download/TR-471.pdf>.
[udpst]
udpst Project Collaborators, "UDP Speed Test Open Broadband project", , <https://github.com/BroadbandForum/obudpst>.
[Y.1540]
Y.1540, I. R., "Internet protocol data communication service - IP packet transfer and availability performance parameters", , <https://www.itu.int/rec/T-REC-Y.1540-201912-I/en>.
[Y.Sup60]
Morton, A., Rapporteur., "Recommendation Y.Sup60, (09/20) Interpreting ITU-T Y.1540 maximum IP-layer capacity measurements", , <https://www.itu.int/rec/T-REC-Y.Sup60/en>.

Authors' Addresses

Len Ciavattone
AT&T Labs
Middletown, NJ
United States of America
Ruediger Geib
Deutsche Telekom
Deutsche Telekom Allee 9
64295 Darmstadt
Germany