Skip to content

Commit 96e2987

Browse files
committed
Merge branch 'net2' of https://github.com/sfackler/rfcs
2 parents 2d53b52 + 7aa647f commit 96e2987

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed

text/0000-net2-mutators.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
- Feature Name: net2_mutators
2+
- Start Date: 2016-01-12
3+
- RFC PR:
4+
- Rust Issue:
5+
6+
# Summary
7+
[summary]: #summary
8+
9+
[RFC 1158](https://github.com/rust-lang/rfcs/pull/1158) proposed the addition
10+
of more functionality for the `TcpStream`, `TcpListener` and `UdpSocket` types,
11+
but was declined so that those APIs could be built up out of tree in the [net2
12+
crate](https://crates.io/crates/net2/). This RFC proposes pulling portions of
13+
net2's APIs into the standard library.
14+
15+
# Motivation
16+
[motivation]: #motivation
17+
18+
The functionality provided by the standard library's wrappers around standard
19+
networking types is fairly limited, and there is a large set of well supported,
20+
standard functionality that is not currently implemented in `std::net` but has
21+
existed in net2 for some time.
22+
23+
All of the methods to be added map directly to equivalent system calls.
24+
25+
This does not cover the entirety of net2's APIs. In particular, this RFC does
26+
not propose to touch the builder types.
27+
28+
# Detailed design
29+
[design]: #detailed-design
30+
31+
The following methods will be added:
32+
33+
```rust
34+
impl TcpStream {
35+
fn set_nodelay(&self, nodelay: bool) -> io::Result<()>;
36+
fn nodelay(&self) -> io::Result<bool>;
37+
38+
fn set_keepalive(&self, keepalive: Option<Duration>) -> io::Result<()>;
39+
fn keepalive(&self) -> io::Result<Option<Duration>>;
40+
41+
fn set_ttl(&self, ttl: u32) -> io::Result<()>;
42+
fn ttl(&self) -> io::Result<u32>;
43+
44+
fn set_only_v6(&self, only_v6: bool) -> io::Result<()>;
45+
fn only_v6(&self) -> io::Result<bool>;
46+
47+
fn take_error(&self) -> io::Result<Option<io::Error>>;
48+
49+
fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()>;
50+
}
51+
52+
impl TcpListener {
53+
fn set_ttl(&self, ttl: u32) -> io::Result<()>;
54+
fn ttl(&self) -> io::Result<u32>;
55+
56+
fn set_only_v6(&self, only_v6: bool) -> io::Result<()>;
57+
fn only_v6(&self) -> io::Result<bool>;
58+
59+
fn take_error(&self) -> io::Result<Option<io::Error>>;
60+
61+
fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()>;
62+
}
63+
64+
impl UdpSocket {
65+
fn set_broadcast(&self, broadcast: bool) -> io::Result<()>;
66+
fn broadcast(&self) -> io::Result<bool>;
67+
68+
fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()>;
69+
fn multicast_loop_v4(&self) -> io::Result<bool>;
70+
71+
fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()>;
72+
fn multicast_ttl_v4(&self) -> io::Result<u32>;
73+
74+
fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()>;
75+
fn multicast_loop_v6(&self) -> io::Result<bool>;
76+
77+
fn set_ttl(&self, ttl: u32) -> io::Result<()>;
78+
fn ttl(&self) -> io::Result<u32>;
79+
80+
fn set_only_v6(&self, only_v6: bool) -> io::Result<()>;
81+
fn only_v6(&self) -> io::Result<bool>;
82+
83+
fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()>;
84+
fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()>;
85+
86+
fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()>;
87+
fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()>;
88+
89+
fn connect<A: ToSocketAddrs>(&self, addr: A) -> Result<()>;
90+
fn send(&self, buf: &[u8]) -> Result<usize>;
91+
fn recv(&self, buf: &mut [u8]) -> Result<usize>;
92+
93+
fn take_error(&self) -> io::Result<Option<io::Error>>;
94+
95+
fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()>;
96+
}
97+
```
98+
99+
The traditional approach would be to add these as unstable, inherent methods.
100+
However, since inherent methods take precedence over trait methods, this would
101+
cause all code using the extension traits in net2 to start reporting stability
102+
errors. Instead, we have two options:
103+
104+
1. Add this functionality as *stable* inherent methods. The rationale here would
105+
be that time in a nursery crate acts as a de facto stabilization period.
106+
2. Add this functionality via *unstable* extension traits. When/if we decide to
107+
stabilize, we would deprecate the trait and add stable inherent methods.
108+
Extension traits are a bit more annoying to work with, but this would give
109+
us a formal stabilization period.
110+
111+
Option 2 seems like the safer approach unless people feel comfortable with these
112+
APIs.
113+
114+
# Drawbacks
115+
[drawbacks]: #drawbacks
116+
117+
This is a fairly significant increase in the surface areas of these APIs, and
118+
most users will never touch some of the more obscure functionality that these
119+
provide.
120+
121+
# Alternatives
122+
[alternatives]: #alternatives
123+
124+
We can leave some or all of this functionality in net2.
125+
126+
# Unresolved questions
127+
[unresolved]: #unresolved-questions
128+
129+
The stabilization path (see above).

0 commit comments

Comments
 (0)