Description
std::net
could be better. Here is a list of things that could be added or changed to std::net
.
Some changes need to be made before 1.0, because they are not backward compatible.
The list:
TcpListener::from_socket
and into_socket
Sometimes a socket is got from outside, for example, from another process, or just created with custom options. For that case TcpListener
needs TcpListener::from_socket
constructor.
And similarly, TcpListener
needs into_socket
reverse operation.
nginx http server can upgrade to new executable without losing and single connection. It clears FD_CLOEXEC
flag and execs. To make such code possible in rust, from_socket
and into_socket
operations are necessary.
TcpListener::bind
: make it cross-platform
Currently, there's a huge difference in TcpListener::bind
between Windows and other OSes.
Rust on Windows creates a socket with flag IPV6_V6ONLY
set to true (that's default behavior on Windows), and false on other OSes.
So on Linux developer can create one socket to serve both IPV4 and IPv6 clients, and developers on Windows need two sockets.
Latter issue could be resolved but allowing socket customization in some form, but I think it is very important for Rust to be as cross-platform as possible by default.
I have a patch set that resolves this issue.
TcpListener::bind_to_port
There's need for simple fn TcpListener::bind_to_port
that creates a socket, capable of simply serving on port, hiding implementation details from end user.
Listening on port is the most common operation, so it deserves a shortcut.
Such shortcut exists in Java, it is ServerSocket(int)
constructor.
Option to disable IPv6
Sometimes systems (especially on servers) have IPv6 enabled but incorrectly configured. On such systems it is useful to have a simple option to disable IPv6.
For example, a server may have both IPv4 and IPv6 addresses, and IPv6 is blocked by a firewall. It a client connects to the IPv6 address first, they may need to wait 2 minutes until the first connect times out.
In Java such a mode can be set with the -Djava.net.preferIPv4Stack=true
property.
I think Rust could use an environment variable like RUST_PREFER_IPV4=true
.
Turning on such an option would make these changes:
bind_on_port
binds only on IPv4connect("host:port")
will connect only to IPv4 hostslookup
would return only IPv4 addresses
However, when IPv6 explicitly requested in code, it should work, e. g. connect("[2a03:2880:2130:cf05:face:b00c::1]:80")
should work regardless of that option.
This option won't be needed in 10 years after widespread adoption of IPv6, but now it is useful for quick-and-dirty fixes.
TcpListener::bind
should fail if there's more than one address.
Currently TcpListener::bind
resolves parameter to a list of IPs, and binds to them until one first successful bind. This is dangerous. Consider a situation. You call bind with param like TcpListener::bind("foo:80")
, and foo is resolved to both IPv4 and IPv6 addresses. Depending on your luck, you get a socket bound to IPv4 only or both IPv4/IPv6 addresses (on Linux). Fail-fast would be better here.
Better behavior is report an error host foo is resolved to more than one address
.
IpAddrFamily
enum
IpAddrFamily
enum is trivial and useful. Rust should have it.
pub enum IpAddrFamily {
V4,
V6
}
lookup_host_as_family
utility
fn lookup_host_as_family(host: &str, family: IpAddrFamily) ...
Sometimes it is useful to resolve host as specific address family (for example, when you know server only talks to IPv4).
This could be done by calling filter
function on resulting iterator, but having this function is convenient. So the issue is minor.
Terminating UdpSocket::recv_from
remotely
detailed in rust-lang/rust#23272
Reverse DNS
see rust-lang/rust#23419 and rust-lang/rust#22608
More socket options
There's lots of stuff you can do with sockets before they're bound or connected, and right now the convenience methods we provide package a lot of these steps into one bundle when they should be separable. This would probably manifest itself as some form of Socket
API which just deals with generic sockets and such.