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