1010//! To see what is going on, run with `RUST_LOG=iroh_pkarr_node_discovery=debug`.
1111use std:: str:: FromStr ;
1212
13- use anyhow :: Context ;
13+ use clap :: Parser ;
1414use iroh_net:: { magic_endpoint:: get_remote_node_id, MagicEndpoint , NodeId } ;
15+ use pkarr:: url:: Url ;
1516
1617const CHAT_ALPN : & [ u8 ] = b"pkarr-discovery-demo-chat" ;
1718
18- async fn chat_server ( ) -> anyhow:: Result < ( ) > {
19+ #[ derive( Parser ) ]
20+ struct Args {
21+ /// The node id to connect to. If not set, the program will start a server.
22+ node_id : Option < NodeId > ,
23+ /// Disable using the mainline DHT for discovery and publishing.
24+ #[ clap( long) ]
25+ disable_dht : bool ,
26+ /// Pkarr relay to use.
27+ #[ clap( long, default_value = "iroh" ) ]
28+ pkarr_relay : PkarrRelay ,
29+ }
30+
31+ #[ derive( Debug , Clone ) ]
32+ enum PkarrRelay {
33+ Disabled ,
34+ Iroh ,
35+ Custom ( Url ) ,
36+ }
37+
38+ impl FromStr for PkarrRelay {
39+ type Err = anyhow:: Error ;
40+
41+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
42+ match s {
43+ "disabled" => Ok ( Self :: Disabled ) ,
44+ "iroh" => Ok ( Self :: Iroh ) ,
45+ s => Ok ( Self :: Custom ( Url :: parse ( s) ?) ) ,
46+ }
47+ }
48+ }
49+
50+ fn build_discovery ( args : Args ) -> iroh_pkarr_node_discovery:: Builder {
51+ let builder = iroh_pkarr_node_discovery:: PkarrNodeDiscovery :: builder ( ) . dht ( !args. disable_dht ) ;
52+ let builder = match args. pkarr_relay {
53+ PkarrRelay :: Disabled => builder,
54+ PkarrRelay :: Iroh => builder. iroh_pkarr_relay ( ) ,
55+ PkarrRelay :: Custom ( url) => builder. pkarr_relay ( url) ,
56+ } ;
57+ builder
58+ }
59+
60+ async fn chat_server ( args : Args ) -> anyhow:: Result < ( ) > {
1961 let secret_key = iroh_net:: key:: SecretKey :: generate ( ) ;
2062 let node_id = secret_key. public ( ) ;
21- let discovery = iroh_pkarr_node_discovery :: PkarrNodeDiscovery :: builder ( )
22- . secret_key ( & secret_key)
23- . build ( ) ;
63+ let discovery = build_discovery ( args )
64+ . secret_key ( secret_key. clone ( ) )
65+ . build ( ) ? ;
2466 let endpoint = MagicEndpoint :: builder ( )
2567 . alpns ( vec ! [ CHAT_ALPN . to_vec( ) ] )
2668 . secret_key ( secret_key)
@@ -51,11 +93,12 @@ async fn chat_server() -> anyhow::Result<()> {
5193 Ok ( ( ) )
5294}
5395
54- async fn chat_client ( remote_node_id : NodeId ) -> anyhow:: Result < ( ) > {
96+ async fn chat_client ( args : Args ) -> anyhow:: Result < ( ) > {
97+ let remote_node_id = args. node_id . unwrap ( ) ;
5598 let secret_key = iroh_net:: key:: SecretKey :: generate ( ) ;
5699 let node_id = secret_key. public ( ) ;
57100 // note: we don't pass a secret key here, because we don't need to publish our address, don't spam the DHT
58- let discovery = iroh_pkarr_node_discovery :: PkarrNodeDiscovery :: builder ( ) . build ( ) ;
101+ let discovery = build_discovery ( args ) . build ( ) ? ;
59102 // we do not need to specify the alpn here, because we are not going to accept connections
60103 let endpoint = MagicEndpoint :: builder ( )
61104 . secret_key ( secret_key)
@@ -66,6 +109,7 @@ async fn chat_client(remote_node_id: NodeId) -> anyhow::Result<()> {
66109 let connection = endpoint
67110 . connect_by_node_id ( & remote_node_id, CHAT_ALPN )
68111 . await ?;
112+ println ! ( "connected to {}" , remote_node_id) ;
69113 let ( mut writer, mut reader) = connection. open_bi ( ) . await ?;
70114 let _copy_to_stdout =
71115 tokio:: spawn ( async move { tokio:: io:: copy ( & mut reader, & mut tokio:: io:: stdout ( ) ) . await } ) ;
@@ -79,16 +123,11 @@ async fn chat_client(remote_node_id: NodeId) -> anyhow::Result<()> {
79123#[ tokio:: main]
80124async fn main ( ) -> anyhow:: Result < ( ) > {
81125 tracing_subscriber:: fmt:: init ( ) ;
82- let args = std:: env:: args ( ) ;
83- let first = args. into_iter ( ) . skip ( 1 ) . next ( ) ;
84- match first {
85- Some ( node_id) => {
86- let node_id = NodeId :: from_str ( & node_id) . context ( "invalid node id" ) ?;
87- chat_client ( node_id) . await ?;
88- }
89- None => {
90- chat_server ( ) . await ?;
91- }
126+ let args = Args :: parse ( ) ;
127+ if args. node_id . is_some ( ) {
128+ chat_client ( args) . await ?;
129+ } else {
130+ chat_server ( args) . await ?;
92131 }
93132 Ok ( ( ) )
94133}
0 commit comments