feat(udp): set SO_MARK for udp cnx

This commit is contained in:
Σrebe - Romain GERARD 2024-07-20 15:55:08 +02:00
parent 2c5cc95c52
commit 97251804dd
No known key found for this signature in database
GPG key ID: 7A42B4B97E0332F4
4 changed files with 20 additions and 4 deletions

View file

@ -1,4 +1,4 @@
use crate::{tcp};
use crate::tcp;
use anyhow::{anyhow, Context};
use futures_util::{FutureExt, TryFutureExt};
use hickory_resolver::config::{LookupIpStrategy, NameServerConfig, Protocol, ResolverConfig, ResolverOpts};

View file

@ -991,8 +991,14 @@ async fn main() {
port,
};
let connect_to_dest = |_| async {
udp::connect(&tunnel.remote.0, tunnel.remote.1, cfg.timeout_connect, &cfg.dns_resolver)
.await
udp::connect(
&tunnel.remote.0,
tunnel.remote.1,
cfg.timeout_connect,
cfg.socket_so_mark,
&cfg.dns_resolver,
)
.await
};
if let Err(err) =
@ -1033,7 +1039,7 @@ async fn main() {
.map(|s| Box::new(s) as Box<dyn T>)
}
LocalProtocol::Udp { .. } => {
udp::connect(&remote.host, remote.port, timeout, dns_resolver)
udp::connect(&remote.host, remote.port, timeout, so_mark, dns_resolver)
.await
.map(|s| Box::new(s) as Box<dyn T>)
}

View file

@ -60,6 +60,7 @@ async fn run_tunnel(
&remote.host,
remote.port,
timeout.unwrap_or(Duration::from_secs(10)),
server_config.socket_so_mark,
&server_config.dns_resolver,
)
.await?;

View file

@ -11,6 +11,7 @@ use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
use tokio::task::JoinSet;
use log::warn;
use socket2::SockRef;
use std::pin::{pin, Pin};
use std::sync::{Arc, Weak};
use std::task::{ready, Poll};
@ -323,6 +324,7 @@ pub async fn connect(
host: &Host<String>,
port: u16,
connect_timeout: Duration,
so_mark: Option<u32>,
dns_resolver: &DnsResolver,
) -> anyhow::Result<MyUdpSocket> {
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.
// We include a delay of ix * 250 milliseconds, as per RFC8305.
// See https://datatracker.ietf.org/doc/html/rfc8305#section-5