diff --git a/src/libstd/io/net/udp.rs b/src/libstd/io/net/udp.rs index 8cdad3f528a48..c38f24c3c9009 100644 --- a/src/libstd/io/net/udp.rs +++ b/src/libstd/io/net/udp.rs @@ -71,6 +71,16 @@ impl UdpSocket { }) } + /// Creates a UDP socket from the given address with `SO_REUSEADDR` set to true. + /// + /// Address type can be any implementor of `ToSocketAddr` trait. See its + /// documentation for concrete examples. + pub fn bind_reusable(addr: A) -> IoResult { + super::with_addresses(addr, |addr| { + UdpSocketImp::bind_reusable(addr).map(|s| UdpSocket { inner: s }) + }) + } + /// Receives data from the socket. On success, returns the number of bytes /// read and the address from whence the data came. pub fn recv_from(&mut self, buf: &mut [u8]) -> IoResult<(uint, SocketAddr)> { diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index 4cf891ac4985e..01a1764ec1df6 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -809,6 +809,28 @@ impl UdpSocket { } } + pub fn bind_reusable(addr: SocketAddr) -> IoResult { + sys::init_net(); + + let fd = try!(socket(addr, libc::SOCK_DGRAM)); + let ret = UdpSocket { + inner: Arc::new(Inner::new(fd)), + read_deadline: 0, + write_deadline: 0, + }; + + setsockopt(fd, libc::SOL_SOCKET, libc::SO_REUSEADDR, true as libc::c_int).unwrap(); + + let mut storage = unsafe { mem::zeroed() }; + let len = addr_to_sockaddr(addr, &mut storage); + let addrp = &storage as *const _ as *const libc::sockaddr; + + match unsafe { libc::bind(fd, addrp, len) } { + -1 => Err(last_error()), + _ => Ok(ret), + } + } + pub fn fd(&self) -> sock_t { self.inner.fd } pub fn set_broadcast(&mut self, on: bool) -> IoResult<()> {