-
Notifications
You must be signed in to change notification settings - Fork 24
Description
Proposal
Problem statement
Currently std::net does not support socket configurations (i.e. setsockopt) before binding to an address. This is also evident from UDPSocket::bind, TcpListener::bind and TcpStream::connect methods.
Motivation, use-cases
Example 1: setting SO_REUSEADDR is common for UDP sockets but it is not possible using std::net.
Example 2: setting SO_EXCLUSIVEADDRUSE in useful on Windows, but it is not possible using std::net.
Solution sketches
Primary solution
Add a new UnboundUdpSocket to support UDP socket configurations before binding to an address. Once bound, UnboundUdpSocket will be consumed and become a regular UdpSocket. The API looks like this:
pub struct UnboundUdpSocket {
inner: net_imp::UnboundUdpSocket,
}
impl UnboundUdpSocket {
pub fn new(addr_family: SocketAddrFamily) -> io::Result<UnboundUdpSocket>;
pub fn set_reuseaddr(&self, enable: bool) -> io::Result<()>; // The example use case.
pub fn bind(self, addr: &SocketAddr) -> io::Result<UdpSocket>;
}
Note:
SocketAddrFamilyis a new type to simplify creating socket without an address.
Similarly add UnboundTcpSocket to support TCP socket configurations before connecting or binding.
The benefits of this solution:
- Compatible with the existing
std::netAPI. - Simple to get started, easy to add more socket configurations gradually.
- Using different types to simplify socket state management.
Alternative solution
There have been other solutions suggested in the PR opened earlier. One is adding UDPSocket::new() to
create an unbound UDP socket. I think it has following downsides:
- Breaking the existing
UDPSocketsemantics: anUDPSocketis always bound. - Adding more complex state management inside
UDPSocket.
Links and related work
Original discussion(s)
The original discussion that prompted this proposal is in Rust internal forum.
Existing crate(s)
The most popular crate for socket programming is probably socket2. However, I believe it's worth it to enhance std::net to support socket configurations before binding.
Note that there is also a deprecated crate net2. I just looked its code now and found it was using a Builder pattern which is surprising similar with what I proposed earlier in the internal forum. For the record, I didn't know the design of net2 until now. In any case, the current proposal no longer suggests the Builder pattern and hopefully is different enough from the net2.
PR
I have had opened an PR on this issue before the ACP process came out (AFAIK). Here is the PR.
What happens now?
This issue is part of the libs-api team API change proposal process. Once this issue is filed the libs-api team will review open proposals in its weekly meeting. You should receive feedback within a week or two.