new checkPort types

This commit is contained in:
Aiden McClelland
2026-03-03 13:07:12 -07:00
parent 6778f37307
commit 16a2fe4e08
3 changed files with 59 additions and 19 deletions

View File

@@ -185,6 +185,16 @@ struct CheckPortParams {
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct CheckPortRes {
pub ip: Ipv4Addr,
pub port: u16,
pub open_externally: bool,
pub open_internally: bool,
pub hairpinning: bool,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct IfconfigPortRes {
pub ip: Ipv4Addr,
pub port: u16,
pub reachable: bool,
@@ -211,15 +221,33 @@ async fn check_port(
ErrorKind::NotFound,
)
})?;
let iface = &*ip_info.name;
let internal_ips = ip_info
.subnets
.iter()
.map(|i| i.addr())
.filter(|a| a.is_ipv4())
.map(|a| SocketAddr::new(a, port))
.collect::<Vec<_>>();
let open_internally = tokio::time::timeout(
Duration::from_secs(5),
tokio::net::TcpStream::connect(&*internal_ips),
)
.await
.map_or(false, |r| r.is_ok());
let client = reqwest::Client::builder();
#[cfg(target_os = "linux")]
let client = client.interface(iface);
let client = client.interface(gateway.as_str());
let url = base_url
.join(&format!("/port/{port}"))
.with_kind(ErrorKind::ParseUrl)?;
let res: CheckPortRes = client
let IfconfigPortRes {
ip,
port,
reachable: open_externally,
} = client
.build()?
.get(url)
.timeout(Duration::from_secs(10))
@@ -228,7 +256,21 @@ async fn check_port(
.error_for_status()?
.json()
.await?;
Ok(res)
let hairpinning = tokio::time::timeout(
Duration::from_secs(5),
tokio::net::TcpStream::connect(SocketAddr::new(ip.into(), port)),
)
.await
.map_or(false, |r| r.is_ok());
Ok(CheckPortRes {
ip,
port,
open_externally,
open_internally,
hairpinning,
})
}
#[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)]

View File

@@ -23,15 +23,6 @@ Pending tasks for AI agents. Remove items when completed.
other crate types. Extracting them requires either moving the type definitions into the sub-crate
(and importing them back into `start-os`) or restructuring to share a common types crate.
- [ ] Make `SetupExecuteParams.password` optional in the backend - @dr-bonez
**Problem**: In `core/src/setup.rs`, `SetupExecuteParams` has `password: EncryptedWire` (non-nullable),
but the frontend needs to send `null` for restore/transfer flows where the user keeps their existing
password. The `AttachParams` type correctly uses `Option<EncryptedWire>` for this purpose.
**Fix**: Change `password: EncryptedWire` to `password: Option<EncryptedWire>` in `SetupExecuteParams`
and handle the `None` case in the `execute` handler (similar to how `attach` handles it).
- [ ] Auto-configure port forwards via UPnP/NAT-PMP/PCP - @dr-bonez
**Goal**: When a binding is marked public, automatically configure port forwards on the user's router
@@ -39,10 +30,11 @@ Pending tasks for AI agents. Remove items when completed.
displaying manual instructions (the port forward mapping from patch-db) when auto-configuration is
unavailable or fails.
- [ ] Decouple createTask from service running state - @dr-bonez
- [ ] Use TLS-ALPN challenges for check-port when addSsl - @dr-bonez
**Problem**: `createTask` currently depends on the service being in a running state.
**Problem**: The `check_port` RPC in `core/src/net/gateway.rs` currently uses an external HTTP
service (`ifconfig_url`) to verify port reachability. This doesn't check whether the port is forwarded to the right place, just that it's open. there's nothing we can do about this if it's a raw forward, but if it goes through the ssl proxy we can do a better verification.
**Goal**: The `input-not-matches` handler in StartOS should queue the task, check it once the
service is ready, then clear it if it matches. This allows tasks to be created regardless of
whether the service is currently running.
**Goal**: When a binding has `addSsl` enabled, use TLS-ALPN-01 challenges to verify port
reachability instead of (or in addition to) the plain TCP check. This more accurately validates
that the SSL port is properly configured and reachable.

View File

@@ -1,3 +1,9 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type CheckPortRes = { ip: string; port: number; reachable: boolean }
export type CheckPortRes = {
ip: string
port: number
openExternally: boolean
openInternally: boolean
hairpinning: boolean
}