mirror of
https://github.com/TrustTunnel/TrustTunnel.git
synced 2026-04-28 03:39:53 +00:00
Pull request 194: TRUST-116 add deterministic source port selection for udp nat in vpnlibs endpoint
Squashed commit of the following: commit08dfcfd9bdMerge:2652f1ca89bf60Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Fri Apr 17 21:33:46 2026 +0500 Merge remote-tracking branch 'origin/dev-1.1' into TRUST-116-add-deterministic-source-port-selection-for-udp-nat-in-vpnlibs-endpoint # Conflicts: # CHANGELOG.md commit2652f1c947Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Fri Apr 17 21:29:52 2026 +0500 Revert "Merge branch 'master' into TRUST-116-add-deterministic-source-port-selection-for-udp-nat-in-vpnlibs-endpoint" This reverts commit5c07c29c40, reversing changes made toc2947015d1. commit5c07c29c40Merge:c294701f73bb77Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Fri Apr 17 21:04:30 2026 +0500 Merge branch 'master' into TRUST-116-add-deterministic-source-port-selection-for-udp-nat-in-vpnlibs-endpoint commitc2947015d1Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Wed Apr 8 19:30:21 2026 +0500 Remove redundant test commit22942df074Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Wed Apr 8 19:26:16 2026 +0500 Update CHANGELOG commitdb336ae2bfAuthor: Ilia Zhirov <i.zhirov@adguard.com> Date: Wed Apr 8 19:20:37 2026 +0500 Preserve client source port on outgoing UDP sockets commitbf1f5e9e3aAuthor: Ilia Zhirov <i.zhirov@adguard.com> Date: Wed Apr 8 19:18:47 2026 +0500 Add unit tests for make_udp_socket_with_preferred_port commit826630e032Author: Ilia Zhirov <i.zhirov@adguard.com> Date: Wed Apr 8 19:16:56 2026 +0500 Add make_udp_socket_with_preferred_port to net_utils commitf73bb77800Author: Bamboo <Bamboo> Date: Mon Mar 16 14:16:15 2026 +0000 skipci: Automatic version increment by Bamboo commit6c6655bcf2Author: Aleksei Zhavoronkov <a.zhavoronkov@adguard.com> Date: Mon Mar 16 13:47:11 2026 +0000 Pull request 184: Fix linter and sync gh and bamboo md linters Squashed commit of the following: commit 315a5cbdc6c9cba5ed02cd0b82863a026d6b429b Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com> Date: Mon Mar 16 15:01:42 2026 +0300 return commit ee70cd9ba2730b5152b98918bf5526b6ddfefe02 Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com> Date: Mon Mar 16 14:53:54 2026 +0300 Fix commit f00f1003574c7e8aefee0c20cc316befc5a0396d Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com> Date: Mon Mar 16 14:52:55 2026 +0300 Use another action commit fb771935f946b0c73a6e83c846dc95fb219c0906 Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com> Date: Mon Mar 16 14:48:11 2026 +0300 Fix linter and sync gh and bamboo md linters commit7adca494d4Author: Bamboo <Bamboo> Date: Mon Mar 16 08:17:56 2026 +0000 skipci: Automatic version increment by Bamboo commit2f4de67487Author: Aleksei Zhavoronkov <a.zhavoronkov@adguard.com> Date: Mon Mar 16 08:17:15 2026 +0000 Pull request 183: Rename PR template and fix its path Squashed commit of the following: commit 8db6e2b64f2635b6c2fed40a66a3212875ab44bc Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com> Date: Mon Mar 16 11:04:13 2026 +0300 Rename PR template and fix its path commit95a1f0c07fAuthor: Bamboo <Bamboo> Date: Mon Mar 16 07:37:39 2026 +0000 skipci: Automatic version increment by Bamboo commitc1a5c0b45eAuthor: Aleksei Zhavoronkov <a.zhavoronkov@adguard.com> Date: Mon Mar 16 07:37:22 2026 +0000 Pull request 182: Add github PR template Squashed commit of the following: commitdd488f21deAuthor: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com> Date: Mon Mar 16 09:54:32 2026 +0300 Add github PR template commit28ba5a6f6cAuthor: Bamboo <Bamboo> Date: Mon Mar 16 06:22:12 2026 +0000 skipci: Automatic version increment by Bamboo commit531f0f7026Author: Aleksei Zhavoronkov <a.zhavoronkov@adguard.com> Date: Mon Mar 16 06:21:56 2026 +0000 Pull request 167: Print message about the QR code for mobile clients Squashed commit of the following: commitc5cec4ea78Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com> Date: Fri Mar 13 11:52:00 2026 +0300 Add blank line before qr message commitcba915c846Author: Zhavoronkov Aleksei <a.zhavoronkov@adguard.com> Date: Fri Mar 13 11:45:02 2026 +0300 Also print page URL with QR-code
This commit is contained in:
parent
a89bf60aaf
commit
52a8a3fc67
3 changed files with 64 additions and 4 deletions
|
|
@ -1,10 +1,10 @@
|
|||
# CHANGELOG
|
||||
|
||||
- [Feature] Preserve client source port on outgoing UDP connections. The endpoint now attempts to bind outgoing UDP sockets to the same source port the client application originally used, falling back to an OS-assigned ephemeral port when unavailable. This reduces NAT rebinding issues for protocols sensitive to source port changes.
|
||||
- [Feature] Added destination port filtering to rules config
|
||||
- Added `[inbound]` section for client filtering
|
||||
- Added `[outbound]` section for destination filtering
|
||||
- Rules in legacy configs are treated as `[inbound]`
|
||||
|
||||
- [Feature] SIGHUP credential reload support
|
||||
- Credentials can now be reloaded without restarting the endpoint via `systemctl reload` or SIGHUP
|
||||
- Added `ExecReload` directive to systemd service template
|
||||
|
|
|
|||
|
|
@ -86,6 +86,25 @@ pub(crate) fn make_udp_socket(is_v4: bool) -> io::Result<UdpSocket> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Try to bind a UDP socket to `preferred_port`. If the port is unavailable,
|
||||
/// fall back to an OS-assigned ephemeral port.
|
||||
pub(crate) fn make_udp_socket_with_preferred_port(
|
||||
is_v4: bool,
|
||||
preferred_port: u16,
|
||||
) -> io::Result<UdpSocket> {
|
||||
let bind_addr = if is_v4 {
|
||||
SocketAddr::from((Ipv4Addr::UNSPECIFIED, preferred_port))
|
||||
} else {
|
||||
SocketAddr::from((Ipv6Addr::UNSPECIFIED, preferred_port))
|
||||
};
|
||||
|
||||
match UdpSocket::bind(bind_addr) {
|
||||
Ok(socket) => Ok(socket),
|
||||
Err(_) if preferred_port != 0 => make_udp_socket(is_v4),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
/// https://www.rfc-editor.org/rfc/rfc9000.html#section-16
|
||||
pub(crate) const fn varint_len(x: usize) -> usize {
|
||||
if x <= 63 {
|
||||
|
|
@ -946,4 +965,44 @@ mod tests {
|
|||
let compat: IpAddr = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0xc0a8, 0x0101));
|
||||
assert_eq!(super::unmap_ipv6(compat), IpAddr::from([192, 168, 1, 1]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preferred_port_binds_when_free() {
|
||||
use super::make_udp_socket_with_preferred_port;
|
||||
|
||||
let socket = make_udp_socket_with_preferred_port(true, 0).unwrap();
|
||||
let port = socket.local_addr().unwrap().port();
|
||||
// Port 0 means OS picks an ephemeral port, so the actual port must be non-zero.
|
||||
assert_ne!(port, 0);
|
||||
drop(socket);
|
||||
|
||||
// Bind to a specific port that we just confirmed is available.
|
||||
let socket = make_udp_socket_with_preferred_port(true, port).unwrap();
|
||||
assert_eq!(socket.local_addr().unwrap().port(), port);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preferred_port_falls_back_when_taken() {
|
||||
use super::make_udp_socket_with_preferred_port;
|
||||
|
||||
// Occupy a port.
|
||||
let holder = make_udp_socket_with_preferred_port(true, 0).unwrap();
|
||||
let occupied_port = holder.local_addr().unwrap().port();
|
||||
|
||||
// Request the same port -- should fall back to an ephemeral port.
|
||||
let socket = make_udp_socket_with_preferred_port(true, occupied_port).unwrap();
|
||||
assert_ne!(socket.local_addr().unwrap().port(), occupied_port);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preferred_port_ipv6() {
|
||||
use super::make_udp_socket_with_preferred_port;
|
||||
|
||||
let socket = make_udp_socket_with_preferred_port(false, 0).unwrap();
|
||||
let port = socket.local_addr().unwrap().port();
|
||||
drop(socket);
|
||||
|
||||
let socket = make_udp_socket_with_preferred_port(false, port).unwrap();
|
||||
assert_eq!(socket.local_addr().unwrap().port(), port);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ impl forwarder::UdpDatagramPipeShared for MultiplexerShared {
|
|||
}
|
||||
let metrics_guard = self.context.metrics.clone().outbound_udp_socket_counter();
|
||||
e.insert(Connection {
|
||||
socket: Arc::new(make_udp_socket(&meta.destination)?),
|
||||
socket: Arc::new(make_udp_socket(&meta.destination, meta.source.port())?),
|
||||
being_listened: false,
|
||||
_metrics_guard: metrics_guard,
|
||||
});
|
||||
|
|
@ -289,8 +289,9 @@ impl datagram_pipe::Sink for MultiplexerSink {
|
|||
}
|
||||
}
|
||||
|
||||
fn make_udp_socket(peer: &SocketAddr) -> io::Result<UdpSocket> {
|
||||
let socket = net_utils::make_udp_socket(peer.is_ipv4())?;
|
||||
fn make_udp_socket(peer: &SocketAddr, preferred_src_port: u16) -> io::Result<UdpSocket> {
|
||||
let socket =
|
||||
net_utils::make_udp_socket_with_preferred_port(peer.is_ipv4(), preferred_src_port)?;
|
||||
socket.connect(peer)?;
|
||||
socket.set_nonblocking(true)?;
|
||||
UdpSocket::from_std(socket)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue