Align SDK UDP host selection with CLI
ci / test (push) Canceled after 0s
ci / fuzz-smoke (push) Canceled after 0s
ci / macos-client (macos-aarch64, macos-14) (push) Canceled after 0s
ci / macos-client (macos-x86_64, macos-13) (push) Canceled after 0s
ci / windows-client (push) Canceled after 0s
ci / package-release (linux-x86_64, ubuntu-latest, , , ) (push) Canceled after 0s
ci / package-release (macos-aarch64, macos-14, , , ) (push) Canceled after 0s
ci / package-release (macos-x86_64, macos-13, , , ) (push) Canceled after 0s
ci / package-release (windows-aarch64, windows-latest, aarch64, windows, aarch64-pc-windows-msvc) (push) Canceled after 0s
ci / package-release (windows-x86_64, windows-latest, , , ) (push) Canceled after 0s
ci / remote-bench (push) Canceled after 0s
ci / publish-gitea-release (push) Canceled after 0s

This commit is contained in:
DuProcess
2026-07-16 21:19:02 -04:00
parent 9303253626
commit 7e4133b315
+100 -8
View File
@@ -155,18 +155,19 @@ impl DoshClientBuilder {
.cloned()
.unwrap_or_default();
let raw_server = host_config.ssh.clone().unwrap_or_else(|| self.host.clone());
let udp_host = self
.udp_host
.clone()
.or_else(|| host_config.dosh_host.clone())
.or_else(|| self.client.config.dosh_host.clone())
.unwrap_or_else(|| destination_host(&raw_server));
let ssh_port = host_config.ssh_port.or(self.client.config.ssh_port);
let ssh_config = load_sdk_ssh_config(host_config.ssh_config.as_deref(), ssh_port)?;
let udp_host = selected_sdk_udp_host(
self.udp_host.as_deref(),
&host_config,
&self.client.config,
&raw_server,
&ssh_config,
)?;
let udp_port = self
.udp_port
.or(host_config.port)
.unwrap_or(self.client.config.dosh_port);
let ssh_port = host_config.ssh_port.or(self.client.config.ssh_port);
let ssh_config = load_sdk_ssh_config(host_config.ssh_config.as_deref(), ssh_port)?;
let requested_user = self
.user
.clone()
@@ -740,6 +741,38 @@ fn destination_host(destination: &str) -> String {
.to_string()
}
fn selected_sdk_udp_host(
explicit: Option<&str>,
host: &HostConfig,
config: &ClientConfig,
raw_server: &str,
ssh_config: &SdkSshConfig,
) -> Result<String> {
let configured = explicit
.map(str::trim)
.filter(|value| !value.is_empty())
.map(ToString::to_string)
.or_else(|| host.dosh_host.clone())
.or_else(|| config.dosh_host.clone());
let ssh_host = || {
ssh_config
.hostname
.clone()
.unwrap_or_else(|| destination_host(raw_server))
};
let Some(raw) = configured else {
return Ok(ssh_host());
};
match raw.trim().to_ascii_lowercase().as_str() {
"ssh" | "auto" => Ok(ssh_host()),
"localhost" => Ok("127.0.0.1".to_string()),
"any" => bail!(
"dosh_host={raw:?} is a server bind policy, not a client destination; use ssh/auto or a host/IP"
),
_ => Ok(raw),
}
}
fn user_from_destination(destination: &str) -> Option<String> {
destination
.rsplit_once('@')
@@ -827,6 +860,65 @@ mod tests {
);
}
#[test]
fn sdk_udp_host_follows_ssh_config_hostname_by_default() {
let ssh_config = SdkSshConfig {
hostname: Some("10.0.0.5".to_string()),
..SdkSshConfig::default()
};
assert_eq!(
selected_sdk_udp_host(
None,
&HostConfig::default(),
&ClientConfig::default(),
"prod",
&ssh_config,
)
.unwrap(),
"10.0.0.5"
);
}
#[test]
fn sdk_udp_host_honors_cli_compatible_special_values() {
let ssh_config = SdkSshConfig {
hostname: Some("10.0.0.5".to_string()),
..SdkSshConfig::default()
};
let host = HostConfig {
dosh_host: Some("ssh".to_string()),
..HostConfig::default()
};
assert_eq!(
selected_sdk_udp_host(None, &host, &ClientConfig::default(), "prod", &ssh_config)
.unwrap(),
"10.0.0.5"
);
assert_eq!(
selected_sdk_udp_host(
Some("localhost"),
&host,
&ClientConfig::default(),
"prod",
&ssh_config,
)
.unwrap(),
"127.0.0.1"
);
assert!(
selected_sdk_udp_host(
Some("any"),
&host,
&ClientConfig::default(),
"prod",
&ssh_config,
)
.is_err()
);
}
#[test]
fn sdk_parses_ssh_config_identity_settings() {
let parsed = parse_sdk_ssh_config(