[fix](trx-client): require per-rig rigctl listeners
Remove the shared rigctl listener path so rigctl only\nruns as per-rig listeners configured through\nfrontends.rigctl.rig_ports.\n\nTighten client config validation to require at least one\nper-rig rigctl port when the rigctl frontend is enabled.\n\nCo-authored-by: Codex <codex@openai.com> Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
@@ -248,11 +248,11 @@ pub struct RigctlFrontendConfig {
|
|||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
/// Listen address
|
/// Listen address
|
||||||
pub listen: IpAddr,
|
pub listen: IpAddr,
|
||||||
/// Listen port (used for single-rig setups or as the fallback base port)
|
/// Legacy shared-listener port. Ignored; per-rig ports must be configured.
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
/// Per-rig port overrides for multi-rig servers.
|
/// Per-rig rigctl listener ports.
|
||||||
/// Maps rig ID → local rigctl port. When non-empty, one rigctl listener
|
/// Maps rig ID -> local rigctl port. One rigctl listener is spawned per
|
||||||
/// is spawned per entry, each routing commands to its assigned rig.
|
/// entry, each routing commands to its assigned rig.
|
||||||
pub rig_ports: HashMap<String, u16>,
|
pub rig_ports: HashMap<String, u16>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,8 +326,22 @@ impl ClientConfig {
|
|||||||
if self.frontends.http.enabled && self.frontends.http.port == 0 {
|
if self.frontends.http.enabled && self.frontends.http.port == 0 {
|
||||||
return Err("[frontends.http].port must be > 0 when enabled".to_string());
|
return Err("[frontends.http].port must be > 0 when enabled".to_string());
|
||||||
}
|
}
|
||||||
if self.frontends.rigctl.enabled && self.frontends.rigctl.port == 0 {
|
if self.frontends.rigctl.enabled && self.frontends.rigctl.rig_ports.is_empty() {
|
||||||
return Err("[frontends.rigctl].port must be > 0 when enabled".to_string());
|
return Err(
|
||||||
|
"[frontends.rigctl].rig_ports must contain at least one rig when enabled"
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for (rig_id, port) in &self.frontends.rigctl.rig_ports {
|
||||||
|
if rig_id.trim().is_empty() {
|
||||||
|
return Err("[frontends.rigctl].rig_ports keys must not be empty".to_string());
|
||||||
|
}
|
||||||
|
if *port == 0 {
|
||||||
|
return Err(format!(
|
||||||
|
"[frontends.rigctl].rig_ports[\"{}\"] must be > 0",
|
||||||
|
rig_id
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if self.frontends.audio.enabled && self.frontends.audio.server_port == 0 {
|
if self.frontends.audio.enabled && self.frontends.audio.server_port == 0 {
|
||||||
return Err("[frontends.audio].server_port must be > 0 when enabled".to_string());
|
return Err("[frontends.audio].server_port must be > 0 when enabled".to_string());
|
||||||
|
|||||||
@@ -337,8 +337,8 @@ async fn async_init() -> DynResult<AppState> {
|
|||||||
for frontend in &frontends {
|
for frontend in &frontends {
|
||||||
let frontend_state_rx = state_rx.clone();
|
let frontend_state_rx = state_rx.clone();
|
||||||
|
|
||||||
// rigctl with per-rig port mapping: spawn one listener per rig entry.
|
// rigctl: always spawn one listener per configured rig entry.
|
||||||
if frontend == "rigctl" && !cfg.frontends.rigctl.rig_ports.is_empty() {
|
if frontend == "rigctl" {
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
for (rig_id, &port) in &cfg.frontends.rigctl.rig_ports {
|
for (rig_id, &port) in &cfg.frontends.rigctl.rig_ports {
|
||||||
let addr = SocketAddr::from((rigctl_listen, port));
|
let addr = SocketAddr::from((rigctl_listen, port));
|
||||||
@@ -378,17 +378,11 @@ async fn async_init() -> DynResult<AppState> {
|
|||||||
|
|
||||||
let addr = match frontend.as_str() {
|
let addr = match frontend.as_str() {
|
||||||
"http" => SocketAddr::from((http_listen, http_port)),
|
"http" => SocketAddr::from((http_listen, http_port)),
|
||||||
"rigctl" => SocketAddr::from((rigctl_listen, rigctl_port)),
|
|
||||||
"httpjson" => SocketAddr::from((http_json_listen, http_json_port)),
|
"httpjson" => SocketAddr::from((http_json_listen, http_json_port)),
|
||||||
other => {
|
other => {
|
||||||
return Err(format!("Frontend missing listen configuration: {}", other).into());
|
return Err(format!("Frontend missing listen configuration: {}", other).into());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if frontend == "rigctl" {
|
|
||||||
if let Ok(mut listen_addr) = frontend_runtime_ctx.rigctl_listen_addr.lock() {
|
|
||||||
*listen_addr = Some(addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
frontend_reg_ctx.spawn_frontend(
|
frontend_reg_ctx.spawn_frontend(
|
||||||
frontend,
|
frontend,
|
||||||
frontend_state_rx,
|
frontend_state_rx,
|
||||||
|
|||||||
Reference in New Issue
Block a user