aboutsummaryrefslogtreecommitdiffstats
path: root/src/api/dashboard
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-10-31 21:12:50 +0100
committertv <tv@krebsco.de>2026-10-31 21:12:50 +0100
commita0c6850d85e1f8f1d9613a323df12d1c94cce8f6 (patch)
treebf4dae1e16c6d78c7810f0d3dfefbd0b06014382 /src/api/dashboard
parentbf33537e04177dd22b6dc6777182ed241e8bdc71 (diff)
links report down
Diffstat (limited to 'src/api/dashboard')
-rw-r--r--src/api/dashboard/clocks.rs1
-rw-r--r--src/api/dashboard/dashboard.html27
-rw-r--r--src/api/dashboard/mod.rs1
3 files changed, 19 insertions, 10 deletions
diff --git a/src/api/dashboard/clocks.rs b/src/api/dashboard/clocks.rs
index 313b78e..9f069be 100644
--- a/src/api/dashboard/clocks.rs
+++ b/src/api/dashboard/clocks.rs
@@ -96,6 +96,7 @@ mod tests {
peer: peer.into(),
transport: None,
relayed: false,
+ down: false,
rtt_us: None,
dormant: false,
others: Vec::new(),
diff --git a/src/api/dashboard/dashboard.html b/src/api/dashboard/dashboard.html
index f45ded3..d2935f6 100644
--- a/src/api/dashboard/dashboard.html
+++ b/src/api/dashboard/dashboard.html
@@ -404,7 +404,7 @@ function renderLegend(measured) {
el("span", { class: "other" }, "other transport"),
el("span", { class: "direct" }, "direct"),
el("span", { class: "relayed" }, "relayed"),
- el("span", { class: "dormant" }, "dormant"),
+ el("span", { class: "dormant" }, "dormant or down"),
el("span", { class: "silent" }, "an end reports no links"));
document.getElementById("legend").replaceChildren(...items);
}
@@ -427,15 +427,19 @@ function edges() {
if (!known || (timed && !knownTimed) ||
(timed === knownTimed && report.secsAgo < known.secsAgo)) {
measured.set(key, { a, b: link.peer, link, secsAgo: report.secsAgo,
- dormant: link.dormant || (known && known.dormant) });
- } else if (link.dormant) {
- known.dormant = true;
+ dormant: link.dormant || (known && known.dormant),
+ down: link.down || (known && known.down) });
+ } else {
+ if (link.dormant) known.dormant = true;
+ if (link.down) known.down = true;
}
}
}
- // Dormant if either end holds the other so, whichever report is drawn.
+ // Dormant, or down, if either end says so, whichever report is drawn.
for (const edge of measured.values()) {
- if (edge.dormant && !edge.link.dormant) edge.link = { ...edge.link, dormant: true };
+ if ((edge.dormant && !edge.link.dormant) || (edge.down && !edge.link.down)) {
+ edge.link = { ...edge.link, dormant: !!edge.dormant, down: !!edge.down };
+ }
}
return { intended, measured };
}
@@ -615,8 +619,10 @@ function renderGraph() {
const nx = -(q.y - p.y) / length, ny = (q.x - p.x) / length;
// An end that reports no links (any more): what's drawn may be out of date.
const silent = !(a in state.graph.measured) || !(b in state.graph.measured);
- // Dormant: a red underlay as wide as the lines, as a dormant node's red outline.
- if (link.dormant) {
+ // Dormant, or down (no path answers, whatever its connection was): a red underlay
+ // as wide as the lines, as a dormant node's red outline.
+ const broken = link.dormant || link.down;
+ if (broken) {
children.push(drawing("underlay " + key, "line", { x1: p.x, y1: p.y, x2: q.x, y2: q.y,
stroke: "var(--bad)", "stroke-opacity": .5, "stroke-width": width + 4,
"stroke-linecap": "round" }));
@@ -627,8 +633,8 @@ function renderGraph() {
const ox = nx * side, oy = ny * side;
const attrs = { x1: p.x + ox, y1: p.y + oy, x2: q.x + ox, y2: q.y + oy,
stroke: colourOf(line.transport),
- // Narrow where dormant (over its underlay).
- "stroke-width": link.dormant ? (line.used ? 1.5 : 0.8) : line.used ? 3 : 1.2 };
+ // Narrow where dormant or down (over its underlay).
+ "stroke-width": broken ? (line.used ? 1.5 : 0.8) : line.used ? 3 : 1.2 };
// Dotted where an end reports nothing, dashed where relayed, solid where direct.
if (silent) {
attrs["stroke-dasharray"] = line.used ? "1 5" : "1 3";
@@ -640,6 +646,7 @@ function renderGraph() {
const description = name(a) + " – " + name(b) +
(line.transport ? " via " + line.transport : "") + (line.used ? " (in use)" : "") +
((line.used ? link.relayed : line.relayed) ? ", relayed" : "") + (link.dormant ? ", dormant" : "") +
+ (line.used && link.down ? ", down" : "") +
(silent ? ", one end reports no links" : "") +
(typeof line.rttMs === "number" ? ", " + line.rttMs.toFixed(1) + " ms" : "") +
", measured " + age(secsAgo + elapsed()) + " ago";
diff --git a/src/api/dashboard/mod.rs b/src/api/dashboard/mod.rs
index 310846a..0e7b442 100644
--- a/src/api/dashboard/mod.rs
+++ b/src/api/dashboard/mod.rs
@@ -331,6 +331,7 @@ fn links_json(links: &[Link]) -> JsonValue {
"peer": link.peer,
"transport": link.transport,
"relayed": link.relayed,
+ "down": link.down,
"rttMs": link.rtt_us.map(|us| f64::from(us) / 1000.0),
"dormant": link.dormant,
"clock": link.clock,