Skip to content

add UnboundUdpSocket to std::net #66

Closed as not planned
Closed as not planned
@keepsimple1

Description

@keepsimple1

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:

  1. Compatible with the existing std::net API.
  2. Simple to get started, easy to add more socket configurations gradually.
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-libs-apiapi-change-proposalA proposal to add or alter unstable APIs in the standard libraries

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions