-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bind
may incorrectly create a dual-stack socket on some platforms
#130668
Comments
You should list under which circumstances. |
This applies when binding to |
The relevant socket option is Rust did expose this option long ago, but not in a useful way: #33052 |
Personally, I don't think it's valid to characterize the current behavior as incorrect, but I can understand that it may be surprising. IMO, the way forward would be to design an explicit API like the old |
A general unbound socket type that can be configured before being bound and turned into a more specific type is probably better than an options builder. the socket configuration API is vast and has a lot of niche platform-specific/special-socket-type stuff. |
@cuviper What the underlying platform APIs look like is not relevant other than the constraints the place on I find it rather unlikely that |
The socket2 crate which follows this paradigm was already mentioned. This is literally the first example in its documentation: use std::net::{SocketAddr, TcpListener};
use socket2::{Socket, Domain, Type};
// Create a TCP listener bound to two addresses.
let socket = Socket::new(Domain::IPV6, Type::STREAM, None)?;
socket.set_only_v6(false)?;
let address: SocketAddr = "[::1]:12345".parse().unwrap();
socket.bind(&address.into())?;
socket.listen(128)?;
let listener: TcpListener = socket.into(); But I think that having a simple way to explicitly set
Actually, the
Yes, and the intent/semantics of the common
Unfortunately, the current situation is indeed not consistent between platforms, and the default cannot be relied on. So an explicit toggle is needed both to ensure dual-stack sockets are used and are not used. If such |
RFC 3493 is irrelevant. It does not specify This is simply an implementation bug in |
IPv6 is not an invention of Rust
I think following the platform default makes sense, not only because it's the status quo, but it's also hard to achieve that otherwise -- especially with local system choices like the Linux sysctl that you would have to check at runtime. |
RFC 3493 also not specify IPv6. C users of Windows and OpenBSD would also have different expectations.
Only Linux seems to have a concept of a platform default. Regardless |
UdpSocket::bind
andTcpListener::bind
can on some platforms incorrectly create a dual-stack socket. It seems very unlikely that these are intended to create dual-stack sockets as the API and documentation make no mention of it. There's also no alternate API that allow for the creation of IPv6 wildcard sockets. This means that if these API were intended to create dual-stack sockets, the standard library would be missing essential IPv6 functionality.Additional there are good reasons to not have or add an API for dual-stack sockets in the standard library:
Users not needing portability and wanting dual-stack sockets, may want to use a 3rd party crate (for example
socket2
) to create dual-stack sockets.This bug have some rather bad consequences:
std
.std
.This affects (at least):
Not affected:
The text was updated successfully, but these errors were encountered: