1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use miette::miette;
use ockam_core::Result;
use ockam_multiaddr::proto::{
DnsAddr, Ip4, Ip6, Node, Project, Secure, Service, Space, Tcp, Worker,
};
use ockam_multiaddr::{Code, MultiAddr, Protocol};
use crate::error::ApiError;
/// Tells whether the input MultiAddr references a local node or a remote node.
///
/// This should be called before cleaning the MultiAddr.
pub fn is_local_node(ma: &MultiAddr) -> miette::Result<bool> {
let at_rust_node;
if let Some(p) = ma.iter().next() {
match p.code() {
// A MultiAddr starting with "/project" will always reference a remote node.
Project::CODE => {
at_rust_node = false;
}
// A MultiAddr starting with "/node" will always reference a local node.
Node::CODE => {
at_rust_node = true;
}
// A "/dnsaddr" will be local if it is "localhost"
DnsAddr::CODE => {
at_rust_node = p
.cast::<DnsAddr>()
.map(|dnsaddr| (*dnsaddr).eq("localhost"))
.ok_or_else(|| miette!("Invalid \"dnsaddr\" value"))?;
}
// A "/ip4" will be local if it matches the loopback address
Ip4::CODE => {
at_rust_node = p
.cast::<Ip4>()
.map(|ip4| ip4.is_loopback())
.ok_or_else(|| miette!("Invalid \"ip4\" value"))?;
}
// A "/ip6" will be local if it matches the loopback address
Ip6::CODE => {
at_rust_node = p
.cast::<Ip6>()
.map(|ip6| ip6.is_loopback())
.ok_or_else(|| miette!("Invalid \"ip6\" value"))?;
}
// A MultiAddr starting with "/service" could reference both local and remote nodes.
_ => {
return Err(miette!("Invalid address, protocol not supported"));
}
}
Ok(at_rust_node)
} else {
Err(miette!("Invalid address"))
}
}
/// Tells whether the input [`Code`] references a local worker.
pub fn local_worker(code: &Code) -> Result<bool> {
match *code {
Node::CODE
| Space::CODE
| Project::CODE
| DnsAddr::CODE
| Ip4::CODE
| Ip6::CODE
| Tcp::CODE
| Secure::CODE => Ok(false),
Worker::CODE | Service::CODE => Ok(true),
_ => Err(ApiError::core(format!("unknown transport type: {code}"))),
}
}