@@ -37,7 +37,7 @@ use std::{
37
37
38
38
use anyhow:: Result ;
39
39
use derive_more:: FromStr ;
40
- use iroh_base:: { NodeAddr , NodeId , PublicKey , RelayUrl } ;
40
+ use iroh_base:: { NodeAddr , NodeId , PublicKey } ;
41
41
use n0_future:: {
42
42
boxed:: BoxStream ,
43
43
task:: { self , AbortOnDropHandle , JoinSet } ,
@@ -65,6 +65,8 @@ const N0_LOCAL_SWARM: &str = "iroh.local.swarm";
65
65
/// Used in the [`crate::endpoint::Source::Discovery`] enum variant as the `name`.
66
66
pub const NAME : & str = "local.swarm.discovery" ;
67
67
68
+ const USER_DATA_ATTRIBUTE : & str = "user-data" ;
69
+
68
70
/// How long we will wait before we stop sending discovery items
69
71
const DISCOVERY_DURATION : Duration = Duration :: from_secs ( 10 ) ;
70
72
@@ -75,7 +77,7 @@ pub struct LocalSwarmDiscovery {
75
77
handle : AbortOnDropHandle < ( ) > ,
76
78
sender : mpsc:: Sender < Message > ,
77
79
/// When `local_addrs` changes, we re-publish our info.
78
- local_addrs : Watchable < Option < ( Option < RelayUrl > , BTreeSet < SocketAddr > ) > > ,
80
+ local_addrs : Watchable < Option < DiscoveryData > > ,
79
81
}
80
82
81
83
#[ derive( Debug ) ]
@@ -148,8 +150,7 @@ impl LocalSwarmDiscovery {
148
150
& rt,
149
151
) ?;
150
152
151
- let local_addrs: Watchable < Option < ( Option < RelayUrl > , BTreeSet < SocketAddr > ) > > =
152
- Watchable :: default ( ) ;
153
+ let local_addrs: Watchable < Option < DiscoveryData > > = Watchable :: default ( ) ;
153
154
let mut addrs_change = local_addrs. watch ( ) ;
154
155
let discovery_fut = async move {
155
156
let mut node_addrs: HashMap < PublicKey , Peer > = HashMap :: default ( ) ;
@@ -166,14 +167,20 @@ impl LocalSwarmDiscovery {
166
167
msg = recv. recv( ) => {
167
168
msg
168
169
}
169
- Ok ( Some ( ( _url, addrs) ) ) = addrs_change. updated( ) => {
170
- tracing:: trace!( ?addrs, "LocalSwarmDiscovery address changed" ) ;
170
+ Ok ( Some ( data) ) = addrs_change. updated( ) => {
171
+ println!( "PUBLISH {data:?}" ) ;
172
+ tracing:: trace!( ?data, "LocalSwarmDiscovery address changed" ) ;
171
173
discovery. remove_all( ) ;
172
174
let addrs =
173
- LocalSwarmDiscovery :: socketaddrs_to_addrs( addrs ) ;
175
+ LocalSwarmDiscovery :: socketaddrs_to_addrs( data . direct_addrs ( ) ) ;
174
176
for addr in addrs {
175
177
discovery. add( addr. 0 , addr. 1 )
176
178
}
179
+ if let Some ( user_data) = data. user_data( ) {
180
+ if let Err ( err) = discovery. set_txt_attribute( USER_DATA_ATTRIBUTE . to_string( ) , Some ( user_data. to_string( ) ) ) {
181
+ warn!( "Failed to set user data in local swarm discovery: {err:?}" ) ;
182
+ }
183
+ }
177
184
continue ;
178
185
}
179
186
} ;
@@ -320,7 +327,7 @@ impl LocalSwarmDiscovery {
320
327
sender. send ( Message :: Discovery ( node_id, peer) ) . await . ok ( ) ;
321
328
} ) ;
322
329
} ;
323
- let addrs = LocalSwarmDiscovery :: socketaddrs_to_addrs ( socketaddrs) ;
330
+ let addrs = LocalSwarmDiscovery :: socketaddrs_to_addrs ( & socketaddrs) ;
324
331
let node_id_str = data_encoding:: BASE32_NOPAD
325
332
. encode ( node_id. as_bytes ( ) )
326
333
. to_ascii_lowercase ( ) ;
@@ -333,7 +340,7 @@ impl LocalSwarmDiscovery {
333
340
discoverer. spawn ( rt)
334
341
}
335
342
336
- fn socketaddrs_to_addrs ( socketaddrs : BTreeSet < SocketAddr > ) -> HashMap < u16 , Vec < IpAddr > > {
343
+ fn socketaddrs_to_addrs ( socketaddrs : & BTreeSet < SocketAddr > ) -> HashMap < u16 , Vec < IpAddr > > {
337
344
let mut addrs: HashMap < u16 , Vec < IpAddr > > = HashMap :: default ( ) ;
338
345
for socketaddr in socketaddrs {
339
346
addrs
@@ -351,6 +358,10 @@ fn peer_to_discovery_item(peer: &Peer, node_id: &NodeId) -> DiscoveryItem {
351
358
. iter ( )
352
359
. map ( |( ip, port) | SocketAddr :: new ( * ip, * port) )
353
360
. collect ( ) ;
361
+ let user_data = match peer. txt_attribute ( USER_DATA_ATTRIBUTE ) {
362
+ Some ( Some ( user_data) ) => user_data. parse ( ) . ok ( ) ,
363
+ _ => None ,
364
+ } ;
354
365
DiscoveryItem {
355
366
node_addr : NodeAddr {
356
367
node_id : * node_id,
@@ -359,7 +370,7 @@ fn peer_to_discovery_item(peer: &Peer, node_id: &NodeId) -> DiscoveryItem {
359
370
} ,
360
371
provenance : NAME ,
361
372
last_updated : None ,
362
- user_data : None ,
373
+ user_data,
363
374
}
364
375
}
365
376
@@ -380,12 +391,7 @@ impl Discovery for LocalSwarmDiscovery {
380
391
}
381
392
382
393
fn publish ( & self , data : & DiscoveryData ) {
383
- self . local_addrs
384
- . set ( Some ( (
385
- data. relay_url ( ) . cloned ( ) ,
386
- data. direct_addrs ( ) . clone ( ) ,
387
- ) ) )
388
- . ok ( ) ;
394
+ self . local_addrs . set ( Some ( data. clone ( ) ) ) . ok ( ) ;
389
395
}
390
396
391
397
fn subscribe ( & self ) -> Option < BoxStream < DiscoveryItem > > {
@@ -413,6 +419,7 @@ mod tests {
413
419
use tracing_test:: traced_test;
414
420
415
421
use super :: super :: * ;
422
+ use crate :: discovery:: UserData ;
416
423
417
424
#[ tokio:: test]
418
425
#[ traced_test]
@@ -421,7 +428,10 @@ mod tests {
421
428
let ( node_id_b, discovery_b) = make_discoverer ( ) ?;
422
429
423
430
// make addr info for discoverer b
424
- let addr_info = DiscoveryData :: new ( None , BTreeSet :: from ( [ "0.0.0.0:11111" . parse ( ) ?] ) ) ;
431
+ let user_data: UserData = "foobar" . parse ( ) ?;
432
+ let addr_info = DiscoveryData :: new ( None , BTreeSet :: from ( [ "0.0.0.0:11111" . parse ( ) ?] ) )
433
+ . with_user_data ( user_data. clone ( ) ) ;
434
+ println ! ( "info {addr_info:?}" ) ;
425
435
426
436
// pass in endpoint, this is never used
427
437
let ep = crate :: endpoint:: Builder :: default ( ) . bind ( ) . await ?;
@@ -441,8 +451,10 @@ mod tests {
441
451
. unwrap ( ) ?;
442
452
assert_eq ! ( s1_res. node_addr. relay_url. as_ref( ) , addr_info. relay_url( ) ) ;
443
453
assert_eq ! ( & s1_res. node_addr. direct_addresses, addr_info. direct_addrs( ) ) ;
454
+ assert_eq ! ( s1_res. user_data. as_ref( ) , Some ( & user_data) ) ;
444
455
assert_eq ! ( s2_res. node_addr. relay_url. as_ref( ) , addr_info. relay_url( ) ) ;
445
456
assert_eq ! ( & s2_res. node_addr. direct_addresses, addr_info. direct_addrs( ) ) ;
457
+ assert_eq ! ( s2_res. user_data. as_ref( ) , Some ( & user_data) ) ;
446
458
447
459
Ok ( ( ) )
448
460
}
@@ -457,9 +469,11 @@ mod tests {
457
469
let ( _, discovery) = make_discoverer ( ) ?;
458
470
let addr_info = DiscoveryData :: new ( None , BTreeSet :: from ( [ "0.0.0.0:11111" . parse ( ) ?] ) ) ;
459
471
460
- for _ in 0 ..num_nodes {
472
+ for i in 0 ..num_nodes {
461
473
let ( node_id, discovery) = make_discoverer ( ) ?;
462
- node_ids. insert ( node_id) ;
474
+ let user_data: UserData = format ! ( "node{i}" ) . parse ( ) ?;
475
+ let addr_info = addr_info. clone ( ) . with_user_data ( user_data. clone ( ) ) ;
476
+ node_ids. insert ( ( node_id, Some ( user_data) ) ) ;
463
477
discovery. publish ( & addr_info) ;
464
478
discoverers. push ( discovery) ;
465
479
}
@@ -470,8 +484,8 @@ mod tests {
470
484
let mut got_ids = BTreeSet :: new ( ) ;
471
485
while got_ids. len ( ) != num_nodes {
472
486
if let Some ( item) = events. next ( ) . await {
473
- if node_ids. contains ( & item. node_addr . node_id ) {
474
- got_ids. insert ( item. node_addr . node_id ) ;
487
+ if node_ids. contains ( & ( item. node_addr . node_id , item . user_data . clone ( ) ) ) {
488
+ got_ids. insert ( ( item. node_addr . node_id , item . user_data ) ) ;
475
489
}
476
490
} else {
477
491
anyhow:: bail!(
0 commit comments