mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-01-03 02:32:03 +00:00
BUG/MEDIUM: quic: fix tasklet_wakeup loop on connection closing
It is possible to trigger a loop of tasklets calls if a QUIC connection is interrupted abruptly by the client. This is caused by the following interaction : * FD iocb is woken up for read. This causes a wakeup on quic_conn tasklet. * quic_conn_io_cb is run and try to read but fails as the connection socket is closed (typically with a ECONNREFUSED). FD read is subscribed to the poller via qc_rcv_buf() which will cause the loop. The looping will stop automatically once the idle-timeout is expired and the connection instance is finally released. To fix this, ensure FD read is subscribed only for transient error cases (EAGAIN or similar). All other cases are considered as fatal and thus all future read operations will fail. Note that for the moment, nothing is reported on the quic_conn which may not skip future reception. This should be improved in a future commit to accelerate connection closing. This bug can be reproduced on a frequent occurence by interrupting the following command. Quic traces should be activated on haproxy side to detect the loop : $ ngtcp2-client --tp-file=/tmp/ngtcp2-tp.txt \ --session-file=/tmp/ngtcp2-session.txt \ -r 0.3 -t 0.3 --exit-on-all-streams-close 127.0.0.1 20443 \ "http://127.0.0.1:20443/?s=1024" This must be backported up to 2.7.
This commit is contained in:
parent
d355bce7e4
commit
7f80d51812
@ -704,7 +704,9 @@ int qc_rcv_buf(struct quic_conn *qc)
|
||||
get_net_port(&qc->local_addr));
|
||||
if (ret <= 0) {
|
||||
/* Subscribe FD for future reception. */
|
||||
fd_want_recv(qc->fd);
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOTCONN)
|
||||
fd_want_recv(qc->fd);
|
||||
/* TODO handle other error codes as fatal on the connection. */
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user