refactor: do not try to bind ipv6 if no ipv6 (#348)

This commit is contained in:
sigoden 2024-01-16 09:03:27 +08:00 committed by GitHub
parent 9b348fc945
commit 3354b1face
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -43,9 +43,11 @@ async fn main() -> Result<()> {
print_completions(*generator, &mut cmd); print_completions(*generator, &mut cmd);
return Ok(()); return Ok(());
} }
let args = Args::parse(matches)?; let mut args = Args::parse(matches)?;
let (new_addrs, print_addrs) = check_addrs(&args)?;
args.addrs = new_addrs;
let running = Arc::new(AtomicBool::new(true)); let running = Arc::new(AtomicBool::new(true));
let listening = print_listening(&args)?; let listening = print_listening(&args, &print_addrs)?;
let handles = serve(args, running.clone())?; let handles = serve(args, running.clone())?;
println!("{listening}"); println!("{listening}");
@ -189,42 +191,64 @@ fn create_listener(addr: SocketAddr) -> Result<TcpListener> {
Ok(listener) Ok(listener)
} }
fn print_listening(args: &Args) -> Result<String> { fn check_addrs(args: &Args) -> Result<(Vec<BindAddr>, Vec<BindAddr>)> {
let mut output = String::new(); let mut new_addrs = vec![];
let mut bind_addrs = vec![]; let mut print_addrs = vec![];
let (mut ipv4, mut ipv6) = (false, false); let (ipv4_addrs, ipv6_addrs) = interface_addrs()?;
for bind_addr in args.addrs.iter() { for bind_addr in args.addrs.iter() {
match bind_addr { match bind_addr {
BindAddr::Address(ip) => { BindAddr::Address(ip) => match &ip {
if ip.is_unspecified() { IpAddr::V4(_) => {
if ip.is_ipv6() { if !ipv4_addrs.is_empty() {
ipv6 = true; new_addrs.push(bind_addr.clone());
} else { if ip.is_unspecified() {
ipv4 = true; print_addrs.extend(ipv4_addrs.clone());
} else {
print_addrs.push(bind_addr.clone());
}
} }
} else {
bind_addrs.push(bind_addr.clone());
} }
} IpAddr::V6(_) => {
_ => bind_addrs.push(bind_addr.clone()), if !ipv6_addrs.is_empty() {
} new_addrs.push(bind_addr.clone());
} if ip.is_unspecified() {
if ipv4 || ipv6 { print_addrs.extend(ipv6_addrs.clone());
let ifaces = } else {
if_addrs::get_if_addrs().with_context(|| "Failed to get local interface addresses")?; print_addrs.push(bind_addr.clone())
for iface in ifaces.into_iter() { }
let local_ip = iface.ip(); }
if ipv4 && local_ip.is_ipv4() { }
bind_addrs.push(BindAddr::Address(local_ip)) },
} _ => {
if ipv6 && local_ip.is_ipv6() { new_addrs.push(bind_addr.clone());
bind_addrs.push(BindAddr::Address(local_ip)) print_addrs.push(bind_addr.clone())
} }
} }
} }
bind_addrs.sort_unstable(); print_addrs.sort_unstable();
let urls = bind_addrs Ok((new_addrs, print_addrs))
.into_iter() }
fn interface_addrs() -> Result<(Vec<BindAddr>, Vec<BindAddr>)> {
let (mut ipv4_addrs, mut ipv6_addrs) = (vec![], vec![]);
let ifaces =
if_addrs::get_if_addrs().with_context(|| "Failed to get local interface addresses")?;
for iface in ifaces.into_iter() {
let ip = iface.ip();
if ip.is_ipv4() {
ipv4_addrs.push(BindAddr::Address(ip))
}
if ip.is_ipv6() {
ipv6_addrs.push(BindAddr::Address(ip))
}
}
Ok((ipv4_addrs, ipv6_addrs))
}
fn print_listening(args: &Args, print_addrs: &[BindAddr]) -> Result<String> {
let mut output = String::new();
let urls = print_addrs
.iter()
.map(|bind_addr| match bind_addr { .map(|bind_addr| match bind_addr {
BindAddr::Address(addr) => { BindAddr::Address(addr) => {
let addr = match addr { let addr = match addr {