This commits add some new options to examples/[server,client] to support testing
of DTLS v1.3.
client: add waitTicket option
If this option is used, the client will wait until it receives a sessionTicket
from the server. This is useful when testing DTLS retransmission.
client: add waitKeyUpdate option
When this option is set, the client waits until the UpdateKey message is
acknowledged by the server. This is useful to test DTLS retransmission logic
This way we can use wolfSSL_Peek() invoked with sz == 0 to process pending
records and, if none of this records is an application data record, we will not
block.
Introduce ACK and retransmission logic, encapsulated in a Dtls13RtxFsm
object. The retransmission or the sending of an ACK is scheduled by setting the
appropriate flag inside the Dtls13RtxFSM object but the actual writing on the
socket is deferred and done in wolfSSL_Accept/Connect.
* Retransmission
Each sent message is encapsulated in a Dtl13RtxRecord and saved on a list. If we
receive an ACK for at record, we remove it from the list so it will be not
retransmitted further, then we will retransmit the remaining
ones. Retransmission is throttled: beside link congestion, this also avoid too
many sequence numbers bounded with a record.
* ACK
For each received record we save the record sequence number, so we can send an
ACK if needed. We send an ACK either if explicitly needed by the flight or if we
detect a disruption.
Co-authored-by: Juliusz Sosinowicz <juliusz@wolfssl.com>
This commit implements the core of the header parsing, building, and the sending
and receiving routines that handle fragmentation and defragmentation.
* In DTLSv1.3 the header used for protected messages is a variable-length header,
and it is described RFC9147 Section 4.
* Fragmentation happens after building the full message, if necessary. If the
underlying I/O can't send a fragment because of a WANT_WRITE error, the sending
of fragments will continue in the next invocation of
wolfSSL_connect/wolfSSL_accept/wolfSSL_write. In this case the message is saved
in a buffer inside the WolfSSL object.
* Defragmentation works like DTLSv1.2 defragmentation, and re-use
most of the same code.
* The Dtls13AddHeaders() function does not add the record layer header, but it
lefts space for it. It is eventually placed by BuildTls13Message() to allow
easier management of sequence numbers.
In DTLSv1.3, because of retransmission and reordering, we may need to encrypt or
decrypt records with older keys. As an example, if the server finished message
is lost, the server will need to retransmit that message using handshake traffic
keys, even if he already used the traffic0 ones (as, for example, to send
NewSessionTicket just after the finished message).
This commit implements a way to save the key bound to a DTLS epoch and setting
the right key/epoch when needed.
as word64 is not always available, introduce an abstract type and companion
operations. They use a word64 if available and fallback on word32[2] otherwise.