(inbound: TcpStream, state: Proxy)
| 133 | pub static NUM_CONNECTIONS: AtomicU64 = AtomicU64::new(0); |
| 134 | |
| 135 | async fn handle_connection(inbound: TcpStream, state: Proxy) -> Result<()> { |
| 136 | let timeouts = &state.config.proxy.timeouts; |
| 137 | |
| 138 | let pp_fut = get_inbound_pp_header(inbound, &state.config.proxy); |
| 139 | let (mut inbound, pp_header) = timeout(timeouts.pp_header, pp_fut) |
| 140 | .await |
| 141 | .context("proxy protocol header timeout")? |
| 142 | .context("failed to read proxy protocol header")?; |
| 143 | info!("client address: {}", DisplayAddr(&pp_header)); |
| 144 | |
| 145 | let (sni, buffer) = timeout(timeouts.handshake, take_sni(&mut inbound)) |
| 146 | .await |
| 147 | .context("take sni timeout")? |
| 148 | .context("failed to take sni")?; |
| 149 | let Some(sni) = sni else { |
| 150 | bail!("no sni found"); |
| 151 | }; |
| 152 | |
| 153 | let (subdomain, base_domain) = sni.split_once('.').context("invalid sni")?; |
| 154 | if state.cert_resolver.get().contains_wildcard(base_domain) { |
| 155 | let dst = parse_dst_info(subdomain)?; |
| 156 | debug!("dst: {dst:?}"); |
| 157 | if dst.is_tls { |
| 158 | tls_passthough::proxy_to_app(state, inbound, pp_header, buffer, &dst.app_id, dst.port) |
| 159 | .await |
| 160 | } else { |
| 161 | state |
| 162 | .proxy(inbound, pp_header, buffer, &dst.app_id, dst.port, dst.is_h2) |
| 163 | .await |
| 164 | } |
| 165 | } else { |
| 166 | tls_passthough::proxy_with_sni(state, inbound, pp_header, buffer, &sni).await |
| 167 | } |
| 168 | } |
| 169 | |
| 170 | #[inline(never)] |
| 171 | pub async fn proxy_main(rt: &Runtime, config: &ProxyConfig, proxy: Proxy) -> Result<()> { |
no test coverage detected