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:
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: anUDPSocket
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.