diff --git a/include/haproxy/listener-t.h b/include/haproxy/listener-t.h index ec57f8867..ce5ed408f 100644 --- a/include/haproxy/listener-t.h +++ b/include/haproxy/listener-t.h @@ -36,6 +36,7 @@ #ifdef USE_OPENSSL #include #endif +#include /* Some pointer types reference below */ struct task; @@ -165,6 +166,9 @@ struct bind_conf { char *ca_sign_pass; /* CAKey passphrase */ struct cert_key_and_chain * ca_sign_ckch; /* CA and possible certificate chain for ca generation */ +#endif +#ifdef USE_QUIC + struct quic_transport_params quic_params; /* QUIC transport parameters. */ #endif struct proxy *frontend; /* the frontend all these listeners belong to, or NULL */ const struct mux_proto_list *mux_proto; /* the mux to use for all incoming connections (specified by the "proto" keyword) */ diff --git a/include/haproxy/receiver-t.h b/include/haproxy/receiver-t.h index 5b17211c4..7284da3f6 100644 --- a/include/haproxy/receiver-t.h +++ b/include/haproxy/receiver-t.h @@ -62,6 +62,11 @@ struct receiver { void (*iocb)(int fd); /* generic I/O handler (typically accept callback) */ struct rx_settings *settings; /* points to the settings used by this receiver */ struct list proto_list; /* list in the protocol header */ +#ifdef USE_QUIC + struct list qpkts; /* QUIC Initial packets to accept new connections */ + struct eb_root odcids; /* QUIC original destination connection IDs. */ + struct eb_root cids; /* QUIC connection IDs. */ +#endif /* warning: this struct is huge, keep it at the bottom */ struct sockaddr_storage addr; /* the address the socket is bound to */ }; diff --git a/src/cfgparse.c b/src/cfgparse.c index 957ae9e61..4dd01bb63 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -78,6 +78,7 @@ #include #include #include +#include /* Used to chain configuration sections definitions. This list @@ -135,6 +136,17 @@ int str2listener(char *str, struct proxy *curproxy, struct bind_conf *bind_conf, goto fail; /* OK the address looks correct */ + +#ifdef USE_QUIC + /* The transport layer automatically switches to QUIC when QUIC + * is selected, regardless of bind_conf settings. We then need + * to initialize QUIC params. + */ + if (proto->sock_type == SOCK_DGRAM && proto->ctrl_type == SOCK_STREAM) { + bind_conf->xprt = xprt_get(XPRT_QUIC); + quic_transport_params_init(&bind_conf->quic_params, 1); + } +#endif if (!create_listeners(bind_conf, ss2, port, end, fd, proto, err)) { memprintf(err, "%s for address '%s'.\n", *err, str); goto fail; diff --git a/src/proto_quic.c b/src/proto_quic.c index 751fc49aa..8b3e91bb9 100644 --- a/src/proto_quic.c +++ b/src/proto_quic.c @@ -46,6 +46,7 @@ #include +static void quic_add_listener(struct protocol *proto, struct listener *listener); static int quic_bind_listener(struct listener *listener, char *errmsg, int errlen); static int quic_connect_server(struct connection *conn, int flags); static void quic_enable_listener(struct listener *listener); @@ -60,7 +61,7 @@ struct protocol proto_quic4 = { .listen = quic_bind_listener, .enable = quic_enable_listener, .disable = quic_disable_listener, - .add = default_add_listener, + .add = quic_add_listener, .unbind = default_unbind_listener, .suspend = default_suspend_listener, .resume = default_resume_listener, @@ -97,7 +98,7 @@ struct protocol proto_quic6 = { .listen = quic_bind_listener, .enable = quic_enable_listener, .disable = quic_disable_listener, - .add = default_add_listener, + .add = quic_add_listener, .unbind = default_unbind_listener, .suspend = default_suspend_listener, .resume = default_resume_listener, @@ -513,6 +514,18 @@ int quic_connect_server(struct connection *conn, int flags) return SF_ERR_NONE; /* connection is OK */ } +/* Add listener to protocol . Technically speaking we just + * initialize a few entries which should be doable during quic_bind_listener(). + * The end of the initialization goes on with the default function. + */ +static void quic_add_listener(struct protocol *proto, struct listener *listener) +{ + LIST_INIT(&listener->rx.qpkts); + listener->rx.odcids = EB_ROOT_UNIQUE; + listener->rx.cids = EB_ROOT_UNIQUE; + default_add_listener(proto, listener); +} + /* This function tries to bind a QUIC4/6 listener. It may return a warning or * an error message in if the message is at most bytes long * (including '\0'). Note that may be NULL if is also zero.