Skip to content

Commit 05a3d6c

Browse files
committed
http local listener initializing with accept_opts
- setting nodelay, keepalive and dualstack
1 parent 09ca20d commit 05a3d6c

File tree

3 files changed

+51
-27
lines changed

3 files changed

+51
-27
lines changed

Cargo.lock

Lines changed: 16 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/shadowsocks-service/src/local/http/server.rs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ use hyper::{
1515
Server,
1616
};
1717
use log::{error, info};
18-
use shadowsocks::{config::ServerAddr, lookup_then};
18+
use shadowsocks::{config::ServerAddr, lookup_then, net::TcpListener};
1919

20-
use crate::local::{context::ServiceContext, loadbalancing::PingBalancer};
20+
use crate::local::{context::ServiceContext, loadbalancing::PingBalancer, LOCAL_DEFAULT_KEEPALIVE_TIMEOUT};
2121

2222
use super::{client_cache::ProxyClientCache, connector::BypassConnector, dispatcher::HttpDispatcher};
2323

@@ -81,21 +81,40 @@ impl Http {
8181
});
8282

8383
let bind_result = match *client_config {
84-
ServerAddr::SocketAddr(sa) => Server::try_bind(&sa),
84+
ServerAddr::SocketAddr(sa) => TcpListener::bind_with_opts(&sa, self.context.accept_opts().clone()).await,
8585
ServerAddr::DomainName(ref dname, port) => lookup_then!(self.context.context_ref(), dname, port, |addr| {
86-
Server::try_bind(&addr)
86+
TcpListener::bind_with_opts(&addr, self.context.accept_opts().clone()).await
8787
})
8888
.map(|(_, b)| b),
8989
};
9090

91-
// HTTP Proxy protocol only defined in HTTP 1.x
9291
let server = match bind_result {
93-
Ok(builder) => builder
94-
.http1_only(true)
95-
.http1_preserve_header_case(true)
96-
.http1_title_case_headers(true)
97-
.tcp_sleep_on_accept_errors(true)
98-
.serve(make_service),
92+
Ok(listener) => {
93+
let listener = listener.into_inner().into_std()?;
94+
let builder = match Server::from_tcp(listener) {
95+
Ok(builder) => builder,
96+
Err(err) => {
97+
error!("hyper server from std::net::TcpListener error: {}", err);
98+
let err = io::Error::new(ErrorKind::InvalidInput, err);
99+
return Err(err);
100+
}
101+
};
102+
103+
builder
104+
.http1_only(true) // HTTP Proxy protocol only defined in HTTP 1.x
105+
.http1_preserve_header_case(true)
106+
.http1_title_case_headers(true)
107+
.tcp_sleep_on_accept_errors(true)
108+
.tcp_keepalive(
109+
self.context
110+
.accept_opts()
111+
.tcp
112+
.keepalive
113+
.or(Some(LOCAL_DEFAULT_KEEPALIVE_TIMEOUT)),
114+
)
115+
.tcp_nodelay(self.context.accept_opts().tcp.nodelay)
116+
.serve(make_service)
117+
}
99118
Err(err) => {
100119
error!("hyper server bind error: {}", err);
101120
let err = io::Error::new(ErrorKind::InvalidInput, err);

crates/shadowsocks/src/net/tcp.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,11 @@ impl TcpListener {
218218
pub async fn accept(&self) -> io::Result<(TokioTcpStream, SocketAddr)> {
219219
future::poll_fn(|cx| self.poll_accept(cx)).await
220220
}
221+
222+
/// Unwraps and take the internal `TcpListener`
223+
pub fn into_inner(self) -> TokioTcpListener {
224+
self.inner
225+
}
221226
}
222227

223228
impl Deref for TcpListener {

0 commit comments

Comments
 (0)