Skip to content

Commit 5d6ba17

Browse files
committed
Add UDP functionality from net2
1 parent 827be2d commit 5d6ba17

File tree

2 files changed

+387
-4
lines changed

2 files changed

+387
-4
lines changed

src/libstd/net/udp.rs

Lines changed: 252 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use fmt;
1212
use io::{self, Error, ErrorKind};
13-
use net::{ToSocketAddrs, SocketAddr};
13+
use net::{ToSocketAddrs, SocketAddr, Ipv4Addr, Ipv6Addr};
1414
use sys_common::net as net_imp;
1515
use sys_common::{AsInner, FromInner, IntoInner};
1616
use time::Duration;
@@ -140,6 +140,221 @@ impl UdpSocket {
140140
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
141141
self.0.write_timeout()
142142
}
143+
144+
/// Sets the value of the `SO_BROADCAST` option for this socket.
145+
///
146+
/// When enabled, this socket is allowed to send packets to a broadcast
147+
/// address.
148+
#[stable(feature = "net2_mutators", since = "1.9.0")]
149+
pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
150+
self.0.set_broadcast(broadcast)
151+
}
152+
153+
/// Gets the value of the `SO_BROADCAST` option for this socket.
154+
///
155+
/// For more information about this option, see
156+
/// [`set_broadcast`][link].
157+
///
158+
/// [link]: #tymethod.set_broadcast
159+
#[stable(feature = "net2_mutators", since = "1.9.0")]
160+
pub fn broadcast(&self) -> io::Result<bool> {
161+
self.0.broadcast()
162+
}
163+
164+
/// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
165+
///
166+
/// If enabled, multicast packets will be looped back to the local socket.
167+
/// Note that this may not have any affect on IPv6 sockets.
168+
#[stable(feature = "net2_mutators", since = "1.9.0")]
169+
pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> {
170+
self.0.set_multicast_loop_v4(multicast_loop_v4)
171+
}
172+
173+
/// Gets the value of the `IP_MULTICAST_LOOP` option for this socket.
174+
///
175+
/// For more information about this option, see
176+
/// [`set_multicast_loop_v4`][link].
177+
///
178+
/// [link]: #tymethod.set_multicast_loop_v4
179+
#[stable(feature = "net2_mutators", since = "1.9.0")]
180+
pub fn multicast_loop_v4(&self) -> io::Result<bool> {
181+
self.0.multicast_loop_v4()
182+
}
183+
184+
/// Sets the value of the `IP_MULTICAST_TTL` option for this socket.
185+
///
186+
/// Indicates the time-to-live value of outgoing multicast packets for
187+
/// this socket. The default value is 1 which means that multicast packets
188+
/// don't leave the local network unless explicitly requested.
189+
///
190+
/// Note that this may not have any affect on IPv6 sockets.
191+
#[stable(feature = "net2_mutators", since = "1.9.0")]
192+
pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> {
193+
self.0.set_multicast_ttl_v4(multicast_ttl_v4)
194+
}
195+
196+
/// Gets the value of the `IP_MULTICAST_TTL` option for this socket.
197+
///
198+
/// For more information about this option, see
199+
/// [`set_multicast_ttl_v4`][link].
200+
///
201+
/// [link]: #tymethod.set_multicast_ttl_v4
202+
#[stable(feature = "net2_mutators", since = "1.9.0")]
203+
pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
204+
self.0.multicast_ttl_v4()
205+
}
206+
207+
/// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
208+
///
209+
/// Controls whether this socket sees the multicast packets it sends itself.
210+
/// Note that this may not have any affect on IPv4 sockets.
211+
#[stable(feature = "net2_mutators", since = "1.9.0")]
212+
pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> {
213+
self.0.set_multicast_loop_v6(multicast_loop_v6)
214+
}
215+
216+
/// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
217+
///
218+
/// For more information about this option, see
219+
/// [`set_multicast_loop_v6`][link].
220+
///
221+
/// [link]: #tymethod.set_multicast_loop_v6
222+
#[stable(feature = "net2_mutators", since = "1.9.0")]
223+
pub fn multicast_loop_v6(&self) -> io::Result<bool> {
224+
self.0.multicast_loop_v6()
225+
}
226+
227+
/// Sets the value for the `IP_TTL` option on this socket.
228+
///
229+
/// This value sets the time-to-live field that is used in every packet sent
230+
/// from this socket.
231+
#[stable(feature = "net2_mutators", since = "1.9.0")]
232+
pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
233+
self.0.set_ttl(ttl)
234+
}
235+
236+
/// Gets the value of the `IP_TTL` option for this socket.
237+
///
238+
/// For more information about this option, see [`set_ttl`][link].
239+
///
240+
/// [link]: #tymethod.set_ttl
241+
#[stable(feature = "net2_mutators", since = "1.9.0")]
242+
pub fn ttl(&self) -> io::Result<u32> {
243+
self.0.ttl()
244+
}
245+
246+
/// Sets the value for the `IPV6_V6ONLY` option on this socket.
247+
///
248+
/// If this is set to `true` then the socket is restricted to sending and
249+
/// receiving IPv6 packets only. If this is the case, an IPv4 and an IPv6
250+
/// application can each bind the same port at the same time.
251+
///
252+
/// If this is set to `false` then the socket can be used to send and
253+
/// receive packets from an IPv4-mapped IPv6 address.
254+
#[stable(feature = "net2_mutators", since = "1.9.0")]
255+
pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
256+
self.0.set_only_v6(only_v6)
257+
}
258+
259+
/// Gets the value of the `IPV6_V6ONLY` option for this socket.
260+
///
261+
/// For more information about this option, see [`set_only_v6`][link].
262+
///
263+
/// [link]: #tymethod.set_only_v6
264+
#[stable(feature = "net2_mutators", since = "1.9.0")]
265+
pub fn only_v6(&self) -> io::Result<bool> {
266+
self.0.only_v6()
267+
}
268+
269+
/// Executes an operation of the `IP_ADD_MEMBERSHIP` type.
270+
///
271+
/// This function specifies a new multicast group for this socket to join.
272+
/// The address must be a valid multicast address, and `interface` is the
273+
/// address of the local interface with which the system should join the
274+
/// multicast group. If it's equal to `INADDR_ANY` then an appropriate
275+
/// interface is chosen by the system.
276+
#[stable(feature = "net2_mutators", since = "1.9.0")]
277+
pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
278+
self.0.join_multicast_v4(multiaddr, interface)
279+
}
280+
281+
/// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type.
282+
///
283+
/// This function specifies a new multicast group for this socket to join.
284+
/// The address must be a valid multicast address, and `interface` is the
285+
/// index of the interface to join/leave (or 0 to indicate any interface).
286+
#[stable(feature = "net2_mutators", since = "1.9.0")]
287+
pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
288+
self.0.join_multicast_v6(multiaddr, interface)
289+
}
290+
291+
/// Executes an operation of the `IP_DROP_MEMBERSHIP` type.
292+
///
293+
/// For more information about this option, see
294+
/// [`join_multicast_v4`][link].
295+
///
296+
/// [link]: #tymethod.join_multicast_v4
297+
#[stable(feature = "net2_mutators", since = "1.9.0")]
298+
pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
299+
self.0.leave_multicast_v4(multiaddr, interface)
300+
}
301+
302+
/// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type.
303+
///
304+
/// For more information about this option, see
305+
/// [`join_multicast_v6`][link].
306+
///
307+
/// [link]: #tymethod.join_multicast_v6
308+
#[stable(feature = "net2_mutators", since = "1.9.0")]
309+
pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
310+
self.0.leave_multicast_v6(multiaddr, interface)
311+
}
312+
313+
/// Get the value of the `SO_ERROR` option on this socket.
314+
///
315+
/// This will retrieve the stored error in the underlying socket, clearing
316+
/// the field in the process. This can be useful for checking errors between
317+
/// calls.
318+
#[stable(feature = "net2_mutators", since = "1.9.0")]
319+
pub fn take_error(&self) -> io::Result<Option<io::Error>> {
320+
self.0.take_error()
321+
}
322+
323+
/// Connects this UDP socket to a remote address, allowing the `send` and
324+
/// `recv` syscalls to be used to send data and also applies filters to only
325+
/// receive data from the specified address.
326+
#[stable(feature = "net2_mutators", since = "1.9.0")]
327+
pub fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
328+
super::each_addr(addr, |addr| self.0.connect(addr))
329+
}
330+
331+
/// Sends data on the socket to the remote address to which it is connected.
332+
///
333+
/// The `connect` method will connect this socket to a remote address. This
334+
/// method will fail if the socket is not connected.
335+
#[stable(feature = "net2_mutators", since = "1.9.0")]
336+
pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
337+
self.0.send(buf)
338+
}
339+
340+
/// Receives data on the socket from the remote address to which it is
341+
/// connected.
342+
///
343+
/// The `connect` method will connect this socket to a remote address. This
344+
/// method will fail if the socket is not connected.
345+
#[stable(feature = "net2_mutators", since = "1.9.0")]
346+
pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
347+
self.0.recv(buf)
348+
}
349+
350+
/// Moves this TCP stream into or out of nonblocking mode.
351+
///
352+
/// On Unix this corresponds to calling fcntl, and on Windows this
353+
/// corresponds to calling ioctlsocket.
354+
#[stable(feature = "net2_mutators", since = "1.9.0")]
355+
pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
356+
self.0.set_nonblocking(nonblocking)
357+
}
143358
}
144359

145360
impl AsInner<net_imp::UdpSocket> for UdpSocket {
@@ -400,4 +615,40 @@ mod tests {
400615
assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
401616
assert!(start.elapsed() > Duration::from_millis(400));
402617
}
618+
619+
#[test]
620+
fn connect_send_recv() {
621+
let addr = next_test_ip4();
622+
623+
let socket = t!(UdpSocket::bind(&addr));
624+
t!(socket.connect(addr));
625+
626+
t!(socket.send(b"hello world"));
627+
628+
let mut buf = [0; 11];
629+
t!(socket.recv(&mut buf));
630+
assert_eq!(b"hello world", &buf[..]);
631+
}
632+
633+
#[test]
634+
fn ttl() {
635+
let ttl = 100;
636+
637+
let addr = next_test_ip4();
638+
639+
let stream = t!(UdpSocket::bind(&addr));
640+
641+
t!(stream.set_ttl(ttl));
642+
assert_eq!(ttl, t!(stream.ttl()));
643+
}
644+
645+
#[test]
646+
fn set_nonblocking() {
647+
let addr = next_test_ip4();
648+
649+
let stream = t!(UdpSocket::bind(&addr));
650+
651+
t!(stream.set_nonblocking(true));
652+
t!(stream.set_nonblocking(false));
653+
}
403654
}

0 commit comments

Comments
 (0)