{{ message }}
Repository navigation
Commit a0ddcac
BUG/MEDIUM: quic: use datagram destination as source for Retry
When a QUIC listener is bound on a wildcard address, the local address
targeted by the client is retrieved on reception via IP_PKTINFO or
equivalent. It is then used as source address for all datagrams of the
connection, either by binding the connection socket on it, or via
ancillary data when the listener socket is used. Without it, the kernel
selects the source address from the route to the client, which may
differ from the one targeted by the client. This is typically the case
when several addresses are assigned to the host, for example VIPs
configured on a loopback interface behind a load balancer in direct
routing mode. As QUIC clients usually rely on connected UDP sockets,
datagrams from another address are then silently dropped by their
kernel.
However, Retry packets are emitted before any connection exists, via
send_retry() which used a bare sendto() on the listener socket without
source address. In the above conditions, the client never receives the
Retry and keeps retransmitting its Initial packet until it gives up.
Retry is emitted in particular when quic-force-retry is set on the bind
line, when a quic-initial send-retry rule matches, or when the number of
half-open connections reaches tune.quic.fe.sec.retry-threshold, so
handshakes may also fail only intermittently under load. Apart from not
using Retry at all, which removes client address validation, the usual
workaround is to explicitly bind each address, in addition to or instead
of the wildcard one.
Fix this by adding a source address parameter to send_retry(), before
the destination one. Its callers set it to the datagram destination
address, and emission now relies on quic_lstnr_sock_send(), which only
uses it if the listener is bound on a wildcard address. Apart from the
source address, the emission is unchanged. Also fix the trace emitted
on send failure, which was a copy of the previous one.
This should fix github issue #3503.
This should be backported up to 2.8. Note that it relies on the two
previous patches:
- MINOR: quic: use the listener for Retry and Version Negotiation emission
- MINOR: quic: define a function to emit a datagram on a listener socket
Prior to 3.4, quic_dgram addresses are of sockaddr_storage type, so the
casts are not necessary. Prior to 2.9, send_retry() is a static
function defined in quic_conn.c.1 parent 5090b6b commit a0ddcac
3 files changed
Lines changed: 14 additions & 8 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1845 | 1845 | | |
1846 | 1846 | | |
1847 | 1847 | | |
1848 | | - | |
| 1848 | + | |
| 1849 | + | |
| 1850 | + | |
1849 | 1851 | | |
1850 | 1852 | | |
1851 | 1853 | | |
| |||
1875 | 1877 | | |
1876 | 1878 | | |
1877 | 1879 | | |
1878 | | - | |
| 1880 | + | |
| 1881 | + | |
| 1882 | + | |
1879 | 1883 | | |
1880 | 1884 | | |
1881 | 1885 | | |
| |||

0 commit comments