Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Netlink module fails to parse IPv6 addresses with zone ID #2080

Closed
torimus opened this issue Aug 24, 2024 · 3 comments
Closed

Netlink module fails to parse IPv6 addresses with zone ID #2080

torimus opened this issue Aug 24, 2024 · 3 comments

Comments

@torimus
Copy link

torimus commented Aug 24, 2024

Problem description: netlink module fails with "Failed to read nameservers" error when parsing valid IPv6 address (in accordance to RFC6874)

Expected behavior: netlink would properly parse correct IPv6

Steps to reproduce:

  • have an IPv6 address with Zone (aka Scope) Identifier in /etc/resolv.conf, like nameserver fd78::1%wlp2s0 (part delimited with '%' character)
  • spawn i3status-rs with block = "net" in config.toml
  • observe "Failed to read nameservers" error in full_text placeholder

This is a known issue in standard Rust library. One solution is to simply discard scope_id part, including '%' delimiter.

Possible quick fix:

diff --git a/src/netlink.rs b/src/netlink.rs
index b8557db..46bf6b6 100644
--- a/src/netlink.rs
+++ b/src/netlink.rs
@@ -438,12 +438,13 @@ async fn read_nameservers() -> Result<Vec<IpAddr>> {
         .await
         .error("Failed to read /etc/resolv.conf")?;
     let mut nameservers = Vec::new();
+    let strip_scope_id = |s: &str| s.chars().take_while(|c| *c != '%').collect::<String>();
 
     for line in file.lines() {
         let mut line_parts = line.split_whitespace();
         if line_parts.next() == Some("nameserver") {
             if let Some(ip) = line_parts.next() {
-                nameservers.push(ip.parse().error("Unable to parse ip")?);
+                nameservers.push(strip_scope_id(ip).parse().error("Unable to parse ip")?);
             }
         }
     }
@MaxVerevkin
Copy link
Collaborator

Thanks for a detailed report.

In case of resolv.conf, which information does the zone id convey? We of course can simply ignore it, but if this zone id implies that a nameserver is only specified for that net interface, then we may use that information to not show this nameserver if it doesn't match iface.

But it may mean something different, I don't know, in which case ignoring it would be fine.

@torimus
Copy link
Author

torimus commented Aug 24, 2024

In my example, this is how NetworkManager declares scope(zone) id by default. Unfortunately the format is not strict to be relied upon - see specification in RFC6874.

It would be ideal, as you suggest, if it could be used to determine name of the network interface for that non-global address, but it does not seem to be the case. I'm all ears if it behaves consistently in practice for different setups.

@MaxVerevkin
Copy link
Collaborator

Hm, okay, I guess a TODO would suffice for now :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants