prometheus_wireguard_exporter
prometheus_wireguard_exporter copied to clipboard
Exporter fails to parse IPv6 link-local addresses with zone IDs
I recently discovered that link-local IPv6 addresses can't be parsed by the exporter and cause errors like this in the log:
Jul 16 20:00:08 wgvm s74b03w8rpp818cdprkmd9qcki34jqvr-unit-script-prometheus-wireguard-exporter-start[807]: thread 'tokio-runtime-worker-0' panicked at 'called `Result::unwrap()` on an `Err` value: AddrParseError(())', src/libcore/result.rs:997:5
Jul 16 20:00:08 wgvm s74b03w8rpp818cdprkmd9qcki34jqvr-unit-script-prometheus-wireguard-exporter-start[807]: note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
Jul 16 20:01:08 wgvm s74b03w8rpp818cdprkmd9qcki34jqvr-unit-script-prometheus-wireguard-exporter-start[807]: [2019-07-16T20:01:08Z TRACE prometheus_wireguard_exporter] Request { method: GET, uri: /metrics, version: HTTP/1.1, headers: {"host": "<http-ip>:9586", "user-agent": "Prometheus/1.8.2", "accept": "application/vnd.google.protobuf;proto=io.prometheus.client.MetricFamily;encoding=delimited;q=0.7,text/plain;version=0.0.4;q=0.3,*/*;q=0.1", "x-prometheus-scrape-timeout-seconds": "10.000000", "accept-encoding": "gzip", "connection": "close"}, body: Body(Empty) }
The reason for this error is that link-local IPv6 addresses can have a so-called zone-id as described in RFC 4007, Section 11 to disambiguate local addresses. In my case one peer had the IPv6 socket address [fe80::d457:12ff:fe48:176b%ens3]:34216
with ens3
being a predictably named network interface.
The problem here is that the socket and IP parsers of Rust in std::net
appear to be unable to parse zone IDs:
>> use std::net::SocketAddr;
>> let addr = "[fe80::1%ens3]:23542".parse::<SocketAddr>().unwrap();
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: AddrParseError(())', src/libcore/result.rs:1009:5
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
1: std::sys_common::backtrace::print
2: std::panicking::default_hook::{{closure}}
3: std::panicking::default_hook
4: std::panicking::rust_panic_with_hook
5: std::panicking::continue_panic_fmt
6: rust_begin_unwind
7: core::panicking::panic_fmt
8: core::result::unwrap_failed
at /build/rustc-1.32.0-src/src/libcore/macros.rs:26
9: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
at /build/rustc-1.32.0-src/src/libcore/result.rs:808
at /tmp/.tmpVAsFH6/user_code_1/src/lib.rs:15
at /build/rustc-1.32.0-src/src/libcore/ops/function.rs:238
at /build/rustc-1.32.0-src/src/libstd/panic.rs:319
10: std::panicking::try::do_call
at /build/rustc-1.32.0-src/src/libstd/panicking.rs:310
11: __rust_maybe_catch_panic
12: run_user_code_1
at /build/rustc-1.32.0-src/src/libstd/panicking.rs:289
at /build/rustc-1.32.0-src/src/libstd/panic.rs:398
at /tmp/.tmpVAsFH6/user_code_1/src/lib.rs:12
13: evcxr::runtime::Runtime::run_loop
14: evcxr::runtime::runtime_hook
15: evcxr::main
16: std::rt::lang_start::{{closure}}
17: std::panicking::try::do_call
18: __rust_maybe_catch_panic
19: std::rt::lang_start_internal
20: main
21: __libc_start_main
22: _start
Panic occurred, the following variables have been lost: addr
The reason for this failure is that the parser doesn't appear to support those addresses. There's currently a pending discussion in rust-lang/rfcs about the issue.
I will close it for now since @Ma27 solution addresses it. We'll probably need to revise the code some time in the future to see if the upstream crate solved the issue.
Tbh I'd prefer to leave this open until we have a proper solution. The problem is still there, we just worked around it (which is valid in our case since zone-ids broke the exporter before).
Good point! Reopened.