11//! Command line arguments.
22use clap:: { Parser , Subcommand } ;
33use dumbpipe:: NodeTicket ;
4- use iroh:: { endpoint:: Connecting , Endpoint , NodeAddr , SecretKey , Watcher } ;
4+ use iroh:: { endpoint:: Connecting , Endpoint , NodeAddr , RelayMode , RelayUrl , SecretKey , Watcher } ;
55use n0_snafu:: { Result , ResultExt } ;
66use std:: {
7- io,
8- net:: { SocketAddr , SocketAddrV4 , SocketAddrV6 , ToSocketAddrs } ,
9- str:: FromStr ,
7+ fmt:: { Display , Formatter } , io, net:: { SocketAddr , SocketAddrV4 , SocketAddrV6 , ToSocketAddrs } , str:: FromStr
108} ;
119use tokio:: {
1210 io:: { AsyncRead , AsyncWrite , AsyncWriteExt } ,
@@ -121,7 +119,15 @@ pub struct CommonArgs {
121119 /// Otherwise, it will be parsed as a hex string.
122120 #[ clap( long) ]
123121 pub custom_alpn : Option < String > ,
124-
122+
123+ /// The relay URL to use as a home relay,
124+ ///
125+ /// Can be set to "disabled" to disable relay servers and "custom"
126+ /// to configure custom servers. The default is the n0 quickest responding
127+ /// relay if the flag is not set.
128+ #[ clap( long, default_value_t = RelayModeOption :: Default ) ]
129+ pub relay : RelayModeOption ,
130+
125131 /// The verbosity level. Repeat to increase verbosity.
126132 #[ clap( short = 'v' , long, action = clap:: ArgAction :: Count ) ]
127133 pub verbose : u8 ,
@@ -148,6 +154,49 @@ fn parse_alpn(alpn: &str) -> Result<Vec<u8>> {
148154 } )
149155}
150156
157+ /// Available command line options for configuring relays.
158+ #[ derive( Clone , Debug ) ]
159+ pub enum RelayModeOption {
160+ /// Disables relays altogether.
161+ Disabled ,
162+ /// Uses the default relay servers.
163+ Default ,
164+ /// Uses a single, custom relay server by URL.
165+ Custom ( RelayUrl ) ,
166+ }
167+
168+ impl FromStr for RelayModeOption {
169+ type Err = anyhow:: Error ;
170+
171+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
172+ match s {
173+ "disabled" => Ok ( Self :: Disabled ) ,
174+ "default" => Ok ( Self :: Default ) ,
175+ _ => Ok ( Self :: Custom ( RelayUrl :: from_str ( s) ?) ) ,
176+ }
177+ }
178+ }
179+
180+ impl Display for RelayModeOption {
181+ fn fmt ( & self , f : & mut Formatter < ' _ > ) -> std:: fmt:: Result {
182+ match self {
183+ Self :: Disabled => f. write_str ( "disabled" ) ,
184+ Self :: Default => f. write_str ( "default" ) ,
185+ Self :: Custom ( url) => url. fmt ( f) ,
186+ }
187+ }
188+ }
189+
190+ impl From < RelayModeOption > for RelayMode {
191+ fn from ( value : RelayModeOption ) -> Self {
192+ match value {
193+ RelayModeOption :: Disabled => RelayMode :: Disabled ,
194+ RelayModeOption :: Default => RelayMode :: Default ,
195+ RelayModeOption :: Custom ( url) => RelayMode :: Custom ( url. into ( ) ) ,
196+ }
197+ }
198+ }
199+
151200#[ derive( Parser , Debug ) ]
152201pub struct ListenArgs {
153202 /// Immediately close our sending side, indicating that we will not transmit any data
@@ -291,7 +340,10 @@ async fn create_endpoint(
291340 common : & CommonArgs ,
292341 alpns : Vec < Vec < u8 > > ,
293342) -> Result < Endpoint > {
294- let mut builder = Endpoint :: builder ( ) . secret_key ( secret_key) . alpns ( alpns) ;
343+ let mut builder = Endpoint :: builder ( )
344+ . secret_key ( secret_key)
345+ . alpns ( alpns)
346+ . relay_mode ( common. relay . clone ( ) . into ( ) ) ;
295347 if let Some ( addr) = common. ipv4_addr {
296348 builder = builder. bind_addr_v4 ( addr) ;
297349 }
0 commit comments