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:
SocketAddrFamily is 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::net API.
- 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
UDPSocket semantics: an UDPSocket is 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.
Proposal
Problem statement
Currently
std::netdoes not support socket configurations (i.e.setsockopt) before binding to an address. This is also evident fromUDPSocket::bind,TcpListener::bindandTcpStream::connectmethods.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
UnboundUdpSocketto support UDP socket configurations before binding to an address. Once bound,UnboundUdpSocketwill be consumed and become a regularUdpSocket. The API looks like this:Note:
SocketAddrFamilyis a new type to simplify creating socket without an address.Similarly add
UnboundTcpSocketto support TCP socket configurations before connecting or binding.The benefits of this solution:
std::netAPI.Alternative solution
There have been other solutions suggested in the PR opened earlier. One is adding
UDPSocket::new()tocreate an unbound UDP socket. I think it has following downsides:
UDPSocketsemantics: anUDPSocketis always bound.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 enhancestd::netto 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 aBuilderpattern which is surprising similar with what I proposed earlier in the internal forum. For the record, I didn't know the design ofnet2until now. In any case, the current proposal no longer suggests the Builder pattern and hopefully is different enough from thenet2.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.