veilid_core/routing_table/types/
signed_node_info.rs1use super::*;
2
3#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
4pub enum SignedNodeInfo {
5 Direct(SignedDirectNodeInfo),
6 Relayed(SignedRelayedNodeInfo),
7}
8
9impl fmt::Display for SignedNodeInfo {
10 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11 match self {
12 Self::Direct(arg0) => {
13 writeln!(f, "direct:")?;
14 write!(f, "{}", indent_all_string(arg0))?;
15 Ok(())
16 }
17 Self::Relayed(arg0) => {
18 writeln!(f, "relayed:")?;
19 write!(f, "{}", indent_all_string(&arg0))?;
20 Ok(())
21 }
22 }
23 }
24}
25
26impl SignedNodeInfo {
27 pub fn validate(
28 &self,
29 node_ids: &TypedNodeIdGroup,
30 crypto: &Crypto,
31 ) -> VeilidAPIResult<TypedNodeIdGroup> {
32 match self {
33 SignedNodeInfo::Direct(d) => d.validate(node_ids, crypto),
34 SignedNodeInfo::Relayed(r) => r.validate(node_ids, crypto),
35 }
36 }
37
38 pub fn has_any_signature(&self) -> bool {
39 match self {
40 SignedNodeInfo::Direct(d) => d.has_any_signature(),
41 SignedNodeInfo::Relayed(r) => r.has_any_signature(),
42 }
43 }
44
45 pub fn timestamp(&self) -> Timestamp {
46 match self {
47 SignedNodeInfo::Direct(d) => d.timestamp(),
48 SignedNodeInfo::Relayed(r) => r.timestamp(),
49 }
50 }
51 pub fn node_info(&self) -> &NodeInfo {
52 match self {
53 SignedNodeInfo::Direct(d) => d.node_info(),
54 SignedNodeInfo::Relayed(r) => r.node_info(),
55 }
56 }
57 pub fn relay_ids(&self) -> TypedNodeIdGroup {
58 match self {
59 SignedNodeInfo::Direct(_) => TypedNodeIdGroup::new(),
60 SignedNodeInfo::Relayed(r) => r.relay_ids().clone(),
61 }
62 }
63 pub fn relay_info(&self) -> Option<&NodeInfo> {
64 match self {
65 SignedNodeInfo::Direct(_) => None,
66 SignedNodeInfo::Relayed(r) => Some(r.relay_info().node_info()),
67 }
68 }
69 pub fn relay_peer_info(&self, routing_domain: RoutingDomain) -> Option<Arc<PeerInfo>> {
70 match self {
71 SignedNodeInfo::Direct(_) => None,
72 SignedNodeInfo::Relayed(r) => Some(Arc::new(
73 PeerInfo::new(
74 routing_domain,
75 r.relay_ids().clone(),
76 SignedNodeInfo::Direct(r.relay_info().clone()),
77 )
78 .unwrap(), )),
80 }
81 }
82 pub fn has_any_dial_info(&self) -> bool {
83 self.node_info().has_dial_info()
84 || self
85 .relay_info()
86 .map(|relay_ni| relay_ni.has_dial_info())
87 .unwrap_or_default()
88 }
89
90 pub fn has_sequencing_matched_dial_info(&self, sequencing: Sequencing) -> bool {
91 for did in self.node_info().dial_info_detail_list() {
93 match sequencing {
94 Sequencing::NoPreference | Sequencing::PreferOrdered => return true,
95 Sequencing::EnsureOrdered => {
96 if did.dial_info.protocol_type().is_ordered() {
97 return true;
98 }
99 }
100 }
101 }
102 self.relay_info()
104 .map(|relay_ni| {
105 for did in relay_ni.dial_info_detail_list() {
106 match sequencing {
107 Sequencing::NoPreference | Sequencing::PreferOrdered => return true,
108 Sequencing::EnsureOrdered => {
109 if did.dial_info.protocol_type().is_ordered() {
110 return true;
111 }
112 }
113 }
114 }
115 false
116 })
117 .unwrap_or_default()
118 }
119
120 #[cfg(feature = "geolocation")]
121 pub fn get_geolocation_info(&self, routing_domain: RoutingDomain) -> GeolocationInfo {
123 if routing_domain != RoutingDomain::PublicInternet {
124 return GeolocationInfo::new(None, vec![]);
126 }
127
128 let get_node_country_code = |node_info: &NodeInfo| {
129 let country_codes = node_info
130 .dial_info_detail_list()
131 .iter()
132 .map(|did| match &did.dial_info {
133 DialInfo::UDP(di) => di.socket_address.ip_addr(),
134 DialInfo::TCP(di) => di.socket_address.ip_addr(),
135 DialInfo::WS(di) => di.socket_address.ip_addr(),
136 DialInfo::WSS(di) => di.socket_address.ip_addr(),
137 })
138 .map(geolocation::query_country_code)
139 .collect::<Vec<_>>();
140
141 if country_codes.is_empty() {
142 return None;
143 }
144
145 let cc0 = country_codes[0];
147
148 if !country_codes.iter().all(|cc| cc.is_some() && *cc == cc0) {
149 return None;
151 }
152
153 cc0
154 };
155
156 match self {
157 SignedNodeInfo::Direct(sni) => {
158 GeolocationInfo::new(get_node_country_code(sni.node_info()), vec![])
159 }
160 SignedNodeInfo::Relayed(sni) => {
161 let relay_cc = get_node_country_code(sni.relay_info().node_info());
162
163 GeolocationInfo::new(get_node_country_code(sni.node_info()), vec![relay_cc])
164 }
165 }
166 }
167
168 pub fn equivalent(&self, other: &SignedNodeInfo) -> bool {
172 match self {
173 SignedNodeInfo::Direct(d) => match other {
174 SignedNodeInfo::Direct(pd) => d.equivalent(pd),
175 SignedNodeInfo::Relayed(_) => false,
176 },
177 SignedNodeInfo::Relayed(r) => match other {
178 SignedNodeInfo::Direct(_) => false,
179 SignedNodeInfo::Relayed(pr) => r.equivalent(pr),
180 },
181 }
182 }
183}