1 // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
14 use io
::{self, Error, ErrorKind}
;
15 use libc
::{c_int, c_void}
;
17 use net
::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr}
;
19 use sys
::net
::{cvt, cvt_r, cvt_gai, Socket, init, wrlen_t}
;
20 use sys
::net
::netc
as c
;
21 use sys_common
::{AsInner, FromInner, IntoInner}
;
24 #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
25 target_os
= "ios", target_os
= "macos",
26 target_os
= "openbsd", target_os
= "netbsd",
27 target_os
= "solaris", target_os
= "haiku"))]
28 use sys
::net
::netc
::IPV6_JOIN_GROUP
as IPV6_ADD_MEMBERSHIP
;
29 #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd",
30 target_os
= "ios", target_os
= "macos",
31 target_os
= "openbsd", target_os
= "netbsd",
32 target_os
= "solaris", target_os
= "haiku")))]
33 use sys
::net
::netc
::IPV6_ADD_MEMBERSHIP
;
34 #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
35 target_os
= "ios", target_os
= "macos",
36 target_os
= "openbsd", target_os
= "netbsd",
37 target_os
= "solaris", target_os
= "haiku"))]
38 use sys
::net
::netc
::IPV6_LEAVE_GROUP
as IPV6_DROP_MEMBERSHIP
;
39 #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd",
40 target_os
= "ios", target_os
= "macos",
41 target_os
= "openbsd", target_os
= "netbsd",
42 target_os
= "solaris", target_os
= "haiku")))]
43 use sys
::net
::netc
::IPV6_DROP_MEMBERSHIP
;
45 #[cfg(any(target_os = "linux", target_os = "android",
46 target_os
= "dragonfly", target_os
= "freebsd",
47 target_os
= "openbsd", target_os
= "netbsd",
48 target_os
= "haiku", target_os
= "bitrig"))]
49 use libc
::MSG_NOSIGNAL
;
50 #[cfg(not(any(target_os = "linux", target_os = "android",
51 target_os
= "dragonfly", target_os
= "freebsd",
52 target_os
= "openbsd", target_os
= "netbsd",
53 target_os
= "haiku", target_os
= "bitrig")))]
54 const MSG_NOSIGNAL
: c_int
= 0x0;
56 ////////////////////////////////////////////////////////////////////////////////
57 // sockaddr and misc bindings
58 ////////////////////////////////////////////////////////////////////////////////
60 pub fn setsockopt
<T
>(sock
: &Socket
, opt
: c_int
, val
: c_int
,
61 payload
: T
) -> io
::Result
<()> {
63 let payload
= &payload
as *const T
as *const c_void
;
64 cvt(c
::setsockopt(*sock
.as_inner(), opt
, val
, payload
,
65 mem
::size_of
::<T
>() as c
::socklen_t
))?
;
70 pub fn getsockopt
<T
: Copy
>(sock
: &Socket
, opt
: c_int
,
71 val
: c_int
) -> io
::Result
<T
> {
73 let mut slot
: T
= mem
::zeroed();
74 let mut len
= mem
::size_of
::<T
>() as c
::socklen_t
;
75 cvt(c
::getsockopt(*sock
.as_inner(), opt
, val
,
76 &mut slot
as *mut _
as *mut _
,
78 assert_eq
!(len
as usize, mem
::size_of
::<T
>());
83 fn sockname
<F
>(f
: F
) -> io
::Result
<SocketAddr
>
84 where F
: FnOnce(*mut c
::sockaddr
, *mut c
::socklen_t
) -> c_int
87 let mut storage
: c
::sockaddr_storage
= mem
::zeroed();
88 let mut len
= mem
::size_of_val(&storage
) as c
::socklen_t
;
89 cvt(f(&mut storage
as *mut _
as *mut _
, &mut len
))?
;
90 sockaddr_to_addr(&storage
, len
as usize)
94 pub fn sockaddr_to_addr(storage
: &c
::sockaddr_storage
,
95 len
: usize) -> io
::Result
<SocketAddr
> {
96 match storage
.ss_family
as c_int
{
98 assert
!(len
as usize >= mem
::size_of
::<c
::sockaddr_in
>());
99 Ok(SocketAddr
::V4(FromInner
::from_inner(unsafe {
100 *(storage
as *const _
as *const c
::sockaddr_in
)
104 assert
!(len
as usize >= mem
::size_of
::<c
::sockaddr_in6
>());
105 Ok(SocketAddr
::V6(FromInner
::from_inner(unsafe {
106 *(storage
as *const _
as *const c
::sockaddr_in6
)
110 Err(Error
::new(ErrorKind
::InvalidInput
, "invalid argument"))
115 #[cfg(target_os = "android")]
116 fn to_ipv6mr_interface(value
: u32) -> c_int
{
120 #[cfg(not(target_os = "android"))]
121 fn to_ipv6mr_interface(value
: u32) -> ::libc
::c_uint
{
122 value
as ::libc
::c_uint
125 ////////////////////////////////////////////////////////////////////////////////
126 // get_host_addresses
127 ////////////////////////////////////////////////////////////////////////////////
129 pub struct LookupHost
{
130 original
: *mut c
::addrinfo
,
131 cur
: *mut c
::addrinfo
,
134 impl Iterator
for LookupHost
{
135 type Item
= SocketAddr
;
136 fn next(&mut self) -> Option
<SocketAddr
> {
139 let cur
= match self.cur
.as_ref() {
143 self.cur
= cur
.ai_next
;
144 match sockaddr_to_addr(mem
::transmute(cur
.ai_addr
),
145 cur
.ai_addrlen
as usize)
147 Ok(addr
) => return Some(addr
),
155 unsafe impl Sync
for LookupHost {}
156 unsafe impl Send
for LookupHost {}
158 impl Drop
for LookupHost
{
160 unsafe { c::freeaddrinfo(self.original) }
164 pub fn lookup_host(host
: &str) -> io
::Result
<LookupHost
> {
167 let c_host
= CString
::new(host
)?
;
168 let hints
= c
::addrinfo
{
171 ai_socktype
: c
::SOCK_STREAM
,
174 ai_addr
: ptr
::null_mut(),
175 ai_canonname
: ptr
::null_mut(),
176 ai_next
: ptr
::null_mut()
178 let mut res
= ptr
::null_mut();
180 match cvt_gai(c
::getaddrinfo(c_host
.as_ptr(), ptr
::null(), &hints
, &mut res
)) {
182 Ok(LookupHost { original: res, cur: res }
)
186 // The lookup failure could be caused by using a stale /etc/resolv.conf.
187 // See https://github.com/rust-lang/rust/issues/41570.
188 // We therefore force a reload of the nameserver information.
192 // the cfg is needed here to avoid an "unreachable pattern" warning
199 ////////////////////////////////////////////////////////////////////////////////
201 ////////////////////////////////////////////////////////////////////////////////
203 pub struct TcpStream
{
208 pub fn connect(addr
: &SocketAddr
) -> io
::Result
<TcpStream
> {
211 let sock
= Socket
::new(addr
, c
::SOCK_STREAM
)?
;
213 let (addrp
, len
) = addr
.into_inner();
214 cvt_r(|| unsafe { c::connect(*sock.as_inner(), addrp, len) }
)?
;
215 Ok(TcpStream { inner: sock }
)
218 pub fn socket(&self) -> &Socket { &self.inner }
220 pub fn into_socket(self) -> Socket { self.inner }
222 pub fn set_read_timeout(&self, dur
: Option
<Duration
>) -> io
::Result
<()> {
223 self.inner
.set_timeout(dur
, c
::SO_RCVTIMEO
)
226 pub fn set_write_timeout(&self, dur
: Option
<Duration
>) -> io
::Result
<()> {
227 self.inner
.set_timeout(dur
, c
::SO_SNDTIMEO
)
230 pub fn read_timeout(&self) -> io
::Result
<Option
<Duration
>> {
231 self.inner
.timeout(c
::SO_RCVTIMEO
)
234 pub fn write_timeout(&self) -> io
::Result
<Option
<Duration
>> {
235 self.inner
.timeout(c
::SO_SNDTIMEO
)
238 pub fn peek(&self, buf
: &mut [u8]) -> io
::Result
<usize> {
242 pub fn read(&self, buf
: &mut [u8]) -> io
::Result
<usize> {
246 pub fn read_to_end(&self, buf
: &mut Vec
<u8>) -> io
::Result
<usize> {
247 self.inner
.read_to_end(buf
)
250 pub fn write(&self, buf
: &[u8]) -> io
::Result
<usize> {
251 let len
= cmp
::min(buf
.len(), <wrlen_t
>::max_value() as usize) as wrlen_t
;
252 let ret
= cvt(unsafe {
253 c
::send(*self.inner
.as_inner(),
254 buf
.as_ptr() as *const c_void
,
261 pub fn peer_addr(&self) -> io
::Result
<SocketAddr
> {
262 sockname(|buf
, len
| unsafe {
263 c
::getpeername(*self.inner
.as_inner(), buf
, len
)
267 pub fn socket_addr(&self) -> io
::Result
<SocketAddr
> {
268 sockname(|buf
, len
| unsafe {
269 c
::getsockname(*self.inner
.as_inner(), buf
, len
)
273 pub fn shutdown(&self, how
: Shutdown
) -> io
::Result
<()> {
274 self.inner
.shutdown(how
)
277 pub fn duplicate(&self) -> io
::Result
<TcpStream
> {
278 self.inner
.duplicate().map(|s
| TcpStream { inner: s }
)
281 pub fn set_nodelay(&self, nodelay
: bool
) -> io
::Result
<()> {
282 self.inner
.set_nodelay(nodelay
)
285 pub fn nodelay(&self) -> io
::Result
<bool
> {
289 pub fn set_ttl(&self, ttl
: u32) -> io
::Result
<()> {
290 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_TTL
, ttl
as c_int
)
293 pub fn ttl(&self) -> io
::Result
<u32> {
294 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_TTL
)?
;
298 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
299 self.inner
.take_error()
302 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
303 self.inner
.set_nonblocking(nonblocking
)
307 impl FromInner
<Socket
> for TcpStream
{
308 fn from_inner(socket
: Socket
) -> TcpStream
{
309 TcpStream { inner: socket }
313 impl fmt
::Debug
for TcpStream
{
314 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
315 let mut res
= f
.debug_struct("TcpStream");
317 if let Ok(addr
) = self.socket_addr() {
318 res
.field("addr", &addr
);
321 if let Ok(peer
) = self.peer_addr() {
322 res
.field("peer", &peer
);
325 let name
= if cfg
!(windows
) {"socket"}
else {"fd"}
;
326 res
.field(name
, &self.inner
.as_inner())
331 ////////////////////////////////////////////////////////////////////////////////
333 ////////////////////////////////////////////////////////////////////////////////
335 pub struct TcpListener
{
340 pub fn bind(addr
: &SocketAddr
) -> io
::Result
<TcpListener
> {
343 let sock
= Socket
::new(addr
, c
::SOCK_STREAM
)?
;
345 // On platforms with Berkeley-derived sockets, this allows
346 // to quickly rebind a socket, without needing to wait for
347 // the OS to clean up the previous one.
349 setsockopt(&sock
, c
::SOL_SOCKET
, c
::SO_REUSEADDR
,
353 // Bind our new socket
354 let (addrp
, len
) = addr
.into_inner();
355 cvt(unsafe { c::bind(*sock.as_inner(), addrp, len as _) }
)?
;
358 cvt(unsafe { c::listen(*sock.as_inner(), 128) }
)?
;
359 Ok(TcpListener { inner: sock }
)
362 pub fn socket(&self) -> &Socket { &self.inner }
364 pub fn into_socket(self) -> Socket { self.inner }
366 pub fn socket_addr(&self) -> io
::Result
<SocketAddr
> {
367 sockname(|buf
, len
| unsafe {
368 c
::getsockname(*self.inner
.as_inner(), buf
, len
)
372 pub fn accept(&self) -> io
::Result
<(TcpStream
, SocketAddr
)> {
373 let mut storage
: c
::sockaddr_storage
= unsafe { mem::zeroed() }
;
374 let mut len
= mem
::size_of_val(&storage
) as c
::socklen_t
;
375 let sock
= self.inner
.accept(&mut storage
as *mut _
as *mut _
,
377 let addr
= sockaddr_to_addr(&storage
, len
as usize)?
;
378 Ok((TcpStream { inner: sock, }
, addr
))
381 pub fn duplicate(&self) -> io
::Result
<TcpListener
> {
382 self.inner
.duplicate().map(|s
| TcpListener { inner: s }
)
385 pub fn set_ttl(&self, ttl
: u32) -> io
::Result
<()> {
386 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_TTL
, ttl
as c_int
)
389 pub fn ttl(&self) -> io
::Result
<u32> {
390 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_TTL
)?
;
394 pub fn set_only_v6(&self, only_v6
: bool
) -> io
::Result
<()> {
395 setsockopt(&self.inner
, c
::IPPROTO_IPV6
, c
::IPV6_V6ONLY
, only_v6
as c_int
)
398 pub fn only_v6(&self) -> io
::Result
<bool
> {
399 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IPV6
, c
::IPV6_V6ONLY
)?
;
403 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
404 self.inner
.take_error()
407 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
408 self.inner
.set_nonblocking(nonblocking
)
412 impl FromInner
<Socket
> for TcpListener
{
413 fn from_inner(socket
: Socket
) -> TcpListener
{
414 TcpListener { inner: socket }
418 impl fmt
::Debug
for TcpListener
{
419 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
420 let mut res
= f
.debug_struct("TcpListener");
422 if let Ok(addr
) = self.socket_addr() {
423 res
.field("addr", &addr
);
426 let name
= if cfg
!(windows
) {"socket"}
else {"fd"}
;
427 res
.field(name
, &self.inner
.as_inner())
432 ////////////////////////////////////////////////////////////////////////////////
434 ////////////////////////////////////////////////////////////////////////////////
436 pub struct UdpSocket
{
441 pub fn bind(addr
: &SocketAddr
) -> io
::Result
<UdpSocket
> {
444 let sock
= Socket
::new(addr
, c
::SOCK_DGRAM
)?
;
445 let (addrp
, len
) = addr
.into_inner();
446 cvt(unsafe { c::bind(*sock.as_inner(), addrp, len as _) }
)?
;
447 Ok(UdpSocket { inner: sock }
)
450 pub fn socket(&self) -> &Socket { &self.inner }
452 pub fn into_socket(self) -> Socket { self.inner }
454 pub fn socket_addr(&self) -> io
::Result
<SocketAddr
> {
455 sockname(|buf
, len
| unsafe {
456 c
::getsockname(*self.inner
.as_inner(), buf
, len
)
460 pub fn recv_from(&self, buf
: &mut [u8]) -> io
::Result
<(usize, SocketAddr
)> {
461 self.inner
.recv_from(buf
)
464 pub fn peek_from(&self, buf
: &mut [u8]) -> io
::Result
<(usize, SocketAddr
)> {
465 self.inner
.peek_from(buf
)
468 pub fn send_to(&self, buf
: &[u8], dst
: &SocketAddr
) -> io
::Result
<usize> {
469 let len
= cmp
::min(buf
.len(), <wrlen_t
>::max_value() as usize) as wrlen_t
;
470 let (dstp
, dstlen
) = dst
.into_inner();
471 let ret
= cvt(unsafe {
472 c
::sendto(*self.inner
.as_inner(),
473 buf
.as_ptr() as *const c_void
, len
,
474 MSG_NOSIGNAL
, dstp
, dstlen
)
479 pub fn duplicate(&self) -> io
::Result
<UdpSocket
> {
480 self.inner
.duplicate().map(|s
| UdpSocket { inner: s }
)
483 pub fn set_read_timeout(&self, dur
: Option
<Duration
>) -> io
::Result
<()> {
484 self.inner
.set_timeout(dur
, c
::SO_RCVTIMEO
)
487 pub fn set_write_timeout(&self, dur
: Option
<Duration
>) -> io
::Result
<()> {
488 self.inner
.set_timeout(dur
, c
::SO_SNDTIMEO
)
491 pub fn read_timeout(&self) -> io
::Result
<Option
<Duration
>> {
492 self.inner
.timeout(c
::SO_RCVTIMEO
)
495 pub fn write_timeout(&self) -> io
::Result
<Option
<Duration
>> {
496 self.inner
.timeout(c
::SO_SNDTIMEO
)
499 pub fn set_broadcast(&self, broadcast
: bool
) -> io
::Result
<()> {
500 setsockopt(&self.inner
, c
::SOL_SOCKET
, c
::SO_BROADCAST
, broadcast
as c_int
)
503 pub fn broadcast(&self) -> io
::Result
<bool
> {
504 let raw
: c_int
= getsockopt(&self.inner
, c
::SOL_SOCKET
, c
::SO_BROADCAST
)?
;
508 pub fn set_multicast_loop_v4(&self, multicast_loop_v4
: bool
) -> io
::Result
<()> {
509 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_MULTICAST_LOOP
, multicast_loop_v4
as c_int
)
512 pub fn multicast_loop_v4(&self) -> io
::Result
<bool
> {
513 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_MULTICAST_LOOP
)?
;
517 pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4
: u32) -> io
::Result
<()> {
518 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_MULTICAST_TTL
, multicast_ttl_v4
as c_int
)
521 pub fn multicast_ttl_v4(&self) -> io
::Result
<u32> {
522 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_MULTICAST_TTL
)?
;
526 pub fn set_multicast_loop_v6(&self, multicast_loop_v6
: bool
) -> io
::Result
<()> {
527 setsockopt(&self.inner
, c
::IPPROTO_IPV6
, c
::IPV6_MULTICAST_LOOP
, multicast_loop_v6
as c_int
)
530 pub fn multicast_loop_v6(&self) -> io
::Result
<bool
> {
531 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IPV6
, c
::IPV6_MULTICAST_LOOP
)?
;
535 pub fn join_multicast_v4(&self, multiaddr
: &Ipv4Addr
, interface
: &Ipv4Addr
)
537 let mreq
= c
::ip_mreq
{
538 imr_multiaddr
: *multiaddr
.as_inner(),
539 imr_interface
: *interface
.as_inner(),
541 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_ADD_MEMBERSHIP
, mreq
)
544 pub fn join_multicast_v6(&self, multiaddr
: &Ipv6Addr
, interface
: u32)
546 let mreq
= c
::ipv6_mreq
{
547 ipv6mr_multiaddr
: *multiaddr
.as_inner(),
548 ipv6mr_interface
: to_ipv6mr_interface(interface
),
550 setsockopt(&self.inner
, c
::IPPROTO_IPV6
, IPV6_ADD_MEMBERSHIP
, mreq
)
553 pub fn leave_multicast_v4(&self, multiaddr
: &Ipv4Addr
, interface
: &Ipv4Addr
)
555 let mreq
= c
::ip_mreq
{
556 imr_multiaddr
: *multiaddr
.as_inner(),
557 imr_interface
: *interface
.as_inner(),
559 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_DROP_MEMBERSHIP
, mreq
)
562 pub fn leave_multicast_v6(&self, multiaddr
: &Ipv6Addr
, interface
: u32)
564 let mreq
= c
::ipv6_mreq
{
565 ipv6mr_multiaddr
: *multiaddr
.as_inner(),
566 ipv6mr_interface
: to_ipv6mr_interface(interface
),
568 setsockopt(&self.inner
, c
::IPPROTO_IPV6
, IPV6_DROP_MEMBERSHIP
, mreq
)
571 pub fn set_ttl(&self, ttl
: u32) -> io
::Result
<()> {
572 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_TTL
, ttl
as c_int
)
575 pub fn ttl(&self) -> io
::Result
<u32> {
576 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_TTL
)?
;
580 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
581 self.inner
.take_error()
584 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
585 self.inner
.set_nonblocking(nonblocking
)
588 pub fn recv(&self, buf
: &mut [u8]) -> io
::Result
<usize> {
592 pub fn peek(&self, buf
: &mut [u8]) -> io
::Result
<usize> {
596 pub fn send(&self, buf
: &[u8]) -> io
::Result
<usize> {
597 let len
= cmp
::min(buf
.len(), <wrlen_t
>::max_value() as usize) as wrlen_t
;
598 let ret
= cvt(unsafe {
599 c
::send(*self.inner
.as_inner(),
600 buf
.as_ptr() as *const c_void
,
607 pub fn connect(&self, addr
: &SocketAddr
) -> io
::Result
<()> {
608 let (addrp
, len
) = addr
.into_inner();
609 cvt_r(|| unsafe { c::connect(*self.inner.as_inner(), addrp, len) }
).map(|_
| ())
613 impl FromInner
<Socket
> for UdpSocket
{
614 fn from_inner(socket
: Socket
) -> UdpSocket
{
615 UdpSocket { inner: socket }
619 impl fmt
::Debug
for UdpSocket
{
620 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
621 let mut res
= f
.debug_struct("UdpSocket");
623 if let Ok(addr
) = self.socket_addr() {
624 res
.field("addr", &addr
);
627 let name
= if cfg
!(windows
) {"socket"}
else {"fd"}
;
628 res
.field(name
, &self.inner
.as_inner())
636 use collections
::HashMap
;
639 fn no_lookup_host_duplicates() {
640 let mut addrs
= HashMap
::new();
641 let lh
= match lookup_host("localhost") {
643 Err(e
) => panic
!("couldn't resolve `localhost': {}", e
)
645 let _na
= lh
.map(|sa
| *addrs
.entry(sa
).or_insert(0) += 1).count();
646 assert
!(addrs
.values().filter(|&&v
| v
> 1).count() == 0);