メインコンテンツまでスキップ

8. Test Load Stream Transmission and Measurement Status Feedback Messages

この節では UDPSTP の RFC テキストを保持し, One-Way IP Capacity metrics, Control and Data phases, Load and Status Feedback PDUs, KDF/HMAC authentication, optional checksum handling, IANA registries, security considerations を扱う.

RFC 原文

8.  Test Load Stream Transmission and Measurement Status Feedback
Messages

This section describes the Data phase of the protocol. The roles of
sender and receiver vary depending on whether the direction of
testing is from server to client, or the reverse.

8.1. Load PDU and Roles

Testing proceeds with one endpoint sending Load PDUs, based on
transmission parameters from the Sending Rate Table, and the other
endpoint sending Status Feedback messages to communicate the traffic
conditions at the receiver. When the server is sending Status
Feedback messages, they will also contain the latest transmission
parameters from the Sending Rate Table that the client SHALL use.

When a Load PDU is received, the receiver SHALL do the following:

1. Verify that the size of the message is greater than or equal to
the 'struct loadHdr' size shown in Figure 9.

2. Validate the checksum for the Load PDU header portion of the
total message (as described in Section 5.6) if the optional
checkSum field is being utilized.

3. Confirm that the PDU ID is 0xBEEF (Load PDU).

If any of the above checks fail, the message SHALL be considered
invalid.

The watchdog timer at the receiver SHALL be reset each time a valid
Load PDU is received (which includes verification of the checkSum, if
in use). See non-graceful test stop in Section 9 for handling the
watchdog timeout expiration at each endpoint. Note that the watchdog
timer's purpose is to detect a connection failure or a massive
congestion condition only.

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 discrete 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 that evaluates
measurements taken locally at the Load PDU receiver. When the client
is the receiver, the information is communicated to the server via
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 are
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; see [Y.1540]) 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:

* A high-speed mode (fast) to achieve high sending rates quickly but
that also backs off quickly when "congestion" is inferred from the
measurements. Consecutive feedback intervals that have a supra-
threshold count of sequence number anomalies and/or contain an
upper delay variation threshold exception in all of the
consecutive intervals are sufficient to declare "congestion"
within a test. The threshold of consecutive feedback intervals
SHALL be configurable with a default of 3 intervals.

* A single-step (slow) mode where all rate adjustments use the
minimum increase or decrease of one step in the Sending Rate
Table. The single-step mode continues after the first inference
of "congestion" from measured impairments.

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 provides the option to retry 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 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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| pduId | 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:

pduId: IANA has assigned the hex value 0xBEEF (Section 12.3.1).

testAction: A one-octet field designating 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 9 for additional
information on test termination.

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

lpduSeqNo: A four-octet field indicating the Load PDU sequence
number (starting at 1). Used to determine loss, out-of-order, and
duplicate totals.

udpPayload: A two-octet field indicating 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: A two-octet field indicating the 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: Two four-octet fields containing 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: Two four-octet fields containing the
local send time of the Load PDU. Used for one-way delay variation
measurements made by the Load PDU receiver.

rttRespDelay: A two-octet field indicating the RTT response delay,
used to "adjust" raw RTT. On the Load PDU sender, it is the
number of ms 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 (see
Section 5.6 for guidance). The checksum does not cover the
payload content. The calculation is done as the very last step of
building the PDU header, with the checkSum field set to zero.

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

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

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

Figure 9: Load PDU

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

When the Load PDU sender receives a Status PDU message, it SHALL
first follow the Message Verification Procedure listed in
Section 6.2, Paragraph 2.

The watchdog timer at the Load PDU sender SHALL be reset each time a
valid Status PDU is received (which includes verification of the
checkSum and/or authDigest, if in use). See non-graceful test stop
in Section 9 for handling the watchdog timeout expiration at each
endpoint.

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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| rttVarMinimum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| rttVarMaximum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| accumTime |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| pduId | testAction | rxStopped |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| spduSeqNo |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
. srStruct (28 octets) .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| subIntSeqNo |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
. sisSav (56 octets) .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| seqErrLoss |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| seqErrOoo |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| seqErrDup |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| clockDeltaMin |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| delayVarMin |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| delayVarMax |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| delayVarSum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| delayVarCnt |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| rttMinimum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| rttVarSample |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| delayMinUpd | reserved1 | reserved2 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| tiDeltaTime |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| tiRxDatagrams |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| tiRxBytes |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| spduTime_sec |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| spduTime_nsec |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| reserved3 | reserved4 | authMode |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| authUnixTime |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
. authDigest (32 octets) .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| keyId | reservedAuth1 | checkSum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Figure 10: Status PDU Layout

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

