mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-04-21 14:35:45 +00:00
MINOR: quic: Kill the connections on ICMP (port unreachable) packet receipt
The send*() syscall which are responsible of such ICMP packets reception fails with ECONNREFUSED as errno. man(7) udp ECONNREFUSED No receiver was associated with the destination address. This might be caused by a previous packet sent over the socket. We must kill asap the underlying connection. Must be backported to 2.7.
This commit is contained in:
parent
dd41a45014
commit
a2c62c3141
@ -44,7 +44,7 @@ struct connection *quic_sock_accept_conn(struct listener *l, int *status);
|
||||
struct task *quic_lstnr_dghdlr(struct task *t, void *ctx, unsigned int state);
|
||||
void quic_lstnr_sock_fd_iocb(int fd);
|
||||
int qc_snd_buf(struct quic_conn *qc, const struct buffer *buf, size_t count,
|
||||
int flags);
|
||||
int flags, int *syscall_errno);
|
||||
int qc_rcv_buf(struct quic_conn *qc);
|
||||
|
||||
/* Set default value for <qc> socket as uninitialized. */
|
||||
|
@ -3422,6 +3422,7 @@ static int qc_prep_pkts(struct quic_conn *qc, struct buffer *buf,
|
||||
*/
|
||||
int qc_send_ppkts(struct buffer *buf, struct ssl_sock_ctx *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
struct quic_conn *qc;
|
||||
char skip_sendto = 0;
|
||||
|
||||
@ -3457,7 +3458,17 @@ int qc_send_ppkts(struct buffer *buf, struct ssl_sock_ctx *ctx)
|
||||
* quic-conn fd management.
|
||||
*/
|
||||
if (!skip_sendto) {
|
||||
if (qc_snd_buf(qc, &tmpbuf, tmpbuf.data, 0)) {
|
||||
int syscall_errno;
|
||||
|
||||
syscall_errno = 0;
|
||||
if (qc_snd_buf(qc, &tmpbuf, tmpbuf.data, 0, &syscall_errno)) {
|
||||
if (syscall_errno == ECONNREFUSED) {
|
||||
/* Let's kill this connection asap. */
|
||||
TRACE_PROTO("UDP port unreachable", QUIC_EV_CONN_SPPKTS, qc);
|
||||
qc_kill_conn(qc);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
skip_sendto = 1;
|
||||
TRACE_ERROR("sendto error, simulate sending for the rest of data", QUIC_EV_CONN_SPPKTS, qc);
|
||||
}
|
||||
@ -3506,9 +3517,11 @@ int qc_send_ppkts(struct buffer *buf, struct ssl_sock_ctx *ctx)
|
||||
}
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
leave:
|
||||
TRACE_LEAVE(QUIC_EV_CONN_SPPKTS, qc);
|
||||
|
||||
return 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Copy into <buf> buffer a stateless reset token depending on the
|
||||
|
@ -501,13 +501,17 @@ static void quic_conn_sock_fd_iocb(int fd)
|
||||
/* Send a datagram stored into <buf> buffer with <sz> as size.
|
||||
* The caller must ensure there is at least <sz> bytes in this buffer.
|
||||
*
|
||||
* Returns 0 on success else non-zero.
|
||||
* Returns 0 on success else non-zero. When failed, this function also
|
||||
* sets <*syscall_errno> to the errno only when the send*() syscall failed.
|
||||
* As the C library will never set errno to 0, the caller must set
|
||||
* <*syscall_errno> to 0 before calling this function to be sure to get
|
||||
* the correct errno in case a send*() syscall failure.
|
||||
*
|
||||
* TODO standardize this function for a generic UDP sendto wrapper. This can be
|
||||
* done by removing the <qc> arg and replace it with address/port.
|
||||
*/
|
||||
int qc_snd_buf(struct quic_conn *qc, const struct buffer *buf, size_t sz,
|
||||
int flags)
|
||||
int flags, int *syscall_errno)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
@ -615,6 +619,7 @@ int qc_snd_buf(struct quic_conn *qc, const struct buffer *buf, size_t sz,
|
||||
EXTRA_COUNTERS_GET(prx->extra_counters_fe,
|
||||
&quic_stats_module);
|
||||
|
||||
*syscall_errno = errno;
|
||||
/* TODO adjust errno for UDP context. */
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK ||
|
||||
errno == ENOTCONN || errno == EINPROGRESS || errno == EBADF) {
|
||||
@ -630,6 +635,10 @@ int qc_snd_buf(struct quic_conn *qc, const struct buffer *buf, size_t sz,
|
||||
HA_ATOMIC_INC(&prx_counters->sendto_err_unknown);
|
||||
}
|
||||
|
||||
/* Note that one must not consider that this macro will not modify errno. */
|
||||
TRACE_PRINTF(TRACE_LEVEL_DEVELOPER, QUIC_EV_CONN_LPKT, qc, 0, 0, 0,
|
||||
"syscall error (errno=%d)", *syscall_errno);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user