MINOR: quic: Missing active_connection_id_limit default value

The peer transport parameter values were not initialized with
the default ones (when absent), especially the
"active_connection_id_limit" parameter with 2 as default value
when absent from received remote transport parameters. This
had as side effect to send too much NEW_CONNECTION_ID frames.
This was the case for curl which does not announce any
"active_connection_id_limit" parameter.
Also rename ->idle_timeout to ->max_idle_timeout to reflect the RFC9000.
This commit is contained in:
Frédéric Lécaille 2021-09-03 16:42:19 +02:00 committed by Amaury Denoyelle
parent d4d6aa7b5c
commit 48fc74af64
3 changed files with 20 additions and 9 deletions

View File

@ -263,14 +263,15 @@ struct preferred_address {
uint8_t stateless_reset_token[QUIC_STATELESS_RESET_TOKEN_LEN]; uint8_t stateless_reset_token[QUIC_STATELESS_RESET_TOKEN_LEN];
}; };
/* Default values for some of transport parameters */ /* Default values for the absent transport parameters */
#define QUIC_DFLT_MAX_UDP_PAYLOAD_SIZE 65527 /* bytes */ #define QUIC_DFLT_MAX_UDP_PAYLOAD_SIZE 65527 /* bytes */
#define QUIC_DFLT_ACK_DELAY_COMPONENT 3 /* milliseconds */ #define QUIC_DFLT_ACK_DELAY_COMPONENT 3 /* milliseconds */
#define QUIC_DFLT_MAX_ACK_DELAY 25 /* milliseconds */ #define QUIC_DFLT_MAX_ACK_DELAY 25 /* milliseconds */
#define QUIC_ACTIVE_CONNECTION_ID_LIMIT 2 /* number of connections */
/* Types of QUIC transport parameters */ /* Types of QUIC transport parameters */
#define QUIC_TP_ORIGINAL_DESTINATION_CONNECTION_ID 0 #define QUIC_TP_ORIGINAL_DESTINATION_CONNECTION_ID 0
#define QUIC_TP_IDLE_TIMEOUT 1 #define QUIC_TP_MAX_IDLE_TIMEOUT 1
#define QUIC_TP_STATELESS_RESET_TOKEN 2 #define QUIC_TP_STATELESS_RESET_TOKEN 2
#define QUIC_TP_MAX_UDP_PAYLOAD_SIZE 3 #define QUIC_TP_MAX_UDP_PAYLOAD_SIZE 3
#define QUIC_TP_INITIAL_MAX_DATA 4 #define QUIC_TP_INITIAL_MAX_DATA 4
@ -300,7 +301,7 @@ struct preferred_address {
* Note that forbidden parameters sent by clients MUST generate TRANSPORT_PARAMETER_ERROR errors. * Note that forbidden parameters sent by clients MUST generate TRANSPORT_PARAMETER_ERROR errors.
*/ */
struct quic_transport_params { struct quic_transport_params {
uint64_t idle_timeout; uint64_t max_idle_timeout;
uint64_t max_udp_payload_size; /* Default: 65527 bytes (max of UDP payload for IPv6) */ uint64_t max_udp_payload_size; /* Default: 65527 bytes (max of UDP payload for IPv6) */
uint64_t initial_max_data; uint64_t initial_max_data;
uint64_t initial_max_stream_data_bidi_local; uint64_t initial_max_stream_data_bidi_local;

View File

@ -423,7 +423,8 @@ static inline unsigned int quic_ack_delay_ms(struct quic_ack *ack_frm,
return ack_frm->ack_delay << conn->tx.params.ack_delay_exponent; return ack_frm->ack_delay << conn->tx.params.ack_delay_exponent;
} }
/* Initialize <dst> transport parameters from <quic_dflt_trasports_parame>. /* Initialize <dst> transport parameters with default values (when absent)
* from <quic_dflt_trasports_params>.
* Never fails. * Never fails.
*/ */
static inline void quic_dflt_transport_params_cpy(struct quic_transport_params *dst) static inline void quic_dflt_transport_params_cpy(struct quic_transport_params *dst)
@ -431,6 +432,7 @@ static inline void quic_dflt_transport_params_cpy(struct quic_transport_params *
dst->max_udp_payload_size = quic_dflt_transport_params.max_udp_payload_size; dst->max_udp_payload_size = quic_dflt_transport_params.max_udp_payload_size;
dst->ack_delay_exponent = quic_dflt_transport_params.ack_delay_exponent; dst->ack_delay_exponent = quic_dflt_transport_params.ack_delay_exponent;
dst->max_ack_delay = quic_dflt_transport_params.max_ack_delay; dst->max_ack_delay = quic_dflt_transport_params.max_ack_delay;
dst->active_connection_id_limit = quic_dflt_transport_params.active_connection_id_limit;
} }
/* Initialize <p> transport parameters depending <server> boolean value which /* Initialize <p> transport parameters depending <server> boolean value which
@ -441,9 +443,10 @@ static inline void quic_dflt_transport_params_cpy(struct quic_transport_params *
static inline void quic_transport_params_init(struct quic_transport_params *p, static inline void quic_transport_params_init(struct quic_transport_params *p,
int server) int server)
{ {
/* Default values (when absent) */
quic_dflt_transport_params_cpy(p); quic_dflt_transport_params_cpy(p);
p->idle_timeout = 30000; p->max_idle_timeout = 30000;
p->initial_max_data = 1 * 1024 * 1024; p->initial_max_data = 1 * 1024 * 1024;
p->initial_max_stream_data_bidi_local = 256 * 1024; p->initial_max_stream_data_bidi_local = 256 * 1024;
@ -549,6 +552,7 @@ static inline int quic_transport_param_decode(struct quic_transport_params *p,
{ {
const unsigned char *end = *buf + len; const unsigned char *end = *buf + len;
quic_dflt_transport_params_cpy(p);
switch (type) { switch (type) {
case QUIC_TP_ORIGINAL_DESTINATION_CONNECTION_ID: case QUIC_TP_ORIGINAL_DESTINATION_CONNECTION_ID:
if (!server || len >= sizeof p->original_destination_connection_id.data) if (!server || len >= sizeof p->original_destination_connection_id.data)
@ -584,8 +588,8 @@ static inline int quic_transport_param_decode(struct quic_transport_params *p,
return 0; return 0;
p->with_preferred_address = 1; p->with_preferred_address = 1;
break; break;
case QUIC_TP_IDLE_TIMEOUT: case QUIC_TP_MAX_IDLE_TIMEOUT:
if (!quic_dec_int(&p->idle_timeout, buf, end)) if (!quic_dec_int(&p->max_idle_timeout, buf, end))
return 0; return 0;
break; break;
case QUIC_TP_MAX_UDP_PAYLOAD_SIZE: case QUIC_TP_MAX_UDP_PAYLOAD_SIZE:
@ -762,8 +766,8 @@ static inline int quic_transport_params_encode(unsigned char *buf,
p->initial_source_connection_id.len)) p->initial_source_connection_id.len))
return 0; return 0;
if (p->idle_timeout && if (p->max_idle_timeout &&
!quic_transport_param_enc_int(&pos, end, QUIC_TP_IDLE_TIMEOUT, p->idle_timeout)) !quic_transport_param_enc_int(&pos, end, QUIC_TP_MAX_IDLE_TIMEOUT, p->max_idle_timeout))
return 0; return 0;
/* /*
@ -825,6 +829,7 @@ static inline int quic_transport_params_encode(unsigned char *buf,
return 0; return 0;
if (p->active_connection_id_limit && if (p->active_connection_id_limit &&
p->active_connection_id_limit != QUIC_ACTIVE_CONNECTION_ID_LIMIT &&
!quic_transport_param_enc_int(&pos, end, QUIC_TP_ACTIVE_CONNECTION_ID_LIMIT, !quic_transport_param_enc_int(&pos, end, QUIC_TP_ACTIVE_CONNECTION_ID_LIMIT,
p->active_connection_id_limit)) p->active_connection_id_limit))
return 0; return 0;

View File

@ -50,10 +50,15 @@
#include <haproxy/trace.h> #include <haproxy/trace.h>
#include <haproxy/xprt_quic.h> #include <haproxy/xprt_quic.h>
/* This is the values of some QUIC transport parameters when absent.
* Should be used to initialize any transport parameters (local or remote)
* before updating them with customized values.
*/
struct quic_transport_params quic_dflt_transport_params = { struct quic_transport_params quic_dflt_transport_params = {
.max_udp_payload_size = QUIC_DFLT_MAX_UDP_PAYLOAD_SIZE, .max_udp_payload_size = QUIC_DFLT_MAX_UDP_PAYLOAD_SIZE,
.ack_delay_exponent = QUIC_DFLT_ACK_DELAY_COMPONENT, .ack_delay_exponent = QUIC_DFLT_ACK_DELAY_COMPONENT,
.max_ack_delay = QUIC_DFLT_MAX_ACK_DELAY, .max_ack_delay = QUIC_DFLT_MAX_ACK_DELAY,
.active_connection_id_limit = QUIC_ACTIVE_CONNECTION_ID_LIMIT,
}; };
/* trace source and events */ /* trace source and events */