diff options
| author | tv <tv@krebsco.de> | 2026-10-30 18:29:01 +0100 |
|---|---|---|
| committer | tv <tv@krebsco.de> | 2026-10-30 18:29:01 +0100 |
| commit | c33ba31c0d27c3f2531fe9f5ac5dbe55326c8349 (patch) | |
| tree | 36411002a2a66b0c83893923736bf387255409aa /src | |
| parent | e3b386c2aa9970f2f999f07ac43b7eb8fe319d8d (diff) | |
links answers connection type
Diffstat (limited to 'src')
| -rw-r--r-- | src/api/dashboard/dashboard.html | 4 | ||||
| -rw-r--r-- | src/api/dashboard/mod.rs | 1 | ||||
| -rw-r--r-- | src/swarm/links.rs | 11 | ||||
| -rw-r--r-- | src/transport/mod.rs | 2 | ||||
| -rw-r--r-- | src/transport/wire.rs | 15 |
5 files changed, 22 insertions, 11 deletions
diff --git a/src/api/dashboard/dashboard.html b/src/api/dashboard/dashboard.html index 9a17d6b..5bed5fe 100644 --- a/src/api/dashboard/dashboard.html +++ b/src/api/dashboard/dashboard.html @@ -366,13 +366,13 @@ function renderGraph() { if (link.dormant) { drawn.setAttribute("stroke-dasharray", line.used ? "1 5" : "1 3"); drawn.setAttribute("stroke-linecap", "round"); - } else if (line.used && link.relayed) { + } else if (line.used ? link.relayed : line.relayed) { drawn.setAttribute("stroke-dasharray", "7 4"); } const title = svg("title"); title.textContent = name(a) + " – " + name(b) + (line.transport ? " via " + line.transport : "") + (line.used ? " (in use)" : "") + - (line.used && link.relayed ? ", relayed" : "") + (link.dormant ? ", dormant" : "") + + ((line.used ? link.relayed : line.relayed) ? ", relayed" : "") + (link.dormant ? ", dormant" : "") + (typeof line.rttMs === "number" ? ", " + line.rttMs.toFixed(1) + " ms" : "") + ", measured " + age(secsAgo + elapsed()) + " ago"; drawn.append(title); diff --git a/src/api/dashboard/mod.rs b/src/api/dashboard/mod.rs index 92271ef..1de21cd 100644 --- a/src/api/dashboard/mod.rs +++ b/src/api/dashboard/mod.rs @@ -240,6 +240,7 @@ fn links_json(links: &[Link]) -> JsonValue { "others": link.others.iter().map(|other| json!({ "transport": other.transport, "rttMs": other.rtt_us.map(|us| f64::from(us) / 1000.0), + "relayed": other.relayed, })).collect::<Vec<_>>(), }) }) diff --git a/src/swarm/links.rs b/src/swarm/links.rs index d7df0d5..04f2e2d 100644 --- a/src/swarm/links.rs +++ b/src/swarm/links.rs @@ -105,7 +105,8 @@ fn scheme_of(address: &str) -> Option<String> { } /// The transports besides `used` the peer proved itself at, with a path up: each with -/// the round trip of its fastest path, if any is measured. +/// the round trip of its fastest path, if any is measured, and whether all of them go +/// through a relay. fn others(destination: Option<&Destination>, used: Option<&str>) -> Vec<OtherPath> { let mut others: Vec<OtherPath> = Vec::new(); for path in destination.map_or(&[][..], |destination| &destination.paths[..]) { @@ -119,14 +120,20 @@ fn others(destination: Option<&Destination>, used: Option<&str>) -> Vec<OtherPat .rtt_ms .filter(|ms| ms.is_finite() && *ms >= 0.0) .map(|ms| (ms * 1000.0).min(f64::from(u32::MAX)) as u32); + let relayed = path.connection == Some(Connection::Relayed); match others.iter_mut().find(|other| other.transport == transport) { Some(other) => { other.rtt_us = match (other.rtt_us, rtt_us) { (Some(a), Some(b)) => Some(a.min(b)), (a, b) => a.or(b), }; + other.relayed &= relayed; } - None => others.push(OtherPath { transport, rtt_us }), + None => others.push(OtherPath { + transport, + rtt_us, + relayed, + }), } } others.sort_by(|a, b| a.transport.cmp(&b.transport)); diff --git a/src/transport/mod.rs b/src/transport/mod.rs index 9d28212..d774402 100644 --- a/src/transport/mod.rs +++ b/src/transport/mod.rs @@ -440,6 +440,8 @@ pub(crate) struct OtherPath { pub(crate) transport: String, /// The round trip of its fastest path, in microseconds, if any is measured. pub(crate) rtt_us: Option<u32>, + /// Only through a relay (libp2p): no direct connection at any of its paths. + pub(crate) relayed: bool, } #[derive(Clone, Serialize, Deserialize)] diff --git a/src/transport/wire.rs b/src/transport/wire.rs index 87063d2..817437a 100644 --- a/src/transport/wire.rs +++ b/src/transport/wire.rs @@ -14,7 +14,7 @@ use super::{MessageKind, ParsedMessage}; /// The wire format's version, the first byte of every payload. Bump it with every change /// to a message type or a codec (`golden_bytes` fails then). -pub(crate) const VERSION: u8 = 8; +pub(crate) const VERSION: u8 = 9; /// What the second byte of a payload says. fn tag(kind: MessageKind) -> u8 { @@ -422,6 +422,7 @@ pub(crate) fn samples() -> Vec<ParsedMessage> { others: vec![crate::transport::OtherPath { transport: "mycelium".into(), rtt_us: None, + relayed: false, }], }], }), @@ -595,7 +596,7 @@ mod tests { }); assert_eq!( hex(&encode(&hello).unwrap()), - format!("080097a5737761726d{epoch_hex}01c403010203c3{}07", run("04")) + format!("090097a5737761726d{epoch_hex}01c403010203c3{}07", run("04")) ); let reply = ParsedMessage::HelloReply(HelloReply { @@ -615,7 +616,7 @@ mod tests { assert_eq!( hex(&encode(&reply).unwrap()), format!( - "080199a5737761726d9192a17091a161{epoch_hex}01c400c2{}05{}", + "090199a5737761726d9192a17091a161{epoch_hex}01c400c2{}05{}", run("04"), run("06") ) @@ -630,7 +631,7 @@ mod tests { }); assert_eq!( hex(&encode(&status).unwrap()), - format!("0803959290c400{epoch_hex}01c3c2") + format!("0903959290c400{epoch_hex}01c3c2") ); let who = ParsedMessage::Who(IdentityProof { @@ -639,7 +640,7 @@ mod tests { }); assert_eq!( hex(&encode(&who).unwrap()), - format!("080692c420{}c440{}", "08".repeat(32), "09".repeat(64)) + format!("090692c420{}c440{}", "08".repeat(32), "09".repeat(64)) ); let ParsedMessage::Me(proof) = decode( &encode(&ParsedMessage::Me(IdentityProof { @@ -653,10 +654,10 @@ mod tests { }; assert_eq!((proof.key, proof.signature), ([8; 32], [9; 64])); - assert_eq!(hex(&encode(&ParsedMessage::Ping(7)).unwrap()), "080807"); + assert_eq!(hex(&encode(&ParsedMessage::Ping(7)).unwrap()), "090807"); assert_eq!( hex(&encode(&ParsedMessage::Pong(u64::MAX)).unwrap()), - "0809cfffffffffffffffff" + "0909cfffffffffffffffff" ); let ParsedMessage::Pong(nonce) = decode(&[VERSION, 9, 0x2a]).unwrap() else { panic!("not a PONG"); |
