|
10 | 10 |
|
11 | 11 | use fmt;
|
12 | 12 | use io::{self, Error, ErrorKind};
|
13 |
| -use net::{ToSocketAddrs, SocketAddr}; |
| 13 | +use net::{ToSocketAddrs, SocketAddr, Ipv4Addr, Ipv6Addr}; |
14 | 14 | use sys_common::net as net_imp;
|
15 | 15 | use sys_common::{AsInner, FromInner, IntoInner};
|
16 | 16 | use time::Duration;
|
@@ -140,6 +140,221 @@ impl UdpSocket {
|
140 | 140 | pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
141 | 141 | self.0.write_timeout()
|
142 | 142 | }
|
| 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 | + } |
143 | 358 | }
|
144 | 359 |
|
145 | 360 | impl AsInner<net_imp::UdpSocket> for UdpSocket {
|
@@ -400,4 +615,40 @@ mod tests {
|
400 | 615 | assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
|
401 | 616 | assert!(start.elapsed() > Duration::from_millis(400));
|
402 | 617 | }
|
| 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 | + } |
403 | 654 | }
|
0 commit comments