Skip to content

Commit e953059

Browse files
mxindendjc
authored andcommitted
fix(udp): retry send on first EINVAL
Android API level < 26 does not support the `libc::IP_TOS` control message. `sendmsg` calls with `libc::IP_TOS` return `libc::EINVAL`. #1516 added a fallback, not setting `libc::IP_TOS` on consecutive calls to `sendmsg` after a failure with `libc::EINVAL`. The current datagram would be dropped. Consecutive datagrams passed to `sendmsg` would succeed as they would be sent without `libc::IP_TOS` through the fallback. Instead of dropping the first datagram on `libc::EINVAL`, this commit adds a retry for it without `libc::IP_TOS`. This is e.g. relevant for Neqo. When establishing a QUIC connection, dropping the first datagram [delays connection establishment by 100ms](https://github.com/mozilla/neqo/blob/3001a3a56f2274eaafaa956fb394f0817f526ae7/neqo-transport/src/rtt.rs#L28). With the retry introduced in this commit, delay due to unsupported `libc::IP_TOS` should be negligeable. Closes #1975.
1 parent a83c6e4 commit e953059

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

quinn-udp/src/unix.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,10 +330,20 @@ fn send(
330330
}
331331
}
332332

333-
if e.raw_os_error() == Some(libc::EINVAL) {
334-
// Some arguments to `sendmsg` are not supported.
335-
// Switch to fallback mode.
333+
// Some arguments to `sendmsg` are not supported. Switch to
334+
// fallback mode and retry if we haven't already.
335+
if e.raw_os_error() == Some(libc::EINVAL) && !state.sendmsg_einval() {
336336
state.set_sendmsg_einval();
337+
prepare_msg(
338+
transmit,
339+
&dst_addr,
340+
&mut msg_hdr,
341+
&mut iovec,
342+
&mut cmsgs,
343+
encode_src_ip,
344+
state.sendmsg_einval(),
345+
);
346+
continue;
337347
}
338348

339349
// - EMSGSIZE is expected for MTU probes. Future work might be able to avoid

0 commit comments

Comments
 (0)