mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-20 21:31:28 +02:00
BUG/MINOR: quic: properly support GSO on backend side
Previously, GSO emission was explicitely disabled on backend side. This is not true since the following patch, thus GSO can be used, for example when transfering large POST requests to a HTTP/3 backend. commit e064e5d46171d32097a84b8f84ccc510a5c211db MINOR: quic: duplicate GSO unsupp status from listener to conn However, GSO on the backend side may cause crash when handling EIO. In this case, GSO must be completely disabled. Previously, this was performed by flagging listener instance. In backend side, this would cause a crash as listener is NULL. This patch fixes it by supporting GSO disable flag for servers. Thus, in qc_send_ppkts(), EIO can be converted either to a listener or server flag depending on the quic_conn proxy side. On backend side, server instance is retrieved via <qc.conn.target>. This is enough to guarantee that server is not deleted. This does not need to be backported.
This commit is contained in:
parent
e653dc304e
commit
0b6908385e
@ -47,6 +47,7 @@
|
||||
#include <haproxy/quic_loss.h>
|
||||
#include <haproxy/quic_pacing.h>
|
||||
#include <haproxy/quic_rx.h>
|
||||
#include <haproxy/quic_tune.h>
|
||||
#include <haproxy/mux_quic.h>
|
||||
|
||||
#include <openssl/rand.h>
|
||||
|
@ -172,6 +172,7 @@ enum srv_init_state {
|
||||
#define SRV_F_DELETED 0x8000 /* srv is deleted but not yet purged */
|
||||
#define SRV_F_STRICT_MAXCONN 0x10000 /* maxconn is to be strictly enforced, as a limit of outbound connections */
|
||||
#define SRV_F_CHK_NO_AUTO_SNI 0x20000 /* disable automatic SNI selection for healthcheck */
|
||||
#define SRV_F_UDP_GSO_NOTSUPP 0x40000 /* UDP GSO is disabled due to a previous error encountered */
|
||||
|
||||
/* configured server options for send-proxy (server->pp_opts) */
|
||||
#define SRV_PP_V1 0x0001 /* proxy protocol version 1 */
|
||||
|
@ -1197,6 +1197,10 @@ struct quic_conn *qc_new_conn(const struct quic_version *qv, int ipv4,
|
||||
struct quic_connection_id *conn_cid = NULL;
|
||||
|
||||
qc->flags = QUIC_FL_CONN_IS_BACK|QUIC_FL_CONN_PEER_VALIDATED_ADDR;
|
||||
/* Duplicate GSO status on server to connection */
|
||||
if (HA_ATOMIC_LOAD(&srv->flags) & SRV_F_UDP_GSO_NOTSUPP)
|
||||
qc->flags |= QUIC_FL_CONN_UDP_GSO_EIO;
|
||||
|
||||
qc->state = QUIC_HS_ST_CLIENT_INITIAL;
|
||||
|
||||
/* This is the original connection ID from the peer server
|
||||
|
@ -289,10 +289,8 @@ static int qc_send_ppkts(struct buffer *buf, struct ssl_sock_ctx *ctx)
|
||||
int ret = 0;
|
||||
struct quic_conn *qc;
|
||||
char skip_sendto = 0;
|
||||
struct listener *l;
|
||||
|
||||
qc = ctx->qc;
|
||||
l = objt_listener(qc->target);
|
||||
TRACE_ENTER(QUIC_EV_CONN_SPPKTS, qc);
|
||||
while (b_contig_data(buf, 0)) {
|
||||
unsigned char *pos;
|
||||
@ -333,15 +331,19 @@ static int qc_send_ppkts(struct buffer *buf, struct ssl_sock_ctx *ctx)
|
||||
/* GSO must not be used if already disabled. */
|
||||
BUG_ON(qc->flags & QUIC_FL_CONN_UDP_GSO_EIO);
|
||||
|
||||
/* TODO: note that at this time for connection to backends this
|
||||
* part is not run because no more than an MTU has been
|
||||
* prepared for such connections (l is not NULL).
|
||||
*/
|
||||
/* Disable permanently UDP GSO for this listener.
|
||||
* Retry standard emission.
|
||||
*/
|
||||
TRACE_ERROR("mark listener UDP GSO as unsupported", QUIC_EV_CONN_SPPKTS, qc, first_pkt);
|
||||
HA_ATOMIC_OR(&l->flags, LI_F_UDP_GSO_NOTSUPP);
|
||||
/* Permanently disable UDP GSO for future conns which use current listener/server instance. */
|
||||
if (!qc_is_back(qc)) {
|
||||
struct listener *l = __objt_listener(qc->target);
|
||||
TRACE_ERROR("mark listener UDP GSO as unsupported", QUIC_EV_CONN_SPPKTS, qc, first_pkt);
|
||||
HA_ATOMIC_OR(&l->flags, LI_F_UDP_GSO_NOTSUPP);
|
||||
}
|
||||
else if (qc->conn) {
|
||||
struct server *srv = __objt_server(qc->conn->target);
|
||||
TRACE_ERROR("mark server UDP GSO as unsupported", QUIC_EV_CONN_SPPKTS, qc, first_pkt);
|
||||
HA_ATOMIC_OR(&srv->flags, SRV_F_UDP_GSO_NOTSUPP);
|
||||
}
|
||||
|
||||
/* Retry emission without GSO. */
|
||||
qc->flags |= QUIC_FL_CONN_UDP_GSO_EIO;
|
||||
continue;
|
||||
}
|
||||
@ -813,9 +815,6 @@ static int qc_prep_pkts(struct quic_conn *qc, struct buffer *buf,
|
||||
dglen == qc->path->mtu &&
|
||||
(char *)end < b_wrap(buf) &&
|
||||
++gso_dgram_cnt < QUIC_MAX_GSO_DGRAMS) {
|
||||
/* TODO: note that for backends GSO is not used. No more than
|
||||
* an MTU is prepared.
|
||||
*/
|
||||
/* A datagram covering the full MTU has been
|
||||
* built, use GSO to built next entry. Do not
|
||||
* reserve extra space for datagram header.
|
||||
|
Loading…
x
Reference in New Issue
Block a user