Here is the format of a token: - format (1 byte) - ODCID (from 9 up 21 bytes) - creation timestamp (4 bytes) - salt (16 bytes) A format byte is required to distinguish the Retry token from others sent in NEW_TOKEN frames. The Retry token is ciphered after having derived a strong secret from the cluster secret and generated the AEAD AAD, as well as a 16 bytes long salt. This salt is added to the token. Obviously it is not ciphered. The format byte is not ciphered too. The AAD are built by quic_generate_retry_token_aad() which concatenates the version, the client SCID and the IP address and port. We had to implement quic_saddr_cpy() to copy the IP address and port to the AAD buffer. Only the Retry SCID is generated on our side to build a Retry packet, the others fields come from the first packet received by the client. It must reuse this Retry SCID in response to our Retry packet. So, we have not to store it on our side. Everything is offloaded to the client (stateless). quic_generate_retry_token() must be used to generate a Retry packet. It calls quic_pkt_encrypt() to cipher the token. quic_generate_retry_check() must be used to check the validity of a Retry token. It is able to decipher a token which arrives into an Initial packet in response to a Retry packet. It calls parse_retry_token() after having deciphered the token to store the ODCID into a local quic_cid struct variable. Finally this ODCID may be stored into the transport parameter thanks to qc_lstnr_params_init(). The Retry token lifetime is 10 seconds. This lifetime is also checked by quic_generate_retry_check(). If quic_generate_retry_check() fails, the received packet is dropped without anymore packet processing at this time.