The primary role of the Status Feedback message is to communicate the
traffic conditions at the Load PDU receiver to the Load PDU sender.
While the Sub-Interval statistics saved (sisSav) structure 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]. The authentication and checkSum fields follow the same
methodology as with the Setup Request and Response. Additional
information regarding fields not defined previously are as follows:

pduId: IANA has assigned the hex value 0xFEED (Section 12.3.1).

spduSeqNo: A four-octet field containing the 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: A four-octet field containing the 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). These
consist of the following fields:

rxDatagrams: A four-octet field Sub-Interval indicating the
number of received datagrams during the Sub-Interval.

rxBytes: An eight-octet field indicating the Sub-Interval byte
count (eight octets chosen to prevent overflow at high speeds).

deltaTime: A four-octet field indicating the exact duration of
the Sub-Interval in us. Used to calculate the received traffic
rate together with rxBytes.

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

delayVarMin/delayVarMax/delayVarSum/delayVarCnt: Four four-octet
fields populated by 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.

rttVarMinimum/rttVarMaximum (in sisSav): Two four-octet fields
populated by the minimum and maximum RTT delay variation
(rttVarSample) in the Sub-Interval designated by the
subIntSeqNo.

accumTime: The accumulated time of the test in ms, 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.

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

rttMinimum (in Status PDU): A four-octet field indicating the
minimum "adjusted" RTT measured since the beginning of the test.
See rttRespDelay (Section 8.1) 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_NODEL when communicated in the
Status PDU.

rttVarSample: A four-octet field indicating the most recent
"adjusted" RTT delay variation measurement. See rttRespDelay
(Section 8.1) 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_NODEL when
communicated in the Status PDU.

delayMinUpd: A one-octet field. Boolean, 0 or 1, indicating that
the clockDeltaMin and/or rttMinimum (in Status PDU), as measured
by the Load PDU receiver, has been updated.

tiDeltaTime/tiRxDatagrams/tiRxBytes: Three four-octet fields
populated by the trial interval time in us, along with the
received datagram and byte counts. Used to calculate the received
traffic rate for the trial interval.

spduTime_sec/spduTime_nsec: Two four-octet fields containing 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.

authMode: Same as in Section 6.1.

authUnixTime: Same as in Section 6.1.

authDigest: Same as in Section 6.1.

keyId: Same as in Section 6.1.

reservedAuth1: Same as in Section 6.1.

checkSum: Same as in Section 6.1.

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

<CODE BEGINS>
//
// Sub-Interval statistics structure for received traffic information
//
#pragma pack(push, 1)
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 rttVarMinimum; // Minimum RTT variation (ms)
uint32_t rttVarMaximum; // Maximum RTT variation (ms)
uint32_t accumTime; // Accumulated time (ms)
};
#pragma pack(pop)
//
// Status Feedback header for UDP payload of status PDUs
//
struct statusHdr {
#define STATUS_ID 0xFEED
uint16_t pduId; // PDU ID
uint8_t testAction; // Test action
uint8_t rxStopped; // Receive traffic stopped (BOOL)
uint32_t spduSeqNo; // Status PDU sequence number
struct sendingRate srStruct; // Sending Rate structure
uint32_t subIntSeqNo; // Sub-Interval sequence number
struct subIntStats sisSav; // Sub-Interval stats saved
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_NODEL UINT32_MAX // No delay data/value
uint32_t rttMinimum; // Min round-trip time sampled (ms)
uint32_t rttVarSample; // Last round-trip time sample (ms)
uint8_t delayMinUpd; // Delay minimum(s) updated (BOOL)
uint8_t reserved1; // (reserved for alignment)
uint16_t reserved2; // (reserved for alignment)
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
uint16_t reserved3; // (reserved for alignment)
uint8_t reserved4; // (reserved for alignment)
// ========== Integrity Verification ==========
uint8_t authMode; // Authentication mode
uint32_t authUnixTime; // Authentication timestamp
uint8_t authDigest[AUTH_DIGEST_LENGTH];
uint8_t keyId; // Key ID in shared table
uint8_t reservedAuth1; // (reserved for alignment)
uint16_t checkSum; // Header checksum
};
<CODE ENDS>

Figure 11: Status PDU