From 3f49d8ab546789da46f1c8d12b8706e6b93d4262 Mon Sep 17 00:00:00 2001 From: fakeshadow <24548779@qq.com> Date: Sun, 7 Nov 2021 22:18:23 +0800 Subject: [PATCH] remove usage of mio::net::TcpSocket (#413) --- actix-server/Cargo.toml | 1 + actix-server/src/builder.rs | 16 +++------------- actix-server/src/socket.rs | 25 +++++++++++++++++++------ actix-server/tests/test_server.rs | 13 ++++++++----- 4 files changed, 31 insertions(+), 24 deletions(-) diff --git a/actix-server/Cargo.toml b/actix-server/Cargo.toml index d58aaa39..b6665b29 100755 --- a/actix-server/Cargo.toml +++ b/actix-server/Cargo.toml @@ -29,6 +29,7 @@ futures-core = { version = "0.3.7", default-features = false, features = ["alloc log = "0.4" mio = { version = "0.7.6", features = ["os-poll", "net"] } num_cpus = "1.13" +socket2 = "0.4.2" tokio = { version = "1.5.1", features = ["sync"] } [dev-dependencies] diff --git a/actix-server/src/builder.rs b/actix-server/src/builder.rs index 0d4abe78..dbf00303 100644 --- a/actix-server/src/builder.rs +++ b/actix-server/src/builder.rs @@ -8,7 +8,8 @@ use crate::{ server::ServerCommand, service::{InternalServiceFactory, ServiceFactory, StreamNewService}, socket::{ - MioListener, MioTcpListener, MioTcpSocket, StdSocketAddr, StdTcpListener, ToSocketAddrs, + create_mio_tcp_listener, MioListener, MioTcpListener, StdSocketAddr, StdTcpListener, + ToSocketAddrs, }, worker::ServerWorkerConfig, Server, @@ -263,7 +264,7 @@ pub(super) fn bind_addr( let mut success = false; let mut sockets = Vec::new(); for addr in addr.to_socket_addrs()? { - match create_tcp_listener(addr, backlog) { + match create_mio_tcp_listener(addr, backlog) { Ok(lst) => { success = true; sockets.push(lst); @@ -283,14 +284,3 @@ pub(super) fn bind_addr( )) } } - -fn create_tcp_listener(addr: StdSocketAddr, backlog: u32) -> io::Result { - let socket = match addr { - StdSocketAddr::V4(_) => MioTcpSocket::new_v4()?, - StdSocketAddr::V6(_) => MioTcpSocket::new_v6()?, - }; - - socket.set_reuseaddr(true)?; - socket.bind(addr)?; - socket.listen(backlog) -} diff --git a/actix-server/src/socket.rs b/actix-server/src/socket.rs index cd7ccc1a..6f641d73 100644 --- a/actix-server/src/socket.rs +++ b/actix-server/src/socket.rs @@ -2,7 +2,7 @@ pub(crate) use std::net::{ SocketAddr as StdSocketAddr, TcpListener as StdTcpListener, ToSocketAddrs, }; -pub(crate) use mio::net::{TcpListener as MioTcpListener, TcpSocket as MioTcpSocket}; +pub(crate) use mio::net::TcpListener as MioTcpListener; #[cfg(unix)] pub(crate) use { mio::net::UnixListener as MioUnixListener, @@ -223,6 +223,22 @@ mod unix_impl { } } +pub(crate) fn create_mio_tcp_listener( + addr: StdSocketAddr, + backlog: u32, +) -> io::Result { + use socket2::{Domain, Protocol, Socket, Type}; + + let socket = Socket::new(Domain::for_address(addr), Type::STREAM, Some(Protocol::TCP))?; + + socket.set_reuse_address(true)?; + socket.set_nonblocking(true)?; + socket.bind(&addr.into())?; + socket.listen(backlog as i32)?; + + Ok(MioTcpListener::from_std(StdTcpListener::from(socket))) +} + #[cfg(test)] mod tests { use super::*; @@ -234,11 +250,8 @@ mod tests { assert_eq!(format!("{}", addr), "127.0.0.1:8080"); let addr: StdSocketAddr = "127.0.0.1:0".parse().unwrap(); - let socket = MioTcpSocket::new_v4().unwrap(); - socket.set_reuseaddr(true).unwrap(); - socket.bind(addr).unwrap(); - let tcp = socket.listen(128).unwrap(); - let lst = MioListener::Tcp(tcp); + let lst = create_mio_tcp_listener(addr, 128).unwrap(); + let lst = MioListener::Tcp(lst); assert!(format!("{:?}", lst).contains("TcpListener")); assert!(format!("{}", lst).contains("127.0.0.1")); } diff --git a/actix-server/tests/test_server.rs b/actix-server/tests/test_server.rs index 0506586e..0a8cd2ae 100644 --- a/actix-server/tests/test_server.rs +++ b/actix-server/tests/test_server.rs @@ -5,14 +5,17 @@ use std::{net, thread, time::Duration}; use actix_rt::{net::TcpStream, time::sleep}; use actix_server::Server; use actix_service::fn_service; +use socket2::{Domain, Protocol, Socket, Type}; fn unused_addr() -> net::SocketAddr { let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap(); - let socket = mio::net::TcpSocket::new_v4().unwrap(); - socket.bind(addr).unwrap(); - socket.set_reuseaddr(true).unwrap(); - let tcp = socket.listen(32).unwrap(); - tcp.local_addr().unwrap() + let socket = + Socket::new(Domain::for_address(addr), Type::STREAM, Some(Protocol::TCP)).unwrap(); + socket.set_reuse_address(true).unwrap(); + socket.set_nonblocking(true).unwrap(); + socket.bind(&addr.into()).unwrap(); + socket.listen(32).unwrap(); + net::TcpListener::from(socket).local_addr().unwrap() } #[test]