-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
std::net wishlist issue #957
Comments
Thanks for writing this up @stepancheg! |
One approach here could be to make a "builder" akin to
This could encompass some of @stepancheg's suggestions as well:
and presumably less common things like @tilpner's request in #25102
And of course you can still have shortcut constructors for common cases, just like A possible issue is that I don't know whether this can be done platform independently. If this seems even remotely reasonable I could think a bit more about it and write up an RFC. |
@kwantam I couldn't agree more! That's precisely the idea I had in mind. I am just uncertain about the precise API, but at the high level it's what I want! |
Some commentary on one item:
(Spelling/grammar corrections bolded)
This is exactly the issue that Happy Eyeballs, a.k.a. RFC 6555, is intended to address.
The problem with quick-and-dirty fixes is that sometimes they impede clean solutions. In particular, Happy Eyeballs (which works by trying IPv6 and IPv4 in parallel, and using whichever succeeds more quickly) gracefully migrates to IPv6 as coverage improves. End machines disabling IPv6, however, in itself impedes IPv6 coverage improving - and also introduces Yet Another Flag Day Eventually when they re-enable it, which is just asking for problems... and thus turning it back on will never actually happen. |
@eternaleye thanks for the corrections.
Sometimes they are. It doesn't mean that such such quick-and-dirty should be impossible. If you have a problem right here right now on production system, you should fix it now, and not waste precious time on clean solution. If your clients do not implement happy eyeballs, you are unlucky. |
Any news on the issues? I've noticed today, that in Hyper documentation example, a server is created that listens only on IPv4:
They cannot (easily) do better, because Rust doesn't provide a way to just bind on port. |
Just as a clarification, However, it is true that I can't expose a way a to simply listen on a certain port, regardless of IP address. |
@seanmonstar no, you can't, because on Linux by default binding to IPv6 makes a socket that listens on both IPv4 and IPv6, so you need to bind on IPv6 only on Linux, and on both IPv4 and IPv6 on Windows. See explanation of how IPV6_V6ONLY works. |
What's the status on this? |
Commenting because I'd also like to know what the status is. |
@zsck what features are you looking for in particular? |
Is there anyone working on allowing TCP client to bind to a local address, or is this still the proposal for that? Personally I suspect we need to move to some kind of builder pattern to best solve this issue since the bind need to happen before the connect (but after creating the socket). |
Would love a reverse DNS lookup! |
std::net
could be better. Here is a list of things that could be added or changed tostd::net
.Some changes need to be made before 1.0, because they are not backward compatible.
The list:
TcpListener::from_socket
andinto_socket
Sometimes a socket is got from outside, for example, from another process, or just created with custom options. For that case
TcpListener
needsTcpListener::from_socket
constructor.And similarly,
TcpListener
needsinto_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
andinto_socket
operations are necessary.TcpListener::bind
: make it cross-platformCurrently, 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 addressesHowever, 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 likeTcpListener::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
enumIpAddrFamily
enum is trivial and useful. Rust should have it.lookup_host_as_family
utilitySometimes 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
remotelydetailed 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.The text was updated successfully, but these errors were encountered: