haproxy/include/haproxy/quic_tp.h
Frederic Lecaille d84463f9f6 MINOR: quic-be: validate the 0-RTT transport parameters
During 0-RTT sessions, some server transport parameters are reused after having
been save from previous sessions. These parameters must not be reduced
when it resends them. The client must check this is the case when some early data
are accepted by the server. This is what is implemented by this patch.

Implement qc_early_tranport_params_validate() which checks the new server parameters
are not reduced.

Also implement qc_ssl_eary_data_accepted() which was not implemented for TLS
stack without 0-RTT support (for instance wolfssl). That said this function
was no more used. This is why the compilation against wolfssl could not fail.
2025-11-13 14:04:31 +01:00

152 lines
5.8 KiB
C

#ifndef _HAPROXY_QUIC_TP_H
#define _HAPROXY_QUIC_TP_H
#ifdef USE_QUIC
#ifndef USE_OPENSSL
#error "Must define USE_OPENSSL"
#endif
#include <haproxy/chunk.h>
#include <haproxy/quic_conn-t.h>
#include <haproxy/quic_tp-t.h>
void quic_transport_params_init(struct quic_transport_params *p, int server);
int quic_transport_params_encode(unsigned char *buf,
const unsigned char *end,
struct quic_transport_params *p,
const struct quic_version *chosen_version,
int server);
int quic_transport_params_store(struct quic_conn *conn, int server,
const unsigned char *buf,
const unsigned char *end, int edata_accepted);
void qc_early_transport_params_cpy(struct quic_conn *qc,
struct quic_early_transport_params *e,
struct quic_transport_params *p);
void qc_early_transport_params_reuse(struct quic_conn *qc,
struct quic_transport_params *p,
const struct quic_early_transport_params *e);
int qc_lstnr_params_init(struct quic_conn *qc,
const struct quic_transport_params *listener_params,
const unsigned char *stateless_reset_token,
const unsigned char *dcid, size_t dcidlen,
const unsigned char *scid, size_t scidlen,
const struct quic_cid *token_odcid);
void qc_srv_params_init(struct quic_conn *qc,
const struct quic_transport_params *srv_params,
const unsigned char *scid, size_t scidlen);
/* Dump <cid> transport parameter connection ID value if present (non null length).
* Used only for debugging purposes.
*/
static inline void quic_tp_cid_dump(struct buffer *buf,
const struct tp_cid *cid)
{
int i;
for (i = 0; i < cid->len; i++)
chunk_appendf(buf, "%02x", cid->data[i]);
}
static inline void quic_tp_version_info_dump(struct buffer *b,
const struct tp_version_information *tp, int local)
{
if (!tp->chosen)
return;
chunk_appendf(b, " versions:chosen=0x%08x", tp->chosen);
if (tp->negotiated_version)
chunk_appendf(b, ",negotiated=0x%08x", tp->negotiated_version->num);
}
static inline void quic_transport_params_dump(struct buffer *b,
const struct quic_conn *qc,
const struct quic_transport_params *p)
{
int local = p == &qc->rx.params;
if (p->original_destination_connection_id.len) {
chunk_appendf(b, " odcid=");
quic_tp_cid_dump(b, &p->original_destination_connection_id);
}
chunk_appendf(b, " iscid=");
quic_tp_cid_dump(b, &p->initial_source_connection_id);
if (p->retry_source_connection_id.len) {
chunk_appendf(b, " rscid=");
quic_tp_cid_dump(b, &p->retry_source_connection_id);
}
chunk_appendf(b, "\n");
chunk_appendf(b, " midle_timeout=%llums", (ull)p->max_idle_timeout);
chunk_appendf(b, " mudp_payload_sz=%llu", (ull)p->max_udp_payload_size);
chunk_appendf(b, " ack_delay_exp=%llu", (ull)p->ack_delay_exponent);
chunk_appendf(b, " mack_delay=%llums", (ull)p->max_ack_delay);
chunk_appendf(b, " act_cid_limit=%llu\n", (ull)p->active_connection_id_limit);
chunk_appendf(b, " md=%llu", (ull)p->initial_max_data);
chunk_appendf(b, " msd_bidi_l=%llu",
(ull)p->initial_max_stream_data_bidi_local);
chunk_appendf(b, " msd_bidi_r=%llu",
(ull)p->initial_max_stream_data_bidi_remote);
chunk_appendf(b, " msd_uni=%llu",
(ull)p->initial_max_stream_data_uni);
chunk_appendf(b, " ms_bidi=%llu", (ull)p->initial_max_streams_bidi);
chunk_appendf(b, " ms_uni=%llu\n", (ull)p->initial_max_streams_uni);
if (p->disable_active_migration || p->with_stateless_reset_token) {
int prev = 0;
chunk_appendf(b, " (");
if (p->disable_active_migration) {
if (prev)
chunk_appendf(b, ",");
prev = 1;
chunk_appendf(b, "no_act_migr");
}
if (p->with_stateless_reset_token) {
if (prev)
chunk_appendf(b, ",");
prev = 1;
chunk_appendf(b, "stless_rst_tok");
}
chunk_appendf(b, ")");
}
if (p->with_preferred_address) {
char bufaddr[INET6_ADDRSTRLEN];
chunk_appendf(b, " pref_addr=");
inet_ntop(AF_INET, &p->preferred_address.ipv4_addr,
bufaddr, sizeof(bufaddr));
chunk_appendf(b, "%s:%hu ", bufaddr, p->preferred_address.ipv4_port);
inet_ntop(AF_INET6, &p->preferred_address.ipv6_addr,
bufaddr, sizeof(bufaddr));
chunk_appendf(b, "[%s]:%hu ", bufaddr, p->preferred_address.ipv6_port);
quic_tp_cid_dump(b, &p->preferred_address.cid);
chunk_appendf(b, "\n");
}
quic_tp_version_info_dump(b, &p->version_information, local);
}
static inline void quic_early_transport_params_dump(struct buffer *b,
const struct quic_conn *qc,
const struct quic_early_transport_params *p)
{
chunk_appendf(b, " mudp_payload_sz=%llu", (ull)p->max_udp_payload_size);
chunk_appendf(b, " act_cid_limit=%llu\n", (ull)p->active_connection_id_limit);
chunk_appendf(b, " md=%llu", (ull)p->initial_max_data);
chunk_appendf(b, " msd_bidi_l=%llu",
(ull)p->initial_max_stream_data_bidi_local);
chunk_appendf(b, " msd_bidi_r=%llu",
(ull)p->initial_max_stream_data_bidi_remote);
chunk_appendf(b, " msd_uni=%llu",
(ull)p->initial_max_stream_data_uni);
chunk_appendf(b, " ms_bidi=%llu", (ull)p->initial_max_streams_bidi);
chunk_appendf(b, " ms_uni=%llu\n", (ull)p->initial_max_streams_uni);
}
#endif /* USE_QUIC */
#endif /* _HAPROXY_QUIC_TP_H */