Bind client UDP sockets by peer family
ci / test (push) Canceled after 0s
ci / fuzz-smoke (push) Canceled after 0s
ci / macos-client (macos-aarch64, macos-14) (push) Canceled after 0s
ci / macos-client (macos-x86_64, macos-13) (push) Canceled after 0s
ci / windows-client (push) Canceled after 0s
ci / package-release (linux-x86_64, ubuntu-latest, , , ) (push) Canceled after 0s
ci / package-release (macos-aarch64, macos-14, , , ) (push) Canceled after 0s
ci / package-release (macos-x86_64, macos-13, , , ) (push) Canceled after 0s
ci / package-release (windows-aarch64, windows-latest, aarch64, windows, aarch64-pc-windows-msvc) (push) Canceled after 0s
ci / package-release (windows-x86_64, windows-latest, , , ) (push) Canceled after 0s
ci / remote-bench (push) Canceled after 0s
ci / publish-gitea-release (push) Canceled after 0s

This commit is contained in:
DuProcess
2026-07-16 20:46:21 -04:00
parent 8644c22554
commit 2dc921b2d5
3 changed files with 33 additions and 10 deletions
+26 -2
View File
@@ -1,6 +1,6 @@
//! UDP error classification shared by Dosh clients, servers, and embedders.
use std::net::SocketAddr;
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
use std::time::{Duration, Instant};
use tokio::net::UdpSocket;
@@ -17,6 +17,17 @@ pub fn is_transient_udp_send_error(err: &std::io::Error) -> bool {
is_transient_udp_error(err)
}
pub fn unspecified_bind_addr_for_peer(peer: SocketAddr) -> SocketAddr {
match peer {
SocketAddr::V4(_) => SocketAddr::from((Ipv4Addr::UNSPECIFIED, 0)),
SocketAddr::V6(_) => SocketAddr::from((Ipv6Addr::UNSPECIFIED, 0)),
}
}
pub async fn bind_udp_for_peer(peer: SocketAddr) -> std::io::Result<UdpSocket> {
UdpSocket::bind(unspecified_bind_addr_for_peer(peer)).await
}
pub async fn send_udp_retrying_transient(
socket: &UdpSocket,
packet: &[u8],
@@ -106,8 +117,9 @@ fn is_transient_udp_os_error(_code: i32) -> bool {
mod tests {
use super::{
is_transient_udp_error, is_transient_udp_send_error, recv_udp_retrying_transient,
send_udp_retrying_transient,
send_udp_retrying_transient, unspecified_bind_addr_for_peer,
};
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
use std::time::Duration;
use tokio::net::UdpSocket;
@@ -127,6 +139,18 @@ mod tests {
assert!(!is_transient_udp_send_error(&fatal));
}
#[test]
fn peer_bind_addr_matches_peer_address_family() {
assert_eq!(
unspecified_bind_addr_for_peer(SocketAddr::from((Ipv4Addr::LOCALHOST, 50000))),
SocketAddr::from((Ipv4Addr::UNSPECIFIED, 0))
);
assert_eq!(
unspecified_bind_addr_for_peer(SocketAddr::from((Ipv6Addr::LOCALHOST, 50000))),
SocketAddr::from((Ipv6Addr::UNSPECIFIED, 0))
);
}
#[tokio::test]
async fn retrying_udp_send_and_receive_round_trip() {
let receiver = UdpSocket::bind("127.0.0.1:0").await.unwrap();