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