feat(udp): set SO_MARK for udp cnx
This commit is contained in:
parent
2c5cc95c52
commit
97251804dd
4 changed files with 20 additions and 4 deletions
|
@ -1,4 +1,4 @@
|
||||||
use crate::{tcp};
|
use crate::tcp;
|
||||||
use anyhow::{anyhow, Context};
|
use anyhow::{anyhow, Context};
|
||||||
use futures_util::{FutureExt, TryFutureExt};
|
use futures_util::{FutureExt, TryFutureExt};
|
||||||
use hickory_resolver::config::{LookupIpStrategy, NameServerConfig, Protocol, ResolverConfig, ResolverOpts};
|
use hickory_resolver::config::{LookupIpStrategy, NameServerConfig, Protocol, ResolverConfig, ResolverOpts};
|
||||||
|
|
12
src/main.rs
12
src/main.rs
|
@ -991,8 +991,14 @@ async fn main() {
|
||||||
port,
|
port,
|
||||||
};
|
};
|
||||||
let connect_to_dest = |_| async {
|
let connect_to_dest = |_| async {
|
||||||
udp::connect(&tunnel.remote.0, tunnel.remote.1, cfg.timeout_connect, &cfg.dns_resolver)
|
udp::connect(
|
||||||
.await
|
&tunnel.remote.0,
|
||||||
|
tunnel.remote.1,
|
||||||
|
cfg.timeout_connect,
|
||||||
|
cfg.socket_so_mark,
|
||||||
|
&cfg.dns_resolver,
|
||||||
|
)
|
||||||
|
.await
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(err) =
|
if let Err(err) =
|
||||||
|
@ -1033,7 +1039,7 @@ async fn main() {
|
||||||
.map(|s| Box::new(s) as Box<dyn T>)
|
.map(|s| Box::new(s) as Box<dyn T>)
|
||||||
}
|
}
|
||||||
LocalProtocol::Udp { .. } => {
|
LocalProtocol::Udp { .. } => {
|
||||||
udp::connect(&remote.host, remote.port, timeout, dns_resolver)
|
udp::connect(&remote.host, remote.port, timeout, so_mark, dns_resolver)
|
||||||
.await
|
.await
|
||||||
.map(|s| Box::new(s) as Box<dyn T>)
|
.map(|s| Box::new(s) as Box<dyn T>)
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,7 @@ async fn run_tunnel(
|
||||||
&remote.host,
|
&remote.host,
|
||||||
remote.port,
|
remote.port,
|
||||||
timeout.unwrap_or(Duration::from_secs(10)),
|
timeout.unwrap_or(Duration::from_secs(10)),
|
||||||
|
server_config.socket_so_mark,
|
||||||
&server_config.dns_resolver,
|
&server_config.dns_resolver,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
|
@ -11,6 +11,7 @@ use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
|
||||||
use tokio::task::JoinSet;
|
use tokio::task::JoinSet;
|
||||||
|
|
||||||
use log::warn;
|
use log::warn;
|
||||||
|
use socket2::SockRef;
|
||||||
use std::pin::{pin, Pin};
|
use std::pin::{pin, Pin};
|
||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use std::task::{ready, Poll};
|
use std::task::{ready, Poll};
|
||||||
|
@ -323,6 +324,7 @@ pub async fn connect(
|
||||||
host: &Host<String>,
|
host: &Host<String>,
|
||||||
port: u16,
|
port: u16,
|
||||||
connect_timeout: Duration,
|
connect_timeout: Duration,
|
||||||
|
so_mark: Option<u32>,
|
||||||
dns_resolver: &DnsResolver,
|
dns_resolver: &DnsResolver,
|
||||||
) -> anyhow::Result<MyUdpSocket> {
|
) -> anyhow::Result<MyUdpSocket> {
|
||||||
info!("Opening UDP connection to {}:{}", host, port);
|
info!("Opening UDP connection to {}:{}", host, port);
|
||||||
|
@ -354,6 +356,13 @@ pub async fn connect(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
if let Some(so_mark) = so_mark {
|
||||||
|
SockRef::from(&socket)
|
||||||
|
.set_mark(so_mark)
|
||||||
|
.with_context(|| format!("cannot set SO_MARK on socket: {:?}", io::Error::last_os_error()))?;
|
||||||
|
}
|
||||||
|
|
||||||
// Spawn the connection attempt in the join set.
|
// Spawn the connection attempt in the join set.
|
||||||
// We include a delay of ix * 250 milliseconds, as per RFC8305.
|
// We include a delay of ix * 250 milliseconds, as per RFC8305.
|
||||||
// See https://datatracker.ietf.org/doc/html/rfc8305#section-5
|
// See https://datatracker.ietf.org/doc/html/rfc8305#section-5
|
||||||
|
|
Loading…
Reference in a new issue