}
/* RFC 9000 14.1 Initial datagram size
+ *
+ * A client MUST expand the payload of all UDP datagrams carrying Initial
+ * packets to at least the smallest allowed maximum datagram size of 1200
+ * bytes by adding PADDING frames to the Initial packet or by coalescing
+ * the Initial packet; see Section 12.2. Initial packets can even be
+ * coalesced with invalid packets, which a receiver will discard.
*
* Similarly, a server MUST expand the payload of all UDP
* datagrams carrying ack-eliciting Initial packets to at least the
* smallest allowed maximum datagram size of 1200 bytes.
*/
if (qel == qc->iel && (!l || !LIST_ISEMPTY(frms) || probe)) {
- /* Ensure that no ack-eliciting packets are sent into too small datagrams */
+ /* Ensure that no Initial packets are sent into too small datagrams */
if (end - pos < QUIC_INITIAL_PACKET_MINLEN) {
TRACE_PROTO("No more enough room to build an Initial packet",
QUIC_EV_CONN_PHPKTS, qc);
break;
}
- /* padding will be set for last QEL, except when probing:
- * to build a PING only non coalesced Initial datagram for
- * instance when blocked by the anti-amplification limit,
- * this datagram MUST be padded.
+ /* padding MUST ALWAYS be set for the last QEL, except:
+ * - for a listener, when probing, that is to say
+ * to build a PING only non coalesced Initial datagram for
+ * instance when blocked by the anti-amplification limit,
+ * this datagram MUST be padded.
*/
padding = 1;
}
pkt_type = quic_enc_level_pkt_type(qc, qel);
- /* <paddding> parameter for qc_build_pkt() must not be set to 1 when
+ /* For listeners:
+ * <paddding> parameter for qc_build_pkt() must not be set to 1 when
* building PING only Initial datagram (a datagram with an Initial
* packet inside containing only a PING frame as ack-eliciting
* frame). This is the case when both <probe> and LIST_EMPTY(<frms>)
* conditions are verified (see qc_do_build_pkt()).
+ *
+ * For clients:
+ * <padding> must be set to 1 only the current packet cannot be coalesed,
+ * i.e. if the next qel is not present or empty.
*/
cur_pkt = qc_build_pkt(&pos, end, qel, tls_ctx, frms,
qc, ver, dglen, pkt_type, must_ack,
- padding && (!l || (!next_qel && (!probe || !LIST_ISEMPTY(frms)))),
+ padding &&
+ ((!l && (!next_qel || LIST_ISEMPTY(next_qel->send_frms))) ||
+ (l && !next_qel && (!probe || !LIST_ISEMPTY(frms)))),
probe, cc, &err);
if (!cur_pkt) {
switch (err) {
int ret = 0;
TRACE_ENTER(QUIC_EV_CONN_TXPKT, qc);
+ TRACE_PRINTF(TRACE_LEVEL_DEVELOPER, QUIC_EV_CONN_TXPKT, qc, 0, 0, 0,
+ "dglen=%u pn=%llu must_ack=%d padding=%d cc=%d probe=%d qel=%c",
+ (unsigned int)dglen, (ull)pn, must_ack, padding, cc, probe,
+ quic_enc_level_char_from_qel(qel, qc));
/* Length field value with CRYPTO frames if present. */
len_frms = 0;