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/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
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(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 )]
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 )]
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.
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
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.
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
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.
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
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 /// println!("{:?}", socket.nodelay()?);
429 /// # Ok(())
430 /// # }
431 /// ```
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 stream = TcpSocket::new_v4()?;
449 ///
450 /// stream.set_nodelay(true)?;
451 /// # Ok(())
452 /// # }
453 /// ```
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 )]
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 )]
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 )]
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 )]
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 /// ```
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.
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 /// ```
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 /// ```
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 /// ```
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 /// ```
755 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
774fn convert_address(address: socket2::SockAddr) -> io::Result<SocketAddr> {
775 match address.as_socket() {
776 Some(address: SocketAddr) => Ok(address),
777 None => Err(io::Error::new(
778 kind:io::ErrorKind::InvalidInput,
779 error:"invalid address family (not IPv4 or IPv6)",
780 )),
781 }
782}
783
784impl fmt::Debug for TcpSocket {
785 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
786 self.inner.fmt(fmt)
787 }
788}
789
790cfg_unix! {
791 impl AsRawFd for TcpSocket {
792 fn as_raw_fd(&self) -> RawFd {
793 self.inner.as_raw_fd()
794 }
795 }
796
797 impl AsFd for TcpSocket {
798 fn as_fd(&self) -> BorrowedFd<'_> {
799 unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
800 }
801 }
802
803 impl FromRawFd for TcpSocket {
804 /// Converts a `RawFd` to a `TcpSocket`.
805 ///
806 /// # Notes
807 ///
808 /// The caller is responsible for ensuring that the socket is in
809 /// non-blocking mode.
810 unsafe fn from_raw_fd(fd: RawFd) -> TcpSocket {
811 let inner = socket2::Socket::from_raw_fd(fd);
812 TcpSocket { inner }
813 }
814 }
815
816 impl IntoRawFd for TcpSocket {
817 fn into_raw_fd(self) -> RawFd {
818 self.inner.into_raw_fd()
819 }
820 }
821}
822
823cfg_windows! {
824 impl IntoRawSocket for TcpSocket {
825 fn into_raw_socket(self) -> RawSocket {
826 self.inner.into_raw_socket()
827 }
828 }
829
830 impl AsRawSocket for TcpSocket {
831 fn as_raw_socket(&self) -> RawSocket {
832 self.inner.as_raw_socket()
833 }
834 }
835
836 impl AsSocket for TcpSocket {
837 fn as_socket(&self) -> BorrowedSocket<'_> {
838 unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) }
839 }
840 }
841
842 impl FromRawSocket for TcpSocket {
843 /// Converts a `RawSocket` to a `TcpStream`.
844 ///
845 /// # Notes
846 ///
847 /// The caller is responsible for ensuring that the socket is in
848 /// non-blocking mode.
849 unsafe fn from_raw_socket(socket: RawSocket) -> TcpSocket {
850 let inner = socket2::Socket::from_raw_socket(socket);
851 TcpSocket { inner }
852 }
853 }
854}
855