server: prompt for listen port before endpoint

also fix a logic bug if user cancels port selection in client
when trying to override endpoint.

fixes #148
pull/153/head
Jake McGinty 2021-09-15 20:43:38 +09:00
parent 4fa689d400
commit cacd80b283
3 changed files with 54 additions and 42 deletions

View File

@ -839,10 +839,11 @@ fn set_listen_port(
interface: &InterfaceName,
unset: bool,
network: NetworkOpt,
) -> Result<(), Error> {
) -> Result<Option<u16>, Error> {
let mut config = InterfaceConfig::from_interface(interface)?;
if let Some(listen_port) = prompts::set_listen_port(&config.interface, unset)? {
let listen_port = prompts::set_listen_port(&config.interface, unset)?;
if let Some(listen_port) = listen_port {
wg::set_listen_port(interface, listen_port, network.backend)?;
log::info!("the interface is updated");
@ -853,7 +854,7 @@ fn set_listen_port(
log::info!("exiting without updating the listen port.");
}
Ok(())
Ok(listen_port.flatten())
}
fn override_endpoint(
@ -862,20 +863,32 @@ fn override_endpoint(
network: NetworkOpt,
) -> Result<(), Error> {
let config = InterfaceConfig::from_interface(interface)?;
if !unset && config.interface.listen_port.is_none() {
println!(
"{}: you need to set a listen port for your interface first.",
"note".bold().yellow()
);
set_listen_port(interface, unset, network)?;
}
let endpoint_contents = if unset {
prompts::unset_override_endpoint()?.then(|| EndpointContents::Unset)
} else {
let listen_port = if let Some(listen_port) = config.interface.listen_port {
Some(listen_port)
} else {
println!(
"{}: you need to set a listen port for your interface first.",
"note".bold().yellow()
);
set_listen_port(interface, unset, network)?
};
let endpoint = if let Some(port) = listen_port {
prompts::override_endpoint(port)?
} else {
None
};
endpoint.map(|endpoint| EndpointContents::Set(endpoint))
};
if let Some(endpoint) = prompts::override_endpoint(unset)? {
if let Some(contents) = endpoint_contents {
log::info!("Updating endpoint.");
Api::new(&config.server).http_form(
"PUT",
"/user/endpoint",
EndpointContents::from(endpoint),
contents,
)?;
} else {
log::info!("exiting without overriding endpoint.");
@ -1119,10 +1132,10 @@ fn run(opt: Opts) -> Result<(), Error> {
Command::DeleteAssociation { interface } => delete_association(&interface)?,
Command::ListAssociations { interface } => list_associations(&interface)?,
Command::SetListenPort { interface, unset } => {
set_listen_port(&interface, unset, opt.network)?
set_listen_port(&interface, unset, opt.network)?;
},
Command::OverrideEndpoint { interface, unset } => {
override_endpoint(&interface, unset, opt.network)?
override_endpoint(&interface, unset, opt.network)?;
},
Command::Completions { shell } => {
Opts::clap().gen_completions_to("innernet", shell, &mut std::io::stdout());

View File

@ -139,16 +139,6 @@ pub fn init_wizard(conf: &ServerConfig, opts: InitializeOpts) -> Result<(), Erro
.interact()?
};
let endpoint: Endpoint = if let Some(endpoint) = opts.external_endpoint {
endpoint
} else if opts.auto_external_endpoint {
let ip = publicip::get_any(Preference::Ipv4)
.ok_or_else(|| anyhow!("couldn't get external IP"))?;
SocketAddr::new(ip, 51820).into()
} else {
prompts::ask_endpoint()?
};
let listen_port: u16 = if let Some(listen_port) = opts.listen_port {
listen_port
} else {
@ -159,6 +149,18 @@ pub fn init_wizard(conf: &ServerConfig, opts: InitializeOpts) -> Result<(), Erro
.map_err(|_| anyhow!("failed to get listen port."))?
};
log::info!("listen port: {}", listen_port);
let endpoint: Endpoint = if let Some(endpoint) = opts.external_endpoint {
endpoint
} else if opts.auto_external_endpoint {
let ip = publicip::get_any(Preference::Ipv4)
.ok_or_else(|| anyhow!("couldn't get external IP"))?;
SocketAddr::new(ip, listen_port).into()
} else {
prompts::ask_endpoint(listen_port)?
};
let our_ip = root_cidr
.iter()
.find(|ip| root_cidr.is_assignable(*ip))

View File

@ -459,7 +459,7 @@ pub fn set_listen_port(
}
}
pub fn ask_endpoint() -> Result<Endpoint, Error> {
pub fn ask_endpoint(listen_port: u16) -> Result<Endpoint, Error> {
println!("getting external IP address.");
let external_ip = if Confirm::with_theme(&*THEME)
@ -475,26 +475,23 @@ pub fn ask_endpoint() -> Result<Endpoint, Error> {
Ok(input(
"External endpoint",
match external_ip {
Some(ip) => Prefill::Editable(SocketAddr::new(ip, 51820).to_string()),
Some(ip) => Prefill::Editable(SocketAddr::new(ip, listen_port).to_string()),
None => Prefill::None,
},
)?)
}
pub fn override_endpoint(unset: bool) -> Result<Option<Option<Endpoint>>, Error> {
let endpoint = if !unset { Some(ask_endpoint()?) } else { None };
Ok(
if confirm(
&(if let Some(endpoint) = &endpoint {
format!("Set external endpoint to {}?", endpoint)
} else {
"Unset external endpoint to enable automatic endpoint discovery?".to_string()
}),
)? {
Some(endpoint)
} else {
None
},
)
pub fn override_endpoint(listen_port: u16) -> Result<Option<Endpoint>, Error> {
let endpoint = ask_endpoint(listen_port)?;
if confirm(&format!("Set external endpoint to {}?", endpoint))? {
Ok(Some(endpoint))
} else {
Ok(None)
}
}
pub fn unset_override_endpoint() -> Result<bool, Error> {
Ok(confirm(
"Unset external endpoint to enable automatic endpoint discovery?",
)?)
}