diff --git a/Cargo.lock b/Cargo.lock index d3b5f860..b20314a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1733,6 +1733,7 @@ dependencies = [ "native-tls", "nix", "once_cell", + "parking_lot", "pin-project", "qrcode", "rand", diff --git a/crates/shadowsocks-service/Cargo.toml b/crates/shadowsocks-service/Cargo.toml index fd7c590d..a75ce714 100644 --- a/crates/shadowsocks-service/Cargo.toml +++ b/crates/shadowsocks-service/Cargo.toml @@ -56,7 +56,7 @@ local-tunnel = ["local"] # Enable socks4 protocol for sslocal local-socks4 = ["local"] # Enable Tun interface protocol for sslocal -local-tun = ["local", "etherparse", "tun", "rand", "smoltcp"] +local-tun = ["local", "etherparse", "tun", "rand", "smoltcp", "parking_lot"] # Enable Stream Cipher Protocol # WARN: Stream Cipher Protocol is proved to be insecure @@ -90,6 +90,7 @@ bytes = "1.0" byte_string = "1.0" byteorder = "1.3" rand = { version = "0.8", optional = true } +parking_lot = { version = "0.11", optional = true } futures = "0.3" tokio = { version = "1.5", features = ["io-util", "macros", "net", "parking_lot", "rt", "sync", "time"] } diff --git a/crates/shadowsocks-service/src/local/tun/tcp.rs b/crates/shadowsocks-service/src/local/tun/tcp.rs index c17a0af6..65f9becd 100644 --- a/crates/shadowsocks-service/src/local/tun/tcp.rs +++ b/crates/shadowsocks-service/src/local/tun/tcp.rs @@ -3,12 +3,13 @@ use std::{ io::{self, ErrorKind}, net::{IpAddr, SocketAddr}, pin::Pin, - sync::{Arc, Mutex as StdMutex}, + sync::Arc, task::{Context, Poll}, time::Duration as StdDuration, }; use log::{error, trace}; +use parking_lot::Mutex as ParkingMutex; use shadowsocks::relay::socks5::Address; use smoltcp::{ iface::{Interface, InterfaceBuilder, Routes, SocketHandle}, @@ -44,7 +45,7 @@ impl TcpSocketManager { } } -type SharedTcpSocketManager = Arc>; +type SharedTcpSocketManager = Arc>; struct TcpConnection { socket_handle: SocketHandle, @@ -53,7 +54,7 @@ struct TcpConnection { impl Drop for TcpConnection { fn drop(&mut self) { - let mut manager = self.manager.lock().unwrap(); + let mut manager = self.manager.lock(); let socket = manager.iface.get_socket::(self.socket_handle); socket.close(); } @@ -62,7 +63,7 @@ impl Drop for TcpConnection { impl TcpConnection { fn new(socket: TcpSocket<'static>, manager: SharedTcpSocketManager) -> TcpConnection { let socket_handle = { - let mut manager = manager.lock().unwrap(); + let mut manager = manager.lock(); manager.iface.add_socket(socket) }; @@ -72,7 +73,7 @@ impl TcpConnection { impl AsyncRead for TcpConnection { fn poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>) -> Poll> { - let mut manager = self.manager.lock().unwrap(); + let mut manager = self.manager.lock(); { let socket = manager.iface.get_socket::(self.socket_handle); if !socket.is_open() { @@ -99,7 +100,7 @@ impl AsyncRead for TcpConnection { impl AsyncWrite for TcpConnection { fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll> { - let mut manager = self.manager.lock().unwrap(); + let mut manager = self.manager.lock(); let n = { let socket = manager.iface.get_socket::(self.socket_handle); if !socket.is_open() { @@ -125,7 +126,7 @@ impl AsyncWrite for TcpConnection { } fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - let mut manager = self.manager.lock().unwrap(); + let mut manager = self.manager.lock(); { let socket = manager.iface.get_socket::(self.socket_handle); // close the transmission half. @@ -186,7 +187,7 @@ impl TcpTun { .finalize(); let manager_notify = Arc::new(Notify::new()); - let manager = Arc::new(StdMutex::new(TcpSocketManager { + let manager = Arc::new(ParkingMutex::new(TcpSocketManager { iface, manager_notify: manager_notify.clone(), })); @@ -197,7 +198,7 @@ impl TcpTun { tokio::spawn(async move { loop { let next_duration = { - let mut manager = manager.lock().unwrap(); + let mut manager = manager.lock(); if let Err(err) = manager.iface.poll(Instant::now()) { error!("virtual device error: {}", err);