envoy
envoy copied to clipboard
quic: Connect client UDP sockets before usage
This change does a few things:
- Calls
connect()on the QUIC UDP sockets, which allows the connection to receive async ICMP error messages onrecvmsgcalls throughout the lifetime of the connection. - Does not call
bind()on a QUIC client UDP socket unless the local address is specified. - If the socket is already connected, call
writev/sendinstead ofsendmsg. Connected sockets should not specify a peer address and hence, writev/send is more appropriate. - Previously, when
EnvoyQuicClientConnectiondid preferred server address probing, it specified the existing remote address, not the new preferred server address. This still worked because thesendmsgcall took in the actual destination IP address. However, when callingconnect(), this caused the socket to connect to the wrong address. This issue is fixed in this PR by creating a socket connection to the preferred server address. - Uses the loopback address for the local address, if one isn't specified, as it is only needed in
createConnectionSocketto get anIoHandle. This avoids having to make the more expensivegetifaddrscall, as mentioned in https://github.com/envoyproxy/envoy/issues/35137. - The
connect()behavior is guarded by the runtime guardenvoy.reloadable_features.quic_connect_client_udp_sockets, defaulted totrue.
Fixes #35137
- Calls
connect()on the QUIC UDP sockets, which allows the socket to know if the peer address is routable earlier.
Not really, we saw connect() succeeded but following write cause "no route to host". The reason we want to connect() here is that connected UDP socket will surface async socket error received from ICMP messages.
/assign @danzh2010
Alyssa is OOO this week. Assigning Ryan who has more QuIC context. /assign @RyanTheOptimist
@danzh2010 I pushed up new changes that I believe fixes all the tests. PTAL!
/retest
/retest
/retest
@danzh2010 friendly ping, thanks!
/retest
/retest
- Calls
connect()on the QUIC UDP sockets, which allows the connection to know if the socket is not routable upon the firstrecvmsgcall via an async ICMP message.
"No route to host" can be reported synchronously during connect() as we observed in the tests. But we want connected UDP socket overall because it surfaces any async errors (from ICMP messages) via following recvmsg through out the connection life time.
- Calls
connect()on the QUIC UDP sockets, which allows the connection to know if the socket is not routable upon the firstrecvmsgcall via an async ICMP message."No route to host" can be reported synchronously during connect() as we observed in the tests. But we want connected UDP socket overall because it surfaces any async errors (from ICMP messages) via following
recvmsgthrough out the connection life time.
Updated the PR description
CC @envoyproxy/runtime-guard-changes: FYI only for changes made to (source/common/runtime/runtime_features.cc).
/retest
Thanks for the great reviews, @danzh2010 and @RyanTheOptimist !