1 // Copyright 2015 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 std
::net
::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}
;
28 pub fn new(family
: c_int
, ty
: c_int
) -> io
::Result
<Socket
> {
29 Ok(Socket { inner: try!(sys::Socket::new(family, ty)) }
)
32 pub fn bind(&self, addr
: &SocketAddr
) -> io
::Result
<()> {
33 #[cfg(not(all(any(target_arch = "aarch64", target_arch = "x86_64"), target_os = "android")))]
34 use sys
::c
::socklen_t
as len_t
;
35 #[cfg(all(any(target_arch = "aarch64", target_arch = "x86_64"), target_os = "android"))]
36 use libc
::c_int
as len_t
;
38 let (addr
, len
) = addr2raw(addr
);
40 ::cvt(c
::bind(self.inner
.raw(), addr
, len
as len_t
)).map(|_
| ())
44 pub fn listen(&self, backlog
: i32) -> io
::Result
<()> {
46 ::cvt(c
::listen(self.inner
.raw(), backlog
)).map(|_
| ())
50 pub fn connect(&self, addr
: &SocketAddr
) -> io
::Result
<()> {
51 let (addr
, len
) = addr2raw(addr
);
53 ::cvt(c
::connect(self.inner
.raw(), addr
, len
)).map(|_
| ())
57 pub fn getsockname(&self) -> io
::Result
<SocketAddr
> {
59 let mut storage
: c
::sockaddr_storage
= mem
::zeroed();
60 let mut len
= mem
::size_of_val(&storage
) as c
::socklen_t
;
61 try
!(::cvt(c
::getsockname(self.inner
.raw(),
62 &mut storage
as *mut _
as *mut _
,
64 raw2addr(&storage
, len
)
69 impl fmt
::Debug
for Socket
{
70 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
71 self.inner
.raw().fmt(f
)
75 impl ::AsInner
for Socket
{
76 type Inner
= sys
::Socket
;
77 fn as_inner(&self) -> &sys
::Socket { &self.inner }
80 impl ::FromInner
for Socket
{
81 type Inner
= sys
::Socket
;
82 fn from_inner(sock
: sys
::Socket
) -> Socket
{
83 Socket { inner: sock }
87 impl ::IntoInner
for Socket
{
88 type Inner
= sys
::Socket
;
89 fn into_inner(self) -> sys
::Socket { self.inner }
92 fn addr2raw(addr
: &SocketAddr
) -> (*const c
::sockaddr
, c
::socklen_t
) {
94 SocketAddr
::V4(ref a
) => {
95 (a
as *const _
as *const _
, mem
::size_of_val(a
) as c
::socklen_t
)
97 SocketAddr
::V6(ref a
) => {
98 (a
as *const _
as *const _
, mem
::size_of_val(a
) as c
::socklen_t
)
103 fn raw2addr(storage
: &c
::sockaddr_storage
, len
: c
::socklen_t
) -> io
::Result
<SocketAddr
> {
104 match storage
.ss_family
as c_int
{
107 assert
!(len
as usize >= mem
::size_of
::<c
::sockaddr_in
>());
108 let sa
= storage
as *const _
as *const c
::sockaddr_in
;
109 let bits
= c
::sockaddr_in_u32(&(*sa
));
110 let ip
= Ipv4Addr
::new((bits
>> 24) as u8,
114 Ok(SocketAddr
::V4(SocketAddrV4
::new(ip
, ::ntoh((*sa
).sin_port
))))
119 assert
!(len
as usize >= mem
::size_of
::<c
::sockaddr_in6
>());
121 let sa
= storage
as *const _
as *const c
::sockaddr_in6
;
122 let arr
= (*sa
).sin6_addr
.s6_addr
;
124 let ip
= Ipv6Addr
::new(
125 (arr
[0] as u16) << 8 | (arr
[1] as u16),
126 (arr
[2] as u16) << 8 | (arr
[3] as u16),
127 (arr
[4] as u16) << 8 | (arr
[5] as u16),
128 (arr
[6] as u16) << 8 | (arr
[7] as u16),
129 (arr
[8] as u16) << 8 | (arr
[9] as u16),
130 (arr
[10] as u16) << 8 | (arr
[11] as u16),
131 (arr
[12] as u16) << 8 | (arr
[13] as u16),
132 (arr
[14] as u16) << 8 | (arr
[15] as u16),
135 Ok(SocketAddr
::V6(SocketAddrV6
::new(ip
,
136 ::ntoh((*sa
).sin6_port
),
138 (*sa
).sin6_scope_id
)))
141 _
=> Err(io
::Error
::new(io
::ErrorKind
::InvalidInput
, "invalid argument")),