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.
16 use io
::{self, Error, ErrorKind}
;
17 use libc
::{c_int, c_void}
;
19 use net
::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr}
;
21 use sys
::net
::{cvt, cvt_r, cvt_gai, Socket, init, wrlen_t}
;
22 use sys
::net
::netc
as c
;
23 use sys_common
::{AsInner, FromInner, IntoInner}
;
26 #[cfg(any(target_os = "dragonfly", target_os = "freebsd",
27 target_os
= "ios", target_os
= "macos",
28 target_os
= "openbsd", target_os
= "netbsd"))]
29 use sys
::net
::netc
::IPV6_JOIN_GROUP
as IPV6_ADD_MEMBERSHIP
;
30 #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd",
31 target_os
= "ios", target_os
= "macos",
32 target_os
= "openbsd", target_os
= "netbsd")))]
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 use sys
::net
::netc
::IPV6_LEAVE_GROUP
as IPV6_DROP_MEMBERSHIP
;
38 #[cfg(not(any(target_os = "dragonfly", target_os = "freebsd",
39 target_os
= "ios", target_os
= "macos",
40 target_os
= "openbsd", target_os
= "netbsd")))]
41 use sys
::net
::netc
::IPV6_DROP_MEMBERSHIP
;
43 ////////////////////////////////////////////////////////////////////////////////
44 // sockaddr and misc bindings
45 ////////////////////////////////////////////////////////////////////////////////
47 pub fn setsockopt
<T
>(sock
: &Socket
, opt
: c_int
, val
: c_int
,
48 payload
: T
) -> io
::Result
<()> {
50 let payload
= &payload
as *const T
as *const c_void
;
51 cvt(c
::setsockopt(*sock
.as_inner(), opt
, val
, payload
,
52 mem
::size_of
::<T
>() as c
::socklen_t
))?
;
57 pub fn getsockopt
<T
: Copy
>(sock
: &Socket
, opt
: c_int
,
58 val
: c_int
) -> io
::Result
<T
> {
60 let mut slot
: T
= mem
::zeroed();
61 let mut len
= mem
::size_of
::<T
>() as c
::socklen_t
;
62 cvt(c
::getsockopt(*sock
.as_inner(), opt
, val
,
63 &mut slot
as *mut _
as *mut _
,
65 assert_eq
!(len
as usize, mem
::size_of
::<T
>());
70 fn sockname
<F
>(f
: F
) -> io
::Result
<SocketAddr
>
71 where F
: FnOnce(*mut c
::sockaddr
, *mut c
::socklen_t
) -> c_int
74 let mut storage
: c
::sockaddr_storage
= mem
::zeroed();
75 let mut len
= mem
::size_of_val(&storage
) as c
::socklen_t
;
76 cvt(f(&mut storage
as *mut _
as *mut _
, &mut len
))?
;
77 sockaddr_to_addr(&storage
, len
as usize)
81 fn sockaddr_to_addr(storage
: &c
::sockaddr_storage
,
82 len
: usize) -> io
::Result
<SocketAddr
> {
83 match storage
.ss_family
as c_int
{
85 assert
!(len
as usize >= mem
::size_of
::<c
::sockaddr_in
>());
86 Ok(SocketAddr
::V4(FromInner
::from_inner(unsafe {
87 *(storage
as *const _
as *const c
::sockaddr_in
)
91 assert
!(len
as usize >= mem
::size_of
::<c
::sockaddr_in6
>());
92 Ok(SocketAddr
::V6(FromInner
::from_inner(unsafe {
93 *(storage
as *const _
as *const c
::sockaddr_in6
)
97 Err(Error
::new(ErrorKind
::InvalidInput
, "invalid argument"))
102 #[cfg(target_os = "android")]
103 fn to_ipv6mr_interface(value
: u32) -> c_int
{
107 #[cfg(not(target_os = "android"))]
108 fn to_ipv6mr_interface(value
: u32) -> ::libc
::c_uint
{
109 value
as ::libc
::c_uint
112 ////////////////////////////////////////////////////////////////////////////////
113 // get_host_addresses
114 ////////////////////////////////////////////////////////////////////////////////
116 pub struct LookupHost
{
117 original
: *mut c
::addrinfo
,
118 cur
: *mut c
::addrinfo
,
121 impl Iterator
for LookupHost
{
122 type Item
= io
::Result
<SocketAddr
>;
123 fn next(&mut self) -> Option
<io
::Result
<SocketAddr
>> {
125 if self.cur
.is_null() { return None }
126 let ret
= sockaddr_to_addr(mem
::transmute((*self.cur
).ai_addr
),
127 (*self.cur
).ai_addrlen
as usize);
128 self.cur
= (*self.cur
).ai_next
as *mut c
::addrinfo
;
134 unsafe impl Sync
for LookupHost {}
135 unsafe impl Send
for LookupHost {}
137 impl Drop
for LookupHost
{
139 unsafe { c::freeaddrinfo(self.original) }
143 pub fn lookup_host(host
: &str) -> io
::Result
<LookupHost
> {
146 let c_host
= CString
::new(host
)?
;
147 let mut res
= ptr
::null_mut();
149 cvt_gai(c
::getaddrinfo(c_host
.as_ptr(), ptr
::null(), ptr
::null(),
151 Ok(LookupHost { original: res, cur: res }
)
155 ////////////////////////////////////////////////////////////////////////////////
157 ////////////////////////////////////////////////////////////////////////////////
159 pub struct TcpStream
{
164 pub fn connect(addr
: &SocketAddr
) -> io
::Result
<TcpStream
> {
167 let sock
= Socket
::new(addr
, c
::SOCK_STREAM
)?
;
169 let (addrp
, len
) = addr
.into_inner();
170 cvt_r(|| unsafe { c::connect(*sock.as_inner(), addrp, len) }
)?
;
171 Ok(TcpStream { inner: sock }
)
174 pub fn socket(&self) -> &Socket { &self.inner }
176 pub fn into_socket(self) -> Socket { self.inner }
178 pub fn set_read_timeout(&self, dur
: Option
<Duration
>) -> io
::Result
<()> {
179 self.inner
.set_timeout(dur
, c
::SO_RCVTIMEO
)
182 pub fn set_write_timeout(&self, dur
: Option
<Duration
>) -> io
::Result
<()> {
183 self.inner
.set_timeout(dur
, c
::SO_SNDTIMEO
)
186 pub fn read_timeout(&self) -> io
::Result
<Option
<Duration
>> {
187 self.inner
.timeout(c
::SO_RCVTIMEO
)
190 pub fn write_timeout(&self) -> io
::Result
<Option
<Duration
>> {
191 self.inner
.timeout(c
::SO_SNDTIMEO
)
194 pub fn read(&self, buf
: &mut [u8]) -> io
::Result
<usize> {
198 pub fn read_to_end(&self, buf
: &mut Vec
<u8>) -> io
::Result
<usize> {
199 self.inner
.read_to_end(buf
)
202 pub fn write(&self, buf
: &[u8]) -> io
::Result
<usize> {
203 let len
= cmp
::min(buf
.len(), <wrlen_t
>::max_value() as usize) as wrlen_t
;
204 let ret
= cvt(unsafe {
205 c
::send(*self.inner
.as_inner(),
206 buf
.as_ptr() as *const c_void
,
213 pub fn peer_addr(&self) -> io
::Result
<SocketAddr
> {
214 sockname(|buf
, len
| unsafe {
215 c
::getpeername(*self.inner
.as_inner(), buf
, len
)
219 pub fn socket_addr(&self) -> io
::Result
<SocketAddr
> {
220 sockname(|buf
, len
| unsafe {
221 c
::getsockname(*self.inner
.as_inner(), buf
, len
)
225 pub fn shutdown(&self, how
: Shutdown
) -> io
::Result
<()> {
226 self.inner
.shutdown(how
)
229 pub fn duplicate(&self) -> io
::Result
<TcpStream
> {
230 self.inner
.duplicate().map(|s
| TcpStream { inner: s }
)
233 pub fn set_nodelay(&self, nodelay
: bool
) -> io
::Result
<()> {
234 self.inner
.set_nodelay(nodelay
)
237 pub fn nodelay(&self) -> io
::Result
<bool
> {
241 pub fn set_ttl(&self, ttl
: u32) -> io
::Result
<()> {
242 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_TTL
, ttl
as c_int
)
245 pub fn ttl(&self) -> io
::Result
<u32> {
246 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_TTL
)?
;
250 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
251 self.inner
.take_error()
254 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
255 self.inner
.set_nonblocking(nonblocking
)
259 impl FromInner
<Socket
> for TcpStream
{
260 fn from_inner(socket
: Socket
) -> TcpStream
{
261 TcpStream { inner: socket }
265 impl fmt
::Debug
for TcpStream
{
266 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
267 let mut res
= f
.debug_struct("TcpStream");
269 if let Ok(addr
) = self.socket_addr() {
270 res
.field("addr", &addr
);
273 if let Ok(peer
) = self.peer_addr() {
274 res
.field("peer", &peer
);
277 let name
= if cfg
!(windows
) {"socket"}
else {"fd"}
;
278 res
.field(name
, &self.inner
.as_inner())
283 ////////////////////////////////////////////////////////////////////////////////
285 ////////////////////////////////////////////////////////////////////////////////
287 pub struct TcpListener
{
292 pub fn bind(addr
: &SocketAddr
) -> io
::Result
<TcpListener
> {
295 let sock
= Socket
::new(addr
, c
::SOCK_STREAM
)?
;
297 // On platforms with Berkeley-derived sockets, this allows
298 // to quickly rebind a socket, without needing to wait for
299 // the OS to clean up the previous one.
301 setsockopt(&sock
, c
::SOL_SOCKET
, c
::SO_REUSEADDR
,
305 // Bind our new socket
306 let (addrp
, len
) = addr
.into_inner();
307 cvt(unsafe { c::bind(*sock.as_inner(), addrp, len) }
)?
;
310 cvt(unsafe { c::listen(*sock.as_inner(), 128) }
)?
;
311 Ok(TcpListener { inner: sock }
)
314 pub fn socket(&self) -> &Socket { &self.inner }
316 pub fn into_socket(self) -> Socket { self.inner }
318 pub fn socket_addr(&self) -> io
::Result
<SocketAddr
> {
319 sockname(|buf
, len
| unsafe {
320 c
::getsockname(*self.inner
.as_inner(), buf
, len
)
324 pub fn accept(&self) -> io
::Result
<(TcpStream
, SocketAddr
)> {
325 let mut storage
: c
::sockaddr_storage
= unsafe { mem::zeroed() }
;
326 let mut len
= mem
::size_of_val(&storage
) as c
::socklen_t
;
327 let sock
= self.inner
.accept(&mut storage
as *mut _
as *mut _
,
329 let addr
= sockaddr_to_addr(&storage
, len
as usize)?
;
330 Ok((TcpStream { inner: sock, }
, addr
))
333 pub fn duplicate(&self) -> io
::Result
<TcpListener
> {
334 self.inner
.duplicate().map(|s
| TcpListener { inner: s }
)
337 pub fn set_ttl(&self, ttl
: u32) -> io
::Result
<()> {
338 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_TTL
, ttl
as c_int
)
341 pub fn ttl(&self) -> io
::Result
<u32> {
342 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_TTL
)?
;
346 pub fn set_only_v6(&self, only_v6
: bool
) -> io
::Result
<()> {
347 setsockopt(&self.inner
, c
::IPPROTO_IPV6
, c
::IPV6_V6ONLY
, only_v6
as c_int
)
350 pub fn only_v6(&self) -> io
::Result
<bool
> {
351 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IPV6
, c
::IPV6_V6ONLY
)?
;
355 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
356 self.inner
.take_error()
359 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
360 self.inner
.set_nonblocking(nonblocking
)
364 impl FromInner
<Socket
> for TcpListener
{
365 fn from_inner(socket
: Socket
) -> TcpListener
{
366 TcpListener { inner: socket }
370 impl fmt
::Debug
for TcpListener
{
371 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
372 let mut res
= f
.debug_struct("TcpListener");
374 if let Ok(addr
) = self.socket_addr() {
375 res
.field("addr", &addr
);
378 let name
= if cfg
!(windows
) {"socket"}
else {"fd"}
;
379 res
.field(name
, &self.inner
.as_inner())
384 ////////////////////////////////////////////////////////////////////////////////
386 ////////////////////////////////////////////////////////////////////////////////
388 pub struct UdpSocket
{
393 pub fn bind(addr
: &SocketAddr
) -> io
::Result
<UdpSocket
> {
396 let sock
= Socket
::new(addr
, c
::SOCK_DGRAM
)?
;
397 let (addrp
, len
) = addr
.into_inner();
398 cvt(unsafe { c::bind(*sock.as_inner(), addrp, len) }
)?
;
399 Ok(UdpSocket { inner: sock }
)
402 pub fn socket(&self) -> &Socket { &self.inner }
404 pub fn into_socket(self) -> Socket { self.inner }
406 pub fn socket_addr(&self) -> io
::Result
<SocketAddr
> {
407 sockname(|buf
, len
| unsafe {
408 c
::getsockname(*self.inner
.as_inner(), buf
, len
)
412 pub fn recv_from(&self, buf
: &mut [u8]) -> io
::Result
<(usize, SocketAddr
)> {
413 let mut storage
: c
::sockaddr_storage
= unsafe { mem::zeroed() }
;
414 let mut addrlen
= mem
::size_of_val(&storage
) as c
::socklen_t
;
415 let len
= cmp
::min(buf
.len(), <wrlen_t
>::max_value() as usize) as wrlen_t
;
418 c
::recvfrom(*self.inner
.as_inner(),
419 buf
.as_mut_ptr() as *mut c_void
,
421 &mut storage
as *mut _
as *mut _
, &mut addrlen
)
423 Ok((n
as usize, sockaddr_to_addr(&storage
, addrlen
as usize)?
))
426 pub fn send_to(&self, buf
: &[u8], dst
: &SocketAddr
) -> io
::Result
<usize> {
427 let len
= cmp
::min(buf
.len(), <wrlen_t
>::max_value() as usize) as wrlen_t
;
428 let (dstp
, dstlen
) = dst
.into_inner();
429 let ret
= cvt(unsafe {
430 c
::sendto(*self.inner
.as_inner(),
431 buf
.as_ptr() as *const c_void
, len
,
437 pub fn duplicate(&self) -> io
::Result
<UdpSocket
> {
438 self.inner
.duplicate().map(|s
| UdpSocket { inner: s }
)
441 pub fn set_read_timeout(&self, dur
: Option
<Duration
>) -> io
::Result
<()> {
442 self.inner
.set_timeout(dur
, c
::SO_RCVTIMEO
)
445 pub fn set_write_timeout(&self, dur
: Option
<Duration
>) -> io
::Result
<()> {
446 self.inner
.set_timeout(dur
, c
::SO_SNDTIMEO
)
449 pub fn read_timeout(&self) -> io
::Result
<Option
<Duration
>> {
450 self.inner
.timeout(c
::SO_RCVTIMEO
)
453 pub fn write_timeout(&self) -> io
::Result
<Option
<Duration
>> {
454 self.inner
.timeout(c
::SO_SNDTIMEO
)
457 pub fn set_broadcast(&self, broadcast
: bool
) -> io
::Result
<()> {
458 setsockopt(&self.inner
, c
::SOL_SOCKET
, c
::SO_BROADCAST
, broadcast
as c_int
)
461 pub fn broadcast(&self) -> io
::Result
<bool
> {
462 let raw
: c_int
= getsockopt(&self.inner
, c
::SOL_SOCKET
, c
::SO_BROADCAST
)?
;
466 pub fn set_multicast_loop_v4(&self, multicast_loop_v4
: bool
) -> io
::Result
<()> {
467 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_MULTICAST_LOOP
, multicast_loop_v4
as c_int
)
470 pub fn multicast_loop_v4(&self) -> io
::Result
<bool
> {
471 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_MULTICAST_LOOP
)?
;
475 pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4
: u32) -> io
::Result
<()> {
476 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_MULTICAST_TTL
, multicast_ttl_v4
as c_int
)
479 pub fn multicast_ttl_v4(&self) -> io
::Result
<u32> {
480 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_MULTICAST_TTL
)?
;
484 pub fn set_multicast_loop_v6(&self, multicast_loop_v6
: bool
) -> io
::Result
<()> {
485 setsockopt(&self.inner
, c
::IPPROTO_IPV6
, c
::IPV6_MULTICAST_LOOP
, multicast_loop_v6
as c_int
)
488 pub fn multicast_loop_v6(&self) -> io
::Result
<bool
> {
489 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IPV6
, c
::IPV6_MULTICAST_LOOP
)?
;
493 pub fn join_multicast_v4(&self, multiaddr
: &Ipv4Addr
, interface
: &Ipv4Addr
)
495 let mreq
= c
::ip_mreq
{
496 imr_multiaddr
: *multiaddr
.as_inner(),
497 imr_interface
: *interface
.as_inner(),
499 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_ADD_MEMBERSHIP
, mreq
)
502 pub fn join_multicast_v6(&self, multiaddr
: &Ipv6Addr
, interface
: u32)
504 let mreq
= c
::ipv6_mreq
{
505 ipv6mr_multiaddr
: *multiaddr
.as_inner(),
506 ipv6mr_interface
: to_ipv6mr_interface(interface
),
508 setsockopt(&self.inner
, c
::IPPROTO_IPV6
, IPV6_ADD_MEMBERSHIP
, mreq
)
511 pub fn leave_multicast_v4(&self, multiaddr
: &Ipv4Addr
, interface
: &Ipv4Addr
)
513 let mreq
= c
::ip_mreq
{
514 imr_multiaddr
: *multiaddr
.as_inner(),
515 imr_interface
: *interface
.as_inner(),
517 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_DROP_MEMBERSHIP
, mreq
)
520 pub fn leave_multicast_v6(&self, multiaddr
: &Ipv6Addr
, interface
: u32)
522 let mreq
= c
::ipv6_mreq
{
523 ipv6mr_multiaddr
: *multiaddr
.as_inner(),
524 ipv6mr_interface
: to_ipv6mr_interface(interface
),
526 setsockopt(&self.inner
, c
::IPPROTO_IPV6
, IPV6_DROP_MEMBERSHIP
, mreq
)
529 pub fn set_ttl(&self, ttl
: u32) -> io
::Result
<()> {
530 setsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_TTL
, ttl
as c_int
)
533 pub fn ttl(&self) -> io
::Result
<u32> {
534 let raw
: c_int
= getsockopt(&self.inner
, c
::IPPROTO_IP
, c
::IP_TTL
)?
;
538 pub fn take_error(&self) -> io
::Result
<Option
<io
::Error
>> {
539 self.inner
.take_error()
542 pub fn set_nonblocking(&self, nonblocking
: bool
) -> io
::Result
<()> {
543 self.inner
.set_nonblocking(nonblocking
)
546 pub fn recv(&self, buf
: &mut [u8]) -> io
::Result
<usize> {
550 pub fn send(&self, buf
: &[u8]) -> io
::Result
<usize> {
551 let len
= cmp
::min(buf
.len(), <wrlen_t
>::max_value() as usize) as wrlen_t
;
552 let ret
= cvt(unsafe {
553 c
::send(*self.inner
.as_inner(),
554 buf
.as_ptr() as *const c_void
,
561 pub fn connect(&self, addr
: &SocketAddr
) -> io
::Result
<()> {
562 let (addrp
, len
) = addr
.into_inner();
563 cvt_r(|| unsafe { c::connect(*self.inner.as_inner(), addrp, len) }
).map(|_
| ())
567 impl FromInner
<Socket
> for UdpSocket
{
568 fn from_inner(socket
: Socket
) -> UdpSocket
{
569 UdpSocket { inner: socket }
573 impl fmt
::Debug
for UdpSocket
{
574 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
575 let mut res
= f
.debug_struct("UdpSocket");
577 if let Ok(addr
) = self.socket_addr() {
578 res
.field("addr", &addr
);
581 let name
= if cfg
!(windows
) {"socket"}
else {"fd"}
;
582 res
.field(name
, &self.inner
.as_inner())