mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-08-06 20:49:46 +00:00
move sanitize and parse
fmt dns dns utils fmt unit test unit test
This commit is contained in:
@@ -3,8 +3,8 @@ use crate::dns::config::zone::ZoneConfig;
|
||||
use crate::dns::config::{DNS_DEFAULT_ADDRESS, DNS_DEFAULT_DOMAIN};
|
||||
use crate::dns::server::DnsServer;
|
||||
use crate::dns::utils::addr::NameServerAddrGroup;
|
||||
use crate::dns::utils::parse;
|
||||
use crate::proto::dns::GetExportConfigResponse;
|
||||
use crate::utils::dns::parse;
|
||||
use derivative::Derivative;
|
||||
use hickory_net::xfer::Protocol;
|
||||
use hickory_proto::rr::{LowerName, Name};
|
||||
|
||||
@@ -1,42 +1,3 @@
|
||||
use hickory_proto::rr::LowerName;
|
||||
use idna::AsciiDenyList;
|
||||
|
||||
pub mod addr;
|
||||
pub mod response;
|
||||
pub mod zone_handler;
|
||||
|
||||
pub fn sanitize(name: &str) -> String {
|
||||
let dot = name.ends_with('.');
|
||||
let mut name = idna::domain_to_ascii_cow(name.as_ref(), AsciiDenyList::EMPTY)
|
||||
.unwrap_or_default()
|
||||
.into_owned()
|
||||
.to_lowercase()
|
||||
.split('.')
|
||||
.map(|label| {
|
||||
label
|
||||
.chars()
|
||||
.map(|c| if c.is_ascii_alphanumeric() { c } else { '-' })
|
||||
.take(63)
|
||||
.collect::<String>()
|
||||
.trim_matches('-')
|
||||
.to_string()
|
||||
})
|
||||
.filter(|label| !label.is_empty())
|
||||
.collect::<Vec<_>>()
|
||||
.join(".");
|
||||
name.truncate(253);
|
||||
if dot {
|
||||
name.push('.');
|
||||
}
|
||||
name
|
||||
}
|
||||
|
||||
pub fn parse(name: &str) -> LowerName {
|
||||
if let Ok(name) = name.parse() {
|
||||
name
|
||||
} else {
|
||||
let sanitized = sanitize(name);
|
||||
tracing::debug!("invalid name: {}, sanitized to: {}", name, sanitized);
|
||||
sanitized.parse().unwrap_or_default()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,57 @@
|
||||
use std::fmt::Debug;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::common::error::Error;
|
||||
use anyhow::Context;
|
||||
use hickory_net::runtime::TokioRuntimeProvider;
|
||||
use hickory_proto::rr::rdata::SRV;
|
||||
use hickory_proto::rr::{IntoName, RData};
|
||||
use hickory_proto::rr::{IntoName, LowerName, RData};
|
||||
use hickory_resolver::config::{
|
||||
ConnectionConfig, LookupIpStrategy, NameServerConfig, ResolverConfig, ResolverOpts,
|
||||
};
|
||||
use hickory_resolver::system_conf::read_system_conf;
|
||||
use hickory_resolver::{Resolver, TokioResolver};
|
||||
use idna::AsciiDenyList;
|
||||
use once_cell::sync::Lazy;
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use tokio::net::lookup_host;
|
||||
|
||||
use crate::common::error::Error;
|
||||
pub fn sanitize(name: impl AsRef<str>) -> String {
|
||||
let name = name.as_ref();
|
||||
let dot = name.ends_with('.');
|
||||
let mut name = idna::domain_to_ascii_cow(name.as_ref(), AsciiDenyList::EMPTY)
|
||||
.unwrap_or_default()
|
||||
.into_owned()
|
||||
.to_lowercase()
|
||||
.split('.')
|
||||
.map(|label| {
|
||||
label
|
||||
.chars()
|
||||
.map(|c| if c.is_ascii_alphanumeric() { c } else { '-' })
|
||||
.take(63)
|
||||
.collect::<String>()
|
||||
.trim_matches('-')
|
||||
.to_string()
|
||||
})
|
||||
.filter(|label| !label.is_empty())
|
||||
.collect::<Vec<_>>()
|
||||
.join(".");
|
||||
name.truncate(253);
|
||||
if dot {
|
||||
name.push('.');
|
||||
}
|
||||
name
|
||||
}
|
||||
|
||||
pub fn parse(name: impl AsRef<str>) -> LowerName {
|
||||
let name = name.as_ref();
|
||||
if let Ok(name) = name.parse() {
|
||||
name
|
||||
} else {
|
||||
let sanitized = sanitize(name);
|
||||
tracing::debug!("invalid name: {}, sanitized to: {}", name, sanitized);
|
||||
sanitized.parse().unwrap_or_default()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolver_conf() -> (ResolverConfig, ResolverOpts) {
|
||||
let mut config = ResolverConfig::default();
|
||||
@@ -161,6 +194,31 @@ mod tests {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn parse_matrix_cases() {
|
||||
let cases = [
|
||||
["Example.COM.", "example.com."],
|
||||
["a_b!.et.net.", "a-b.et.net."],
|
||||
["foo..bar.com.", "foo.bar.com."],
|
||||
[
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com.",
|
||||
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.com.",
|
||||
],
|
||||
["___", "___"],
|
||||
["!", ""],
|
||||
["", ""],
|
||||
];
|
||||
|
||||
for [input, expected] in cases {
|
||||
let parsed = parse(input);
|
||||
let expected: LowerName = expected.parse().unwrap();
|
||||
assert_eq!(
|
||||
parsed, expected,
|
||||
"parse({input:?}) should equal {expected:?}, got {parsed:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_socket_addrs() {
|
||||
let url = url::Url::parse("tcp://github-ci-test.easytier.cn:80").unwrap();
|
||||
|
||||
Reference in New Issue
Block a user