1 use std::net::{self, SocketAddr};
2 #[cfg(unix)]
3 use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
4 #[cfg(windows)]
5 use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
6 use std::{fmt, io};
7 
8 use super::{TcpSocket, TcpStream};
9 use crate::io_source::IoSource;
10 use crate::{event, sys, Interest, Registry, Token};
11 
12 /// A structure representing a socket server
13 ///
14 /// # Examples
15 ///
16 #[cfg_attr(feature = "os-poll", doc = "```")]
17 #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
18 /// # use std::error::Error;
19 /// # fn main() -> Result<(), Box<dyn Error>> {
20 /// use mio::{Events, Interest, Poll, Token};
21 /// use mio::net::TcpListener;
22 /// use std::time::Duration;
23 ///
24 /// let mut listener = TcpListener::bind("127.0.0.1:34255".parse()?)?;
25 ///
26 /// let mut poll = Poll::new()?;
27 /// let mut events = Events::with_capacity(128);
28 ///
29 /// // Register the socket with `Poll`
30 /// poll.registry().register(&mut listener, Token(0), Interest::READABLE)?;
31 ///
32 /// poll.poll(&mut events, Some(Duration::from_millis(100)))?;
33 ///
34 /// // There may be a socket ready to be accepted
35 /// #     Ok(())
36 /// # }
37 /// ```
38 pub struct TcpListener {
39     inner: IoSource<net::TcpListener>,
40 }
41 
42 impl TcpListener {
43     /// Convenience method to bind a new TCP listener to the specified address
44     /// to receive new connections.
45     ///
46     /// This function will take the following steps:
47     ///
48     /// 1. Create a new TCP socket.
49     /// 2. Set the `SO_REUSEADDR` option on the socket on Unix.
50     /// 3. Bind the socket to the specified address.
51     /// 4. Calls `listen` on the socket to prepare it to receive new connections.
bind(addr: SocketAddr) -> io::Result<TcpListener>52     pub fn bind(addr: SocketAddr) -> io::Result<TcpListener> {
53         let socket = TcpSocket::new_for_addr(addr)?;
54 
55         // On platforms with Berkeley-derived sockets, this allows to quickly
56         // rebind a socket, without needing to wait for the OS to clean up the
57         // previous one.
58         //
59         // On Windows, this allows rebinding sockets which are actively in use,
60         // which allows “socket hijacking”, so we explicitly don't set it here.
61         // https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse
62         #[cfg(not(windows))]
63         socket.set_reuseaddr(true)?;
64 
65         socket.bind(addr)?;
66         socket.listen(1024)
67     }
68 
69     /// Creates a new `TcpListener` from a standard `net::TcpListener`.
70     ///
71     /// This function is intended to be used to wrap a TCP listener from the
72     /// standard library in the Mio equivalent. The conversion assumes nothing
73     /// about the underlying listener; ; it is left up to the user to set it
74     /// in non-blocking mode.
from_std(listener: net::TcpListener) -> TcpListener75     pub fn from_std(listener: net::TcpListener) -> TcpListener {
76         TcpListener {
77             inner: IoSource::new(listener),
78         }
79     }
80 
81     /// Accepts a new `TcpStream`.
82     ///
83     /// This may return an `Err(e)` where `e.kind()` is
84     /// `io::ErrorKind::WouldBlock`. This means a stream may be ready at a later
85     /// point and one should wait for an event before calling `accept` again.
86     ///
87     /// If an accepted stream is returned, the remote address of the peer is
88     /// returned along with it.
accept(&self) -> io::Result<(TcpStream, SocketAddr)>89     pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
90         self.inner.do_io(|inner| {
91             sys::tcp::accept(inner).map(|(stream, addr)| (TcpStream::from_std(stream), addr))
92         })
93     }
94 
95     /// Returns the local socket address of this listener.
local_addr(&self) -> io::Result<SocketAddr>96     pub fn local_addr(&self) -> io::Result<SocketAddr> {
97         self.inner.local_addr()
98     }
99 
100     /// Sets the value for the `IP_TTL` option on this socket.
101     ///
102     /// This value sets the time-to-live field that is used in every packet sent
103     /// from this socket.
set_ttl(&self, ttl: u32) -> io::Result<()>104     pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
105         self.inner.set_ttl(ttl)
106     }
107 
108     /// Gets the value of the `IP_TTL` option for this socket.
109     ///
110     /// For more information about this option, see [`set_ttl`][link].
111     ///
112     /// [link]: #method.set_ttl
ttl(&self) -> io::Result<u32>113     pub fn ttl(&self) -> io::Result<u32> {
114         self.inner.ttl()
115     }
116 
117     /// Get the value of the `SO_ERROR` option on this socket.
118     ///
119     /// This will retrieve the stored error in the underlying socket, clearing
120     /// the field in the process. This can be useful for checking errors between
121     /// calls.
take_error(&self) -> io::Result<Option<io::Error>>122     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
123         self.inner.take_error()
124     }
125 }
126 
127 impl event::Source for TcpListener {
register( &mut self, registry: &Registry, token: Token, interests: Interest, ) -> io::Result<()>128     fn register(
129         &mut self,
130         registry: &Registry,
131         token: Token,
132         interests: Interest,
133     ) -> io::Result<()> {
134         self.inner.register(registry, token, interests)
135     }
136 
reregister( &mut self, registry: &Registry, token: Token, interests: Interest, ) -> io::Result<()>137     fn reregister(
138         &mut self,
139         registry: &Registry,
140         token: Token,
141         interests: Interest,
142     ) -> io::Result<()> {
143         self.inner.reregister(registry, token, interests)
144     }
145 
deregister(&mut self, registry: &Registry) -> io::Result<()>146     fn deregister(&mut self, registry: &Registry) -> io::Result<()> {
147         self.inner.deregister(registry)
148     }
149 }
150 
151 impl fmt::Debug for TcpListener {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result152     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
153         self.inner.fmt(f)
154     }
155 }
156 
157 #[cfg(unix)]
158 impl IntoRawFd for TcpListener {
into_raw_fd(self) -> RawFd159     fn into_raw_fd(self) -> RawFd {
160         self.inner.into_inner().into_raw_fd()
161     }
162 }
163 
164 #[cfg(unix)]
165 impl AsRawFd for TcpListener {
as_raw_fd(&self) -> RawFd166     fn as_raw_fd(&self) -> RawFd {
167         self.inner.as_raw_fd()
168     }
169 }
170 
171 #[cfg(unix)]
172 impl FromRawFd for TcpListener {
173     /// Converts a `RawFd` to a `TcpListener`.
174     ///
175     /// # Notes
176     ///
177     /// The caller is responsible for ensuring that the socket is in
178     /// non-blocking mode.
from_raw_fd(fd: RawFd) -> TcpListener179     unsafe fn from_raw_fd(fd: RawFd) -> TcpListener {
180         TcpListener::from_std(FromRawFd::from_raw_fd(fd))
181     }
182 }
183 
184 #[cfg(windows)]
185 impl IntoRawSocket for TcpListener {
into_raw_socket(self) -> RawSocket186     fn into_raw_socket(self) -> RawSocket {
187         self.inner.into_inner().into_raw_socket()
188     }
189 }
190 
191 #[cfg(windows)]
192 impl AsRawSocket for TcpListener {
as_raw_socket(&self) -> RawSocket193     fn as_raw_socket(&self) -> RawSocket {
194         self.inner.as_raw_socket()
195     }
196 }
197 
198 #[cfg(windows)]
199 impl FromRawSocket for TcpListener {
200     /// Converts a `RawSocket` to a `TcpListener`.
201     ///
202     /// # Notes
203     ///
204     /// The caller is responsible for ensuring that the socket is in
205     /// non-blocking mode.
from_raw_socket(socket: RawSocket) -> TcpListener206     unsafe fn from_raw_socket(socket: RawSocket) -> TcpListener {
207         TcpListener::from_std(FromRawSocket::from_raw_socket(socket))
208     }
209 }
210