-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
add UnboundUdpSocket to std::net #97672
Conversation
Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
|
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @joshtriplett (or someone else) soon. Please see the contribution instructions for more information. |
r? rust-lang/libs-api @rustbot label +T-libs-api -T-libs |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Some config doesn't inherit through an accept call (eg, ioctl flags), so you might still need a way to do that, and some config is required to be done before accept (eg sdn/rcvbuf). There's also multicast join/leave stuff too that I'm not sure how you fit in. I had to write all this myself a few months ago already, it was such a pain to incorporated into other libs that I wound up writing my own networking layer and protocol stack. |
At the public API level, we won't expose
This is where this PR comes in. It provides a basis to support such configs. In current diff, we only implemented
It is already supported by |
I hope this is planned so it will work with both TCP and UDP, even if UDP is your current need. It would suck to have to have multiple ways to construct a socket. I was referring to socket opts for TCP, but UDP has a couple too. I read the internals discussion, and the unbound state and builder idea was to allow for configuration calls before the socket is actually created, from my understanding. But there isn't just one point for config, there are two for TCP in the case of an accepting socket. The C sematics are ugly because it was done piecemeal and we definitely do not want to keep the C calls structure since it would create portability issues. Eg, to create a non-blocking server tcp socket, you cannot set non-blocking on the socket itself before accept. That's what I mean by not inherited through the accept call. (There is a small set of these that have to wait until after The nice thing would be to set it on the some builder or prototype socket and have it handled whenever. This way each networking library doesn't need to hand the socket back to you for post- It is often considered bad and non-portable to rely on Another one is And of course the net socket family should work with I think the current attempt might lead to difference in socket config by system if used for accepting sockets. |
The problem with that is you have to build a way to change these options on the socket after whatever runtime or system has taken the socket over. Instead of relying on each system to write in a door to do join/leave calls. It might be wroth thinking of if we want to allow a those calls from another part of the system. I thinkg it isn't a bad idea, much easier than trying to grab the scoket from the runtime when we need to change group or source memberships. |
TCP support follows the same way. In fact, the underlying support is already in this PR (look for
Not before
This is fine. For TCP, The bottom line is: this part of Of course, the current
In my opinion, this particular issue is not in the scope of the
I don't think it's supported in
|
I'm not sure what you mean by |
I was hoping this would solve my issue with not being able to use things like tokio or other network libs in the rust ecosystem effectively. I need to do things like setting the snd and recv buffer sizes, setting non/blocking, zerocopy, and a few others. At present this isn't possible without ugly hacks in any package and make rust networking code a fairly bad experience. Very rarely do you get to keep the socket you are creating. Often you wrap it in something else to hand back to whatever network libs, system, or async runtime you are using. So under this system the socket config is scattered and sometimes still not possible without the same ugly hacks (eg, if you are using tokio there is still no way to config a server side tcp socket). |
If I understand, you won't be able to use types from Although the current Also, I'm not familiar with With this PR, I hope |
Under the way you are proposing, I still don't think you get there. You might have cover another usecase, but there are still a couple others where yet another parital API would need to be done to cover, sot there would essentially be three different ways, all necessary, to cover some some socket use cases. Even then, they are likely to not be able to set the same things in the same ways on different OSes - this is the warning to not assume your setsockopt calls will be inherited by the accepting socket since that is implementation dependent and this might only work on your unix variant (I'm unsure as to the extent of that difference though).
Not quite what I was trying to get across. When most people use rust networking it will be with something else, even something simple like the tungsten websocket API takes control of the sockets. Tokio (I've use it and std-async - which uses smol I believe) has a was to hand it a socket and it will take ownership, but your config chances end there. The example I was using was a server side tcp socket that a generated by In order to do full socket configuration in a portable way, you need to also be able to do config at a couple other points in the lifecycle of the socket (eg, after If you want to main the thinnest layers over the C API, this probably isn't possible. You start to have conflicting goals/requirements. Last time I dealt with this I had to make a couple small compromises (I created a handle to fd that could be used to manipulate the fd, but I had needs that were a little more sophisticated than most). Rust's networking is lacks cohesion so it can be difficult to figure out how to fix it piecemeal without just wanting to tear it down, but I definitely applaud you're attempt. I don't think this is far off in the wrong direction given your goals, but there are a few things are are going to be left out. It will still be an improvement. Good luck. I would hate to see someone do all this work only to have to retool it as soon as the next person needed something done. |
@m-ou-se since you are one of the assignees, may I ask if you have any thoughts or comments about this PR? Thanks. |
☔ The latest upstream changes (presumably #95897) made this pull request unmergeable. Please resolve the merge conflicts. |
fe25662
to
3d67802
Compare
This comment has been minimized.
This comment has been minimized.
@m-ou-se could you please take a look at this PR? Thanks! |
☔ The latest upstream changes (presumably #97437) made this pull request unmergeable. Please resolve the merge conflicts. |
I tested @keepsimple1 patch with great success. I even added reuseport. But I'm wondering :
Thanks |
Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
|
@jkerdreux-imt Thanks for testing the patch! I'm really glad to hear that it works for you. Regarding your 2nd question:
I think one probably would adopt If we were to implement And, another way of looking at adding |
Just to clarify, I didn't know why |
@m-ou-se I just found out the new ACP process, should I create one ACP for this PR? |
@keepsimple1 Is AF_UNSPEC supported? The modern way of open a net connection in C makes it so you dont have to touch the address structures or speficy IP version. The call structure is now:
In that call sequece you don't ahve to know which IP version dns is going to reutrn and let the os handle that do ryou. |
|
|
218e87b
to
b20df88
Compare
force-pushed to get rid of the merge commit. (Lesson to myself: don't use GitHub online tools to resolve the conflicts). |
This comment has been minimized.
This comment has been minimized.
☔ The latest upstream changes (presumably #78802) made this pull request unmergeable. Please resolve the merge conflicts. |
9342e97
to
fc88c25
Compare
☔ The latest upstream changes (presumably #100640) made this pull request unmergeable. Please resolve the merge conflicts. |
b86fd03
to
76d295f
Compare
☔ The latest upstream changes (presumably #103048) made this pull request unmergeable. Please resolve the merge conflicts. |
76d295f
to
cea23eb
Compare
… before binding to an address. Once bound, the socket becomes a regular UdpSocket.
cea23eb
to
3fc1276
Compare
Closing since the ACP was rejected. |
(Thanks to the original discussions in Rust internal forum, I finally found some courage to open this PR, thinking it is not something needs a RFC based on what I learned. Of course I might be totally wrong. Any comments are greatly appreciated. )
Motivation
Currently
std::net
does not support socket configurations before binding to an address. For example, setSO_REUSEADDR
is common for UDP sockets and it is not possible usingstd::net
.Proposal
Add
UnboundUdpSocket
instd::net
to support UDP socket configurations before binding to an address. Once bound, the socket will become a regularUdpSocket
.Similarly
UnboundTcpSocket
is to support TCP socket configurations before connecting or binding.Implementation
The implementation is straightforward and kept to minimum at this moment.
Note1: for
UnboundUdpSocket
, only configurations ofSO_REUSEADDR
is implemented in its public API. It is because what I needed, also because adding more methods is not the key point of this patch.Note2: for
UnboundTcpSocket
, because the current codebase already setsSO_REUSEADDR
forTcpListener
, this diff only prepares forUnboundTcpSocket
by implementing itsnet_imp
part. I did not have a specific need to add for TCP at this moment, hence did not implement its public API.Note3:
UnboundUdpSocket
is also useful for Windows platforms by supportingSO_EXCLUSIVEADDRUSE
.Also, the issue number99999
is a placeholder.Prior art
The most popular crate for socket programming is probably
socket2
. However, I believestd::net
is worth to be enhanced to support socket operations before binding.Thanks
Again, thanks for all comments in the Rust internals discussion I linked at the top. They are very helpful and encouraging.
EDIT:
SocketAddrFamily
so that we can create aSocket
without a fullSocketAddr
.EDIT:
none
as the number 99999 was taken recently.EDIT: