MINOR: quic: Dynamic Retry implementation

We rely on <conn_opening> stats counter and tune.quic.retry_threshold
setting to dynamically start sending Retry packets. We continue to send such packets
when "quic-force-retry" setting is set. The difference is when we receive tokens.
We check them regardless of this setting because the Retry could have been
dynamically started. We must also send Retry packets when we receive Initial
packets without token if the dynamic Retry threshold was reached but only for connection
which are not currently opening or in others words for Initial packets without
connection already instantiated. Indeed, we must not send Retry packets for all
Initial packets without token. For instance a client may have already sent an
Initial packet without receiving Retry packet because the Retry feature was not
started, then the Retry starts on exeeding the threshold value due to others
connections, then finally our client decide to send another Initial packet
(to ACK Initial CRYPTO data for instance). It does this without token. So, for
this already existing connection we must not send a Retry packet.
This commit is contained in:
Frédéric Lécaille 2022-05-20 16:37:36 +02:00
parent 9286210aa8
commit dfd1301035

View File

@ -5315,16 +5315,18 @@ static void qc_lstnr_pkt_rcv(unsigned char *buf, const unsigned char *end,
/* TODO Retry should be automatically activated if
* suspect network usage is detected.
*/
if (l->bind_conf->quic_force_retry && global.cluster_secret) {
if (global.cluster_secret) {
if (!token_len) {
TRACE_PROTO("Initial without token, sending retry", QUIC_EV_CONN_LPKT);
if (send_retry(l->rx.fd, &dgram->saddr, pkt)) {
TRACE_PROTO("Error during Retry generation", QUIC_EV_CONN_LPKT);
if (l->bind_conf->quic_force_retry) {
TRACE_PROTO("Initial without token, sending retry", QUIC_EV_CONN_LPKT);
if (send_retry(l->rx.fd, &dgram->saddr, pkt)) {
TRACE_PROTO("Error during Retry generation", QUIC_EV_CONN_LPKT);
goto err;
}
HA_ATOMIC_INC(&prx_counters->retry_sent);
goto err;
}
HA_ATOMIC_INC(&prx_counters->retry_sent);
goto err;
}
else {
if (*buf == QUIC_TOKEN_FMT_RETRY) {
@ -5380,6 +5382,18 @@ static void qc_lstnr_pkt_rcv(unsigned char *buf, const unsigned char *end,
goto drop;
}
if (global.cluster_secret && !pkt->token_len && !l->bind_conf->quic_force_retry &&
HA_ATOMIC_LOAD(&prx_counters->conn_opening) >= global.tune.quic_retry_threshold) {
TRACE_PROTO("Initial without token, sending retry", QUIC_EV_CONN_LPKT);
if (send_retry(l->rx.fd, &dgram->saddr, pkt)) {
TRACE_PROTO("Error during Retry generation", QUIC_EV_CONN_LPKT);
goto err;
}
HA_ATOMIC_INC(&prx_counters->retry_sent);
goto err;
}
/* RFC 9000 7.2. Negotiating Connection IDs:
* When an Initial packet is sent by a client that has not previously
* received an Initial or Retry packet from the server, the client