The UDP Speed Test Protocol (UDPSTP) for One-Way IP Capacity Metric Measurement
Extracted elements (35)
A KDF (NIST SP 800-108 counter mode with HMAC-SHA-256) was introduced to provide cryptographic separation of client and server key material from a single shared secret, reducing the risk of key compromise while requiring only one execution per test connection to minimize overhead.
Closed-loop feedback from receiver to sender was the primary gap motivating UDPSTP: OWAMP (RFC 4656), TWAMP (RFC 5357), and STAMP (RFC 8762) support asymmetric traffic and two-way communication but lack closed-loop feedback, which is necessary to limit congestion of the measured bottleneck to a short time range.
Encryption support was deliberately omitted because the protocol carries only synthetic payload data with no direct user information; this also increases the number of low-end devices that can support the test methodology without sufficient processing power for encryption.
The load rate adjustment algorithm is hosted at the server regardless of direction so that algorithm updates affect only server hosts—a far smaller and more manageable set than the diverse population of client devices.
UDPSTP is not interoperable with OWAMP (RFC 4656), TWAMP (RFC 5357), or STAMP (RFC 8762); those protocols lack closed-loop feedback operation. UDPSTP is at least partially compliant with RFC 8085 Section 3.1 when the bottleneck is congested, limiting congestion duration to the minimum required to determine capacity.
A client (and in general, a consumer) MUST NOT be able to initiate a fixed-rate test; fixed-rate testing is restricted to network operators for operation and maintenance within their own domain.
All messages defined by UDPSTP SHALL use UDP transport.
Any field labeled 'reserved for alignment' in any PDU MUST be set to 0 by the sender and MUST be ignored upon receipt.
Congestion MUST be indicated if Status Feedback PDUs show either sequence number anomalies were detected OR the delay range exceeded the upper delay variation threshold. Recommended thresholds are 10 for sequence number gaps, 30 ms lower, and 90 ms upper delay variation.
In Mode 1, the receiver SHALL use a 10-second tolerance window (±5 seconds) on the authUnixTime field to distinguish replay of a PDU; if validation of authDigest fails, the receiver SHOULD NOT continue with the Control phase and SHOULD implement silent rejection.
In Mode 2, if authentication validation of a Status PDU fails the receiver SHALL ignore the message; if the watchdog timer subsequently expires, the test session SHALL prematurely terminate and no further load traffic SHALL be transmitted.
The client source IP address and server destination IP address MUST NOT be a broadcast or multicast address; any Test Setup Request or Response containing such an address MUST be silently dropped and ignored.
The IPv4 Don't Fragment (DF) bit SHOULD be set for all tests unless IP fragmentation is itself an attribute being measured, to avoid measurement distortion from Layer 3 fragmentation.
The KDF algorithm SHALL be a Key Derivation Function in Counter Mode (NIST SP 800-108 Section 4.1) using HMAC-SHA-256 as the PRF. The total derived key material SHALL be 512 bits: 256 bits for the Client Authentication Key and 256 bits for the Server Authentication Key.
The Load PDU timeout and Status PDU timeout MUST each be no more than 1 second by default; expiry of the Load PDU timeout closes the receiver and stops Status PDU feedback, while expiry of the Status PDU timeout closes the sender and stops load packets.
The load rate adjustment algorithm MUST NOT be used as a general Congestion Control Algorithm (CCA); its purpose is limited to determining Maximum IP-Layer Capacity during infrequent, diagnostic, short-term measurements.
The nominal duration of a measurement interval at the Destination (testIntTime) MUST default to a value of no more than 10 seconds.
The number of concurrent independent tests of a path SHALL be limited to one, regardless of the number of flows, to prevent measurement impairment and additional congestion on the bottleneck.
The protocol MUST utilize the standard UDP checksum for all IPv4 and IPv6 datagrams to protect both the intended recipient and other potential recipients to whom a corrupted packet may be delivered.
An active measurement technique such as UDPSTP is better suited to protect the privacy of measurement participants than passive methods because it uses synthetic payload data containing no direct user information (per RFC 7594).
Multi-connection (multi-flow) testing is supported: mcIndex (1 octet, 0-based) identifies a connection within a test, mcCount (1 octet) is the total connection count, and mcIdent (2 octets, pseudorandom non-zero) associates all connections of a single test. Each connection is processed independently by the server.
The KDF uses Kin (shared key identified by keyId), Label='UDPSTP' (UTF-8), and Context=the UTF-8 string of authUnixTime from the very first Setup Request PDU as a session nonce. Derived keys are used for all subsequent PDUs of that test connection; the KDF executes only once per connection.
The load rate adjustment algorithm always executes at the server regardless of test direction. In upstream tests, the client uses transmission parameters communicated by the server in periodic Status Feedback messages (not a local Sending Rate Table), enabling the server to control both sending rates and the adjustment algorithm.
The server assigns a unique ephemeral UDP port per test connection (returned in the testPort field of the Setup Response). The server immediately sends a Null Request from that port to open firewall pinholes; Status messages during the Data phase also keep NAT/firewall mappings active.
Two security authentication modes: Mode 1 (AUTHMODE_1=1) requires HMAC-SHA-256 authentication only during the Control phase; Mode 2 (AUTHMODE_2=2) additionally authenticates Status Feedback PDUs during the Data phase. Values 60-63 are reserved for experimentation.
UDPSTP operates over UDP transport in two phases: a Control phase (Test Setup Request/Response and Test Activation Request/Response) and a Data phase (Load PDUs and Status Feedback PDUs). The client always initiates the connection to a server listening on the standard UDPSTP port.
IANA assigned a new user port number for UDPSTP (Section 12.1) and registered 'HMAC-SHA-256' as a new KeyTable KDF entry in the registry defined by RFC 7210, binding counter-mode KDF usage to this protocol (Section 12.2).
IANA created the 'UDPSTP Registry Group' comprising: PDU Identifier Registry (0xACE1 Setup, 0xACE2 Activation, 0xBEEF Load, 0xDEAD Null Request, 0xBEEE Status), Protocol Version Registry (value 20), Test Setup PDU Modifier Bitmap Registry, Authentication Mode Registry (AUTHMODE_1=1, AUTHMODE_2=2, 60-63 experimentation), Command Response Registries for Setup and Activation PDUs, Test Activation Command Request Registry, Modifier Bitmap Registry, and Rate Adjustment Algo Registry.
Authentication uses HMAC-SHA-256 over the entire PDU with authDigest and checkSum fields preset to zero before hashing. Replay protection is provided by a 32-bit authUnixTime with a ±5-second tolerance window. Encryption is deliberately omitted because only synthetic payload data is carried.
Requests with an invalid authDigest SHOULD fail silently (no response) to prevent enumeration; exceptions are permitted only for operator troubleshooting. Fixed-rate testing, which bypasses congestion control, is restricted to intra-domain operator use to prevent traffic starvation on shared paths.
Connection lifecycle: (1) Client sends Setup Request to standard port → server accepts, allocates ephemeral port, sends Setup Response + Null Request; (2) Client sends Activation Request to ephemeral port → server accepts/modifies/rejects; (3) Sender streams Load PDUs, receiver streams Status Feedback PDUs; (4) Server sets TEST_ACT_STOP in outgoing PDU → client acknowledges with TEST_ACT_STOP → graceful teardown. Watchdog timers at both ends enforce non-graceful termination on silence.
Load PDU (pduId=0xBEEF, 2 octets): contains pduId (2), testAction (1), rxStopped (1), lpduSeqNo (4), udpPayload (2), spduSeqErr (2), spduTime_sec (4), spduTime_nsec (4), followed by variable payload; authentication is not applied to Load PDUs, but the optional UDPSTP checksum SHALL be used when UDP data integrity is uncertain.
Null Request PDU (pduId=0xDEAD, 2 octets): sent by the server from its new ephemeral port to open firewall pinholes; contains pduId (2), protocolVer (2), cmdRequest (1), cmdResponse (1), reserved1 (1), authMode (1), authUnixTime (4), authDigest (32), keyId (1), reservedAuth1 (1), checkSum (2); big-endian.
Test Activation PDU (pduId=0xACE2, 2 octets): carries srStruct (28 octets: txInterval1/2, udpPayload1/2, burstSize1/2, udpAddon2), lowThresh (2), upperThresh (2), trialInt (2), testIntTime (2), dscpEcn (1), srIndexConf (2), useOwDelVar (1), highSpeedDelta (1), slowAdjThresh (2), seqErrThresh (2), ignoreOooDup (1), modifierBitmap (1), rateAdjAlgo (1), subIntPeriod (2), plus authentication fields; big-endian.
Test Setup PDU (pduId=0xACE1, 2 octets; protocolVer=20): includes mcIndex (1), mcCount (1), mcIdent (2), cmdRequest (1), cmdResponse (1), maxBandwidth (2), testPort (2), modifierBitmap (1), authMode (1), authUnixTime (4), authDigest (32 octets HMAC-SHA-256), keyId (1), reservedAuth1 (1), checkSum (2); big-endian.