2 use crate::ffi::CString;
4 use crate::io::{self, Error, ErrorKind, IoSlice, IoSliceMut};
6 use crate::net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr};
8 use crate::sys::net::{cvt, cvt_r, cvt_gai, Socket, init, wrlen_t};
9 use crate::sys::net::netc as c;
10 use crate::sys_common::{AsInner, FromInner, IntoInner};
11 use crate::time::Duration;
12 use crate::convert::{TryFrom, TryInto};
14 use libc::{c_int, c_void};
16 #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
17 target_os = "ios", target_os = "macos",
18 target_os = "openbsd", target_os = "netbsd",
19 target_os = "solaris", target_os = "haiku", target_os = "l4re"))]
20 use crate::sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP;
21 #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd",
22 target_os = "ios", target_os = "macos",
23 target_os = "openbsd", target_os = "netbsd",
24 target_os = "solaris", target_os = "haiku", target_os = "l4re")))]
25 use crate::sys::net::netc::IPV6_ADD_MEMBERSHIP;
26 #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
27 target_os = "ios", target_os = "macos",
28 target_os = "openbsd", target_os = "netbsd",
29 target_os = "solaris", target_os = "haiku", target_os = "l4re"))]
30 use crate::sys::net::netc::IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP;
31 #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd",
32 target_os = "ios", target_os = "macos",
33 target_os = "openbsd", target_os = "netbsd",
34 target_os = "solaris", target_os = "haiku", target_os = "l4re")))]
35 use crate::sys::net::netc::IPV6_DROP_MEMBERSHIP;
37 #[cfg(any(target_os = "linux", target_os = "android",
38 target_os = "dragonfly", target_os = "freebsd",
39 target_os = "openbsd", target_os = "netbsd",
40 target_os = "haiku"))]
41 use libc::MSG_NOSIGNAL;
42 #[cfg(not(any(target_os = "linux", target_os = "android",
43 target_os = "dragonfly", target_os = "freebsd",
44 target_os = "openbsd", target_os = "netbsd",
45 target_os = "haiku")))]
46 const MSG_NOSIGNAL: c_int = 0x0;
48 ////////////////////////////////////////////////////////////////////////////////
49 // sockaddr and misc bindings
50 ////////////////////////////////////////////////////////////////////////////////
52 pub fn setsockopt<T>(sock: &Socket, opt: c_int, val: c_int,
53 payload: T) -> io::Result<()> {
55 let payload = &payload as *const T as *const c_void;
56 cvt(c::setsockopt(*sock.as_inner(), opt, val, payload,
57 mem::size_of::<T>() as c::socklen_t))?;
62 pub fn getsockopt<T: Copy>(sock: &Socket, opt: c_int,
63 val: c_int) -> io::Result<T> {
65 let mut slot: T = mem::zeroed();
66 let mut len = mem::size_of::<T>() as c::socklen_t;
67 cvt(c::getsockopt(*sock.as_inner(), opt, val,
68 &mut slot as *mut _ as *mut _,
70 assert_eq!(len as usize, mem::size_of::<T>());
75 fn sockname<F>(f: F) -> io::Result<SocketAddr>
76 where F: FnOnce(*mut c::sockaddr, *mut c::socklen_t) -> c_int
79 let mut storage: c::sockaddr_storage = mem::zeroed();
80 let mut len = mem::size_of_val(&storage) as c::socklen_t;
81 cvt(f(&mut storage as *mut _ as *mut _, &mut len))?;
82 sockaddr_to_addr(&storage, len as usize)
86 pub fn sockaddr_to_addr(storage: &c::sockaddr_storage,
87 len: usize) -> io::Result<SocketAddr> {
88 match storage.ss_family as c_int {
90 assert!(len as usize >= mem::size_of::<c::sockaddr_in>());
91 Ok(SocketAddr::V4(FromInner::from_inner(unsafe {
92 *(storage as *const _ as *const c::sockaddr_in)
96 assert!(len as usize >= mem::size_of::<c::sockaddr_in6>());
97 Ok(SocketAddr::V6(FromInner::from_inner(unsafe {
98 *(storage as *const _ as *const c::sockaddr_in6)
102 Err(Error::new(ErrorKind::InvalidInput, "invalid argument"))
107 #[cfg(target_os = "android")]
108 fn to_ipv6mr_interface(value: u32) -> c_int {
112 #[cfg(not(target_os = "android"))]
113 fn to_ipv6mr_interface(value: u32) -> libc::c_uint {
114 value as libc::c_uint
117 ////////////////////////////////////////////////////////////////////////////////
118 // get_host_addresses
119 ////////////////////////////////////////////////////////////////////////////////
121 pub struct LookupHost {
122 original: *mut c::addrinfo,
123 cur: *mut c::addrinfo,
128 pub fn port(&self) -> u16 {
133 impl Iterator for LookupHost {
134 type Item = SocketAddr;
135 fn next(&mut self) -> Option<SocketAddr> {
138 let cur = self.cur.as_ref()?;
139 self.cur = cur.ai_next;
140 match sockaddr_to_addr(mem::transmute(cur.ai_addr),
141 cur.ai_addrlen as usize)
143 Ok(addr) => return Some(addr),
151 unsafe impl Sync for LookupHost {}
152 unsafe impl Send for LookupHost {}
154 impl Drop for LookupHost {
156 unsafe { c::freeaddrinfo(self.original) }
160 impl TryFrom<&str> for LookupHost {
161 type Error = io::Error;
163 fn try_from(s: &str) -> io::Result<LookupHost> {
164 macro_rules! try_opt {
165 ($e:expr, $msg:expr) => (
168 None => return Err(io::Error::new(io::ErrorKind::InvalidInput,
174 // split the string by ':' and convert the second part to u16
175 let mut parts_iter = s.rsplitn(2, ':');
176 let port_str = try_opt!(parts_iter.next(), "invalid socket address");
177 let host = try_opt!(parts_iter.next(), "invalid socket address");
178 let port: u16 = try_opt!(port_str.parse().ok(), "invalid port value");
180 (host, port).try_into()
184 impl<'a> TryFrom<(&'a str, u16)> for LookupHost {
185 type Error = io::Error;
187 fn try_from((host, port): (&'a str, u16)) -> io::Result<LookupHost> {
190 let c_host = CString::new(host)?;
191 let mut hints: c::addrinfo = unsafe { mem::zeroed() };
192 hints.ai_socktype = c::SOCK_STREAM;
193 let mut res = ptr::null_mut();
195 cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res)).map(|_| {
196 LookupHost { original: res, cur: res, port }
202 ////////////////////////////////////////////////////////////////////////////////
204 ////////////////////////////////////////////////////////////////////////////////
206 pub struct TcpStream {
211 pub fn connect(addr: io::Result<&SocketAddr>) -> io::Result<TcpStream> {
216 let sock = Socket::new(addr, c::SOCK_STREAM)?;
218 let (addrp, len) = addr.into_inner();
219 cvt_r(|| unsafe { c::connect(*sock.as_inner(), addrp, len) })?;
220 Ok(TcpStream { inner: sock })
223 pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result<TcpStream> {
226 let sock = Socket::new(addr, c::SOCK_STREAM)?;
227 sock.connect_timeout(addr, timeout)?;
228 Ok(TcpStream { inner: sock })
231 pub fn socket(&self) -> &Socket { &self.inner }
233 pub fn into_socket(self) -> Socket { self.inner }
235 pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
236 self.inner.set_timeout(dur, c::SO_RCVTIMEO)
239 pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
240 self.inner.set_timeout(dur, c::SO_SNDTIMEO)
243 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
244 self.inner.timeout(c::SO_RCVTIMEO)
247 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
248 self.inner.timeout(c::SO_SNDTIMEO)
251 pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
255 pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
259 pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
260 self.inner.read_vectored(bufs)
263 pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
264 let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;
265 let ret = cvt(unsafe {
266 c::send(*self.inner.as_inner(),
267 buf.as_ptr() as *const c_void,
274 pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
275 self.inner.write_vectored(bufs)
278 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
279 sockname(|buf, len| unsafe {
280 c::getpeername(*self.inner.as_inner(), buf, len)
284 pub fn socket_addr(&self) -> io::Result<SocketAddr> {
285 sockname(|buf, len| unsafe {
286 c::getsockname(*self.inner.as_inner(), buf, len)
290 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
291 self.inner.shutdown(how)
294 pub fn duplicate(&self) -> io::Result<TcpStream> {
295 self.inner.duplicate().map(|s| TcpStream { inner: s })
298 pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
299 self.inner.set_nodelay(nodelay)
302 pub fn nodelay(&self) -> io::Result<bool> {
306 pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
307 setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int)
310 pub fn ttl(&self) -> io::Result<u32> {
311 let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL)?;
315 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
316 self.inner.take_error()
319 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
320 self.inner.set_nonblocking(nonblocking)
324 impl FromInner<Socket> for TcpStream {
325 fn from_inner(socket: Socket) -> TcpStream {
326 TcpStream { inner: socket }
330 impl fmt::Debug for TcpStream {
331 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
332 let mut res = f.debug_struct("TcpStream");
334 if let Ok(addr) = self.socket_addr() {
335 res.field("addr", &addr);
338 if let Ok(peer) = self.peer_addr() {
339 res.field("peer", &peer);
342 let name = if cfg!(windows) {"socket"} else {"fd"};
343 res.field(name, &self.inner.as_inner())
348 ////////////////////////////////////////////////////////////////////////////////
350 ////////////////////////////////////////////////////////////////////////////////
352 pub struct TcpListener {
357 pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<TcpListener> {
362 let sock = Socket::new(addr, c::SOCK_STREAM)?;
364 // On platforms with Berkeley-derived sockets, this allows
365 // to quickly rebind a socket, without needing to wait for
366 // the OS to clean up the previous one.
368 setsockopt(&sock, c::SOL_SOCKET, c::SO_REUSEADDR,
372 // Bind our new socket
373 let (addrp, len) = addr.into_inner();
374 cvt(unsafe { c::bind(*sock.as_inner(), addrp, len as _) })?;
377 cvt(unsafe { c::listen(*sock.as_inner(), 128) })?;
378 Ok(TcpListener { inner: sock })
381 pub fn socket(&self) -> &Socket { &self.inner }
383 pub fn into_socket(self) -> Socket { self.inner }
385 pub fn socket_addr(&self) -> io::Result<SocketAddr> {
386 sockname(|buf, len| unsafe {
387 c::getsockname(*self.inner.as_inner(), buf, len)
391 pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
392 let mut storage: c::sockaddr_storage = unsafe { mem::zeroed() };
393 let mut len = mem::size_of_val(&storage) as c::socklen_t;
394 let sock = self.inner.accept(&mut storage as *mut _ as *mut _,
396 let addr = sockaddr_to_addr(&storage, len as usize)?;
397 Ok((TcpStream { inner: sock, }, addr))
400 pub fn duplicate(&self) -> io::Result<TcpListener> {
401 self.inner.duplicate().map(|s| TcpListener { inner: s })
404 pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
405 setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int)
408 pub fn ttl(&self) -> io::Result<u32> {
409 let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL)?;
413 pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
414 setsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_V6ONLY, only_v6 as c_int)
417 pub fn only_v6(&self) -> io::Result<bool> {
418 let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_V6ONLY)?;
422 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
423 self.inner.take_error()
426 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
427 self.inner.set_nonblocking(nonblocking)
431 impl FromInner<Socket> for TcpListener {
432 fn from_inner(socket: Socket) -> TcpListener {
433 TcpListener { inner: socket }
437 impl fmt::Debug for TcpListener {
438 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
439 let mut res = f.debug_struct("TcpListener");
441 if let Ok(addr) = self.socket_addr() {
442 res.field("addr", &addr);
445 let name = if cfg!(windows) {"socket"} else {"fd"};
446 res.field(name, &self.inner.as_inner())
451 ////////////////////////////////////////////////////////////////////////////////
453 ////////////////////////////////////////////////////////////////////////////////
455 pub struct UdpSocket {
460 pub fn bind(addr: io::Result<&SocketAddr>) -> io::Result<UdpSocket> {
465 let sock = Socket::new(addr, c::SOCK_DGRAM)?;
466 let (addrp, len) = addr.into_inner();
467 cvt(unsafe { c::bind(*sock.as_inner(), addrp, len as _) })?;
468 Ok(UdpSocket { inner: sock })
471 pub fn socket(&self) -> &Socket { &self.inner }
473 pub fn into_socket(self) -> Socket { self.inner }
475 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
476 sockname(|buf, len| unsafe {
477 c::getpeername(*self.inner.as_inner(), buf, len)
481 pub fn socket_addr(&self) -> io::Result<SocketAddr> {
482 sockname(|buf, len| unsafe {
483 c::getsockname(*self.inner.as_inner(), buf, len)
487 pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
488 self.inner.recv_from(buf)
491 pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
492 self.inner.peek_from(buf)
495 pub fn send_to(&self, buf: &[u8], dst: &SocketAddr) -> io::Result<usize> {
496 let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;
497 let (dstp, dstlen) = dst.into_inner();
498 let ret = cvt(unsafe {
499 c::sendto(*self.inner.as_inner(),
500 buf.as_ptr() as *const c_void, len,
501 MSG_NOSIGNAL, dstp, dstlen)
506 pub fn duplicate(&self) -> io::Result<UdpSocket> {
507 self.inner.duplicate().map(|s| UdpSocket { inner: s })
510 pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
511 self.inner.set_timeout(dur, c::SO_RCVTIMEO)
514 pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
515 self.inner.set_timeout(dur, c::SO_SNDTIMEO)
518 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
519 self.inner.timeout(c::SO_RCVTIMEO)
522 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
523 self.inner.timeout(c::SO_SNDTIMEO)
526 pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
527 setsockopt(&self.inner, c::SOL_SOCKET, c::SO_BROADCAST, broadcast as c_int)
530 pub fn broadcast(&self) -> io::Result<bool> {
531 let raw: c_int = getsockopt(&self.inner, c::SOL_SOCKET, c::SO_BROADCAST)?;
535 pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> {
536 setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP, multicast_loop_v4 as c_int)
539 pub fn multicast_loop_v4(&self) -> io::Result<bool> {
540 let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?;
544 pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> {
545 setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl_v4 as c_int)
548 pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
549 let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?;
553 pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> {
554 setsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP, multicast_loop_v6 as c_int)
557 pub fn multicast_loop_v6(&self) -> io::Result<bool> {
558 let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP)?;
562 pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr)
564 let mreq = c::ip_mreq {
565 imr_multiaddr: *multiaddr.as_inner(),
566 imr_interface: *interface.as_inner(),
568 setsockopt(&self.inner, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq)
571 pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32)
573 let mreq = c::ipv6_mreq {
574 ipv6mr_multiaddr: *multiaddr.as_inner(),
575 ipv6mr_interface: to_ipv6mr_interface(interface),
577 setsockopt(&self.inner, c::IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq)
580 pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr)
582 let mreq = c::ip_mreq {
583 imr_multiaddr: *multiaddr.as_inner(),
584 imr_interface: *interface.as_inner(),
586 setsockopt(&self.inner, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq)
589 pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32)
591 let mreq = c::ipv6_mreq {
592 ipv6mr_multiaddr: *multiaddr.as_inner(),
593 ipv6mr_interface: to_ipv6mr_interface(interface),
595 setsockopt(&self.inner, c::IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, mreq)
598 pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
599 setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int)
602 pub fn ttl(&self) -> io::Result<u32> {
603 let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL)?;
607 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
608 self.inner.take_error()
611 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
612 self.inner.set_nonblocking(nonblocking)
615 pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
619 pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
623 pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
624 let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;
625 let ret = cvt(unsafe {
626 c::send(*self.inner.as_inner(),
627 buf.as_ptr() as *const c_void,
634 pub fn connect(&self, addr: io::Result<&SocketAddr>) -> io::Result<()> {
635 let (addrp, len) = addr?.into_inner();
636 cvt_r(|| unsafe { c::connect(*self.inner.as_inner(), addrp, len) }).map(|_| ())
640 impl FromInner<Socket> for UdpSocket {
641 fn from_inner(socket: Socket) -> UdpSocket {
642 UdpSocket { inner: socket }
646 impl fmt::Debug for UdpSocket {
647 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
648 let mut res = f.debug_struct("UdpSocket");
650 if let Ok(addr) = self.socket_addr() {
651 res.field("addr", &addr);
654 let name = if cfg!(windows) {"socket"} else {"fd"};
655 res.field(name, &self.inner.as_inner())
663 use crate::collections::HashMap;
666 fn no_lookup_host_duplicates() {
667 let mut addrs = HashMap::new();
668 let lh = match LookupHost::try_from(("localhost", 0)) {
670 Err(e) => panic!("couldn't resolve `localhost': {}", e)
672 for sa in lh { *addrs.entry(sa).or_insert(0) += 1; };
673 assert_eq!(addrs.iter().filter(|&(_, &v)| v > 1).collect::<Vec<_>>(), vec![],
674 "There should be no duplicate localhost entries");