Skip to content

Commit 6b2a018

Browse files
committed
feat: support wildcard custom domains in gateway TXT resolution
Add fallback to `_dstack-app-address-wildcard.{parent}` TXT record when exact `_dstack-app-address.{sni}` lookup fails. This allows a single TXT record to route all subdomains of a custom domain to the same app, while still allowing per-subdomain overrides via exact records.
1 parent 00d3a9f commit 6b2a018

1 file changed

Lines changed: 18 additions & 2 deletions

File tree

gateway/src/proxy/tls_passthough.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ async fn resolve_app_address(prefix: &str, sni: &str, compat: bool) -> Result<Ap
5858
};
5959
return AppAddress::parse(data).context("failed to parse app address");
6060
}
61-
anyhow::bail!("failed to resolve legacy app address");
6261
} else {
6362
let lookup = resolver
6463
.txt_lookup(txt_domain)
@@ -69,8 +68,25 @@ async fn resolve_app_address(prefix: &str, sni: &str, compat: bool) -> Result<Ap
6968
.txt_data()
7069
.first()
7170
.context("no data in txt record")?;
72-
AppAddress::parse(data).context("failed to parse app address")
71+
return AppAddress::parse(data).context("failed to parse app address");
7372
}
73+
74+
// wildcard fallback: try {prefix}-wildcard.{parent_domain}
75+
if let Some((_, parent)) = sni.split_once('.') {
76+
let wildcard_domain = format!("{prefix}-wildcard.{parent}");
77+
let lookup = resolver
78+
.txt_lookup(wildcard_domain)
79+
.await
80+
.context("failed to lookup wildcard app address")?;
81+
let txt_record = lookup.iter().next().context("no txt record found")?;
82+
let data = txt_record
83+
.txt_data()
84+
.first()
85+
.context("no data in txt record")?;
86+
return AppAddress::parse(data).context("failed to parse app address");
87+
}
88+
89+
anyhow::bail!("failed to resolve app address for {sni}");
7490
}
7591

7692
pub(crate) async fn proxy_with_sni(

0 commit comments

Comments
 (0)