@@ -69,21 +69,41 @@ async fn resolve_app_address(prefix: &str, sni: &str, compat: bool, state: &Prox
6969 let Some ( txt_record) = lookup. iter ( ) . next ( ) else {
7070 continue ;
7171 } ;
72- let Some ( data) = txt_record. txt_data ( ) . first ( ) else {
73- continue ;
74- } ;
75- return AppAddress :: parse ( data) . context ( "failed to parse app address" ) ;
72+ let locked = state. lock ( ) ;
73+ if let Ok ( addr) = select_app_address ( txt_record. txt_data ( ) , & locked. state . apps ) {
74+ return Ok ( addr) ;
75+ }
76+ }
77+ } else if let Ok ( lookup) = resolver. txt_lookup ( txt_domain) . await {
78+ if let Some ( txt_record) = lookup. iter ( ) . next ( ) {
79+ let locked = state. lock ( ) ;
80+ if let Ok ( addr) = select_app_address ( txt_record. txt_data ( ) , & locked. state . apps ) {
81+ return Ok ( addr) ;
82+ }
7683 }
77- anyhow:: bail!( "failed to resolve legacy app address" ) ;
78- } else {
84+ }
85+
86+ // wildcard fallback: try {prefix}-wildcard.{parent_domain}
87+ if let Some ( ( _, parent) ) = sni. split_once ( '.' ) {
88+ let wildcard_domain = format ! ( "{prefix}-wildcard.{parent}" ) ;
7989 let lookup = resolver
80- . txt_lookup ( txt_domain )
90+ . txt_lookup ( & wildcard_domain )
8191 . await
82- . context ( "failed to lookup app address" ) ?;
83- let txt_record = lookup. iter ( ) . next ( ) . context ( "no txt record found" ) ?;
92+ . with_context ( || {
93+ format ! ( "failed to lookup wildcard app address for {sni} via {wildcard_domain}" )
94+ } ) ?;
95+ let txt_record = lookup
96+ . iter ( )
97+ . next ( )
98+ . with_context ( || format ! ( "no txt record found for {sni} via {wildcard_domain}" ) ) ?;
8499 let locked = state. lock ( ) ;
85- select_app_address ( txt_record. txt_data ( ) , & locked. state . apps )
100+ return select_app_address ( txt_record. txt_data ( ) , & locked. state . apps )
101+ . with_context ( || {
102+ format ! ( "failed to parse app address for {sni} via {wildcard_domain}" )
103+ } ) ;
86104 }
105+
106+ anyhow:: bail!( "failed to resolve app address for {sni}" ) ;
87107}
88108
89109pub ( crate ) async fn proxy_with_sni (
@@ -97,8 +117,8 @@ pub(crate) async fn proxy_with_sni(
97117 let dns_timeout = state. config . proxy . timeouts . dns_resolve ;
98118 let addr = timeout ( dns_timeout, resolve_app_address ( ns_prefix, sni, compat, & state) )
99119 . await
100- . context ( "DNS TXT resolve timeout" ) ?
101- . context ( "failed to resolve app address" ) ?;
120+ . with_context ( || format ! ( "DNS TXT resolve timeout for {sni}" ) ) ?
121+ . with_context ( || format ! ( "failed to resolve app address for {sni}" ) ) ?;
102122 debug ! ( "target address is {}:{}" , addr. app_id, addr. port) ;
103123 proxy_to_app ( state, inbound, buffer, & addr. app_id , addr. port ) . await
104124}
0 commit comments