Skip to content

Commit

Permalink
fix(udp): retry on ErrorKind::Interrupted
Browse files Browse the repository at this point in the history
On Linux and Android, `quinn-udp` will retry a send on `ErrorKind::Interrupted`:

https://github.com/quinn-rs/quinn/blob/e318cc4a80436fd9fa19c02886d682c49efca185/quinn-udp/src/unix.rs#L305-L312

Do the same on all other unix platforms.
  • Loading branch information
mxinden committed Dec 3, 2024
1 parent 53e13f2 commit 937638a
Showing 1 changed file with 35 additions and 30 deletions.
65 changes: 35 additions & 30 deletions quinn-udp/src/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,25 +383,27 @@ fn send(state: &UdpSocketState, io: SockRef<'_>, transmit: &Transmit<'_>) -> io:
hdrs[i].msg_datalen = chunk.len();
cnt += 1;
}
let n = unsafe { sendmsg_x(io.as_raw_fd(), hdrs.as_ptr(), cnt as u32, 0) };
if n >= 0 {
return Ok(());
}
let e = io::Error::last_os_error();
match e.kind() {
io::ErrorKind::Interrupted => {
// Retry the transmission
}
io::ErrorKind::WouldBlock => return Err(e),
_ => {
// - EMSGSIZE is expected for MTU probes. Future work might be able to avoid
// these by automatically clamping the MTUD upper bound to the interface MTU.
if e.raw_os_error() != Some(libc::EMSGSIZE) {
return Err(e);
loop {
let n = unsafe { sendmsg_x(io.as_raw_fd(), hdrs.as_ptr(), cnt as u32, 0) };
if n == -1 {
let e = io::Error::last_os_error();
match e.kind() {
io::ErrorKind::Interrupted => {
// Retry the transmission
continue;
}
io::ErrorKind::WouldBlock => return Err(e),
_ => {
// - EMSGSIZE is expected for MTU probes. Future work might be able to avoid
// these by automatically clamping the MTUD upper bound to the interface MTU.
if e.raw_os_error() != Some(libc::EMSGSIZE) {
return Err(e);
}
}
}
}
return Ok(());
}
Ok(())
}

#[cfg(any(target_os = "openbsd", target_os = "netbsd", apple_slow))]
Expand All @@ -419,24 +421,27 @@ fn send(state: &UdpSocketState, io: SockRef<'_>, transmit: &Transmit<'_>) -> io:
cfg!(apple) || cfg!(target_os = "openbsd") || cfg!(target_os = "netbsd"),
state.sendmsg_einval(),
);
let n = unsafe { libc::sendmsg(io.as_raw_fd(), &hdr, 0) };
if n == -1 {
let e = io::Error::last_os_error();
match e.kind() {
io::ErrorKind::Interrupted => {
// Retry the transmission
}
io::ErrorKind::WouldBlock => return Err(e),
_ => {
// - EMSGSIZE is expected for MTU probes. Future work might be able to avoid
// these by automatically clamping the MTUD upper bound to the interface MTU.
if e.raw_os_error() != Some(libc::EMSGSIZE) {
return Err(e);
loop {
let n = unsafe { libc::sendmsg(io.as_raw_fd(), &hdr, 0) };
if n == -1 {
let e = io::Error::last_os_error();
match e.kind() {
io::ErrorKind::Interrupted => {
// Retry the transmission
continue;
}
io::ErrorKind::WouldBlock => return Err(e),
_ => {
// - EMSGSIZE is expected for MTU probes. Future work might be able to avoid
// these by automatically clamping the MTUD upper bound to the interface MTU.
if e.raw_os_error() != Some(libc::EMSGSIZE) {
return Err(e);
}
}
}
}
return Ok(());
}
Ok(())
}

#[cfg(not(any(apple, target_os = "openbsd", target_os = "netbsd", solarish)))]
Expand Down

0 comments on commit 937638a

Please sign in to comment.