From f66010e6f9a4b974807ff7623c9b64ecc603bad0 Mon Sep 17 00:00:00 2001 From: lurenjia Date: Tue, 28 Apr 2026 23:23:41 +0800 Subject: [PATCH] fix: preserve URL type in matches_scheme (#2179) Avoid resolving Url::as_ref() to the full URL string before TunnelScheme conversion. Add regression coverage for owned/borrowed URLs and the UDP IPv6 hole-punch branch condition. Co-authored-by: KKRainbow <443152178@qq.com> --- easytier/src/connector/direct.rs | 11 +++++++++++ easytier/src/tunnel/mod.rs | 25 ++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/easytier/src/connector/direct.rs b/easytier/src/connector/direct.rs index c9265092..d4abb637 100644 --- a/easytier/src/connector/direct.rs +++ b/easytier/src/connector/direct.rs @@ -802,12 +802,23 @@ mod tests { wait_route_appear_with_cost, }, proto::peer_rpc::GetIpListResponse, + tunnel::{IpScheme, TunnelScheme, matches_scheme}, }; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use super::{TESTING, mapped_listener_port, resolve_mapped_listener_addrs}; + #[test] + fn udp_ipv6_url_matches_hole_punch_branch_condition() { + let remote_url: url::Url = "udp://[2001:db8::1]:11010".parse().unwrap(); + let takes_udp_ipv6_hole_punch_branch = + matches_scheme!(remote_url, TunnelScheme::Ip(IpScheme::Udp)) + && matches!(remote_url.host(), Some(url::Host::Ipv6(_))); + + assert!(takes_udp_ipv6_hole_punch_branch); + } + #[test] fn mapped_listener_port_uses_ip_scheme_defaults() { assert_eq!( diff --git a/easytier/src/tunnel/mod.rs b/easytier/src/tunnel/mod.rs index 36feb753..a090b074 100644 --- a/easytier/src/tunnel/mod.rs +++ b/easytier/src/tunnel/mod.rs @@ -371,9 +371,13 @@ impl TryFrom<&url::Url> for TunnelScheme { } } +pub(crate) fn get_scheme_by_url(l: &url::Url) -> Result { + l.try_into() +} + macro_rules! __matches_scheme__ { ($url:expr, $( $pattern:pat_param )|+ ) => { - matches!($crate::tunnel::TunnelScheme::try_from(($url).as_ref()), Ok($( $pattern )|+)) + matches!($crate::tunnel::get_scheme_by_url(&$url), Ok($( $pattern )|+)) }; } @@ -393,3 +397,22 @@ macro_rules! __matches_protocol__ { } pub(crate) use __matches_protocol__ as matches_protocol; + +#[cfg(test)] +mod tests { + use super::{IpScheme, TunnelScheme, matches_scheme}; + + #[test] + fn matches_scheme_accepts_owned_url() { + let url: url::Url = "udp://[2001:db8::1]:11010".parse().unwrap(); + + assert!(matches_scheme!(url, TunnelScheme::Ip(IpScheme::Udp))); + } + + #[test] + fn matches_scheme_accepts_borrowed_url() { + let url: url::Url = "udp://[2001:db8::1]:11010".parse().unwrap(); + + assert!(matches_scheme!(&url, TunnelScheme::Ip(IpScheme::Udp))); + } +}