Fix Network: Attempt binding to IPv4 when binding to IPv6 fails with EAFNOSUPPORT error
This commit is contained in:
@@ -16,6 +16,7 @@ If you are upgrading from v0.16.x, replace the binary (or run `docker pull`). If
|
||||
- Patching ids containing digits in JSON Pointers failes.
|
||||
- Patching nested objects with `null` values fails.
|
||||
- SQL directory: Return `Failed` instead of `Error` when the query returns no results.
|
||||
- Network: Attempt binding to IPv4 when binding to IPv6 fails with `EAFNOSUPPORT` error.
|
||||
|
||||
## [0.16.4] - 2026-05-05
|
||||
|
||||
|
||||
@@ -24,7 +24,11 @@ use rustls::{
|
||||
ALL_VERSIONS, ServerConfig, SupportedCipherSuite,
|
||||
crypto::aws_lc_rs::{ALL_CIPHER_SUITES, cipher_suite::*, default_provider},
|
||||
};
|
||||
use std::{str::FromStr, sync::Arc};
|
||||
use std::{
|
||||
net::{IpAddr, Ipv4Addr, SocketAddr as StdSocketAddr},
|
||||
str::FromStr,
|
||||
sync::Arc,
|
||||
};
|
||||
use store::registry::{RegistryObject, bootstrap::Bootstrap};
|
||||
use tokio::net::TcpSocket;
|
||||
use tokio_rustls::TlsAcceptor;
|
||||
@@ -109,13 +113,39 @@ impl Listeners {
|
||||
let mut listeners = Vec::new();
|
||||
for addr in listener.bind.iter() {
|
||||
// Parse bind address and build socket
|
||||
let addr = addr.0;
|
||||
let mut addr = addr.0;
|
||||
let socket = match if addr.is_ipv4() {
|
||||
TcpSocket::new_v4()
|
||||
} else {
|
||||
TcpSocket::new_v6()
|
||||
} {
|
||||
Ok(socket) => socket,
|
||||
Err(err)
|
||||
if is_eafnosupport(&err)
|
||||
&& addr.is_ipv6()
|
||||
&& addr.ip().is_unspecified() =>
|
||||
{
|
||||
let v4_addr =
|
||||
StdSocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), addr.port());
|
||||
bp.build_warning(
|
||||
id,
|
||||
format!(
|
||||
"IPv6 unavailable on this host ({err}); \
|
||||
falling back from {addr} to {v4_addr}"
|
||||
),
|
||||
);
|
||||
addr = v4_addr;
|
||||
match TcpSocket::new_v4() {
|
||||
Ok(socket) => socket,
|
||||
Err(err) => {
|
||||
bp.build_error(
|
||||
id,
|
||||
format!("Failed to create IPv4 fallback socket: {err}"),
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
bp.build_error(id, format!("Failed to create socket: {err}"));
|
||||
return;
|
||||
@@ -284,3 +314,19 @@ impl Listeners {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_eafnosupport(err: &std::io::Error) -> bool {
|
||||
let code = err.raw_os_error();
|
||||
#[cfg(unix)]
|
||||
{
|
||||
code == Some(libc::EAFNOSUPPORT)
|
||||
}
|
||||
#[cfg(windows)]
|
||||
{
|
||||
code == Some(10047)
|
||||
}
|
||||
#[cfg(not(any(unix, windows)))]
|
||||
{
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user