@@ -73,6 +73,7 @@ pub struct MdnsDiscovery {
73
73
#[ allow( dead_code) ]
74
74
handle : AbortOnDropHandle < ( ) > ,
75
75
sender : mpsc:: Sender < Message > ,
76
+ advertise : bool ,
76
77
/// When `local_addrs` changes, we re-publish our info.
77
78
local_addrs : Watchable < Option < NodeData > > ,
78
79
}
@@ -127,39 +128,73 @@ impl Subscribers {
127
128
128
129
/// Builder for [`MdnsDiscovery`].
129
130
#[ derive( Debug ) ]
130
- pub struct MdnsDiscoveryBuilder ;
131
+ pub struct MdnsDiscoveryBuilder {
132
+ advertise : bool ,
133
+ }
134
+
135
+ impl MdnsDiscoveryBuilder {
136
+ /// Creates a new [`MdnsDiscoveryBuilder`] with default settings.
137
+ pub fn new ( ) -> Self {
138
+ Self { advertise : true }
139
+ }
140
+
141
+ /// Sets whether this node should advertise its presence.
142
+ ///
143
+ /// Default is true.
144
+ pub fn advertise ( mut self , advertise : bool ) -> Self {
145
+ self . advertise = advertise;
146
+ self
147
+ }
148
+
149
+ /// Builds an [`MdnsDiscovery`] instance with the configured settings.
150
+ pub fn build ( self , node_id : NodeId ) -> Result < MdnsDiscovery , IntoDiscoveryError > {
151
+ MdnsDiscovery :: new ( node_id, self . advertise )
152
+ }
153
+ }
154
+
155
+ impl Default for MdnsDiscoveryBuilder {
156
+ fn default ( ) -> Self {
157
+ Self :: new ( )
158
+ }
159
+ }
131
160
132
161
impl IntoDiscovery for MdnsDiscoveryBuilder {
133
162
fn into_discovery (
134
163
self ,
135
164
context : & DiscoveryContext ,
136
165
) -> Result < impl Discovery , IntoDiscoveryError > {
137
- MdnsDiscovery :: new ( context. node_id ( ) )
166
+ self . build ( context. node_id ( ) )
138
167
}
139
168
}
140
169
141
170
impl MdnsDiscovery {
142
171
/// Returns a [`MdnsDiscoveryBuilder`] that implements [`IntoDiscovery`].
143
172
pub fn builder ( ) -> MdnsDiscoveryBuilder {
144
- MdnsDiscoveryBuilder
173
+ MdnsDiscoveryBuilder :: new ( )
145
174
}
146
175
147
176
/// Create a new [`MdnsDiscovery`] Service.
148
177
///
149
- /// This starts a [`Discoverer`] that broadcasts your addresses and receives addresses from other nodes in your local network.
178
+ /// This starts a [`Discoverer`] that broadcasts your addresses (if advertise is set to true)
179
+ /// and receives addresses from other nodes in your local network.
150
180
///
151
181
/// # Errors
152
182
/// Returns an error if the network does not allow ipv4 OR ipv6.
153
183
///
154
184
/// # Panics
155
185
/// This relies on [`tokio::runtime::Handle::current`] and will panic if called outside of the context of a tokio runtime.
156
- pub fn new ( node_id : NodeId ) -> Result < Self , IntoDiscoveryError > {
186
+ pub fn new ( node_id : NodeId , advertise : bool ) -> Result < Self , IntoDiscoveryError > {
157
187
debug ! ( "Creating new MdnsDiscovery service" ) ;
158
188
let ( send, mut recv) = mpsc:: channel ( 64 ) ;
159
189
let task_sender = send. clone ( ) ;
160
190
let rt = tokio:: runtime:: Handle :: current ( ) ;
161
- let discovery =
162
- MdnsDiscovery :: spawn_discoverer ( node_id, task_sender. clone ( ) , BTreeSet :: new ( ) , & rt) ?;
191
+ let discovery = MdnsDiscovery :: spawn_discoverer (
192
+ node_id,
193
+ advertise,
194
+ task_sender. clone ( ) ,
195
+ BTreeSet :: new ( ) ,
196
+ & rt,
197
+ ) ?;
163
198
164
199
let local_addrs: Watchable < Option < NodeData > > = Watchable :: default ( ) ;
165
200
let mut addrs_change = local_addrs. watch ( ) ;
@@ -311,13 +346,15 @@ impl MdnsDiscovery {
311
346
let handle = task:: spawn ( discovery_fut. instrument ( info_span ! ( "swarm-discovery.actor" ) ) ) ;
312
347
Ok ( Self {
313
348
handle : AbortOnDropHandle :: new ( handle) ,
349
+ advertise,
314
350
sender : send,
315
351
local_addrs,
316
352
} )
317
353
}
318
354
319
355
fn spawn_discoverer (
320
356
node_id : PublicKey ,
357
+ advertise : bool ,
321
358
sender : mpsc:: Sender < Message > ,
322
359
socketaddrs : BTreeSet < SocketAddr > ,
323
360
rt : & tokio:: runtime:: Handle ,
@@ -337,15 +374,17 @@ impl MdnsDiscovery {
337
374
sender. send ( Message :: Discovery ( node_id, peer) ) . await . ok ( ) ;
338
375
} ) ;
339
376
} ;
340
- let addrs = MdnsDiscovery :: socketaddrs_to_addrs ( & socketaddrs) ;
341
377
let node_id_str = data_encoding:: BASE32_NOPAD
342
378
. encode ( node_id. as_bytes ( ) )
343
379
. to_ascii_lowercase ( ) ;
344
380
let mut discoverer = Discoverer :: new_interactive ( N0_LOCAL_SWARM . to_string ( ) , node_id_str)
345
381
. with_callback ( callback)
346
382
. with_ip_class ( IpClass :: Auto ) ;
347
- for addr in addrs {
348
- discoverer = discoverer. with_addrs ( addr. 0 , addr. 1 ) ;
383
+ if advertise {
384
+ let addrs = MdnsDiscovery :: socketaddrs_to_addrs ( & socketaddrs) ;
385
+ for addr in addrs {
386
+ discoverer = discoverer. with_addrs ( addr. 0 , addr. 1 ) ;
387
+ }
349
388
}
350
389
discoverer
351
390
. spawn ( rt)
@@ -406,7 +445,9 @@ impl Discovery for MdnsDiscovery {
406
445
}
407
446
408
447
fn publish ( & self , data : & NodeData ) {
409
- self . local_addrs . set ( Some ( data. clone ( ) ) ) . ok ( ) ;
448
+ if self . advertise {
449
+ self . local_addrs . set ( Some ( data. clone ( ) ) ) . ok ( ) ;
450
+ }
410
451
}
411
452
412
453
fn subscribe ( & self ) -> Option < BoxStream < DiscoveryItem > > {
@@ -440,8 +481,10 @@ mod tests {
440
481
#[ tokio:: test]
441
482
#[ traced_test]
442
483
async fn mdns_publish_resolve ( ) -> Result {
443
- let ( _, discovery_a) = make_discoverer ( ) ?;
444
- let ( node_id_b, discovery_b) = make_discoverer ( ) ?;
484
+ // Create discoverer A with advertise=false (only listens)
485
+ let ( _, discovery_a) = make_discoverer ( false ) ?;
486
+ // Create discoverer B with advertise=true (will broadcast)
487
+ let ( node_id_b, discovery_b) = make_discoverer ( true ) ?;
445
488
446
489
// make addr info for discoverer b
447
490
let user_data: UserData = "foobar" . parse ( ) ?;
@@ -477,11 +520,11 @@ mod tests {
477
520
let mut node_ids = BTreeSet :: new ( ) ;
478
521
let mut discoverers = vec ! [ ] ;
479
522
480
- let ( _, discovery) = make_discoverer ( ) ?;
523
+ let ( _, discovery) = make_discoverer ( false ) ?;
481
524
let node_data = NodeData :: new ( None , BTreeSet :: from ( [ "0.0.0.0:11111" . parse ( ) . unwrap ( ) ] ) ) ;
482
525
483
526
for i in 0 ..num_nodes {
484
- let ( node_id, discovery) = make_discoverer ( ) ?;
527
+ let ( node_id, discovery) = make_discoverer ( true ) ?;
485
528
let user_data: UserData = format ! ( "node{i}" ) . parse ( ) ?;
486
529
let node_data = node_data. clone ( ) . with_user_data ( Some ( user_data. clone ( ) ) ) ;
487
530
node_ids. insert ( ( node_id, Some ( user_data) ) ) ;
@@ -513,9 +556,38 @@ mod tests {
513
556
. context ( "timeout" ) ?
514
557
}
515
558
516
- fn make_discoverer ( ) -> Result < ( PublicKey , MdnsDiscovery ) > {
559
+ #[ tokio:: test]
560
+ #[ traced_test]
561
+ async fn non_advertising_node_not_discovered ( ) -> Result {
562
+ let ( _, discovery_a) = make_discoverer ( false ) ?;
563
+ let ( node_id_b, discovery_b) = make_discoverer ( false ) ?;
564
+
565
+ let ( node_id_c, discovery_c) = make_discoverer ( true ) ?;
566
+ let node_data_c =
567
+ NodeData :: new ( None , BTreeSet :: from ( [ "0.0.0.0:22222" . parse ( ) . unwrap ( ) ] ) ) ;
568
+ discovery_c. publish ( & node_data_c) ;
569
+
570
+ let node_data_b =
571
+ NodeData :: new ( None , BTreeSet :: from ( [ "0.0.0.0:11111" . parse ( ) . unwrap ( ) ] ) ) ;
572
+ discovery_b. publish ( & node_data_b) ;
573
+
574
+ let mut stream_c = discovery_a. resolve ( node_id_c) . unwrap ( ) ;
575
+ let result_c = tokio:: time:: timeout ( Duration :: from_secs ( 2 ) , stream_c. next ( ) ) . await ;
576
+ assert ! ( result_c. is_ok( ) , "Advertising node should be discoverable" ) ;
577
+
578
+ let mut stream_b = discovery_a. resolve ( node_id_b) . unwrap ( ) ;
579
+ let result_b = tokio:: time:: timeout ( Duration :: from_secs ( 2 ) , stream_b. next ( ) ) . await ;
580
+ assert ! (
581
+ result_b. is_err( ) ,
582
+ "Expected timeout since node b isn't advertising"
583
+ ) ;
584
+
585
+ Ok ( ( ) )
586
+ }
587
+
588
+ fn make_discoverer ( advertise : bool ) -> Result < ( PublicKey , MdnsDiscovery ) > {
517
589
let node_id = SecretKey :: generate ( rand:: thread_rng ( ) ) . public ( ) ;
518
- Ok ( ( node_id, MdnsDiscovery :: new ( node_id) ?) )
590
+ Ok ( ( node_id, MdnsDiscovery :: new ( node_id, advertise ) ?) )
519
591
}
520
592
}
521
593
}
0 commit comments