• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::net::{TcpListener, TcpStream};
2 
3 use std::fmt;
4 use std::io;
5 use std::net::SocketAddr;
6 
7 #[cfg(unix)]
8 use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
9 use std::time::Duration;
10 
11 cfg_windows! {
12     use crate::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket, AsSocket, BorrowedSocket};
13 }
14 
15 cfg_net! {
16     /// A TCP socket that has not yet been converted to a `TcpStream` or
17     /// `TcpListener`.
18     ///
19     /// `TcpSocket` wraps an operating system socket and enables the caller to
20     /// configure the socket before establishing a TCP connection or accepting
21     /// inbound connections. The caller is able to set socket option and explicitly
22     /// bind the socket with a socket address.
23     ///
24     /// The underlying socket is closed when the `TcpSocket` value is dropped.
25     ///
26     /// `TcpSocket` should only be used directly if the default configuration used
27     /// by `TcpStream::connect` and `TcpListener::bind` does not meet the required
28     /// use case.
29     ///
30     /// Calling `TcpStream::connect("127.0.0.1:8080")` is equivalent to:
31     ///
32     /// ```no_run
33     /// use tokio::net::TcpSocket;
34     ///
35     /// use std::io;
36     ///
37     /// #[tokio::main]
38     /// async fn main() -> io::Result<()> {
39     ///     let addr = "127.0.0.1:8080".parse().unwrap();
40     ///
41     ///     let socket = TcpSocket::new_v4()?;
42     ///     let stream = socket.connect(addr).await?;
43     /// # drop(stream);
44     ///
45     ///     Ok(())
46     /// }
47     /// ```
48     ///
49     /// Calling `TcpListener::bind("127.0.0.1:8080")` is equivalent to:
50     ///
51     /// ```no_run
52     /// use tokio::net::TcpSocket;
53     ///
54     /// use std::io;
55     ///
56     /// #[tokio::main]
57     /// async fn main() -> io::Result<()> {
58     ///     let addr = "127.0.0.1:8080".parse().unwrap();
59     ///
60     ///     let socket = TcpSocket::new_v4()?;
61     ///     // On platforms with Berkeley-derived sockets, this allows to quickly
62     ///     // rebind a socket, without needing to wait for the OS to clean up the
63     ///     // previous one.
64     ///     //
65     ///     // On Windows, this allows rebinding sockets which are actively in use,
66     ///     // which allows “socket hijacking”, so we explicitly don't set it here.
67     ///     // https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse
68     ///     socket.set_reuseaddr(true)?;
69     ///     socket.bind(addr)?;
70     ///
71     ///     let listener = socket.listen(1024)?;
72     /// # drop(listener);
73     ///
74     ///     Ok(())
75     /// }
76     /// ```
77     ///
78     /// Setting socket options not explicitly provided by `TcpSocket` may be done by
79     /// accessing the `RawFd`/`RawSocket` using [`AsRawFd`]/[`AsRawSocket`] and
80     /// setting the option with a crate like [`socket2`].
81     ///
82     /// [`RawFd`]: https://doc.rust-lang.org/std/os/unix/io/type.RawFd.html
83     /// [`RawSocket`]: https://doc.rust-lang.org/std/os/windows/io/type.RawSocket.html
84     /// [`AsRawFd`]: https://doc.rust-lang.org/std/os/unix/io/trait.AsRawFd.html
85     /// [`AsRawSocket`]: https://doc.rust-lang.org/std/os/windows/io/trait.AsRawSocket.html
86     /// [`socket2`]: https://docs.rs/socket2/
87     #[cfg_attr(docsrs, doc(alias = "connect_std"))]
88     pub struct TcpSocket {
89         inner: socket2::Socket,
90     }
91 }
92 
93 impl TcpSocket {
94     /// Creates a new socket configured for IPv4.
95     ///
96     /// Calls `socket(2)` with `AF_INET` and `SOCK_STREAM`.
97     ///
98     /// # Returns
99     ///
100     /// On success, the newly created `TcpSocket` is returned. If an error is
101     /// encountered, it is returned instead.
102     ///
103     /// # Examples
104     ///
105     /// Create a new IPv4 socket and start listening.
106     ///
107     /// ```no_run
108     /// use tokio::net::TcpSocket;
109     ///
110     /// use std::io;
111     ///
112     /// #[tokio::main]
113     /// async fn main() -> io::Result<()> {
114     ///     let addr = "127.0.0.1:8080".parse().unwrap();
115     ///     let socket = TcpSocket::new_v4()?;
116     ///     socket.bind(addr)?;
117     ///
118     ///     let listener = socket.listen(128)?;
119     /// # drop(listener);
120     ///     Ok(())
121     /// }
122     /// ```
new_v4() -> io::Result<TcpSocket>123     pub fn new_v4() -> io::Result<TcpSocket> {
124         TcpSocket::new(socket2::Domain::IPV4)
125     }
126 
127     /// Creates a new socket configured for IPv6.
128     ///
129     /// Calls `socket(2)` with `AF_INET6` and `SOCK_STREAM`.
130     ///
131     /// # Returns
132     ///
133     /// On success, the newly created `TcpSocket` is returned. If an error is
134     /// encountered, it is returned instead.
135     ///
136     /// # Examples
137     ///
138     /// Create a new IPv6 socket and start listening.
139     ///
140     /// ```no_run
141     /// use tokio::net::TcpSocket;
142     ///
143     /// use std::io;
144     ///
145     /// #[tokio::main]
146     /// async fn main() -> io::Result<()> {
147     ///     let addr = "[::1]:8080".parse().unwrap();
148     ///     let socket = TcpSocket::new_v6()?;
149     ///     socket.bind(addr)?;
150     ///
151     ///     let listener = socket.listen(128)?;
152     /// # drop(listener);
153     ///     Ok(())
154     /// }
155     /// ```
new_v6() -> io::Result<TcpSocket>156     pub fn new_v6() -> io::Result<TcpSocket> {
157         TcpSocket::new(socket2::Domain::IPV6)
158     }
159 
new(domain: socket2::Domain) -> io::Result<TcpSocket>160     fn new(domain: socket2::Domain) -> io::Result<TcpSocket> {
161         let ty = socket2::Type::STREAM;
162         #[cfg(any(
163             target_os = "android",
164             target_os = "dragonfly",
165             target_os = "freebsd",
166             target_os = "fuchsia",
167             target_os = "illumos",
168             target_os = "linux",
169             target_os = "netbsd",
170             target_os = "openbsd"
171         ))]
172         let ty = ty.nonblocking();
173         let inner = socket2::Socket::new(domain, ty, Some(socket2::Protocol::TCP))?;
174         #[cfg(not(any(
175             target_os = "android",
176             target_os = "dragonfly",
177             target_os = "freebsd",
178             target_os = "fuchsia",
179             target_os = "illumos",
180             target_os = "linux",
181             target_os = "netbsd",
182             target_os = "openbsd"
183         )))]
184         inner.set_nonblocking(true)?;
185         Ok(TcpSocket { inner })
186     }
187 
188     /// Allows the socket to bind to an in-use address.
189     ///
190     /// Behavior is platform specific. Refer to the target platform's
191     /// documentation for more details.
192     ///
193     /// # Examples
194     ///
195     /// ```no_run
196     /// use tokio::net::TcpSocket;
197     ///
198     /// use std::io;
199     ///
200     /// #[tokio::main]
201     /// async fn main() -> io::Result<()> {
202     ///     let addr = "127.0.0.1:8080".parse().unwrap();
203     ///
204     ///     let socket = TcpSocket::new_v4()?;
205     ///     socket.set_reuseaddr(true)?;
206     ///     socket.bind(addr)?;
207     ///
208     ///     let listener = socket.listen(1024)?;
209     /// # drop(listener);
210     ///
211     ///     Ok(())
212     /// }
213     /// ```
set_reuseaddr(&self, reuseaddr: bool) -> io::Result<()>214     pub fn set_reuseaddr(&self, reuseaddr: bool) -> io::Result<()> {
215         self.inner.set_reuse_address(reuseaddr)
216     }
217 
218     /// Retrieves the value set for `SO_REUSEADDR` on this socket.
219     ///
220     /// # Examples
221     ///
222     /// ```no_run
223     /// use tokio::net::TcpSocket;
224     ///
225     /// use std::io;
226     ///
227     /// #[tokio::main]
228     /// async fn main() -> io::Result<()> {
229     ///     let addr = "127.0.0.1:8080".parse().unwrap();
230     ///
231     ///     let socket = TcpSocket::new_v4()?;
232     ///     socket.set_reuseaddr(true)?;
233     ///     assert!(socket.reuseaddr().unwrap());
234     ///     socket.bind(addr)?;
235     ///
236     ///     let listener = socket.listen(1024)?;
237     ///     Ok(())
238     /// }
239     /// ```
reuseaddr(&self) -> io::Result<bool>240     pub fn reuseaddr(&self) -> io::Result<bool> {
241         self.inner.reuse_address()
242     }
243 
244     /// Allows the socket to bind to an in-use port. Only available for unix systems
245     /// (excluding Solaris & Illumos).
246     ///
247     /// Behavior is platform specific. Refer to the target platform's
248     /// documentation for more details.
249     ///
250     /// # Examples
251     ///
252     /// ```no_run
253     /// use tokio::net::TcpSocket;
254     ///
255     /// use std::io;
256     ///
257     /// #[tokio::main]
258     /// async fn main() -> io::Result<()> {
259     ///     let addr = "127.0.0.1:8080".parse().unwrap();
260     ///
261     ///     let socket = TcpSocket::new_v4()?;
262     ///     socket.set_reuseport(true)?;
263     ///     socket.bind(addr)?;
264     ///
265     ///     let listener = socket.listen(1024)?;
266     ///     Ok(())
267     /// }
268     /// ```
269     #[cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos")))]
270     #[cfg_attr(
271         docsrs,
272         doc(cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos"))))
273     )]
set_reuseport(&self, reuseport: bool) -> io::Result<()>274     pub fn set_reuseport(&self, reuseport: bool) -> io::Result<()> {
275         self.inner.set_reuse_port(reuseport)
276     }
277 
278     /// Allows the socket to bind to an in-use port. Only available for unix systems
279     /// (excluding Solaris & Illumos).
280     ///
281     /// Behavior is platform specific. Refer to the target platform's
282     /// documentation for more details.
283     ///
284     /// # Examples
285     ///
286     /// ```no_run
287     /// use tokio::net::TcpSocket;
288     ///
289     /// use std::io;
290     ///
291     /// #[tokio::main]
292     /// async fn main() -> io::Result<()> {
293     ///     let addr = "127.0.0.1:8080".parse().unwrap();
294     ///
295     ///     let socket = TcpSocket::new_v4()?;
296     ///     socket.set_reuseport(true)?;
297     ///     assert!(socket.reuseport().unwrap());
298     ///     socket.bind(addr)?;
299     ///
300     ///     let listener = socket.listen(1024)?;
301     ///     Ok(())
302     /// }
303     /// ```
304     #[cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos")))]
305     #[cfg_attr(
306         docsrs,
307         doc(cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos"))))
308     )]
reuseport(&self) -> io::Result<bool>309     pub fn reuseport(&self) -> io::Result<bool> {
310         self.inner.reuse_port()
311     }
312 
313     /// Sets the size of the TCP send buffer on this socket.
314     ///
315     /// On most operating systems, this sets the `SO_SNDBUF` socket option.
set_send_buffer_size(&self, size: u32) -> io::Result<()>316     pub fn set_send_buffer_size(&self, size: u32) -> io::Result<()> {
317         self.inner.set_send_buffer_size(size as usize)
318     }
319 
320     /// Returns the size of the TCP send buffer for this socket.
321     ///
322     /// On most operating systems, this is the value of the `SO_SNDBUF` socket
323     /// option.
324     ///
325     /// Note that if [`set_send_buffer_size`] has been called on this socket
326     /// previously, the value returned by this function may not be the same as
327     /// the argument provided to `set_send_buffer_size`. This is for the
328     /// following reasons:
329     ///
330     /// * Most operating systems have minimum and maximum allowed sizes for the
331     ///   send buffer, and will clamp the provided value if it is below the
332     ///   minimum or above the maximum. The minimum and maximum buffer sizes are
333     ///   OS-dependent.
334     /// * Linux will double the buffer size to account for internal bookkeeping
335     ///   data, and returns the doubled value from `getsockopt(2)`. As per `man
336     ///   7 socket`:
337     ///   > Sets or gets the maximum socket send buffer in bytes. The
338     ///   > kernel doubles this value (to allow space for bookkeeping
339     ///   > overhead) when it is set using `setsockopt(2)`, and this doubled
340     ///   > value is returned by `getsockopt(2)`.
341     ///
342     /// [`set_send_buffer_size`]: #method.set_send_buffer_size
send_buffer_size(&self) -> io::Result<u32>343     pub fn send_buffer_size(&self) -> io::Result<u32> {
344         self.inner.send_buffer_size().map(|n| n as u32)
345     }
346 
347     /// Sets the size of the TCP receive buffer on this socket.
348     ///
349     /// On most operating systems, this sets the `SO_RCVBUF` socket option.
set_recv_buffer_size(&self, size: u32) -> io::Result<()>350     pub fn set_recv_buffer_size(&self, size: u32) -> io::Result<()> {
351         self.inner.set_recv_buffer_size(size as usize)
352     }
353 
354     /// Returns the size of the TCP receive buffer for this socket.
355     ///
356     /// On most operating systems, this is the value of the `SO_RCVBUF` socket
357     /// option.
358     ///
359     /// Note that if [`set_recv_buffer_size`] has been called on this socket
360     /// previously, the value returned by this function may not be the same as
361     /// the argument provided to `set_send_buffer_size`. This is for the
362     /// following reasons:
363     ///
364     /// * Most operating systems have minimum and maximum allowed sizes for the
365     ///   receive buffer, and will clamp the provided value if it is below the
366     ///   minimum or above the maximum. The minimum and maximum buffer sizes are
367     ///   OS-dependent.
368     /// * Linux will double the buffer size to account for internal bookkeeping
369     ///   data, and returns the doubled value from `getsockopt(2)`. As per `man
370     ///   7 socket`:
371     ///   > Sets or gets the maximum socket send buffer in bytes. The
372     ///   > kernel doubles this value (to allow space for bookkeeping
373     ///   > overhead) when it is set using `setsockopt(2)`, and this doubled
374     ///   > value is returned by `getsockopt(2)`.
375     ///
376     /// [`set_recv_buffer_size`]: #method.set_recv_buffer_size
recv_buffer_size(&self) -> io::Result<u32>377     pub fn recv_buffer_size(&self) -> io::Result<u32> {
378         self.inner.recv_buffer_size().map(|n| n as u32)
379     }
380 
381     /// Sets the linger duration of this socket by setting the SO_LINGER option.
382     ///
383     /// This option controls the action taken when a stream has unsent messages and the stream is
384     /// closed. If SO_LINGER is set, the system shall block the process until it can transmit the
385     /// data or until the time expires.
386     ///
387     /// If SO_LINGER is not specified, and the socket is closed, the system handles the call in a
388     /// way that allows the process to continue as quickly as possible.
set_linger(&self, dur: Option<Duration>) -> io::Result<()>389     pub fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
390         self.inner.set_linger(dur)
391     }
392 
393     /// Reads the linger duration for this socket by getting the `SO_LINGER`
394     /// option.
395     ///
396     /// For more information about this option, see [`set_linger`].
397     ///
398     /// [`set_linger`]: TcpSocket::set_linger
linger(&self) -> io::Result<Option<Duration>>399     pub fn linger(&self) -> io::Result<Option<Duration>> {
400         self.inner.linger()
401     }
402 
403     /// Sets the value of the `TCP_NODELAY` option on this socket.
404     ///
405     /// If set, this option disables the Nagle algorithm. This means that segments are always
406     /// sent as soon as possible, even if there is only a small amount of data. When not set,
407     /// data is buffered until there is a sufficient amount to send out, thereby avoiding
408     /// the frequent sending of small packets.
409     ///
410     /// # Examples
411     ///
412     /// ```no_run
413     /// use tokio::net::TcpSocket;
414     ///
415     /// # async fn dox() -> Result<(), Box<dyn std::error::Error>> {
416     /// let socket = TcpSocket::new_v4()?;
417     ///
418     /// println!("{:?}", socket.nodelay()?);
419     /// # Ok(())
420     /// # }
421     /// ```
set_nodelay(&self, nodelay: bool) -> io::Result<()>422     pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
423         self.inner.set_nodelay(nodelay)
424     }
425 
426     /// Gets the value of the `TCP_NODELAY` option on this socket.
427     ///
428     /// For more information about this option, see [`set_nodelay`].
429     ///
430     /// [`set_nodelay`]: TcpSocket::set_nodelay
431     ///
432     /// # Examples
433     ///
434     /// ```no_run
435     /// use tokio::net::TcpSocket;
436     ///
437     /// # async fn dox() -> Result<(), Box<dyn std::error::Error>> {
438     /// let stream = TcpSocket::new_v4()?;
439     ///
440     /// stream.set_nodelay(true)?;
441     /// # Ok(())
442     /// # }
443     /// ```
nodelay(&self) -> io::Result<bool>444     pub fn nodelay(&self) -> io::Result<bool> {
445         self.inner.nodelay()
446     }
447 
448     /// Gets the value of the `IP_TOS` option for this socket.
449     ///
450     /// For more information about this option, see [`set_tos`].
451     ///
452     /// **NOTE:** On Windows, `IP_TOS` is only supported on [Windows 8+ or
453     /// Windows Server 2012+.](https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options)
454     ///
455     /// [`set_tos`]: Self::set_tos
456     // https://docs.rs/socket2/0.5.3/src/socket2/socket.rs.html#1464
457     #[cfg(not(any(
458         target_os = "fuchsia",
459         target_os = "redox",
460         target_os = "solaris",
461         target_os = "illumos",
462     )))]
463     #[cfg_attr(
464         docsrs,
465         doc(cfg(not(any(
466             target_os = "fuchsia",
467             target_os = "redox",
468             target_os = "solaris",
469             target_os = "illumos",
470         ))))
471     )]
tos(&self) -> io::Result<u32>472     pub fn tos(&self) -> io::Result<u32> {
473         self.inner.tos()
474     }
475 
476     /// Sets the value for the `IP_TOS` option on this socket.
477     ///
478     /// This value sets the type-of-service field that is used in every packet
479     /// sent from this socket.
480     ///
481     /// **NOTE:** On Windows, `IP_TOS` is only supported on [Windows 8+ or
482     /// Windows Server 2012+.](https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options)
483     // https://docs.rs/socket2/0.5.3/src/socket2/socket.rs.html#1446
484     #[cfg(not(any(
485         target_os = "fuchsia",
486         target_os = "redox",
487         target_os = "solaris",
488         target_os = "illumos",
489     )))]
490     #[cfg_attr(
491         docsrs,
492         doc(cfg(not(any(
493             target_os = "fuchsia",
494             target_os = "redox",
495             target_os = "solaris",
496             target_os = "illumos",
497         ))))
498     )]
set_tos(&self, tos: u32) -> io::Result<()>499     pub fn set_tos(&self, tos: u32) -> io::Result<()> {
500         self.inner.set_tos(tos)
501     }
502 
503     /// Gets the value for the `SO_BINDTODEVICE` option on this socket
504     ///
505     /// This value gets the socket binded device's interface name.
506     #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux",))]
507     #[cfg_attr(
508         docsrs,
509         doc(cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux",)))
510     )]
device(&self) -> io::Result<Option<Vec<u8>>>511     pub fn device(&self) -> io::Result<Option<Vec<u8>>> {
512         self.inner.device()
513     }
514 
515     /// Sets the value for the `SO_BINDTODEVICE` option on this socket
516     ///
517     /// If a socket is bound to an interface, only packets received from that
518     /// particular interface are processed by the socket. Note that this only
519     /// works for some socket types, particularly `AF_INET` sockets.
520     ///
521     /// If `interface` is `None` or an empty string it removes the binding.
522     #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
523     #[cfg_attr(
524         docsrs,
525         doc(cfg(all(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))))
526     )]
bind_device(&self, interface: Option<&[u8]>) -> io::Result<()>527     pub fn bind_device(&self, interface: Option<&[u8]>) -> io::Result<()> {
528         self.inner.bind_device(interface)
529     }
530 
531     /// Gets the local address of this socket.
532     ///
533     /// Will fail on windows if called before `bind`.
534     ///
535     /// # Examples
536     ///
537     /// ```no_run
538     /// use tokio::net::TcpSocket;
539     ///
540     /// use std::io;
541     ///
542     /// #[tokio::main]
543     /// async fn main() -> io::Result<()> {
544     ///     let addr = "127.0.0.1:8080".parse().unwrap();
545     ///
546     ///     let socket = TcpSocket::new_v4()?;
547     ///     socket.bind(addr)?;
548     ///     assert_eq!(socket.local_addr().unwrap().to_string(), "127.0.0.1:8080");
549     ///     let listener = socket.listen(1024)?;
550     ///     Ok(())
551     /// }
552     /// ```
local_addr(&self) -> io::Result<SocketAddr>553     pub fn local_addr(&self) -> io::Result<SocketAddr> {
554         self.inner.local_addr().and_then(convert_address)
555     }
556 
557     /// Returns the value of the `SO_ERROR` option.
take_error(&self) -> io::Result<Option<io::Error>>558     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
559         self.inner.take_error()
560     }
561 
562     /// Binds the socket to the given address.
563     ///
564     /// This calls the `bind(2)` operating-system function. Behavior is
565     /// platform specific. Refer to the target platform's documentation for more
566     /// details.
567     ///
568     /// # Examples
569     ///
570     /// Bind a socket before listening.
571     ///
572     /// ```no_run
573     /// use tokio::net::TcpSocket;
574     ///
575     /// use std::io;
576     ///
577     /// #[tokio::main]
578     /// async fn main() -> io::Result<()> {
579     ///     let addr = "127.0.0.1:8080".parse().unwrap();
580     ///
581     ///     let socket = TcpSocket::new_v4()?;
582     ///     socket.bind(addr)?;
583     ///
584     ///     let listener = socket.listen(1024)?;
585     /// # drop(listener);
586     ///
587     ///     Ok(())
588     /// }
589     /// ```
bind(&self, addr: SocketAddr) -> io::Result<()>590     pub fn bind(&self, addr: SocketAddr) -> io::Result<()> {
591         self.inner.bind(&addr.into())
592     }
593 
594     /// Establishes a TCP connection with a peer at the specified socket address.
595     ///
596     /// The `TcpSocket` is consumed. Once the connection is established, a
597     /// connected [`TcpStream`] is returned. If the connection fails, the
598     /// encountered error is returned.
599     ///
600     /// [`TcpStream`]: TcpStream
601     ///
602     /// This calls the `connect(2)` operating-system function. Behavior is
603     /// platform specific. Refer to the target platform's documentation for more
604     /// details.
605     ///
606     /// # Examples
607     ///
608     /// Connecting to a peer.
609     ///
610     /// ```no_run
611     /// use tokio::net::TcpSocket;
612     ///
613     /// use std::io;
614     ///
615     /// #[tokio::main]
616     /// async fn main() -> io::Result<()> {
617     ///     let addr = "127.0.0.1:8080".parse().unwrap();
618     ///
619     ///     let socket = TcpSocket::new_v4()?;
620     ///     let stream = socket.connect(addr).await?;
621     /// # drop(stream);
622     ///
623     ///     Ok(())
624     /// }
625     /// ```
connect(self, addr: SocketAddr) -> io::Result<TcpStream>626     pub async fn connect(self, addr: SocketAddr) -> io::Result<TcpStream> {
627         if let Err(err) = self.inner.connect(&addr.into()) {
628             #[cfg(unix)]
629             if err.raw_os_error() != Some(libc::EINPROGRESS) {
630                 return Err(err);
631             }
632             #[cfg(windows)]
633             if err.kind() != io::ErrorKind::WouldBlock {
634                 return Err(err);
635             }
636         }
637         #[cfg(unix)]
638         let mio = {
639             use std::os::unix::io::{FromRawFd, IntoRawFd};
640 
641             let raw_fd = self.inner.into_raw_fd();
642             unsafe { mio::net::TcpStream::from_raw_fd(raw_fd) }
643         };
644 
645         #[cfg(windows)]
646         let mio = {
647             use std::os::windows::io::{FromRawSocket, IntoRawSocket};
648 
649             let raw_socket = self.inner.into_raw_socket();
650             unsafe { mio::net::TcpStream::from_raw_socket(raw_socket) }
651         };
652 
653         TcpStream::connect_mio(mio).await
654     }
655 
656     /// Converts the socket into a `TcpListener`.
657     ///
658     /// `backlog` defines the maximum number of pending connections are queued
659     /// by the operating system at any given time. Connection are removed from
660     /// the queue with [`TcpListener::accept`]. When the queue is full, the
661     /// operating-system will start rejecting connections.
662     ///
663     /// [`TcpListener::accept`]: TcpListener::accept
664     ///
665     /// This calls the `listen(2)` operating-system function, marking the socket
666     /// as a passive socket. Behavior is platform specific. Refer to the target
667     /// platform's documentation for more details.
668     ///
669     /// # Examples
670     ///
671     /// Create a `TcpListener`.
672     ///
673     /// ```no_run
674     /// use tokio::net::TcpSocket;
675     ///
676     /// use std::io;
677     ///
678     /// #[tokio::main]
679     /// async fn main() -> io::Result<()> {
680     ///     let addr = "127.0.0.1:8080".parse().unwrap();
681     ///
682     ///     let socket = TcpSocket::new_v4()?;
683     ///     socket.bind(addr)?;
684     ///
685     ///     let listener = socket.listen(1024)?;
686     /// # drop(listener);
687     ///
688     ///     Ok(())
689     /// }
690     /// ```
listen(self, backlog: u32) -> io::Result<TcpListener>691     pub fn listen(self, backlog: u32) -> io::Result<TcpListener> {
692         self.inner.listen(backlog as i32)?;
693         #[cfg(unix)]
694         let mio = {
695             use std::os::unix::io::{FromRawFd, IntoRawFd};
696 
697             let raw_fd = self.inner.into_raw_fd();
698             unsafe { mio::net::TcpListener::from_raw_fd(raw_fd) }
699         };
700 
701         #[cfg(windows)]
702         let mio = {
703             use std::os::windows::io::{FromRawSocket, IntoRawSocket};
704 
705             let raw_socket = self.inner.into_raw_socket();
706             unsafe { mio::net::TcpListener::from_raw_socket(raw_socket) }
707         };
708 
709         TcpListener::new(mio)
710     }
711 
712     /// Converts a [`std::net::TcpStream`] into a `TcpSocket`. The provided
713     /// socket must not have been connected prior to calling this function. This
714     /// function is typically used together with crates such as [`socket2`] to
715     /// configure socket options that are not available on `TcpSocket`.
716     ///
717     /// [`std::net::TcpStream`]: struct@std::net::TcpStream
718     /// [`socket2`]: https://docs.rs/socket2/
719     ///
720     /// # Notes
721     ///
722     /// The caller is responsible for ensuring that the socket is in
723     /// non-blocking mode. Otherwise all I/O operations on the socket
724     /// will block the thread, which will cause unexpected behavior.
725     /// Non-blocking mode can be set using [`set_nonblocking`].
726     ///
727     /// [`set_nonblocking`]: std::net::TcpStream::set_nonblocking
728     ///
729     /// # Examples
730     ///
731     /// ```
732     /// use tokio::net::TcpSocket;
733     /// use socket2::{Domain, Socket, Type};
734     ///
735     /// #[tokio::main]
736     /// async fn main() -> std::io::Result<()> {
737     ///     let socket2_socket = Socket::new(Domain::IPV4, Type::STREAM, None)?;
738     ///     socket2_socket.set_nonblocking(true)?;
739     ///
740     ///     let socket = TcpSocket::from_std_stream(socket2_socket.into());
741     ///
742     ///     Ok(())
743     /// }
744     /// ```
from_std_stream(std_stream: std::net::TcpStream) -> TcpSocket745     pub fn from_std_stream(std_stream: std::net::TcpStream) -> TcpSocket {
746         #[cfg(unix)]
747         {
748             use std::os::unix::io::{FromRawFd, IntoRawFd};
749 
750             let raw_fd = std_stream.into_raw_fd();
751             unsafe { TcpSocket::from_raw_fd(raw_fd) }
752         }
753 
754         #[cfg(windows)]
755         {
756             use std::os::windows::io::{FromRawSocket, IntoRawSocket};
757 
758             let raw_socket = std_stream.into_raw_socket();
759             unsafe { TcpSocket::from_raw_socket(raw_socket) }
760         }
761     }
762 }
763 
convert_address(address: socket2::SockAddr) -> io::Result<SocketAddr>764 fn convert_address(address: socket2::SockAddr) -> io::Result<SocketAddr> {
765     match address.as_socket() {
766         Some(address) => Ok(address),
767         None => Err(io::Error::new(
768             io::ErrorKind::InvalidInput,
769             "invalid address family (not IPv4 or IPv6)",
770         )),
771     }
772 }
773 
774 impl fmt::Debug for TcpSocket {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result775     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
776         self.inner.fmt(fmt)
777     }
778 }
779 
780 #[cfg(unix)]
781 impl AsRawFd for TcpSocket {
as_raw_fd(&self) -> RawFd782     fn as_raw_fd(&self) -> RawFd {
783         self.inner.as_raw_fd()
784     }
785 }
786 
787 #[cfg(unix)]
788 impl AsFd for TcpSocket {
as_fd(&self) -> BorrowedFd<'_>789     fn as_fd(&self) -> BorrowedFd<'_> {
790         unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
791     }
792 }
793 
794 #[cfg(unix)]
795 impl FromRawFd for TcpSocket {
796     /// Converts a `RawFd` to a `TcpSocket`.
797     ///
798     /// # Notes
799     ///
800     /// The caller is responsible for ensuring that the socket is in
801     /// non-blocking mode.
from_raw_fd(fd: RawFd) -> TcpSocket802     unsafe fn from_raw_fd(fd: RawFd) -> TcpSocket {
803         let inner = socket2::Socket::from_raw_fd(fd);
804         TcpSocket { inner }
805     }
806 }
807 
808 #[cfg(unix)]
809 impl IntoRawFd for TcpSocket {
into_raw_fd(self) -> RawFd810     fn into_raw_fd(self) -> RawFd {
811         self.inner.into_raw_fd()
812     }
813 }
814 
815 cfg_windows! {
816     impl IntoRawSocket for TcpSocket {
817         fn into_raw_socket(self) -> RawSocket {
818             self.inner.into_raw_socket()
819         }
820     }
821 
822     impl AsRawSocket for TcpSocket {
823         fn as_raw_socket(&self) -> RawSocket {
824             self.inner.as_raw_socket()
825         }
826     }
827 
828     impl AsSocket for TcpSocket {
829         fn as_socket(&self) -> BorrowedSocket<'_> {
830             unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
831         }
832     }
833 
834     impl FromRawSocket for TcpSocket {
835         /// Converts a `RawSocket` to a `TcpStream`.
836         ///
837         /// # Notes
838         ///
839         /// The caller is responsible for ensuring that the socket is in
840         /// non-blocking mode.
841         unsafe fn from_raw_socket(socket: RawSocket) -> TcpSocket {
842             let inner = socket2::Socket::from_raw_socket(socket);
843             TcpSocket { inner }
844         }
845     }
846 }
847