fix blocking issue when using dual-stack sockets
This commit is contained in:
parent
800ca15eb9
commit
8a284d56a7
@ -43,7 +43,7 @@ async fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match Socks5Server::set_config(cfg.local) {
|
match Socks5Server::set_config(cfg.local).await {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("{err}");
|
eprintln!("{err}");
|
||||||
|
@ -3,7 +3,7 @@ use bytes::Bytes;
|
|||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use quinn::VarInt;
|
use quinn::VarInt;
|
||||||
use socket2::{Domain, Protocol, SockAddr, Socket, Type};
|
use socket2::Socket;
|
||||||
use socks5_proto::{Address, Reply};
|
use socks5_proto::{Address, Reply};
|
||||||
use socks5_server::{
|
use socks5_server::{
|
||||||
auth::{NoAuth, Password},
|
auth::{NoAuth, Password},
|
||||||
@ -13,7 +13,7 @@ use socks5_server::{
|
|||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
io::{Error as IoError, ErrorKind},
|
io::{Error as IoError, ErrorKind},
|
||||||
net::{IpAddr, SocketAddr, TcpListener as StdTcpListener, UdpSocket as StdUdpSocket},
|
net::{SocketAddr, TcpListener as StdTcpListener, UdpSocket as StdUdpSocket},
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicU16, Ordering},
|
atomic::{AtomicU16, Ordering},
|
||||||
Arc,
|
Arc,
|
||||||
@ -38,22 +38,16 @@ pub struct Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Server {
|
impl Server {
|
||||||
pub fn set_config(cfg: Local) -> Result<(), Error> {
|
pub async fn set_config(cfg: Local) -> Result<(), Error> {
|
||||||
let socket = {
|
let socket = {
|
||||||
let domain = match cfg.server.ip() {
|
let socket = Socket::from(TcpListener::bind(&cfg.server).await?.into_std()?);
|
||||||
IpAddr::V4(_) => Domain::IPV4,
|
|
||||||
IpAddr::V6(_) => Domain::IPV6,
|
|
||||||
};
|
|
||||||
|
|
||||||
let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))?;
|
|
||||||
|
|
||||||
if let Some(dual_stack) = cfg.dual_stack {
|
if let Some(dual_stack) = cfg.dual_stack {
|
||||||
socket.set_only_v6(!dual_stack)?;
|
socket.set_only_v6(!dual_stack)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.set_reuse_address(true)?;
|
socket.set_reuse_address(true)?;
|
||||||
socket.bind(&SockAddr::from(cfg.server))?;
|
|
||||||
socket.listen(128)?;
|
|
||||||
TcpListener::from_std(StdTcpListener::from(socket))?
|
TcpListener::from_std(StdTcpListener::from(socket))?
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -117,30 +111,29 @@ impl Server {
|
|||||||
assoc: Associate<associate::NeedReply>,
|
assoc: Associate<associate::NeedReply>,
|
||||||
_addr: Address,
|
_addr: Address,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
async fn get_assoc_socket() -> Result<(Arc<AssociatedUdpSocket>, SocketAddr), IoError> {
|
async fn get_assoc_socket() -> Result<Arc<AssociatedUdpSocket>, IoError> {
|
||||||
let domain = match SERVER.get().unwrap().addr.ip() {
|
let socket = Socket::from(
|
||||||
IpAddr::V4(_) => Domain::IPV4,
|
UdpSocket::bind(SERVER.get().unwrap().addr)
|
||||||
IpAddr::V6(_) => Domain::IPV6,
|
.await?
|
||||||
};
|
.into_std()?,
|
||||||
|
);
|
||||||
let socket = Socket::new(domain, Type::DGRAM, Some(Protocol::UDP))?;
|
|
||||||
|
|
||||||
if let Some(dual_stack) = SERVER.get().unwrap().dual_stack {
|
if let Some(dual_stack) = SERVER.get().unwrap().dual_stack {
|
||||||
socket.set_only_v6(!dual_stack)?;
|
socket.set_only_v6(!dual_stack)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.bind(&SockAddr::from(SERVER.get().unwrap().addr))?;
|
|
||||||
|
|
||||||
let socket = AssociatedUdpSocket::from((
|
let socket = AssociatedUdpSocket::from((
|
||||||
UdpSocket::from_std(StdUdpSocket::from(socket))?,
|
UdpSocket::from_std(StdUdpSocket::from(socket))?,
|
||||||
SERVER.get().unwrap().max_pkt_size,
|
SERVER.get().unwrap().max_pkt_size,
|
||||||
));
|
));
|
||||||
|
|
||||||
let addr = socket.local_addr()?;
|
Ok(Arc::new(socket))
|
||||||
Ok((Arc::new(socket), addr))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match get_assoc_socket().await {
|
match get_assoc_socket()
|
||||||
|
.await
|
||||||
|
.and_then(|socket| socket.local_addr().map(|addr| (socket, addr)))
|
||||||
|
{
|
||||||
Ok((assoc_socket, assoc_addr)) => {
|
Ok((assoc_socket, assoc_addr)) => {
|
||||||
let assoc = assoc
|
let assoc = assoc
|
||||||
.reply(Reply::Succeeded, Address::SocketAddress(assoc_addr))
|
.reply(Reply::Succeeded, Address::SocketAddress(assoc_addr))
|
||||||
|
@ -13,12 +13,12 @@ use quinn::{
|
|||||||
};
|
};
|
||||||
use register_count::{Counter, Register};
|
use register_count::{Counter, Register};
|
||||||
use rustls::{version, ServerConfig as RustlsServerConfig};
|
use rustls::{version, ServerConfig as RustlsServerConfig};
|
||||||
use socket2::{Domain, Protocol, SockAddr, Socket, Type};
|
use socket2::Socket;
|
||||||
use std::{
|
use std::{
|
||||||
collections::{hash_map::Entry, HashMap},
|
collections::{hash_map::Entry, HashMap},
|
||||||
future::Future,
|
future::Future,
|
||||||
io::{Error as IoError, ErrorKind},
|
io::{Error as IoError, ErrorKind},
|
||||||
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, UdpSocket as StdUdpSocket},
|
net::{Ipv4Addr, Ipv6Addr, SocketAddr, UdpSocket as StdUdpSocket},
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicBool, AtomicUsize, Ordering},
|
atomic::{AtomicBool, AtomicUsize, Ordering},
|
||||||
@ -95,24 +95,16 @@ impl Server {
|
|||||||
|
|
||||||
config.transport_config(Arc::new(tp_cfg));
|
config.transport_config(Arc::new(tp_cfg));
|
||||||
|
|
||||||
let domain = match cfg.server.ip() {
|
let socket = Socket::from(StdUdpSocket::bind(cfg.server)?);
|
||||||
IpAddr::V4(_) => Domain::IPV4,
|
|
||||||
IpAddr::V6(_) => Domain::IPV6,
|
|
||||||
};
|
|
||||||
|
|
||||||
let socket = Socket::new(domain, Type::DGRAM, Some(Protocol::UDP))?;
|
|
||||||
|
|
||||||
if let Some(dual_stack) = cfg.dual_stack {
|
if let Some(dual_stack) = cfg.dual_stack {
|
||||||
socket.set_only_v6(!dual_stack)?;
|
socket.set_only_v6(!dual_stack)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.bind(&SockAddr::from(cfg.server))?;
|
|
||||||
let socket = StdUdpSocket::from(socket);
|
|
||||||
|
|
||||||
let ep = Endpoint::new(
|
let ep = Endpoint::new(
|
||||||
EndpointConfig::default(),
|
EndpointConfig::default(),
|
||||||
Some(config),
|
Some(config),
|
||||||
socket,
|
StdUdpSocket::from(socket),
|
||||||
Arc::new(TokioRuntime),
|
Arc::new(TokioRuntime),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -593,12 +585,14 @@ impl UdpSession {
|
|||||||
let socket_v4 =
|
let socket_v4 =
|
||||||
Arc::new(UdpSocket::bind(SocketAddr::from((Ipv4Addr::UNSPECIFIED, 0))).await?);
|
Arc::new(UdpSocket::bind(SocketAddr::from((Ipv4Addr::UNSPECIFIED, 0))).await?);
|
||||||
let socket_v6 = if udp_relay_ipv6 {
|
let socket_v6 = if udp_relay_ipv6 {
|
||||||
let socket = Socket::new(Domain::IPV6, Type::DGRAM, Some(Protocol::UDP))?;
|
let socket = Socket::from(
|
||||||
|
UdpSocket::bind(SocketAddr::from((Ipv6Addr::UNSPECIFIED, 0)))
|
||||||
|
.await?
|
||||||
|
.into_std()?,
|
||||||
|
);
|
||||||
|
|
||||||
socket.set_only_v6(true)?;
|
socket.set_only_v6(true)?;
|
||||||
socket.bind(&SockAddr::from(SocketAddr::from((
|
|
||||||
Ipv6Addr::UNSPECIFIED,
|
|
||||||
0,
|
|
||||||
))))?;
|
|
||||||
Some(Arc::new(UdpSocket::from_std(StdUdpSocket::from(socket))?))
|
Some(Arc::new(UdpSocket::from_std(StdUdpSocket::from(socket))?))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
Loading…
x
Reference in New Issue
Block a user