]> git.lizzy.rs Git - rust.git/blob - src/libstd/sys/common/net.rs
Ignore unknown address types when looking up hosts
[rust.git] / src / libstd / sys / common / net.rs
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.
4 //
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.
10
11 use prelude::v1::*;
12
13 use cmp;
14 use ffi::CString;
15 use fmt;
16 use io::{self, Error, ErrorKind};
17 use libc::{c_int, c_void};
18 use mem;
19 use net::{SocketAddr, Shutdown, Ipv4Addr, Ipv6Addr};
20 use ptr;
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};
24 use time::Duration;
25
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;
42
43 ////////////////////////////////////////////////////////////////////////////////
44 // sockaddr and misc bindings
45 ////////////////////////////////////////////////////////////////////////////////
46
47 pub fn setsockopt<T>(sock: &Socket, opt: c_int, val: c_int,
48                      payload: T) -> io::Result<()> {
49     unsafe {
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))?;
53         Ok(())
54     }
55 }
56
57 pub fn getsockopt<T: Copy>(sock: &Socket, opt: c_int,
58                        val: c_int) -> io::Result<T> {
59     unsafe {
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 _,
64                           &mut len))?;
65         assert_eq!(len as usize, mem::size_of::<T>());
66         Ok(slot)
67     }
68 }
69
70 fn sockname<F>(f: F) -> io::Result<SocketAddr>
71     where F: FnOnce(*mut c::sockaddr, *mut c::socklen_t) -> c_int
72 {
73     unsafe {
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)
78     }
79 }
80
81 fn sockaddr_to_addr(storage: &c::sockaddr_storage,
82                     len: usize) -> io::Result<SocketAddr> {
83     match storage.ss_family as c_int {
84         c::AF_INET => {
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)
88             })))
89         }
90         c::AF_INET6 => {
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)
94             })))
95         }
96         _ => {
97             Err(Error::new(ErrorKind::InvalidInput, "invalid argument"))
98         }
99     }
100 }
101
102 #[cfg(target_os = "android")]
103 fn to_ipv6mr_interface(value: u32) -> c_int {
104     value as c_int
105 }
106
107 #[cfg(not(target_os = "android"))]
108 fn to_ipv6mr_interface(value: u32) -> ::libc::c_uint {
109     value as ::libc::c_uint
110 }
111
112 ////////////////////////////////////////////////////////////////////////////////
113 // get_host_addresses
114 ////////////////////////////////////////////////////////////////////////////////
115
116 pub struct LookupHost {
117     original: *mut c::addrinfo,
118     cur: *mut c::addrinfo,
119 }
120
121 impl Iterator for LookupHost {
122     type Item = SocketAddr;
123     fn next(&mut self) -> Option<SocketAddr> {
124         let result;
125         unsafe {
126             if self.cur.is_null() { return None }
127             result = sockaddr_to_addr(mem::transmute((*self.cur).ai_addr),
128                                       (*self.cur).ai_addrlen as usize).ok();
129             self.cur = (*self.cur).ai_next as *mut c::addrinfo;
130         }
131         match result {
132             Some(r) => Some(r),
133             None => self.next(),
134         }
135     }
136 }
137
138 unsafe impl Sync for LookupHost {}
139 unsafe impl Send for LookupHost {}
140
141 impl Drop for LookupHost {
142     fn drop(&mut self) {
143         unsafe { c::freeaddrinfo(self.original) }
144     }
145 }
146
147 pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
148     init();
149
150     let c_host = CString::new(host)?;
151     let mut res = ptr::null_mut();
152     unsafe {
153         cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), ptr::null(),
154                                &mut res))?;
155         Ok(LookupHost { original: res, cur: res })
156     }
157 }
158
159 ////////////////////////////////////////////////////////////////////////////////
160 // TCP streams
161 ////////////////////////////////////////////////////////////////////////////////
162
163 pub struct TcpStream {
164     inner: Socket,
165 }
166
167 impl TcpStream {
168     pub fn connect(addr: &SocketAddr) -> io::Result<TcpStream> {
169         init();
170
171         let sock = Socket::new(addr, c::SOCK_STREAM)?;
172
173         let (addrp, len) = addr.into_inner();
174         cvt_r(|| unsafe { c::connect(*sock.as_inner(), addrp, len) })?;
175         Ok(TcpStream { inner: sock })
176     }
177
178     pub fn socket(&self) -> &Socket { &self.inner }
179
180     pub fn into_socket(self) -> Socket { self.inner }
181
182     pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
183         self.inner.set_timeout(dur, c::SO_RCVTIMEO)
184     }
185
186     pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
187         self.inner.set_timeout(dur, c::SO_SNDTIMEO)
188     }
189
190     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
191         self.inner.timeout(c::SO_RCVTIMEO)
192     }
193
194     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
195         self.inner.timeout(c::SO_SNDTIMEO)
196     }
197
198     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
199         self.inner.read(buf)
200     }
201
202     pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
203         self.inner.read_to_end(buf)
204     }
205
206     pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
207         let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;
208         let ret = cvt(unsafe {
209             c::send(*self.inner.as_inner(),
210                     buf.as_ptr() as *const c_void,
211                     len,
212                     0)
213         })?;
214         Ok(ret as usize)
215     }
216
217     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
218         sockname(|buf, len| unsafe {
219             c::getpeername(*self.inner.as_inner(), buf, len)
220         })
221     }
222
223     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
224         sockname(|buf, len| unsafe {
225             c::getsockname(*self.inner.as_inner(), buf, len)
226         })
227     }
228
229     pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
230         self.inner.shutdown(how)
231     }
232
233     pub fn duplicate(&self) -> io::Result<TcpStream> {
234         self.inner.duplicate().map(|s| TcpStream { inner: s })
235     }
236
237     pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
238         self.inner.set_nodelay(nodelay)
239     }
240
241     pub fn nodelay(&self) -> io::Result<bool> {
242         self.inner.nodelay()
243     }
244
245     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
246         setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int)
247     }
248
249     pub fn ttl(&self) -> io::Result<u32> {
250         let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL)?;
251         Ok(raw as u32)
252     }
253
254     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
255         self.inner.take_error()
256     }
257
258     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
259         self.inner.set_nonblocking(nonblocking)
260     }
261 }
262
263 impl FromInner<Socket> for TcpStream {
264     fn from_inner(socket: Socket) -> TcpStream {
265         TcpStream { inner: socket }
266     }
267 }
268
269 impl fmt::Debug for TcpStream {
270     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
271         let mut res = f.debug_struct("TcpStream");
272
273         if let Ok(addr) = self.socket_addr() {
274             res.field("addr", &addr);
275         }
276
277         if let Ok(peer) = self.peer_addr() {
278             res.field("peer", &peer);
279         }
280
281         let name = if cfg!(windows) {"socket"} else {"fd"};
282         res.field(name, &self.inner.as_inner())
283             .finish()
284     }
285 }
286
287 ////////////////////////////////////////////////////////////////////////////////
288 // TCP listeners
289 ////////////////////////////////////////////////////////////////////////////////
290
291 pub struct TcpListener {
292     inner: Socket,
293 }
294
295 impl TcpListener {
296     pub fn bind(addr: &SocketAddr) -> io::Result<TcpListener> {
297         init();
298
299         let sock = Socket::new(addr, c::SOCK_STREAM)?;
300
301         // On platforms with Berkeley-derived sockets, this allows
302         // to quickly rebind a socket, without needing to wait for
303         // the OS to clean up the previous one.
304         if !cfg!(windows) {
305             setsockopt(&sock, c::SOL_SOCKET, c::SO_REUSEADDR,
306                        1 as c_int)?;
307         }
308
309         // Bind our new socket
310         let (addrp, len) = addr.into_inner();
311         cvt(unsafe { c::bind(*sock.as_inner(), addrp, len) })?;
312
313         // Start listening
314         cvt(unsafe { c::listen(*sock.as_inner(), 128) })?;
315         Ok(TcpListener { inner: sock })
316     }
317
318     pub fn socket(&self) -> &Socket { &self.inner }
319
320     pub fn into_socket(self) -> Socket { self.inner }
321
322     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
323         sockname(|buf, len| unsafe {
324             c::getsockname(*self.inner.as_inner(), buf, len)
325         })
326     }
327
328     pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
329         let mut storage: c::sockaddr_storage = unsafe { mem::zeroed() };
330         let mut len = mem::size_of_val(&storage) as c::socklen_t;
331         let sock = self.inner.accept(&mut storage as *mut _ as *mut _,
332                                      &mut len)?;
333         let addr = sockaddr_to_addr(&storage, len as usize)?;
334         Ok((TcpStream { inner: sock, }, addr))
335     }
336
337     pub fn duplicate(&self) -> io::Result<TcpListener> {
338         self.inner.duplicate().map(|s| TcpListener { inner: s })
339     }
340
341     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
342         setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int)
343     }
344
345     pub fn ttl(&self) -> io::Result<u32> {
346         let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL)?;
347         Ok(raw as u32)
348     }
349
350     pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
351         setsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_V6ONLY, only_v6 as c_int)
352     }
353
354     pub fn only_v6(&self) -> io::Result<bool> {
355         let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_V6ONLY)?;
356         Ok(raw != 0)
357     }
358
359     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
360         self.inner.take_error()
361     }
362
363     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
364         self.inner.set_nonblocking(nonblocking)
365     }
366 }
367
368 impl FromInner<Socket> for TcpListener {
369     fn from_inner(socket: Socket) -> TcpListener {
370         TcpListener { inner: socket }
371     }
372 }
373
374 impl fmt::Debug for TcpListener {
375     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
376         let mut res = f.debug_struct("TcpListener");
377
378         if let Ok(addr) = self.socket_addr() {
379             res.field("addr", &addr);
380         }
381
382         let name = if cfg!(windows) {"socket"} else {"fd"};
383         res.field(name, &self.inner.as_inner())
384             .finish()
385     }
386 }
387
388 ////////////////////////////////////////////////////////////////////////////////
389 // UDP
390 ////////////////////////////////////////////////////////////////////////////////
391
392 pub struct UdpSocket {
393     inner: Socket,
394 }
395
396 impl UdpSocket {
397     pub fn bind(addr: &SocketAddr) -> io::Result<UdpSocket> {
398         init();
399
400         let sock = Socket::new(addr, c::SOCK_DGRAM)?;
401         let (addrp, len) = addr.into_inner();
402         cvt(unsafe { c::bind(*sock.as_inner(), addrp, len) })?;
403         Ok(UdpSocket { inner: sock })
404     }
405
406     pub fn socket(&self) -> &Socket { &self.inner }
407
408     pub fn into_socket(self) -> Socket { self.inner }
409
410     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
411         sockname(|buf, len| unsafe {
412             c::getsockname(*self.inner.as_inner(), buf, len)
413         })
414     }
415
416     pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
417         let mut storage: c::sockaddr_storage = unsafe { mem::zeroed() };
418         let mut addrlen = mem::size_of_val(&storage) as c::socklen_t;
419         let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;
420
421         let n = cvt(unsafe {
422             c::recvfrom(*self.inner.as_inner(),
423                         buf.as_mut_ptr() as *mut c_void,
424                         len, 0,
425                         &mut storage as *mut _ as *mut _, &mut addrlen)
426         })?;
427         Ok((n as usize, sockaddr_to_addr(&storage, addrlen as usize)?))
428     }
429
430     pub fn send_to(&self, buf: &[u8], dst: &SocketAddr) -> io::Result<usize> {
431         let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;
432         let (dstp, dstlen) = dst.into_inner();
433         let ret = cvt(unsafe {
434             c::sendto(*self.inner.as_inner(),
435                       buf.as_ptr() as *const c_void, len,
436                       0, dstp, dstlen)
437         })?;
438         Ok(ret as usize)
439     }
440
441     pub fn duplicate(&self) -> io::Result<UdpSocket> {
442         self.inner.duplicate().map(|s| UdpSocket { inner: s })
443     }
444
445     pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
446         self.inner.set_timeout(dur, c::SO_RCVTIMEO)
447     }
448
449     pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
450         self.inner.set_timeout(dur, c::SO_SNDTIMEO)
451     }
452
453     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
454         self.inner.timeout(c::SO_RCVTIMEO)
455     }
456
457     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
458         self.inner.timeout(c::SO_SNDTIMEO)
459     }
460
461     pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
462         setsockopt(&self.inner, c::SOL_SOCKET, c::SO_BROADCAST, broadcast as c_int)
463     }
464
465     pub fn broadcast(&self) -> io::Result<bool> {
466         let raw: c_int = getsockopt(&self.inner, c::SOL_SOCKET, c::SO_BROADCAST)?;
467         Ok(raw != 0)
468     }
469
470     pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> {
471         setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP, multicast_loop_v4 as c_int)
472     }
473
474     pub fn multicast_loop_v4(&self) -> io::Result<bool> {
475         let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)?;
476         Ok(raw != 0)
477     }
478
479     pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> {
480         setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl_v4 as c_int)
481     }
482
483     pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
484         let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)?;
485         Ok(raw as u32)
486     }
487
488     pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> {
489         setsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP, multicast_loop_v6 as c_int)
490     }
491
492     pub fn multicast_loop_v6(&self) -> io::Result<bool> {
493         let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP)?;
494         Ok(raw != 0)
495     }
496
497     pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr)
498                          -> io::Result<()> {
499         let mreq = c::ip_mreq {
500             imr_multiaddr: *multiaddr.as_inner(),
501             imr_interface: *interface.as_inner(),
502         };
503         setsockopt(&self.inner, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq)
504     }
505
506     pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32)
507                          -> io::Result<()> {
508         let mreq = c::ipv6_mreq {
509             ipv6mr_multiaddr: *multiaddr.as_inner(),
510             ipv6mr_interface: to_ipv6mr_interface(interface),
511         };
512         setsockopt(&self.inner, c::IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq)
513     }
514
515     pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr)
516                           -> io::Result<()> {
517         let mreq = c::ip_mreq {
518             imr_multiaddr: *multiaddr.as_inner(),
519             imr_interface: *interface.as_inner(),
520         };
521         setsockopt(&self.inner, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq)
522     }
523
524     pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32)
525                           -> io::Result<()> {
526         let mreq = c::ipv6_mreq {
527             ipv6mr_multiaddr: *multiaddr.as_inner(),
528             ipv6mr_interface: to_ipv6mr_interface(interface),
529         };
530         setsockopt(&self.inner, c::IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, mreq)
531     }
532
533     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
534         setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int)
535     }
536
537     pub fn ttl(&self) -> io::Result<u32> {
538         let raw: c_int = getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL)?;
539         Ok(raw as u32)
540     }
541
542     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
543         self.inner.take_error()
544     }
545
546     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
547         self.inner.set_nonblocking(nonblocking)
548     }
549
550     pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
551         self.inner.read(buf)
552     }
553
554     pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
555         let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;
556         let ret = cvt(unsafe {
557             c::send(*self.inner.as_inner(),
558                     buf.as_ptr() as *const c_void,
559                     len,
560                     0)
561         })?;
562         Ok(ret as usize)
563     }
564
565     pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> {
566         let (addrp, len) = addr.into_inner();
567         cvt_r(|| unsafe { c::connect(*self.inner.as_inner(), addrp, len) }).map(|_| ())
568     }
569 }
570
571 impl FromInner<Socket> for UdpSocket {
572     fn from_inner(socket: Socket) -> UdpSocket {
573         UdpSocket { inner: socket }
574     }
575 }
576
577 impl fmt::Debug for UdpSocket {
578     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
579         let mut res = f.debug_struct("UdpSocket");
580
581         if let Ok(addr) = self.socket_addr() {
582             res.field("addr", &addr);
583         }
584
585         let name = if cfg!(windows) {"socket"} else {"fd"};
586         res.field(name, &self.inner.as_inner())
587             .finish()
588     }
589 }