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 cvt_gai(c
::getaddrinfo(c_host
.as_ptr(), ptr
::null(), &hints
,
182 Ok(LookupHost { original: res, cur: res }
)
186 ////////////////////////////////////////////////////////////////////////////////
188 ////////////////////////////////////////////////////////////////////////////////
190 pub struct TcpStream
{
195 pub fn connect(addr
: &SocketAddr
) -> io
::Result
<TcpStream
> {
198 let sock
= Socket
::new(addr
, c
::SOCK_STREAM
)?
;
200 let (addrp
, len
) = addr
.into_inner();
201 cvt_r(|| unsafe { c::connect(*sock.as_inner(), addrp, len) }
)?
;
202 Ok(TcpStream { inner: sock }
)
205 pub fn socket(&self) -> &Socket { &self.inner }
207 pub fn into_socket(self) -> Socket { self.inner }
209 pub fn set_read_timeout(&self, dur
: Option
<Duration
>) -> io
::Result
<()> {
210 self.inner
.set_timeout(dur
, c
::SO_RCVTIMEO
)
213 pub fn set_write_timeout(&self, dur
: Option
<Duration
>) -> io
::Result
<()> {
214 self.inner
.set_timeout(dur
, c
::SO_SNDTIMEO
)
217 pub fn read_timeout(&self) -> io
::Result
<Option
<Duration
>> {
218 self.inner
.timeout(c
::SO_RCVTIMEO
)
221 pub fn write_timeout(&self) -> io
::Result
<Option
<Duration
>> {
222 self.inner
.timeout(c
::SO_SNDTIMEO
)
225 pub fn peek(&self, buf
: &mut [u8]) -> io
::Result
<usize> {
229 pub fn read(&self, buf
: &mut [u8]) -> io
::Result
<usize> {
233 pub fn read_to_end(&self, buf
: &mut Vec
<u8>) -> io
::Result
<usize> {
234 self.inner
.read_to_end(buf
)
237 pub fn write(&self, buf
: &[u8]) -> io
::Result
<usize> {
238 let len
= cmp
::min(buf
.len(), <wrlen_t
>::max_value() as usize) as wrlen_t
;
239 let ret
= cvt(unsafe {
240 c
::send(*self.inner
.as_inner(),
241 buf
.as_ptr() as *const c_void
,
248 pub fn peer_addr(&self) -> io
::Result
<SocketAddr
> {
249 sockname(|buf
, len
| unsafe {
250 c
::getpeername(*self.inner
.as_inner(), buf
, len
)
254 pub fn socket_addr(&self) -> io
::Result
<SocketAddr
> {
255 sockname(|buf
, len
| unsafe {
256 c
::getsockname(*self.inner
.as_inner(), buf
, len
)
260 pub fn shutdown(&self, how
: Shutdown
) -> io
::Result
<()> {
261 self.inner
.shutdown(how
)
264 pub fn duplicate(&self) -> io
::Result
<TcpStream
> {
265 self.inner
.duplicate().map(|s
| TcpStream { inner: s }
)
268 pub fn set_nodelay(&self, nodelay
: bool
) -> io
::Result
<()> {
269 self.inner
.set_nodelay(nodelay
)
272 pub fn nodelay(&self) -> io
::Result
<bool
> {
276 pub fn set_ttl(&self, ttl
: u32) -> io
::Result
<()> {
277 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_TTL
, ttl
as c_int
)
280 pub fn ttl(&self) -> io
::Result
<u32> {
281 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_TTL
)?
;
285 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
286 self.inner
.take_error()
289 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
290 self.inner
.set_nonblocking(nonblocking
)
294 impl FromInner
<Socket
> for TcpStream
{
295 fn from_inner(socket
: Socket
) -> TcpStream
{
296 TcpStream { inner: socket }
300 impl fmt
::Debug
for TcpStream
{
301 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
302 let mut res
= f
.debug_struct("TcpStream");
304 if let Ok(addr
) = self.socket_addr() {
305 res
.field("addr", &addr
);
308 if let Ok(peer
) = self.peer_addr() {
309 res
.field("peer", &peer
);
312 let name
= if cfg
!(windows
) {"socket"}
else {"fd"}
;
313 res
.field(name
, &self.inner
.as_inner())
318 ////////////////////////////////////////////////////////////////////////////////
320 ////////////////////////////////////////////////////////////////////////////////
322 pub struct TcpListener
{
327 pub fn bind(addr
: &SocketAddr
) -> io
::Result
<TcpListener
> {
330 let sock
= Socket
::new(addr
, c
::SOCK_STREAM
)?
;
332 // On platforms with Berkeley-derived sockets, this allows
333 // to quickly rebind a socket, without needing to wait for
334 // the OS to clean up the previous one.
336 setsockopt(&sock
, c
::SOL_SOCKET
, c
::SO_REUSEADDR
,
340 // Bind our new socket
341 let (addrp
, len
) = addr
.into_inner();
342 cvt(unsafe { c::bind(*sock.as_inner(), addrp, len) }
)?
;
345 cvt(unsafe { c::listen(*sock.as_inner(), 128) }
)?
;
346 Ok(TcpListener { inner: sock }
)
349 pub fn socket(&self) -> &Socket { &self.inner }
351 pub fn into_socket(self) -> Socket { self.inner }
353 pub fn socket_addr(&self) -> io
::Result
<SocketAddr
> {
354 sockname(|buf
, len
| unsafe {
355 c
::getsockname(*self.inner
.as_inner(), buf
, len
)
359 pub fn accept(&self) -> io
::Result
<(TcpStream
, SocketAddr
)> {
360 let mut storage
: c
::sockaddr_storage
= unsafe { mem::zeroed() }
;
361 let mut len
= mem
::size_of_val(&storage
) as c
::socklen_t
;
362 let sock
= self.inner
.accept(&mut storage
as *mut _
as *mut _
,
364 let addr
= sockaddr_to_addr(&storage
, len
as usize)?
;
365 Ok((TcpStream { inner: sock, }
, addr
))
368 pub fn duplicate(&self) -> io
::Result
<TcpListener
> {
369 self.inner
.duplicate().map(|s
| TcpListener { inner: s }
)
372 pub fn set_ttl(&self, ttl
: u32) -> io
::Result
<()> {
373 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_TTL
, ttl
as c_int
)
376 pub fn ttl(&self) -> io
::Result
<u32> {
377 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_TTL
)?
;
381 pub fn set_only_v6(&self, only_v6
: bool
) -> io
::Result
<()> {
382 setsockopt(&self.inner
, c
::IPPROTO_IPV6
, c
::IPV6_V6ONLY
, only_v6
as c_int
)
385 pub fn only_v6(&self) -> io
::Result
<bool
> {
386 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IPV6
, c
::IPV6_V6ONLY
)?
;
390 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
391 self.inner
.take_error()
394 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
395 self.inner
.set_nonblocking(nonblocking
)
399 impl FromInner
<Socket
> for TcpListener
{
400 fn from_inner(socket
: Socket
) -> TcpListener
{
401 TcpListener { inner: socket }
405 impl fmt
::Debug
for TcpListener
{
406 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
407 let mut res
= f
.debug_struct("TcpListener");
409 if let Ok(addr
) = self.socket_addr() {
410 res
.field("addr", &addr
);
413 let name
= if cfg
!(windows
) {"socket"}
else {"fd"}
;
414 res
.field(name
, &self.inner
.as_inner())
419 ////////////////////////////////////////////////////////////////////////////////
421 ////////////////////////////////////////////////////////////////////////////////
423 pub struct UdpSocket
{
428 pub fn bind(addr
: &SocketAddr
) -> io
::Result
<UdpSocket
> {
431 let sock
= Socket
::new(addr
, c
::SOCK_DGRAM
)?
;
432 let (addrp
, len
) = addr
.into_inner();
433 cvt(unsafe { c::bind(*sock.as_inner(), addrp, len) }
)?
;
434 Ok(UdpSocket { inner: sock }
)
437 pub fn socket(&self) -> &Socket { &self.inner }
439 pub fn into_socket(self) -> Socket { self.inner }
441 pub fn socket_addr(&self) -> io
::Result
<SocketAddr
> {
442 sockname(|buf
, len
| unsafe {
443 c
::getsockname(*self.inner
.as_inner(), buf
, len
)
447 pub fn recv_from(&self, buf
: &mut [u8]) -> io
::Result
<(usize, SocketAddr
)> {
448 self.inner
.recv_from(buf
)
451 pub fn peek_from(&self, buf
: &mut [u8]) -> io
::Result
<(usize, SocketAddr
)> {
452 self.inner
.peek_from(buf
)
455 pub fn send_to(&self, buf
: &[u8], dst
: &SocketAddr
) -> io
::Result
<usize> {
456 let len
= cmp
::min(buf
.len(), <wrlen_t
>::max_value() as usize) as wrlen_t
;
457 let (dstp
, dstlen
) = dst
.into_inner();
458 let ret
= cvt(unsafe {
459 c
::sendto(*self.inner
.as_inner(),
460 buf
.as_ptr() as *const c_void
, len
,
461 MSG_NOSIGNAL
, dstp
, dstlen
)
466 pub fn duplicate(&self) -> io
::Result
<UdpSocket
> {
467 self.inner
.duplicate().map(|s
| UdpSocket { inner: s }
)
470 pub fn set_read_timeout(&self, dur
: Option
<Duration
>) -> io
::Result
<()> {
471 self.inner
.set_timeout(dur
, c
::SO_RCVTIMEO
)
474 pub fn set_write_timeout(&self, dur
: Option
<Duration
>) -> io
::Result
<()> {
475 self.inner
.set_timeout(dur
, c
::SO_SNDTIMEO
)
478 pub fn read_timeout(&self) -> io
::Result
<Option
<Duration
>> {
479 self.inner
.timeout(c
::SO_RCVTIMEO
)
482 pub fn write_timeout(&self) -> io
::Result
<Option
<Duration
>> {
483 self.inner
.timeout(c
::SO_SNDTIMEO
)
486 pub fn set_broadcast(&self, broadcast
: bool
) -> io
::Result
<()> {
487 setsockopt(&self.inner
, c
::SOL_SOCKET
, c
::SO_BROADCAST
, broadcast
as c_int
)
490 pub fn broadcast(&self) -> io
::Result
<bool
> {
491 let raw
: c_int
= getsockopt(&self.inner
, c
::SOL_SOCKET
, c
::SO_BROADCAST
)?
;
495 pub fn set_multicast_loop_v4(&self, multicast_loop_v4
: bool
) -> io
::Result
<()> {
496 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_MULTICAST_LOOP
, multicast_loop_v4
as c_int
)
499 pub fn multicast_loop_v4(&self) -> io
::Result
<bool
> {
500 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_MULTICAST_LOOP
)?
;
504 pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4
: u32) -> io
::Result
<()> {
505 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_MULTICAST_TTL
, multicast_ttl_v4
as c_int
)
508 pub fn multicast_ttl_v4(&self) -> io
::Result
<u32> {
509 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_MULTICAST_TTL
)?
;
513 pub fn set_multicast_loop_v6(&self, multicast_loop_v6
: bool
) -> io
::Result
<()> {
514 setsockopt(&self.inner
, c
::IPPROTO_IPV6
, c
::IPV6_MULTICAST_LOOP
, multicast_loop_v6
as c_int
)
517 pub fn multicast_loop_v6(&self) -> io
::Result
<bool
> {
518 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IPV6
, c
::IPV6_MULTICAST_LOOP
)?
;
522 pub fn join_multicast_v4(&self, multiaddr
: &Ipv4Addr
, interface
: &Ipv4Addr
)
524 let mreq
= c
::ip_mreq
{
525 imr_multiaddr
: *multiaddr
.as_inner(),
526 imr_interface
: *interface
.as_inner(),
528 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_ADD_MEMBERSHIP
, mreq
)
531 pub fn join_multicast_v6(&self, multiaddr
: &Ipv6Addr
, interface
: u32)
533 let mreq
= c
::ipv6_mreq
{
534 ipv6mr_multiaddr
: *multiaddr
.as_inner(),
535 ipv6mr_interface
: to_ipv6mr_interface(interface
),
537 setsockopt(&self.inner
, c
::IPPROTO_IPV6
, IPV6_ADD_MEMBERSHIP
, mreq
)
540 pub fn leave_multicast_v4(&self, multiaddr
: &Ipv4Addr
, interface
: &Ipv4Addr
)
542 let mreq
= c
::ip_mreq
{
543 imr_multiaddr
: *multiaddr
.as_inner(),
544 imr_interface
: *interface
.as_inner(),
546 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_DROP_MEMBERSHIP
, mreq
)
549 pub fn leave_multicast_v6(&self, multiaddr
: &Ipv6Addr
, interface
: u32)
551 let mreq
= c
::ipv6_mreq
{
552 ipv6mr_multiaddr
: *multiaddr
.as_inner(),
553 ipv6mr_interface
: to_ipv6mr_interface(interface
),
555 setsockopt(&self.inner
, c
::IPPROTO_IPV6
, IPV6_DROP_MEMBERSHIP
, mreq
)
558 pub fn set_ttl(&self, ttl
: u32) -> io
::Result
<()> {
559 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_TTL
, ttl
as c_int
)
562 pub fn ttl(&self) -> io
::Result
<u32> {
563 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_TTL
)?
;
567 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
568 self.inner
.take_error()
571 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
572 self.inner
.set_nonblocking(nonblocking
)
575 pub fn recv(&self, buf
: &mut [u8]) -> io
::Result
<usize> {
579 pub fn peek(&self, buf
: &mut [u8]) -> io
::Result
<usize> {
583 pub fn send(&self, buf
: &[u8]) -> io
::Result
<usize> {
584 let len
= cmp
::min(buf
.len(), <wrlen_t
>::max_value() as usize) as wrlen_t
;
585 let ret
= cvt(unsafe {
586 c
::send(*self.inner
.as_inner(),
587 buf
.as_ptr() as *const c_void
,
594 pub fn connect(&self, addr
: &SocketAddr
) -> io
::Result
<()> {
595 let (addrp
, len
) = addr
.into_inner();
596 cvt_r(|| unsafe { c::connect(*self.inner.as_inner(), addrp, len) }
).map(|_
| ())
600 impl FromInner
<Socket
> for UdpSocket
{
601 fn from_inner(socket
: Socket
) -> UdpSocket
{
602 UdpSocket { inner: socket }
606 impl fmt
::Debug
for UdpSocket
{
607 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
608 let mut res
= f
.debug_struct("UdpSocket");
610 if let Ok(addr
) = self.socket_addr() {
611 res
.field("addr", &addr
);
614 let name
= if cfg
!(windows
) {"socket"}
else {"fd"}
;
615 res
.field(name
, &self.inner
.as_inner())
623 use collections
::HashMap
;
626 fn no_lookup_host_duplicates() {
627 let mut addrs
= HashMap
::new();
628 let lh
= match lookup_host("localhost") {
630 Err(e
) => panic
!("couldn't resolve `localhost': {}", e
)
632 let _na
= lh
.map(|sa
| *addrs
.entry(sa
).or_insert(0) += 1).count();
633 assert
!(addrs
.values().filter(|&&v
| v
> 1).count() == 0);