@@ -16,7 +16,10 @@ use super::{
16
16
} ;
17
17
use crate :: {
18
18
disco:: SendAddr ,
19
- magicsock:: { node_map:: best_addr:: TRUST_UDP_ADDR_DURATION , HEARTBEAT_INTERVAL } ,
19
+ magicsock:: {
20
+ node_map:: path_validity:: { self , PathValidity } ,
21
+ HEARTBEAT_INTERVAL ,
22
+ } ,
20
23
} ;
21
24
22
25
/// The minimum time between pings to an endpoint.
@@ -30,7 +33,7 @@ const DISCO_PING_INTERVAL: Duration = Duration::from_secs(5);
30
33
/// This state is used for both the relay path and any direct UDP paths.
31
34
///
32
35
/// [`NodeState`]: super::node_state::NodeState
33
- #[ derive( Debug , Clone , PartialEq , Eq ) ]
36
+ #[ derive( Debug , Clone ) ]
34
37
pub ( super ) struct PathState {
35
38
/// The node for which this path exists.
36
39
node_id : NodeId ,
@@ -47,18 +50,19 @@ pub(super) struct PathState {
47
50
/// The time this endpoint was last advertised via a call-me-maybe DISCO message.
48
51
pub ( super ) call_me_maybe_time : Option < Instant > ,
49
52
50
- /// The most recent [`PongReply`].
53
+ // /// The most recent [`PongReply`].
54
+ // ///
55
+ // /// Previous replies are cleared when they are no longer relevant to determine whether
56
+ // /// this path can still be used to reach the remote node.
57
+ // pub(super) recent_pong: Option<PongReply>,
58
+ /// Tracks whether this path is valid.
51
59
///
52
- /// Previous replies are cleared when they are no longer relevant to determine whether
53
- /// this path can still be used to reach the remote node.
54
- pub ( super ) recent_pong : Option < PongReply > ,
60
+ /// See [`PathValidity`] docs.
61
+ pub ( super ) validity : PathValidity ,
55
62
/// When the last payload data was **received** via this path.
56
63
///
57
64
/// This excludes DISCO messages.
58
65
pub ( super ) last_payload_msg : Option < Instant > ,
59
- /// Whether the last payload msg was within [`TRUST_UDP_ADDR_DURATION`] of either
60
- /// the last trusted payload message or a recent pong.
61
- pub ( super ) last_payload_trusted : bool ,
62
66
/// Sources is a map of [`Source`]s to [`Instant`]s, keeping track of all the ways we have
63
67
/// learned about this path
64
68
///
@@ -77,9 +81,8 @@ impl PathState {
77
81
last_ping : None ,
78
82
last_got_ping : None ,
79
83
call_me_maybe_time : None ,
80
- recent_pong : None ,
84
+ validity : PathValidity :: empty ( ) ,
81
85
last_payload_msg : None ,
82
- last_payload_trusted : false ,
83
86
sources,
84
87
}
85
88
}
@@ -105,9 +108,8 @@ impl PathState {
105
108
last_ping : None ,
106
109
last_got_ping : None ,
107
110
call_me_maybe_time : None ,
108
- recent_pong : None ,
111
+ validity : PathValidity :: empty ( ) ,
109
112
last_payload_msg : Some ( now) ,
110
- last_payload_trusted : false ,
111
113
sources,
112
114
}
113
115
}
@@ -126,7 +128,7 @@ impl PathState {
126
128
127
129
pub ( super ) fn add_pong_reply ( & mut self , r : PongReply ) {
128
130
if let SendAddr :: Udp ( ref path) = self . path {
129
- if self . recent_pong . is_none ( ) {
131
+ if self . validity . is_empty ( ) {
130
132
event ! (
131
133
target: "iroh::_events::holepunched" ,
132
134
Level :: DEBUG ,
@@ -136,27 +138,16 @@ impl PathState {
136
138
) ;
137
139
}
138
140
}
139
- self . recent_pong = Some ( r) ;
140
141
141
- if let Some ( last_payload_msg) = self . last_payload_msg {
142
- self . last_payload_trusted = self . within_trusted_pong_duration ( last_payload_msg) ;
143
- }
144
- }
145
-
146
- fn within_trusted_pong_duration ( & self , instant : Instant ) -> bool {
147
- if let Some ( pong) = & self . recent_pong {
148
- return pong. pong_at <= instant && instant < pong. pong_at + TRUST_UDP_ADDR_DURATION ;
149
- }
150
-
151
- false
142
+ self . validity = PathValidity :: new ( r) ;
152
143
}
153
144
154
145
pub ( super ) fn receive_payload ( & mut self , now : Instant ) {
155
146
self . last_payload_msg = Some ( now) ;
156
-
157
- if self . within_trusted_pong_duration ( now ) {
158
- self . last_payload_trusted = true ;
159
- }
147
+ // TODO(matheus23): It's not necessarily UDP. Kinda weird to have this thing
148
+ // Also, it all results in the same 6.5s timeout anyways, maybe we just remove it?
149
+ self . validity
150
+ . receive_payload ( now , path_validity :: Source :: Udp ) ;
160
151
}
161
152
162
153
#[ cfg( test) ]
@@ -167,9 +158,8 @@ impl PathState {
167
158
last_ping : None ,
168
159
last_got_ping : None ,
169
160
call_me_maybe_time : None ,
170
- recent_pong : Some ( r) ,
161
+ validity : PathValidity :: new ( r) ,
171
162
last_payload_msg : None ,
172
- last_payload_trusted : false ,
173
163
sources : HashMap :: new ( ) ,
174
164
}
175
165
}
@@ -205,8 +195,8 @@ impl PathState {
205
195
/// - When the last payload transmission occurred.
206
196
/// - when the last ping from them was received.
207
197
pub ( super ) fn last_alive ( & self ) -> Option < Instant > {
208
- self . recent_pong
209
- . as_ref ( )
198
+ self . validity
199
+ . get_pong ( )
210
200
. map ( |pong| & pong. pong_at )
211
201
. into_iter ( )
212
202
. chain ( self . last_payload_msg . as_ref ( ) )
@@ -216,21 +206,6 @@ impl PathState {
216
206
. copied ( )
217
207
}
218
208
219
- fn last_confirmed_at ( & self ) -> Option < Instant > {
220
- let last_trusted_payload_msg = if self . last_payload_trusted {
221
- self . last_payload_msg
222
- } else {
223
- None
224
- } ;
225
-
226
- self . recent_pong
227
- . as_ref ( )
228
- . map ( |pong| pong. pong_at )
229
- . into_iter ( )
230
- . chain ( last_trusted_payload_msg)
231
- . max ( )
232
- }
233
-
234
209
/// The last control or DISCO message **about** this path.
235
210
///
236
211
/// This is the most recent instant among:
@@ -242,8 +217,8 @@ impl PathState {
242
217
pub ( super ) fn last_control_msg ( & self , now : Instant ) -> Option < ( Duration , ControlMsg ) > {
243
218
// get every control message and assign it its kind
244
219
let last_pong = self
245
- . recent_pong
246
- . as_ref ( )
220
+ . validity
221
+ . get_pong ( )
247
222
. map ( |pong| ( pong. pong_at , ControlMsg :: Pong ) ) ;
248
223
let last_call_me_maybe = self
249
224
. call_me_maybe_time
@@ -263,19 +238,7 @@ impl PathState {
263
238
264
239
/// Returns the latency from the most recent pong, if available.
265
240
pub ( super ) fn latency ( & self ) -> Option < Duration > {
266
- self . recent_pong . as_ref ( ) . map ( |p| p. latency )
267
- }
268
-
269
- /// Returns the latency and confirmed_at time if this path would make for a valid best addr `now`
270
- pub ( crate ) fn valid_best_addr_candidate ( & self , now : Instant ) -> Option < ( Duration , Instant ) > {
271
- let latency = self . recent_pong . as_ref ( ) ?. latency ;
272
- let confirmed_at = self . last_confirmed_at ( ) ?;
273
-
274
- if confirmed_at <= now && now < confirmed_at + TRUST_UDP_ADDR_DURATION {
275
- return Some ( ( latency, confirmed_at) ) ;
276
- }
277
-
278
- None
241
+ self . validity . get_pong ( ) . map ( |p| p. latency )
279
242
}
280
243
281
244
pub ( super ) fn needs_ping ( & self , now : & Instant ) -> bool {
@@ -336,15 +299,15 @@ impl PathState {
336
299
self . last_ping = None ;
337
300
self . last_got_ping = None ;
338
301
self . call_me_maybe_time = None ;
339
- self . recent_pong = None ;
302
+ self . validity = PathValidity :: empty ( ) ;
340
303
}
341
304
342
305
fn summary ( & self , mut w : impl std:: fmt:: Write ) -> std:: fmt:: Result {
343
306
write ! ( w, "{{ " ) ?;
344
307
if self . is_active ( ) {
345
308
write ! ( w, "active " ) ?;
346
309
}
347
- if let Some ( ref pong) = self . recent_pong {
310
+ if let Some ( pong) = self . validity . get_pong ( ) {
348
311
write ! ( w, "pong-received({:?} ago) " , pong. pong_at. elapsed( ) ) ?;
349
312
}
350
313
if let Some ( when) = self . last_incoming_ping ( ) {
0 commit comments