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

pull/352/head
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
1 changed files with 55 additions and 31 deletions

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 {
IpAddr::V4(_) => {
if !ipv4_addrs.is_empty() {
new_addrs.push(bind_addr.clone());
if ip.is_unspecified() { if ip.is_unspecified() {
if ip.is_ipv6() { print_addrs.extend(ipv4_addrs.clone());
ipv6 = true;
} else { } else {
ipv4 = true; print_addrs.push(bind_addr.clone());
} }
}
}
IpAddr::V6(_) => {
if !ipv6_addrs.is_empty() {
new_addrs.push(bind_addr.clone());
if ip.is_unspecified() {
print_addrs.extend(ipv6_addrs.clone());
} else { } else {
bind_addrs.push(bind_addr.clone()); print_addrs.push(bind_addr.clone())
} }
} }
_ => bind_addrs.push(bind_addr.clone()), }
},
_ => {
new_addrs.push(bind_addr.clone());
print_addrs.push(bind_addr.clone())
} }
} }
if ipv4 || ipv6 { }
print_addrs.sort_unstable();
Ok((new_addrs, print_addrs))
}
fn interface_addrs() -> Result<(Vec<BindAddr>, Vec<BindAddr>)> {
let (mut ipv4_addrs, mut ipv6_addrs) = (vec![], vec![]);
let ifaces = let ifaces =
if_addrs::get_if_addrs().with_context(|| "Failed to get local interface addresses")?; if_addrs::get_if_addrs().with_context(|| "Failed to get local interface addresses")?;
for iface in ifaces.into_iter() { for iface in ifaces.into_iter() {
let local_ip = iface.ip(); let ip = iface.ip();
if ipv4 && local_ip.is_ipv4() { if ip.is_ipv4() {
bind_addrs.push(BindAddr::Address(local_ip)) ipv4_addrs.push(BindAddr::Address(ip))
} }
if ipv6 && local_ip.is_ipv6() { if ip.is_ipv6() {
bind_addrs.push(BindAddr::Address(local_ip)) ipv6_addrs.push(BindAddr::Address(ip))
} }
} }
} Ok((ipv4_addrs, ipv6_addrs))
bind_addrs.sort_unstable(); }
let urls = bind_addrs
.into_iter() 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 {