tokio/net/tcp/
socket.rs

1use crate::net::{TcpListener, TcpStream};
2
3use std::fmt;
4use std::io;
5use std::net::SocketAddr;
6
7#[cfg(unix)]
8use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
9use std::time::Duration;
10
11cfg_windows! {
12    use crate::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket, AsSocket, BorrowedSocket};
13}
14
15cfg_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/fd/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/fd/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
93impl 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    /// ```
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    /// ```
156    pub fn new_v6() -> io::Result<TcpSocket> {
157        TcpSocket::new(socket2::Domain::IPV6)
158    }
159
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    /// Sets value for the `SO_KEEPALIVE` option on this socket.
189    pub fn set_keepalive(&self, keepalive: bool) -> io::Result<()> {
190        self.inner.set_keepalive(keepalive)
191    }
192
193    /// Gets the value of the `SO_KEEPALIVE` option on this socket.
194    pub fn keepalive(&self) -> io::Result<bool> {
195        self.inner.keepalive()
196    }
197
198    /// Allows the socket to bind to an in-use address.
199    ///
200    /// Behavior is platform specific. Refer to the target platform's
201    /// documentation for more details.
202    ///
203    /// # Examples
204    ///
205    /// ```no_run
206    /// use tokio::net::TcpSocket;
207    ///
208    /// use std::io;
209    ///
210    /// #[tokio::main]
211    /// async fn main() -> io::Result<()> {
212    ///     let addr = "127.0.0.1:8080".parse().unwrap();
213    ///
214    ///     let socket = TcpSocket::new_v4()?;
215    ///     socket.set_reuseaddr(true)?;
216    ///     socket.bind(addr)?;
217    ///
218    ///     let listener = socket.listen(1024)?;
219    /// # drop(listener);
220    ///
221    ///     Ok(())
222    /// }
223    /// ```
224    pub fn set_reuseaddr(&self, reuseaddr: bool) -> io::Result<()> {
225        self.inner.set_reuse_address(reuseaddr)
226    }
227
228    /// Retrieves the value set for `SO_REUSEADDR` on this socket.
229    ///
230    /// # Examples
231    ///
232    /// ```no_run
233    /// use tokio::net::TcpSocket;
234    ///
235    /// use std::io;
236    ///
237    /// #[tokio::main]
238    /// async fn main() -> io::Result<()> {
239    ///     let addr = "127.0.0.1:8080".parse().unwrap();
240    ///
241    ///     let socket = TcpSocket::new_v4()?;
242    ///     socket.set_reuseaddr(true)?;
243    ///     assert!(socket.reuseaddr().unwrap());
244    ///     socket.bind(addr)?;
245    ///
246    ///     let listener = socket.listen(1024)?;
247    ///     Ok(())
248    /// }
249    /// ```
250    pub fn reuseaddr(&self) -> io::Result<bool> {
251        self.inner.reuse_address()
252    }
253
254    /// Allows the socket to bind to an in-use port. Only available for unix systems
255    /// (excluding Solaris & Illumos).
256    ///
257    /// Behavior is platform specific. Refer to the target platform's
258    /// documentation for more details.
259    ///
260    /// # Examples
261    ///
262    /// ```no_run
263    /// use tokio::net::TcpSocket;
264    ///
265    /// use std::io;
266    ///
267    /// #[tokio::main]
268    /// async fn main() -> io::Result<()> {
269    ///     let addr = "127.0.0.1:8080".parse().unwrap();
270    ///
271    ///     let socket = TcpSocket::new_v4()?;
272    ///     socket.set_reuseport(true)?;
273    ///     socket.bind(addr)?;
274    ///
275    ///     let listener = socket.listen(1024)?;
276    ///     Ok(())
277    /// }
278    /// ```
279    #[cfg(all(
280        unix,
281        not(target_os = "solaris"),
282        not(target_os = "illumos"),
283        not(target_os = "cygwin"),
284    ))]
285    #[cfg_attr(
286        docsrs,
287        doc(cfg(all(
288            unix,
289            not(target_os = "solaris"),
290            not(target_os = "illumos"),
291            not(target_os = "cygwin"),
292        )))
293    )]
294    pub fn set_reuseport(&self, reuseport: bool) -> io::Result<()> {
295        self.inner.set_reuse_port(reuseport)
296    }
297
298    /// Allows the socket to bind to an in-use port. Only available for unix systems
299    /// (excluding Solaris & Illumos).
300    ///
301    /// Behavior is platform specific. Refer to the target platform's
302    /// documentation for more details.
303    ///
304    /// # Examples
305    ///
306    /// ```no_run
307    /// use tokio::net::TcpSocket;
308    ///
309    /// use std::io;
310    ///
311    /// #[tokio::main]
312    /// async fn main() -> io::Result<()> {
313    ///     let addr = "127.0.0.1:8080".parse().unwrap();
314    ///
315    ///     let socket = TcpSocket::new_v4()?;
316    ///     socket.set_reuseport(true)?;
317    ///     assert!(socket.reuseport().unwrap());
318    ///     socket.bind(addr)?;
319    ///
320    ///     let listener = socket.listen(1024)?;
321    ///     Ok(())
322    /// }
323    /// ```
324    #[cfg(all(
325        unix,
326        not(target_os = "solaris"),
327        not(target_os = "illumos"),
328        not(target_os = "cygwin"),
329    ))]
330    #[cfg_attr(
331        docsrs,
332        doc(cfg(all(
333            unix,
334            not(target_os = "solaris"),
335            not(target_os = "illumos"),
336            not(target_os = "cygwin"),
337        )))
338    )]
339    pub fn reuseport(&self) -> io::Result<bool> {
340        self.inner.reuse_port()
341    }
342
343    /// Sets the size of the TCP send buffer on this socket.
344    ///
345    /// On most operating systems, this sets the `SO_SNDBUF` socket option.
346    pub fn set_send_buffer_size(&self, size: u32) -> io::Result<()> {
347        self.inner.set_send_buffer_size(size as usize)
348    }
349
350    /// Returns the size of the TCP send buffer for this socket.
351    ///
352    /// On most operating systems, this is the value of the `SO_SNDBUF` socket
353    /// option.
354    ///
355    /// Note that if [`set_send_buffer_size`] has been called on this socket
356    /// previously, the value returned by this function may not be the same as
357    /// the argument provided to `set_send_buffer_size`. This is for the
358    /// following reasons:
359    ///
360    /// * Most operating systems have minimum and maximum allowed sizes for the
361    ///   send buffer, and will clamp the provided value if it is below the
362    ///   minimum or above the maximum. The minimum and maximum buffer sizes are
363    ///   OS-dependent.
364    /// * Linux will double the buffer size to account for internal bookkeeping
365    ///   data, and returns the doubled value from `getsockopt(2)`. As per `man
366    ///   7 socket`:
367    ///   > Sets or gets the maximum socket send buffer in bytes. The
368    ///   > kernel doubles this value (to allow space for bookkeeping
369    ///   > overhead) when it is set using `setsockopt(2)`, and this doubled
370    ///   > value is returned by `getsockopt(2)`.
371    ///
372    /// [`set_send_buffer_size`]: #method.set_send_buffer_size
373    pub fn send_buffer_size(&self) -> io::Result<u32> {
374        self.inner.send_buffer_size().map(|n| n as u32)
375    }
376
377    /// Sets the size of the TCP receive buffer on this socket.
378    ///
379    /// On most operating systems, this sets the `SO_RCVBUF` socket option.
380    pub fn set_recv_buffer_size(&self, size: u32) -> io::Result<()> {
381        self.inner.set_recv_buffer_size(size as usize)
382    }
383
384    /// Returns the size of the TCP receive buffer for this socket.
385    ///
386    /// On most operating systems, this is the value of the `SO_RCVBUF` socket
387    /// option.
388    ///
389    /// Note that if [`set_recv_buffer_size`] has been called on this socket
390    /// previously, the value returned by this function may not be the same as
391    /// the argument provided to `set_recv_buffer_size`. This is for the
392    /// following reasons:
393    ///
394    /// * Most operating systems have minimum and maximum allowed sizes for the
395    ///   receive buffer, and will clamp the provided value if it is below the
396    ///   minimum or above the maximum. The minimum and maximum buffer sizes are
397    ///   OS-dependent.
398    /// * Linux will double the buffer size to account for internal bookkeeping
399    ///   data, and returns the doubled value from `getsockopt(2)`. As per `man
400    ///   7 socket`:
401    ///   > Sets or gets the maximum socket send buffer in bytes. The
402    ///   > kernel doubles this value (to allow space for bookkeeping
403    ///   > overhead) when it is set using `setsockopt(2)`, and this doubled
404    ///   > value is returned by `getsockopt(2)`.
405    ///
406    /// [`set_recv_buffer_size`]: #method.set_recv_buffer_size
407    pub fn recv_buffer_size(&self) -> io::Result<u32> {
408        self.inner.recv_buffer_size().map(|n| n as u32)
409    }
410
411    /// Sets the linger duration of this socket by setting the `SO_LINGER` option.
412    ///
413    /// This option controls the action taken when a stream has unsent messages and the stream is
414    /// closed. If `SO_LINGER` is set, the system shall block the process until it can transmit the
415    /// data or until the time expires.
416    ///
417    /// If `SO_LINGER` is not specified, and the socket is closed, the system handles the call in a
418    /// way that allows the process to continue as quickly as possible.
419    pub fn set_linger(&self, dur: Option<Duration>) -> io::Result<()> {
420        self.inner.set_linger(dur)
421    }
422
423    /// Reads the linger duration for this socket by getting the `SO_LINGER`
424    /// option.
425    ///
426    /// For more information about this option, see [`set_linger`].
427    ///
428    /// [`set_linger`]: TcpSocket::set_linger
429    pub fn linger(&self) -> io::Result<Option<Duration>> {
430        self.inner.linger()
431    }
432
433    /// Sets the value of the `TCP_NODELAY` option on this socket.
434    ///
435    /// If set, this option disables the Nagle algorithm. This means that segments are always
436    /// sent as soon as possible, even if there is only a small amount of data. When not set,
437    /// data is buffered until there is a sufficient amount to send out, thereby avoiding
438    /// the frequent sending of small packets.
439    ///
440    /// # Examples
441    ///
442    /// ```no_run
443    /// use tokio::net::TcpSocket;
444    ///
445    /// # async fn dox() -> Result<(), Box<dyn std::error::Error>> {
446    /// let socket = TcpSocket::new_v4()?;
447    ///
448    /// socket.set_nodelay(true)?;
449    /// # Ok(())
450    /// # }
451    /// ```
452    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
453        self.inner.set_nodelay(nodelay)
454    }
455
456    /// Gets the value of the `TCP_NODELAY` option on this socket.
457    ///
458    /// For more information about this option, see [`set_nodelay`].
459    ///
460    /// [`set_nodelay`]: TcpSocket::set_nodelay
461    ///
462    /// # Examples
463    ///
464    /// ```no_run
465    /// use tokio::net::TcpSocket;
466    ///
467    /// # async fn dox() -> Result<(), Box<dyn std::error::Error>> {
468    /// let socket = TcpSocket::new_v4()?;
469    ///
470    /// println!("{:?}", socket.nodelay()?);
471    /// # Ok(())
472    /// # }
473    /// ```
474    pub fn nodelay(&self) -> io::Result<bool> {
475        self.inner.nodelay()
476    }
477
478    /// Gets the value of the `IP_TOS` option for this socket.
479    ///
480    /// For more information about this option, see [`set_tos`].
481    ///
482    /// **NOTE:** On Windows, `IP_TOS` is only supported on [Windows 8+ or
483    /// Windows Server 2012+.](https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options)
484    ///
485    /// [`set_tos`]: Self::set_tos
486    // https://docs.rs/socket2/0.5.3/src/socket2/socket.rs.html#1464
487    #[cfg(not(any(
488        target_os = "fuchsia",
489        target_os = "redox",
490        target_os = "solaris",
491        target_os = "illumos",
492        target_os = "haiku"
493    )))]
494    #[cfg_attr(
495        docsrs,
496        doc(cfg(not(any(
497            target_os = "fuchsia",
498            target_os = "redox",
499            target_os = "solaris",
500            target_os = "illumos",
501            target_os = "haiku"
502        ))))
503    )]
504    pub fn tos(&self) -> io::Result<u32> {
505        self.inner.tos()
506    }
507
508    /// Sets the value for the `IP_TOS` option on this socket.
509    ///
510    /// This value sets the type-of-service field that is used in every packet
511    /// sent from this socket.
512    ///
513    /// **NOTE:** On Windows, `IP_TOS` is only supported on [Windows 8+ or
514    /// Windows Server 2012+.](https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options)
515    // https://docs.rs/socket2/0.5.3/src/socket2/socket.rs.html#1446
516    #[cfg(not(any(
517        target_os = "fuchsia",
518        target_os = "redox",
519        target_os = "solaris",
520        target_os = "illumos",
521        target_os = "haiku"
522    )))]
523    #[cfg_attr(
524        docsrs,
525        doc(cfg(not(any(
526            target_os = "fuchsia",
527            target_os = "redox",
528            target_os = "solaris",
529            target_os = "illumos",
530            target_os = "haiku"
531        ))))
532    )]
533    pub fn set_tos(&self, tos: u32) -> io::Result<()> {
534        self.inner.set_tos(tos)
535    }
536
537    /// Gets the value for the `SO_BINDTODEVICE` option on this socket
538    ///
539    /// This value gets the socket binded device's interface name.
540    #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux",))]
541    #[cfg_attr(
542        docsrs,
543        doc(cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux",)))
544    )]
545    pub fn device(&self) -> io::Result<Option<Vec<u8>>> {
546        self.inner.device()
547    }
548
549    /// Sets the value for the `SO_BINDTODEVICE` option on this socket
550    ///
551    /// If a socket is bound to an interface, only packets received from that
552    /// particular interface are processed by the socket. Note that this only
553    /// works for some socket types, particularly `AF_INET` sockets.
554    ///
555    /// If `interface` is `None` or an empty string it removes the binding.
556    #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
557    #[cfg_attr(
558        docsrs,
559        doc(cfg(all(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))))
560    )]
561    pub fn bind_device(&self, interface: Option<&[u8]>) -> io::Result<()> {
562        self.inner.bind_device(interface)
563    }
564
565    /// Gets the local address of this socket.
566    ///
567    /// Will fail on windows if called before `bind`.
568    ///
569    /// # Examples
570    ///
571    /// ```no_run
572    /// use tokio::net::TcpSocket;
573    ///
574    /// use std::io;
575    ///
576    /// #[tokio::main]
577    /// async fn main() -> io::Result<()> {
578    ///     let addr = "127.0.0.1:8080".parse().unwrap();
579    ///
580    ///     let socket = TcpSocket::new_v4()?;
581    ///     socket.bind(addr)?;
582    ///     assert_eq!(socket.local_addr().unwrap().to_string(), "127.0.0.1:8080");
583    ///     let listener = socket.listen(1024)?;
584    ///     Ok(())
585    /// }
586    /// ```
587    pub fn local_addr(&self) -> io::Result<SocketAddr> {
588        self.inner.local_addr().and_then(convert_address)
589    }
590
591    /// Returns the value of the `SO_ERROR` option.
592    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
593        self.inner.take_error()
594    }
595
596    /// Binds the socket to the given address.
597    ///
598    /// This calls the `bind(2)` operating-system function. Behavior is
599    /// platform specific. Refer to the target platform's documentation for more
600    /// details.
601    ///
602    /// # Examples
603    ///
604    /// Bind a socket before listening.
605    ///
606    /// ```no_run
607    /// use tokio::net::TcpSocket;
608    ///
609    /// use std::io;
610    ///
611    /// #[tokio::main]
612    /// async fn main() -> io::Result<()> {
613    ///     let addr = "127.0.0.1:8080".parse().unwrap();
614    ///
615    ///     let socket = TcpSocket::new_v4()?;
616    ///     socket.bind(addr)?;
617    ///
618    ///     let listener = socket.listen(1024)?;
619    /// # drop(listener);
620    ///
621    ///     Ok(())
622    /// }
623    /// ```
624    pub fn bind(&self, addr: SocketAddr) -> io::Result<()> {
625        self.inner.bind(&addr.into())
626    }
627
628    /// Establishes a TCP connection with a peer at the specified socket address.
629    ///
630    /// The `TcpSocket` is consumed. Once the connection is established, a
631    /// connected [`TcpStream`] is returned. If the connection fails, the
632    /// encountered error is returned.
633    ///
634    /// [`TcpStream`]: TcpStream
635    ///
636    /// This calls the `connect(2)` operating-system function. Behavior is
637    /// platform specific. Refer to the target platform's documentation for more
638    /// details.
639    ///
640    /// # Examples
641    ///
642    /// Connecting to a peer.
643    ///
644    /// ```no_run
645    /// use tokio::net::TcpSocket;
646    ///
647    /// use std::io;
648    ///
649    /// #[tokio::main]
650    /// async fn main() -> io::Result<()> {
651    ///     let addr = "127.0.0.1:8080".parse().unwrap();
652    ///
653    ///     let socket = TcpSocket::new_v4()?;
654    ///     let stream = socket.connect(addr).await?;
655    /// # drop(stream);
656    ///
657    ///     Ok(())
658    /// }
659    /// ```
660    pub async fn connect(self, addr: SocketAddr) -> io::Result<TcpStream> {
661        if let Err(err) = self.inner.connect(&addr.into()) {
662            #[cfg(unix)]
663            if err.raw_os_error() != Some(libc::EINPROGRESS) {
664                return Err(err);
665            }
666            #[cfg(windows)]
667            if err.kind() != io::ErrorKind::WouldBlock {
668                return Err(err);
669            }
670        }
671        #[cfg(unix)]
672        let mio = {
673            use std::os::unix::io::{FromRawFd, IntoRawFd};
674
675            let raw_fd = self.inner.into_raw_fd();
676            unsafe { mio::net::TcpStream::from_raw_fd(raw_fd) }
677        };
678
679        #[cfg(windows)]
680        let mio = {
681            use std::os::windows::io::{FromRawSocket, IntoRawSocket};
682
683            let raw_socket = self.inner.into_raw_socket();
684            unsafe { mio::net::TcpStream::from_raw_socket(raw_socket) }
685        };
686
687        TcpStream::connect_mio(mio).await
688    }
689
690    /// Converts the socket into a `TcpListener`.
691    ///
692    /// `backlog` defines the maximum number of pending connections are queued
693    /// by the operating system at any given time. Connection are removed from
694    /// the queue with [`TcpListener::accept`]. When the queue is full, the
695    /// operating-system will start rejecting connections.
696    ///
697    /// [`TcpListener::accept`]: TcpListener::accept
698    ///
699    /// This calls the `listen(2)` operating-system function, marking the socket
700    /// as a passive socket. Behavior is platform specific. Refer to the target
701    /// platform's documentation for more details.
702    ///
703    /// # Examples
704    ///
705    /// Create a `TcpListener`.
706    ///
707    /// ```no_run
708    /// use tokio::net::TcpSocket;
709    ///
710    /// use std::io;
711    ///
712    /// #[tokio::main]
713    /// async fn main() -> io::Result<()> {
714    ///     let addr = "127.0.0.1:8080".parse().unwrap();
715    ///
716    ///     let socket = TcpSocket::new_v4()?;
717    ///     socket.bind(addr)?;
718    ///
719    ///     let listener = socket.listen(1024)?;
720    /// # drop(listener);
721    ///
722    ///     Ok(())
723    /// }
724    /// ```
725    pub fn listen(self, backlog: u32) -> io::Result<TcpListener> {
726        self.inner.listen(backlog as i32)?;
727        #[cfg(unix)]
728        let mio = {
729            use std::os::unix::io::{FromRawFd, IntoRawFd};
730
731            let raw_fd = self.inner.into_raw_fd();
732            unsafe { mio::net::TcpListener::from_raw_fd(raw_fd) }
733        };
734
735        #[cfg(windows)]
736        let mio = {
737            use std::os::windows::io::{FromRawSocket, IntoRawSocket};
738
739            let raw_socket = self.inner.into_raw_socket();
740            unsafe { mio::net::TcpListener::from_raw_socket(raw_socket) }
741        };
742
743        TcpListener::new(mio)
744    }
745
746    /// Converts a [`std::net::TcpStream`] into a `TcpSocket`. The provided
747    /// socket must not have been connected prior to calling this function. This
748    /// function is typically used together with crates such as [`socket2`] to
749    /// configure socket options that are not available on `TcpSocket`.
750    ///
751    /// [`std::net::TcpStream`]: struct@std::net::TcpStream
752    /// [`socket2`]: https://docs.rs/socket2/
753    ///
754    /// # Notes
755    ///
756    /// The caller is responsible for ensuring that the socket is in
757    /// non-blocking mode. Otherwise all I/O operations on the socket
758    /// will block the thread, which will cause unexpected behavior.
759    /// Non-blocking mode can be set using [`set_nonblocking`].
760    ///
761    /// [`set_nonblocking`]: std::net::TcpStream::set_nonblocking
762    ///
763    /// # Examples
764    ///
765    /// ```
766    /// use tokio::net::TcpSocket;
767    /// use socket2::{Domain, Socket, Type};
768    ///
769    /// #[tokio::main]
770    /// async fn main() -> std::io::Result<()> {
771    /// #   if cfg!(miri) { return Ok(()); } // No `socket` in miri.
772    ///     let socket2_socket = Socket::new(Domain::IPV4, Type::STREAM, None)?;
773    ///     socket2_socket.set_nonblocking(true)?;
774    ///
775    ///     let socket = TcpSocket::from_std_stream(socket2_socket.into());
776    ///
777    ///     Ok(())
778    /// }
779    /// ```
780    pub fn from_std_stream(std_stream: std::net::TcpStream) -> TcpSocket {
781        #[cfg(unix)]
782        {
783            use std::os::unix::io::{FromRawFd, IntoRawFd};
784
785            let raw_fd = std_stream.into_raw_fd();
786            unsafe { TcpSocket::from_raw_fd(raw_fd) }
787        }
788
789        #[cfg(windows)]
790        {
791            use std::os::windows::io::{FromRawSocket, IntoRawSocket};
792
793            let raw_socket = std_stream.into_raw_socket();
794            unsafe { TcpSocket::from_raw_socket(raw_socket) }
795        }
796    }
797}
798
799fn convert_address(address: socket2::SockAddr) -> io::Result<SocketAddr> {
800    match address.as_socket() {
801        Some(address) => Ok(address),
802        None => Err(io::Error::new(
803            io::ErrorKind::InvalidInput,
804            "invalid address family (not IPv4 or IPv6)",
805        )),
806    }
807}
808
809impl fmt::Debug for TcpSocket {
810    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
811        self.inner.fmt(fmt)
812    }
813}
814
815// These trait implementations can't be build on Windows, so we completely
816// ignore them, even when building documentation.
817#[cfg(unix)]
818cfg_unix! {
819    impl AsRawFd for TcpSocket {
820        fn as_raw_fd(&self) -> RawFd {
821            self.inner.as_raw_fd()
822        }
823    }
824
825    impl AsFd for TcpSocket {
826        fn as_fd(&self) -> BorrowedFd<'_> {
827            unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
828        }
829    }
830
831    impl FromRawFd for TcpSocket {
832        /// Converts a `RawFd` to a `TcpSocket`.
833        ///
834        /// # Notes
835        ///
836        /// The caller is responsible for ensuring that the socket is in
837        /// non-blocking mode.
838        unsafe fn from_raw_fd(fd: RawFd) -> TcpSocket {
839            let inner = socket2::Socket::from_raw_fd(fd);
840            TcpSocket { inner }
841        }
842    }
843
844    impl IntoRawFd for TcpSocket {
845        fn into_raw_fd(self) -> RawFd {
846            self.inner.into_raw_fd()
847        }
848    }
849}
850
851cfg_windows! {
852    impl IntoRawSocket for TcpSocket {
853        fn into_raw_socket(self) -> RawSocket {
854            self.inner.into_raw_socket()
855        }
856    }
857
858    impl AsRawSocket for TcpSocket {
859        fn as_raw_socket(&self) -> RawSocket {
860            self.inner.as_raw_socket()
861        }
862    }
863
864    impl AsSocket for TcpSocket {
865        fn as_socket(&self) -> BorrowedSocket<'_> {
866            unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
867        }
868    }
869
870    impl FromRawSocket for TcpSocket {
871        /// Converts a `RawSocket` to a `TcpStream`.
872        ///
873        /// # Notes
874        ///
875        /// The caller is responsible for ensuring that the socket is in
876        /// non-blocking mode.
877        unsafe fn from_raw_socket(socket: RawSocket) -> TcpSocket {
878            let inner = socket2::Socket::from_raw_socket(socket);
879            TcpSocket { inner }
880        }
881    }
882}