1 //! Primitives for working with UDP 2 //! 3 //! The types provided in this module are non-blocking by default and are 4 //! designed to be portable across all supported Mio platforms. As long as the 5 //! [portability guidelines] are followed, the behavior should be identical no 6 //! matter the target platform. 7 //! 8 //! [portability guidelines]: ../struct.Poll.html#portability 9 10 #![allow(deprecated)] 11 12 use {sys, Ready, Poll, PollOpt, Token}; 13 use io::{self, MapNonBlock}; 14 use event::Evented; 15 use poll::SelectorId; 16 use std::net::{self, Ipv4Addr, Ipv6Addr, SocketAddr}; 17 18 /// A User Datagram Protocol socket. 19 /// 20 /// This is an implementation of a bound UDP socket. This supports both IPv4 and 21 /// IPv6 addresses, and there is no corresponding notion of a server because UDP 22 /// is a datagram protocol. 23 #[derive(Debug)] 24 pub struct UdpSocket { 25 sys: sys::UdpSocket, 26 selector_id: SelectorId, 27 } 28 29 impl UdpSocket { 30 /// Creates a UDP socket from the given address. bind(addr: &SocketAddr) -> io::Result<UdpSocket>31 pub fn bind(addr: &SocketAddr) -> io::Result<UdpSocket> { 32 let socket = net::UdpSocket::bind(addr)?; 33 UdpSocket::from_socket(socket) 34 } 35 36 /// Creates a new mio-wrapped socket from an underlying and bound std 37 /// socket. 38 /// 39 /// This function requires that `socket` has previously been bound to an 40 /// address to work correctly, and returns an I/O object which can be used 41 /// with mio to send/receive UDP messages. 42 /// 43 /// This can be used in conjunction with net2's `UdpBuilder` interface to 44 /// configure a socket before it's handed off to mio, such as setting 45 /// options like `reuse_address` or binding to multiple addresses. from_socket(socket: net::UdpSocket) -> io::Result<UdpSocket>46 pub fn from_socket(socket: net::UdpSocket) -> io::Result<UdpSocket> { 47 Ok(UdpSocket { 48 sys: sys::UdpSocket::new(socket)?, 49 selector_id: SelectorId::new(), 50 }) 51 } 52 53 /// Returns the socket address that this socket was created from. local_addr(&self) -> io::Result<SocketAddr>54 pub fn local_addr(&self) -> io::Result<SocketAddr> { 55 self.sys.local_addr() 56 } 57 58 /// Creates a new independently owned handle to the underlying socket. 59 /// 60 /// The returned `UdpSocket` is a reference to the same socket that this 61 /// object references. Both handles will read and write the same port, and 62 /// options set on one socket will be propagated to the other. try_clone(&self) -> io::Result<UdpSocket>63 pub fn try_clone(&self) -> io::Result<UdpSocket> { 64 self.sys.try_clone() 65 .map(|s| { 66 UdpSocket { 67 sys: s, 68 selector_id: self.selector_id.clone(), 69 } 70 }) 71 } 72 73 /// Sends data on the socket to the given address. On success, returns the 74 /// number of bytes written. 75 /// 76 /// Address type can be any implementor of `ToSocketAddrs` trait. See its 77 /// documentation for concrete examples. send_to(&self, buf: &[u8], target: &SocketAddr) -> io::Result<Option<usize>>78 pub fn send_to(&self, buf: &[u8], target: &SocketAddr) 79 -> io::Result<Option<usize>> { 80 self.sys.send_to(buf, target).map_non_block() 81 } 82 83 /// Receives data from the socket and stores data in the supplied buffer `buf`. On success, 84 /// returns the number of bytes read and the address from whence the data came. 85 /// 86 /// The function must be called with valid byte array `buf` of sufficient size to 87 /// hold the message bytes. If a message is too long to fit in the supplied buffer, 88 /// excess bytes may be discarded. 89 /// 90 /// The function does not read from `buf`, but is overwriting previous content of `buf`. 91 /// 92 /// Assuming the function has read `n` bytes, slicing `&buf[..n]` provides 93 /// efficient access with iterators and boundary checks. recv_from(&self, buf: &mut [u8]) -> io::Result<Option<(usize, SocketAddr)>>94 pub fn recv_from(&self, buf: &mut [u8]) 95 -> io::Result<Option<(usize, SocketAddr)>> { 96 self.sys.recv_from(buf).map_non_block() 97 } 98 99 /// Sends data on the socket to the address previously bound via connect(). On success, 100 /// returns the number of bytes written. send(&self, buf: &[u8]) -> io::Result<Option<usize>>101 pub fn send(&self, buf: &[u8]) 102 -> io::Result<Option<usize>> { 103 self.sys.send(buf).map_non_block() 104 } 105 106 /// Receives data from the socket previously bound with connect() and stores data in 107 /// the supplied buffer `buf`. On success, returns the number of bytes read. 108 /// 109 /// The function must be called with valid byte array `buf` of sufficient size to 110 /// hold the message bytes. If a message is too long to fit in the supplied buffer, 111 /// excess bytes may be discarded. 112 /// 113 /// The function does not read from `buf`, but is overwriting previous content of `buf`. 114 /// 115 /// Assuming the function has read `n` bytes, slicing `&buf[..n]` provides 116 /// efficient access with iterators and boundary checks. recv(&self, buf: &mut [u8]) -> io::Result<Option<usize>>117 pub fn recv(&self, buf: &mut [u8]) 118 -> io::Result<Option<usize>> { 119 self.sys.recv(buf).map_non_block() 120 } 121 122 /// Connects the UDP socket setting the default destination for `send()` 123 /// and limiting packets that are read via `recv` from the address specified 124 /// in `addr`. connect(&self, addr: SocketAddr) -> io::Result<()>125 pub fn connect(&self, addr: SocketAddr) 126 -> io::Result<()> { 127 self.sys.connect(addr) 128 } 129 130 /// Gets the value of the `SO_BROADCAST` option for this socket. 131 /// 132 /// For more information about this option, see 133 /// [`set_broadcast`][link]. 134 /// 135 /// [link]: #method.set_broadcast broadcast(&self) -> io::Result<bool>136 pub fn broadcast(&self) -> io::Result<bool> { 137 self.sys.broadcast() 138 } 139 140 /// Sets the value of the `SO_BROADCAST` option for this socket. 141 /// 142 /// When enabled, this socket is allowed to send packets to a broadcast 143 /// address. set_broadcast(&self, on: bool) -> io::Result<()>144 pub fn set_broadcast(&self, on: bool) -> io::Result<()> { 145 self.sys.set_broadcast(on) 146 } 147 148 /// Gets the value of the `IP_MULTICAST_LOOP` option for this socket. 149 /// 150 /// For more information about this option, see 151 /// [`set_multicast_loop_v4`][link]. 152 /// 153 /// [link]: #method.set_multicast_loop_v4 multicast_loop_v4(&self) -> io::Result<bool>154 pub fn multicast_loop_v4(&self) -> io::Result<bool> { 155 self.sys.multicast_loop_v4() 156 } 157 158 /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket. 159 /// 160 /// If enabled, multicast packets will be looped back to the local socket. 161 /// Note that this may not have any affect on IPv6 sockets. set_multicast_loop_v4(&self, on: bool) -> io::Result<()>162 pub fn set_multicast_loop_v4(&self, on: bool) -> io::Result<()> { 163 self.sys.set_multicast_loop_v4(on) 164 } 165 166 /// Gets the value of the `IP_MULTICAST_TTL` option for this socket. 167 /// 168 /// For more information about this option, see 169 /// [`set_multicast_ttl_v4`][link]. 170 /// 171 /// [link]: #method.set_multicast_ttl_v4 multicast_ttl_v4(&self) -> io::Result<u32>172 pub fn multicast_ttl_v4(&self) -> io::Result<u32> { 173 self.sys.multicast_ttl_v4() 174 } 175 176 /// Sets the value of the `IP_MULTICAST_TTL` option for this socket. 177 /// 178 /// Indicates the time-to-live value of outgoing multicast packets for 179 /// this socket. The default value is 1 which means that multicast packets 180 /// don't leave the local network unless explicitly requested. 181 /// 182 /// Note that this may not have any affect on IPv6 sockets. set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()>183 pub fn set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()> { 184 self.sys.set_multicast_ttl_v4(ttl) 185 } 186 187 /// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket. 188 /// 189 /// For more information about this option, see 190 /// [`set_multicast_loop_v6`][link]. 191 /// 192 /// [link]: #method.set_multicast_loop_v6 multicast_loop_v6(&self) -> io::Result<bool>193 pub fn multicast_loop_v6(&self) -> io::Result<bool> { 194 self.sys.multicast_loop_v6() 195 } 196 197 /// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket. 198 /// 199 /// Controls whether this socket sees the multicast packets it sends itself. 200 /// Note that this may not have any affect on IPv4 sockets. set_multicast_loop_v6(&self, on: bool) -> io::Result<()>201 pub fn set_multicast_loop_v6(&self, on: bool) -> io::Result<()> { 202 self.sys.set_multicast_loop_v6(on) 203 } 204 205 /// Gets the value of the `IP_TTL` option for this socket. 206 /// 207 /// For more information about this option, see [`set_ttl`][link]. 208 /// 209 /// [link]: #method.set_ttl ttl(&self) -> io::Result<u32>210 pub fn ttl(&self) -> io::Result<u32> { 211 self.sys.ttl() 212 } 213 214 /// Sets the value for the `IP_TTL` option on this socket. 215 /// 216 /// This value sets the time-to-live field that is used in every packet sent 217 /// from this socket. set_ttl(&self, ttl: u32) -> io::Result<()>218 pub fn set_ttl(&self, ttl: u32) -> io::Result<()> { 219 self.sys.set_ttl(ttl) 220 } 221 222 /// Executes an operation of the `IP_ADD_MEMBERSHIP` type. 223 /// 224 /// This function specifies a new multicast group for this socket to join. 225 /// The address must be a valid multicast address, and `interface` is the 226 /// address of the local interface with which the system should join the 227 /// multicast group. If it's equal to `INADDR_ANY` then an appropriate 228 /// interface is chosen by the system. join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()>229 pub fn join_multicast_v4(&self, 230 multiaddr: &Ipv4Addr, 231 interface: &Ipv4Addr) -> io::Result<()> { 232 self.sys.join_multicast_v4(multiaddr, interface) 233 } 234 235 /// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type. 236 /// 237 /// This function specifies a new multicast group for this socket to join. 238 /// The address must be a valid multicast address, and `interface` is the 239 /// index of the interface to join/leave (or 0 to indicate any interface). join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()>240 pub fn join_multicast_v6(&self, 241 multiaddr: &Ipv6Addr, 242 interface: u32) -> io::Result<()> { 243 self.sys.join_multicast_v6(multiaddr, interface) 244 } 245 246 /// Executes an operation of the `IP_DROP_MEMBERSHIP` type. 247 /// 248 /// For more information about this option, see 249 /// [`join_multicast_v4`][link]. 250 /// 251 /// [link]: #method.join_multicast_v4 leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()>252 pub fn leave_multicast_v4(&self, 253 multiaddr: &Ipv4Addr, 254 interface: &Ipv4Addr) -> io::Result<()> { 255 self.sys.leave_multicast_v4(multiaddr, interface) 256 } 257 258 /// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type. 259 /// 260 /// For more information about this option, see 261 /// [`join_multicast_v6`][link]. 262 /// 263 /// [link]: #method.join_multicast_v6 leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()>264 pub fn leave_multicast_v6(&self, 265 multiaddr: &Ipv6Addr, 266 interface: u32) -> io::Result<()> { 267 self.sys.leave_multicast_v6(multiaddr, interface) 268 } 269 270 /// Get the value of the `SO_ERROR` option on this socket. 271 /// 272 /// This will retrieve the stored error in the underlying socket, clearing 273 /// the field in the process. This can be useful for checking errors between 274 /// calls. take_error(&self) -> io::Result<Option<io::Error>>275 pub fn take_error(&self) -> io::Result<Option<io::Error>> { 276 self.sys.take_error() 277 } 278 } 279 280 impl Evented for UdpSocket { register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()>281 fn register(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> { 282 self.selector_id.associate_selector(poll)?; 283 self.sys.register(poll, token, interest, opts) 284 } 285 reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()>286 fn reregister(&self, poll: &Poll, token: Token, interest: Ready, opts: PollOpt) -> io::Result<()> { 287 self.sys.reregister(poll, token, interest, opts) 288 } 289 deregister(&self, poll: &Poll) -> io::Result<()>290 fn deregister(&self, poll: &Poll) -> io::Result<()> { 291 self.sys.deregister(poll) 292 } 293 } 294 295 /* 296 * 297 * ===== UNIX ext ===== 298 * 299 */ 300 301 #[cfg(all(unix, not(target_os = "fuchsia")))] 302 use std::os::unix::io::{IntoRawFd, AsRawFd, FromRawFd, RawFd}; 303 304 #[cfg(all(unix, not(target_os = "fuchsia")))] 305 impl IntoRawFd for UdpSocket { into_raw_fd(self) -> RawFd306 fn into_raw_fd(self) -> RawFd { 307 self.sys.into_raw_fd() 308 } 309 } 310 311 #[cfg(all(unix, not(target_os = "fuchsia")))] 312 impl AsRawFd for UdpSocket { as_raw_fd(&self) -> RawFd313 fn as_raw_fd(&self) -> RawFd { 314 self.sys.as_raw_fd() 315 } 316 } 317 318 #[cfg(all(unix, not(target_os = "fuchsia")))] 319 impl FromRawFd for UdpSocket { from_raw_fd(fd: RawFd) -> UdpSocket320 unsafe fn from_raw_fd(fd: RawFd) -> UdpSocket { 321 UdpSocket { 322 sys: FromRawFd::from_raw_fd(fd), 323 selector_id: SelectorId::new(), 324 } 325 } 326 } 327