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::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
9 #[cfg(windows)]
10 use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
11 
12 cfg_net! {
13     /// A TCP socket that has not yet been converted to a `TcpStream` or
14     /// `TcpListener`.
15     ///
16     /// `TcpSocket` wraps an operating system socket and enables the caller to
17     /// configure the socket before establishing a TCP connection or accepting
18     /// inbound connections. The caller is able to set socket option and explicitly
19     /// bind the socket with a socket address.
20     ///
21     /// The underlying socket is closed when the `TcpSocket` value is dropped.
22     ///
23     /// `TcpSocket` should only be used directly if the default configuration used
24     /// by `TcpStream::connect` and `TcpListener::bind` does not meet the required
25     /// use case.
26     ///
27     /// Calling `TcpStream::connect("127.0.0.1:8080")` is equivalent to:
28     ///
29     /// ```no_run
30     /// use tokio::net::TcpSocket;
31     ///
32     /// use std::io;
33     ///
34     /// #[tokio::main]
35     /// async fn main() -> io::Result<()> {
36     ///     let addr = "127.0.0.1:8080".parse().unwrap();
37     ///
38     ///     let socket = TcpSocket::new_v4()?;
39     ///     let stream = socket.connect(addr).await?;
40     /// # drop(stream);
41     ///
42     ///     Ok(())
43     /// }
44     /// ```
45     ///
46     /// Calling `TcpListener::bind("127.0.0.1:8080")` is equivalent to:
47     ///
48     /// ```no_run
49     /// use tokio::net::TcpSocket;
50     ///
51     /// use std::io;
52     ///
53     /// #[tokio::main]
54     /// async fn main() -> io::Result<()> {
55     ///     let addr = "127.0.0.1:8080".parse().unwrap();
56     ///
57     ///     let socket = TcpSocket::new_v4()?;
58     ///     // On platforms with Berkeley-derived sockets, this allows to quickly
59     ///     // rebind a socket, without needing to wait for the OS to clean up the
60     ///     // previous one.
61     ///     //
62     ///     // On Windows, this allows rebinding sockets which are actively in use,
63     ///     // which allows “socket hijacking”, so we explicitly don't set it here.
64     ///     // https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse
65     ///     socket.set_reuseaddr(true)?;
66     ///     socket.bind(addr)?;
67     ///
68     ///     let listener = socket.listen(1024)?;
69     /// # drop(listener);
70     ///
71     ///     Ok(())
72     /// }
73     /// ```
74     ///
75     /// Setting socket options not explicitly provided by `TcpSocket` may be done by
76     /// accessing the `RawFd`/`RawSocket` using [`AsRawFd`]/[`AsRawSocket`] and
77     /// setting the option with a crate like [`socket2`].
78     ///
79     /// [`RawFd`]: https://doc.rust-lang.org/std/os/unix/io/type.RawFd.html
80     /// [`RawSocket`]: https://doc.rust-lang.org/std/os/windows/io/type.RawSocket.html
81     /// [`AsRawFd`]: https://doc.rust-lang.org/std/os/unix/io/trait.AsRawFd.html
82     /// [`AsRawSocket`]: https://doc.rust-lang.org/std/os/windows/io/trait.AsRawSocket.html
83     /// [`socket2`]: https://docs.rs/socket2/
84     pub struct TcpSocket {
85         inner: mio::net::TcpSocket,
86     }
87 }
88 
89 impl TcpSocket {
90     /// Create a new socket configured for IPv4.
91     ///
92     /// Calls `socket(2)` with `AF_INET` and `SOCK_STREAM`.
93     ///
94     /// # Returns
95     ///
96     /// On success, the newly created `TcpSocket` is returned. If an error is
97     /// encountered, it is returned instead.
98     ///
99     /// # Examples
100     ///
101     /// Create a new IPv4 socket and start listening.
102     ///
103     /// ```no_run
104     /// use tokio::net::TcpSocket;
105     ///
106     /// use std::io;
107     ///
108     /// #[tokio::main]
109     /// async fn main() -> io::Result<()> {
110     ///     let addr = "127.0.0.1:8080".parse().unwrap();
111     ///     let socket = TcpSocket::new_v4()?;
112     ///     socket.bind(addr)?;
113     ///
114     ///     let listener = socket.listen(128)?;
115     /// # drop(listener);
116     ///     Ok(())
117     /// }
118     /// ```
new_v4() -> io::Result<TcpSocket>119     pub fn new_v4() -> io::Result<TcpSocket> {
120         let inner = mio::net::TcpSocket::new_v4()?;
121         Ok(TcpSocket { inner })
122     }
123 
124     /// Create a new socket configured for IPv6.
125     ///
126     /// Calls `socket(2)` with `AF_INET6` and `SOCK_STREAM`.
127     ///
128     /// # Returns
129     ///
130     /// On success, the newly created `TcpSocket` is returned. If an error is
131     /// encountered, it is returned instead.
132     ///
133     /// # Examples
134     ///
135     /// Create a new IPv6 socket and start listening.
136     ///
137     /// ```no_run
138     /// use tokio::net::TcpSocket;
139     ///
140     /// use std::io;
141     ///
142     /// #[tokio::main]
143     /// async fn main() -> io::Result<()> {
144     ///     let addr = "[::1]:8080".parse().unwrap();
145     ///     let socket = TcpSocket::new_v6()?;
146     ///     socket.bind(addr)?;
147     ///
148     ///     let listener = socket.listen(128)?;
149     /// # drop(listener);
150     ///     Ok(())
151     /// }
152     /// ```
new_v6() -> io::Result<TcpSocket>153     pub fn new_v6() -> io::Result<TcpSocket> {
154         let inner = mio::net::TcpSocket::new_v6()?;
155         Ok(TcpSocket { inner })
156     }
157 
158     /// Allow the socket to bind to an in-use address.
159     ///
160     /// Behavior is platform specific. Refer to the target platform's
161     /// documentation for more details.
162     ///
163     /// # Examples
164     ///
165     /// ```no_run
166     /// use tokio::net::TcpSocket;
167     ///
168     /// use std::io;
169     ///
170     /// #[tokio::main]
171     /// async fn main() -> io::Result<()> {
172     ///     let addr = "127.0.0.1:8080".parse().unwrap();
173     ///
174     ///     let socket = TcpSocket::new_v4()?;
175     ///     socket.set_reuseaddr(true)?;
176     ///     socket.bind(addr)?;
177     ///
178     ///     let listener = socket.listen(1024)?;
179     /// # drop(listener);
180     ///
181     ///     Ok(())
182     /// }
183     /// ```
set_reuseaddr(&self, reuseaddr: bool) -> io::Result<()>184     pub fn set_reuseaddr(&self, reuseaddr: bool) -> io::Result<()> {
185         self.inner.set_reuseaddr(reuseaddr)
186     }
187 
188     /// Retrieves the value set for `SO_REUSEADDR` on this socket
189     ///
190     /// # Examples
191     ///
192     /// ```no_run
193     /// use tokio::net::TcpSocket;
194     ///
195     /// use std::io;
196     ///
197     /// #[tokio::main]
198     /// async fn main() -> io::Result<()> {
199     ///     let addr = "127.0.0.1:8080".parse().unwrap();
200     ///
201     ///     let socket = TcpSocket::new_v4()?;
202     ///     socket.set_reuseaddr(true)?;
203     ///     assert!(socket.reuseaddr().unwrap());
204     ///     socket.bind(addr)?;
205     ///
206     ///     let listener = socket.listen(1024)?;
207     ///     Ok(())
208     /// }
209     /// ```
reuseaddr(&self) -> io::Result<bool>210     pub fn reuseaddr(&self) -> io::Result<bool> {
211         self.inner.get_reuseaddr()
212     }
213 
214     /// Allow the socket to bind to an in-use port. Only available for unix systems
215     /// (excluding Solaris & Illumos).
216     ///
217     /// Behavior is platform specific. Refer to the target platform's
218     /// documentation for more details.
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_reuseport(true)?;
233     ///     socket.bind(addr)?;
234     ///
235     ///     let listener = socket.listen(1024)?;
236     ///     Ok(())
237     /// }
238     /// ```
239     #[cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos")))]
240     #[cfg_attr(
241         docsrs,
242         doc(cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos"))))
243     )]
set_reuseport(&self, reuseport: bool) -> io::Result<()>244     pub fn set_reuseport(&self, reuseport: bool) -> io::Result<()> {
245         self.inner.set_reuseport(reuseport)
246     }
247 
248     /// Allow the socket to bind to an in-use port. Only available for unix systems
249     /// (excluding Solaris & Illumos).
250     ///
251     /// Behavior is platform specific. Refer to the target platform's
252     /// documentation for more details.
253     ///
254     /// # Examples
255     ///
256     /// ```no_run
257     /// use tokio::net::TcpSocket;
258     ///
259     /// use std::io;
260     ///
261     /// #[tokio::main]
262     /// async fn main() -> io::Result<()> {
263     ///     let addr = "127.0.0.1:8080".parse().unwrap();
264     ///
265     ///     let socket = TcpSocket::new_v4()?;
266     ///     socket.set_reuseport(true)?;
267     ///     assert!(socket.reuseport().unwrap());
268     ///     socket.bind(addr)?;
269     ///
270     ///     let listener = socket.listen(1024)?;
271     ///     Ok(())
272     /// }
273     /// ```
274     #[cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos")))]
275     #[cfg_attr(
276         docsrs,
277         doc(cfg(all(unix, not(target_os = "solaris"), not(target_os = "illumos"))))
278     )]
reuseport(&self) -> io::Result<bool>279     pub fn reuseport(&self) -> io::Result<bool> {
280         self.inner.get_reuseport()
281     }
282 
283     /// Sets the size of the TCP send buffer on this socket.
284     ///
285     /// On most operating systems, this sets the `SO_SNDBUF` socket option.
set_send_buffer_size(&self, size: u32) -> io::Result<()>286     pub fn set_send_buffer_size(&self, size: u32) -> io::Result<()> {
287         self.inner.set_send_buffer_size(size)
288     }
289 
290     /// Returns the size of the TCP send buffer for this socket.
291     ///
292     /// On most operating systems, this is the value of the `SO_SNDBUF` socket
293     /// option.
294     ///
295     /// Note that if [`set_send_buffer_size`] has been called on this socket
296     /// previously, the value returned by this function may not be the same as
297     /// the argument provided to `set_send_buffer_size`. This is for the
298     /// following reasons:
299     ///
300     /// * Most operating systems have minimum and maximum allowed sizes for the
301     ///   send buffer, and will clamp the provided value if it is below the
302     ///   minimum or above the maximum. The minimum and maximum buffer sizes are
303     ///   OS-dependent.
304     /// * Linux will double the buffer size to account for internal bookkeeping
305     ///   data, and returns the doubled value from `getsockopt(2)`. As per `man
306     ///   7 socket`:
307     ///   > Sets or gets the maximum socket send buffer in bytes. The
308     ///   > kernel doubles this value (to allow space for bookkeeping
309     ///   > overhead) when it is set using `setsockopt(2)`, and this doubled
310     ///   > value is returned by `getsockopt(2)`.
311     ///
312     /// [`set_send_buffer_size`]: #method.set_send_buffer_size
send_buffer_size(&self) -> io::Result<u32>313     pub fn send_buffer_size(&self) -> io::Result<u32> {
314         self.inner.get_send_buffer_size()
315     }
316 
317     /// Sets the size of the TCP receive buffer on this socket.
318     ///
319     /// On most operating systems, this sets the `SO_RCVBUF` socket option.
set_recv_buffer_size(&self, size: u32) -> io::Result<()>320     pub fn set_recv_buffer_size(&self, size: u32) -> io::Result<()> {
321         self.inner.set_recv_buffer_size(size)
322     }
323 
324     /// Returns the size of the TCP receive buffer for this socket.
325     ///
326     /// On most operating systems, this is the value of the `SO_RCVBUF` socket
327     /// option.
328     ///
329     /// Note that if [`set_recv_buffer_size`] has been called on this socket
330     /// previously, the value returned by this function may not be the same as
331     /// the argument provided to `set_send_buffer_size`. This is for the
332     /// following reasons:
333     ///
334     /// * Most operating systems have minimum and maximum allowed sizes for the
335     ///   receive buffer, and will clamp the provided value if it is below the
336     ///   minimum or above the maximum. The minimum and maximum buffer sizes are
337     ///   OS-dependent.
338     /// * Linux will double the buffer size to account for internal bookkeeping
339     ///   data, and returns the doubled value from `getsockopt(2)`. As per `man
340     ///   7 socket`:
341     ///   > Sets or gets the maximum socket send buffer in bytes. The
342     ///   > kernel doubles this value (to allow space for bookkeeping
343     ///   > overhead) when it is set using `setsockopt(2)`, and this doubled
344     ///   > value is returned by `getsockopt(2)`.
345     ///
346     /// [`set_recv_buffer_size`]: #method.set_recv_buffer_size
recv_buffer_size(&self) -> io::Result<u32>347     pub fn recv_buffer_size(&self) -> io::Result<u32> {
348         self.inner.get_recv_buffer_size()
349     }
350 
351     /// Get the local address of this socket.
352     ///
353     /// Will fail on windows if called before `bind`.
354     ///
355     /// # Examples
356     ///
357     /// ```no_run
358     /// use tokio::net::TcpSocket;
359     ///
360     /// use std::io;
361     ///
362     /// #[tokio::main]
363     /// async fn main() -> io::Result<()> {
364     ///     let addr = "127.0.0.1:8080".parse().unwrap();
365     ///
366     ///     let socket = TcpSocket::new_v4()?;
367     ///     socket.bind(addr)?;
368     ///     assert_eq!(socket.local_addr().unwrap().to_string(), "127.0.0.1:8080");
369     ///     let listener = socket.listen(1024)?;
370     ///     Ok(())
371     /// }
372     /// ```
local_addr(&self) -> io::Result<SocketAddr>373     pub fn local_addr(&self) -> io::Result<SocketAddr> {
374         self.inner.get_localaddr()
375     }
376 
377     /// Bind the socket to the given address.
378     ///
379     /// This calls the `bind(2)` operating-system function. Behavior is
380     /// platform specific. Refer to the target platform's documentation for more
381     /// details.
382     ///
383     /// # Examples
384     ///
385     /// Bind a socket before listening.
386     ///
387     /// ```no_run
388     /// use tokio::net::TcpSocket;
389     ///
390     /// use std::io;
391     ///
392     /// #[tokio::main]
393     /// async fn main() -> io::Result<()> {
394     ///     let addr = "127.0.0.1:8080".parse().unwrap();
395     ///
396     ///     let socket = TcpSocket::new_v4()?;
397     ///     socket.bind(addr)?;
398     ///
399     ///     let listener = socket.listen(1024)?;
400     /// # drop(listener);
401     ///
402     ///     Ok(())
403     /// }
404     /// ```
bind(&self, addr: SocketAddr) -> io::Result<()>405     pub fn bind(&self, addr: SocketAddr) -> io::Result<()> {
406         self.inner.bind(addr)
407     }
408 
409     /// Establish a TCP connection with a peer at the specified socket address.
410     ///
411     /// The `TcpSocket` is consumed. Once the connection is established, a
412     /// connected [`TcpStream`] is returned. If the connection fails, the
413     /// encountered error is returned.
414     ///
415     /// [`TcpStream`]: TcpStream
416     ///
417     /// This calls the `connect(2)` operating-system function. Behavior is
418     /// platform specific. Refer to the target platform's documentation for more
419     /// details.
420     ///
421     /// # Examples
422     ///
423     /// Connecting to a peer.
424     ///
425     /// ```no_run
426     /// use tokio::net::TcpSocket;
427     ///
428     /// use std::io;
429     ///
430     /// #[tokio::main]
431     /// async fn main() -> io::Result<()> {
432     ///     let addr = "127.0.0.1:8080".parse().unwrap();
433     ///
434     ///     let socket = TcpSocket::new_v4()?;
435     ///     let stream = socket.connect(addr).await?;
436     /// # drop(stream);
437     ///
438     ///     Ok(())
439     /// }
440     /// ```
connect(self, addr: SocketAddr) -> io::Result<TcpStream>441     pub async fn connect(self, addr: SocketAddr) -> io::Result<TcpStream> {
442         let mio = self.inner.connect(addr)?;
443         TcpStream::connect_mio(mio).await
444     }
445 
446     /// Convert the socket into a `TcpListener`.
447     ///
448     /// `backlog` defines the maximum number of pending connections are queued
449     /// by the operating system at any given time. Connection are removed from
450     /// the queue with [`TcpListener::accept`]. When the queue is full, the
451     /// operating-system will start rejecting connections.
452     ///
453     /// [`TcpListener::accept`]: TcpListener::accept
454     ///
455     /// This calls the `listen(2)` operating-system function, marking the socket
456     /// as a passive socket. Behavior is platform specific. Refer to the target
457     /// platform's documentation for more details.
458     ///
459     /// # Examples
460     ///
461     /// Create a `TcpListener`.
462     ///
463     /// ```no_run
464     /// use tokio::net::TcpSocket;
465     ///
466     /// use std::io;
467     ///
468     /// #[tokio::main]
469     /// async fn main() -> io::Result<()> {
470     ///     let addr = "127.0.0.1:8080".parse().unwrap();
471     ///
472     ///     let socket = TcpSocket::new_v4()?;
473     ///     socket.bind(addr)?;
474     ///
475     ///     let listener = socket.listen(1024)?;
476     /// # drop(listener);
477     ///
478     ///     Ok(())
479     /// }
480     /// ```
listen(self, backlog: u32) -> io::Result<TcpListener>481     pub fn listen(self, backlog: u32) -> io::Result<TcpListener> {
482         let mio = self.inner.listen(backlog)?;
483         TcpListener::new(mio)
484     }
485 
486     /// Converts a [`std::net::TcpStream`] into a `TcpSocket`. The provided
487     /// socket must not have been connected prior to calling this function. This
488     /// function is typically used together with crates such as [`socket2`] to
489     /// configure socket options that are not available on `TcpSocket`.
490     ///
491     /// [`std::net::TcpStream`]: struct@std::net::TcpStream
492     /// [`socket2`]: https://docs.rs/socket2/
493     ///
494     /// # Examples
495     ///
496     /// ```
497     /// use tokio::net::TcpSocket;
498     /// use socket2::{Domain, Socket, Type};
499     ///
500     /// #[tokio::main]
501     /// async fn main() -> std::io::Result<()> {
502     ///
503     ///     let socket2_socket = Socket::new(Domain::IPV4, Type::STREAM, None)?;
504     ///
505     ///     let socket = TcpSocket::from_std_stream(socket2_socket.into());
506     ///
507     ///     Ok(())
508     /// }
509     /// ```
from_std_stream(std_stream: std::net::TcpStream) -> TcpSocket510     pub fn from_std_stream(std_stream: std::net::TcpStream) -> TcpSocket {
511         #[cfg(unix)]
512         {
513             use std::os::unix::io::{FromRawFd, IntoRawFd};
514 
515             let raw_fd = std_stream.into_raw_fd();
516             unsafe { TcpSocket::from_raw_fd(raw_fd) }
517         }
518 
519         #[cfg(windows)]
520         {
521             use std::os::windows::io::{FromRawSocket, IntoRawSocket};
522 
523             let raw_socket = std_stream.into_raw_socket();
524             unsafe { TcpSocket::from_raw_socket(raw_socket) }
525         }
526     }
527 }
528 
529 impl fmt::Debug for TcpSocket {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result530     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
531         self.inner.fmt(fmt)
532     }
533 }
534 
535 #[cfg(unix)]
536 impl AsRawFd for TcpSocket {
as_raw_fd(&self) -> RawFd537     fn as_raw_fd(&self) -> RawFd {
538         self.inner.as_raw_fd()
539     }
540 }
541 
542 #[cfg(unix)]
543 impl FromRawFd for TcpSocket {
544     /// Converts a `RawFd` to a `TcpSocket`.
545     ///
546     /// # Notes
547     ///
548     /// The caller is responsible for ensuring that the socket is in
549     /// non-blocking mode.
from_raw_fd(fd: RawFd) -> TcpSocket550     unsafe fn from_raw_fd(fd: RawFd) -> TcpSocket {
551         let inner = mio::net::TcpSocket::from_raw_fd(fd);
552         TcpSocket { inner }
553     }
554 }
555 
556 #[cfg(unix)]
557 impl IntoRawFd for TcpSocket {
into_raw_fd(self) -> RawFd558     fn into_raw_fd(self) -> RawFd {
559         self.inner.into_raw_fd()
560     }
561 }
562 
563 #[cfg(windows)]
564 impl IntoRawSocket for TcpSocket {
into_raw_socket(self) -> RawSocket565     fn into_raw_socket(self) -> RawSocket {
566         self.inner.into_raw_socket()
567     }
568 }
569 
570 #[cfg(windows)]
571 impl AsRawSocket for TcpSocket {
as_raw_socket(&self) -> RawSocket572     fn as_raw_socket(&self) -> RawSocket {
573         self.inner.as_raw_socket()
574     }
575 }
576 
577 #[cfg(windows)]
578 impl FromRawSocket for TcpSocket {
579     /// Converts a `RawSocket` to a `TcpStream`.
580     ///
581     /// # Notes
582     ///
583     /// The caller is responsible for ensuring that the socket is in
584     /// non-blocking mode.
from_raw_socket(socket: RawSocket) -> TcpSocket585     unsafe fn from_raw_socket(socket: RawSocket) -> TcpSocket {
586         let inner = mio::net::TcpSocket::from_raw_socket(socket);
587         TcpSocket { inner }
588     }
589 }
590