]> git.lizzy.rs Git - rust.git/blob - src/libstd/sys/common/net.rs
std: Clean out deprecated APIs
[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         try!(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         try!(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         try!(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 = io::Result<SocketAddr>;
123     fn next(&mut self) -> Option<io::Result<SocketAddr>> {
124         unsafe {
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;
129             Some(ret)
130         }
131     }
132 }
133
134 unsafe impl Sync for LookupHost {}
135 unsafe impl Send for LookupHost {}
136
137 impl Drop for LookupHost {
138     fn drop(&mut self) {
139         unsafe { c::freeaddrinfo(self.original) }
140     }
141 }
142
143 pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
144     init();
145
146     let c_host = try!(CString::new(host));
147     let mut res = ptr::null_mut();
148     unsafe {
149         try!(cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), ptr::null(),
150                                    &mut res)));
151         Ok(LookupHost { original: res, cur: res })
152     }
153 }
154
155 ////////////////////////////////////////////////////////////////////////////////
156 // TCP streams
157 ////////////////////////////////////////////////////////////////////////////////
158
159 pub struct TcpStream {
160     inner: Socket,
161 }
162
163 impl TcpStream {
164     pub fn connect(addr: &SocketAddr) -> io::Result<TcpStream> {
165         init();
166
167         let sock = try!(Socket::new(addr, c::SOCK_STREAM));
168
169         let (addrp, len) = addr.into_inner();
170         try!(cvt_r(|| unsafe { c::connect(*sock.as_inner(), addrp, len) }));
171         Ok(TcpStream { inner: sock })
172     }
173
174     pub fn socket(&self) -> &Socket { &self.inner }
175
176     pub fn into_socket(self) -> Socket { self.inner }
177
178     pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
179         self.inner.set_timeout(dur, c::SO_RCVTIMEO)
180     }
181
182     pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
183         self.inner.set_timeout(dur, c::SO_SNDTIMEO)
184     }
185
186     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
187         self.inner.timeout(c::SO_RCVTIMEO)
188     }
189
190     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
191         self.inner.timeout(c::SO_SNDTIMEO)
192     }
193
194     pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
195         self.inner.read(buf)
196     }
197
198     pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
199         self.inner.read_to_end(buf)
200     }
201
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 = try!(cvt(unsafe {
205             c::send(*self.inner.as_inner(),
206                     buf.as_ptr() as *const c_void,
207                     len,
208                     0)
209         }));
210         Ok(ret as usize)
211     }
212
213     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
214         sockname(|buf, len| unsafe {
215             c::getpeername(*self.inner.as_inner(), buf, len)
216         })
217     }
218
219     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
220         sockname(|buf, len| unsafe {
221             c::getsockname(*self.inner.as_inner(), buf, len)
222         })
223     }
224
225     pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
226         self.inner.shutdown(how)
227     }
228
229     pub fn duplicate(&self) -> io::Result<TcpStream> {
230         self.inner.duplicate().map(|s| TcpStream { inner: s })
231     }
232
233     pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
234         self.inner.set_nodelay(nodelay)
235     }
236
237     pub fn nodelay(&self) -> io::Result<bool> {
238         self.inner.nodelay()
239     }
240
241     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
242         setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int)
243     }
244
245     pub fn ttl(&self) -> io::Result<u32> {
246         let raw: c_int = try!(getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL));
247         Ok(raw as u32)
248     }
249
250     pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
251         setsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_V6ONLY, only_v6 as c_int)
252     }
253
254     pub fn only_v6(&self) -> io::Result<bool> {
255         let raw: c_int = try!(getsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_V6ONLY));
256         Ok(raw != 0)
257     }
258
259     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
260         let raw: c_int = try!(getsockopt(&self.inner, c::SOL_SOCKET, c::SO_ERROR));
261         if raw == 0 {
262             Ok(None)
263         } else {
264             Ok(Some(io::Error::from_raw_os_error(raw as i32)))
265         }
266     }
267
268     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
269         self.inner.set_nonblocking(nonblocking)
270     }
271 }
272
273 impl FromInner<Socket> for TcpStream {
274     fn from_inner(socket: Socket) -> TcpStream {
275         TcpStream { inner: socket }
276     }
277 }
278
279 impl fmt::Debug for TcpStream {
280     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
281         let mut res = f.debug_struct("TcpStream");
282
283         if let Ok(addr) = self.socket_addr() {
284             res.field("addr", &addr);
285         }
286
287         if let Ok(peer) = self.peer_addr() {
288             res.field("peer", &peer);
289         }
290
291         let name = if cfg!(windows) {"socket"} else {"fd"};
292         res.field(name, &self.inner.as_inner())
293             .finish()
294     }
295 }
296
297 ////////////////////////////////////////////////////////////////////////////////
298 // TCP listeners
299 ////////////////////////////////////////////////////////////////////////////////
300
301 pub struct TcpListener {
302     inner: Socket,
303 }
304
305 impl TcpListener {
306     pub fn bind(addr: &SocketAddr) -> io::Result<TcpListener> {
307         init();
308
309         let sock = try!(Socket::new(addr, c::SOCK_STREAM));
310
311         // On platforms with Berkeley-derived sockets, this allows
312         // to quickly rebind a socket, without needing to wait for
313         // the OS to clean up the previous one.
314         if !cfg!(windows) {
315             try!(setsockopt(&sock, c::SOL_SOCKET, c::SO_REUSEADDR,
316                             1 as c_int));
317         }
318
319         // Bind our new socket
320         let (addrp, len) = addr.into_inner();
321         try!(cvt(unsafe { c::bind(*sock.as_inner(), addrp, len) }));
322
323         // Start listening
324         try!(cvt(unsafe { c::listen(*sock.as_inner(), 128) }));
325         Ok(TcpListener { inner: sock })
326     }
327
328     pub fn socket(&self) -> &Socket { &self.inner }
329
330     pub fn into_socket(self) -> Socket { self.inner }
331
332     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
333         sockname(|buf, len| unsafe {
334             c::getsockname(*self.inner.as_inner(), buf, len)
335         })
336     }
337
338     pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
339         let mut storage: c::sockaddr_storage = unsafe { mem::zeroed() };
340         let mut len = mem::size_of_val(&storage) as c::socklen_t;
341         let sock = try!(self.inner.accept(&mut storage as *mut _ as *mut _,
342                                           &mut len));
343         let addr = try!(sockaddr_to_addr(&storage, len as usize));
344         Ok((TcpStream { inner: sock, }, addr))
345     }
346
347     pub fn duplicate(&self) -> io::Result<TcpListener> {
348         self.inner.duplicate().map(|s| TcpListener { inner: s })
349     }
350
351     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
352         setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int)
353     }
354
355     pub fn ttl(&self) -> io::Result<u32> {
356         let raw: c_int = try!(getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL));
357         Ok(raw as u32)
358     }
359
360     pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
361         setsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_V6ONLY, only_v6 as c_int)
362     }
363
364     pub fn only_v6(&self) -> io::Result<bool> {
365         let raw: c_int = try!(getsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_V6ONLY));
366         Ok(raw != 0)
367     }
368
369     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
370         let raw: c_int = try!(getsockopt(&self.inner, c::SOL_SOCKET, c::SO_ERROR));
371         if raw == 0 {
372             Ok(None)
373         } else {
374             Ok(Some(io::Error::from_raw_os_error(raw as i32)))
375         }
376     }
377
378     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
379         self.inner.set_nonblocking(nonblocking)
380     }
381 }
382
383 impl FromInner<Socket> for TcpListener {
384     fn from_inner(socket: Socket) -> TcpListener {
385         TcpListener { inner: socket }
386     }
387 }
388
389 impl fmt::Debug for TcpListener {
390     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
391         let mut res = f.debug_struct("TcpListener");
392
393         if let Ok(addr) = self.socket_addr() {
394             res.field("addr", &addr);
395         }
396
397         let name = if cfg!(windows) {"socket"} else {"fd"};
398         res.field(name, &self.inner.as_inner())
399             .finish()
400     }
401 }
402
403 ////////////////////////////////////////////////////////////////////////////////
404 // UDP
405 ////////////////////////////////////////////////////////////////////////////////
406
407 pub struct UdpSocket {
408     inner: Socket,
409 }
410
411 impl UdpSocket {
412     pub fn bind(addr: &SocketAddr) -> io::Result<UdpSocket> {
413         init();
414
415         let sock = try!(Socket::new(addr, c::SOCK_DGRAM));
416         let (addrp, len) = addr.into_inner();
417         try!(cvt(unsafe { c::bind(*sock.as_inner(), addrp, len) }));
418         Ok(UdpSocket { inner: sock })
419     }
420
421     pub fn socket(&self) -> &Socket { &self.inner }
422
423     pub fn into_socket(self) -> Socket { self.inner }
424
425     pub fn socket_addr(&self) -> io::Result<SocketAddr> {
426         sockname(|buf, len| unsafe {
427             c::getsockname(*self.inner.as_inner(), buf, len)
428         })
429     }
430
431     pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
432         let mut storage: c::sockaddr_storage = unsafe { mem::zeroed() };
433         let mut addrlen = mem::size_of_val(&storage) as c::socklen_t;
434         let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;
435
436         let n = try!(cvt(unsafe {
437             c::recvfrom(*self.inner.as_inner(),
438                         buf.as_mut_ptr() as *mut c_void,
439                         len, 0,
440                         &mut storage as *mut _ as *mut _, &mut addrlen)
441         }));
442         Ok((n as usize, try!(sockaddr_to_addr(&storage, addrlen as usize))))
443     }
444
445     pub fn send_to(&self, buf: &[u8], dst: &SocketAddr) -> io::Result<usize> {
446         let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;
447         let (dstp, dstlen) = dst.into_inner();
448         let ret = try!(cvt(unsafe {
449             c::sendto(*self.inner.as_inner(),
450                       buf.as_ptr() as *const c_void, len,
451                       0, dstp, dstlen)
452         }));
453         Ok(ret as usize)
454     }
455
456     pub fn duplicate(&self) -> io::Result<UdpSocket> {
457         self.inner.duplicate().map(|s| UdpSocket { inner: s })
458     }
459
460     pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
461         self.inner.set_timeout(dur, c::SO_RCVTIMEO)
462     }
463
464     pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
465         self.inner.set_timeout(dur, c::SO_SNDTIMEO)
466     }
467
468     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
469         self.inner.timeout(c::SO_RCVTIMEO)
470     }
471
472     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
473         self.inner.timeout(c::SO_SNDTIMEO)
474     }
475
476     pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
477         setsockopt(&self.inner, c::SOL_SOCKET, c::SO_BROADCAST, broadcast as c_int)
478     }
479
480     pub fn broadcast(&self) -> io::Result<bool> {
481         let raw: c_int = try!(getsockopt(&self.inner, c::SOL_SOCKET, c::SO_BROADCAST));
482         Ok(raw != 0)
483     }
484
485     pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> {
486         setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP, multicast_loop_v4 as c_int)
487     }
488
489     pub fn multicast_loop_v4(&self) -> io::Result<bool> {
490         let raw: c_int = try!(getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP));
491         Ok(raw != 0)
492     }
493
494     pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> {
495         setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL, multicast_ttl_v4 as c_int)
496     }
497
498     pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
499         let raw: c_int = try!(getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL));
500         Ok(raw as u32)
501     }
502
503     pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> {
504         setsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP, multicast_loop_v6 as c_int)
505     }
506
507     pub fn multicast_loop_v6(&self) -> io::Result<bool> {
508         let raw: c_int = try!(getsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP));
509         Ok(raw != 0)
510     }
511
512     pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr)
513                          -> io::Result<()> {
514         let mreq = c::ip_mreq {
515             imr_multiaddr: *multiaddr.as_inner(),
516             imr_interface: *interface.as_inner(),
517         };
518         setsockopt(&self.inner, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq)
519     }
520
521     pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32)
522                          -> io::Result<()> {
523         let mreq = c::ipv6_mreq {
524             ipv6mr_multiaddr: *multiaddr.as_inner(),
525             ipv6mr_interface: to_ipv6mr_interface(interface),
526         };
527         setsockopt(&self.inner, c::IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq)
528     }
529
530     pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr)
531                           -> io::Result<()> {
532         let mreq = c::ip_mreq {
533             imr_multiaddr: *multiaddr.as_inner(),
534             imr_interface: *interface.as_inner(),
535         };
536         setsockopt(&self.inner, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq)
537     }
538
539     pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32)
540                           -> io::Result<()> {
541         let mreq = c::ipv6_mreq {
542             ipv6mr_multiaddr: *multiaddr.as_inner(),
543             ipv6mr_interface: to_ipv6mr_interface(interface),
544         };
545         setsockopt(&self.inner, c::IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, mreq)
546     }
547
548     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
549         setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int)
550     }
551
552     pub fn ttl(&self) -> io::Result<u32> {
553         let raw: c_int = try!(getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL));
554         Ok(raw as u32)
555     }
556
557     pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
558         setsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_V6ONLY, only_v6 as c_int)
559     }
560
561     pub fn only_v6(&self) -> io::Result<bool> {
562         let raw: c_int = try!(getsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_V6ONLY));
563         Ok(raw != 0)
564     }
565
566     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
567         let raw: c_int = try!(getsockopt(&self.inner, c::SOL_SOCKET, c::SO_ERROR));
568         if raw == 0 {
569             Ok(None)
570         } else {
571             Ok(Some(io::Error::from_raw_os_error(raw as i32)))
572         }
573     }
574
575     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
576         self.inner.set_nonblocking(nonblocking)
577     }
578
579     pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
580         self.inner.read(buf)
581     }
582
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 = try!(cvt(unsafe {
586             c::send(*self.inner.as_inner(),
587                     buf.as_ptr() as *const c_void,
588                     len,
589                     0)
590         }));
591         Ok(ret as usize)
592     }
593
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(|_| ())
597     }
598 }
599
600 impl FromInner<Socket> for UdpSocket {
601     fn from_inner(socket: Socket) -> UdpSocket {
602         UdpSocket { inner: socket }
603     }
604 }
605
606 impl fmt::Debug for UdpSocket {
607     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
608         let mut res = f.debug_struct("UdpSocket");
609
610         if let Ok(addr) = self.socket_addr() {
611             res.field("addr", &addr);
612         }
613
614         let name = if cfg!(windows) {"socket"} else {"fd"};
615         res.field(name, &self.inner.as_inner())
616             .finish()
617     }
618 }