From ee1c9244553f68da49b532224c4c82a77f400c7c Mon Sep 17 00:00:00 2001 From: Daniil Smirnov Date: Wed, 21 Jan 2015 21:40:54 +0300 Subject: [PATCH 1/5] Adds `bind_reusable` method to UdpSocket --- src/libstd/io/net/udp.rs | 10 ++++++++++ src/libstd/sys/common/net.rs | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+) 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..4d35f60d10f46 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(self.fd(), libc::SOL_SOCKET, libc::SO_REUSEADDR, on as libc::c_int); + + 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<()> { From 7d68369d20d40f49dc947588f5eeaef2737f6259 Mon Sep 17 00:00:00 2001 From: Daniil Smirnov Date: Wed, 21 Jan 2015 22:29:15 +0300 Subject: [PATCH 2/5] Fix copy-pasted code: replace `on` with true constant --- src/libstd/sys/common/net.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index 4d35f60d10f46..08b9570042987 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -819,7 +819,7 @@ impl UdpSocket { write_deadline: 0, }; - setsockopt(self.fd(), libc::SOL_SOCKET, libc::SO_REUSEADDR, on as libc::c_int); + setsockopt(self.fd(), libc::SOL_SOCKET, libc::SO_REUSEADDR, true as libc::c_int); let mut storage = unsafe { mem::zeroed() }; let len = addr_to_sockaddr(addr, &mut storage); From 3f8eef326de59dea28217a74b848459cd030cbde Mon Sep 17 00:00:00 2001 From: Daniil Smirnov Date: Wed, 21 Jan 2015 22:31:22 +0300 Subject: [PATCH 3/5] Fix copy-pasted code: `fd` is a local variable. --- src/libstd/sys/common/net.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index 08b9570042987..366986e6000ab 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -819,7 +819,7 @@ impl UdpSocket { write_deadline: 0, }; - setsockopt(self.fd(), libc::SOL_SOCKET, libc::SO_REUSEADDR, true as libc::c_int); + setsockopt(fd, libc::SOL_SOCKET, libc::SO_REUSEADDR, true as libc::c_int); let mut storage = unsafe { mem::zeroed() }; let len = addr_to_sockaddr(addr, &mut storage); From 35421ef2cc84d6dcc61896bac146675c1932e14d Mon Sep 17 00:00:00 2001 From: Daniil Smirnov Date: Wed, 21 Jan 2015 22:36:40 +0300 Subject: [PATCH 4/5] Unwrap setsockopt error. --- src/libstd/sys/common/net.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index 366986e6000ab..f00bfb33a23f4 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -819,7 +819,7 @@ impl UdpSocket { write_deadline: 0, }; - setsockopt(fd, libc::SOL_SOCKET, libc::SO_REUSEADDR, true as libc::c_int); + 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); From d424b872e5a689fdae43f47d81450f57fd3f4d67 Mon Sep 17 00:00:00 2001 From: Daniil Smirnov Date: Thu, 22 Jan 2015 00:11:19 +0300 Subject: [PATCH 5/5] Trim trailing whitespace --- src/libstd/sys/common/net.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/common/net.rs b/src/libstd/sys/common/net.rs index f00bfb33a23f4..01a1764ec1df6 100644 --- a/src/libstd/sys/common/net.rs +++ b/src/libstd/sys/common/net.rs @@ -819,7 +819,7 @@ impl UdpSocket { write_deadline: 0, }; - setsockopt(fd, libc::SOL_SOCKET, libc::SO_REUSEADDR, true as libc::c_int).unwrap(); + 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);