diff --git a/config-example.toml b/config-example.toml index 5203cc0..61e14e9 100644 --- a/config-example.toml +++ b/config-example.toml @@ -44,7 +44,8 @@ reverse_proxy = [ ] }, ] # Optional: TLS setting. if https_port is specified and tls is true above, this must be given. -tls = { https_redirection = true, tls_cert_path = 'localhost.pem', tls_cert_key_path = 'localhost.pem' } +tls = { https_redirection = true, tls_cert_path = '/certs/localhost.pem', tls_cert_key_path = '/certs/localhost.pem' } # for docker volume mounted certs +#tls = { https_redirection = true, tls_cert_path = './localhost.pem', tls_cert_key_path = './localhost.pem' } # for local ## List of destinations to send data to. diff --git a/docker-bin/run.sh b/docker-bin/run.sh index e89d790..b02efcb 100644 --- a/docker-bin/run.sh +++ b/docker-bin/run.sh @@ -51,6 +51,13 @@ EOF cp -p /etc/cron.daily/logrotate /etc/cron.hourly/ service cron start +# debug level logging + LOG_LEVEL=info + if [ ${DEBUG} ]; then + echo "Logging in debug mode" + LOG_LEVEL=debug + fi + echo "Start rpxy" -RUST_LOG=info /opt/rpxy/sbin/rpxy --config ${CONFIG_FILE} +RUST_LOG=${LOG_LEVEL} /opt/rpxy/sbin/rpxy --config ${CONFIG_FILE} diff --git a/docker-compose.yml b/docker-compose.yml index 0cac872..422c9d7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,8 +9,10 @@ services: - 127.0.0.1:8443:8443 build: context: ./ + environment: + - DEBUG=true tty: false privileged: true volumes: - - ./example-certs:/tmp/certs:ro + - ./localhost.pem:/certs/localhost.pem:ro - ./config-example.toml:/etc/rpxy.toml:ro diff --git a/src/proxy/proxy_handler.rs b/src/proxy/proxy_handler.rs index dcc73ef..cc6dff9 100644 --- a/src/proxy/proxy_handler.rs +++ b/src/proxy/proxy_handler.rs @@ -118,13 +118,19 @@ where let mut response_upgraded = res_backend .extensions_mut() .remove::() - .expect("Response does not have an upgrade extension") + .ok_or_else(|| anyhow!("Response does not have an upgrade extension"))? // TODO: any response code? .await?; + // TODO: H3で死ぬことがある + // thread 'rpxy' panicked at 'Failed to upgrade request: hyper::Error(User(ManualUpgrade))', src/proxy/proxy_handler.rs:124:63 tokio::spawn(async move { - let mut request_upgraded = request_upgraded.await.expect("Failed to upgrade request"); + let mut request_upgraded = request_upgraded.await.map_err(|e| { + error!("Failed to upgrade request: {}", e); + anyhow!("Failed to upgrade request: {}", e) + })?; // TODO: any response code? copy_bidirectional(&mut response_upgraded, &mut request_upgraded) .await - .expect("Coping between upgraded connections failed"); + .map_err(|e| anyhow!("Coping between upgraded connections failed: {}", e))?; // TODO: any response code? + Ok(()) as Result<()> }); Ok(res_backend) } else { diff --git a/src/proxy/proxy_tls.rs b/src/proxy/proxy_tls.rs index 39fd1cb..a97d712 100644 --- a/src/proxy/proxy_tls.rs +++ b/src/proxy/proxy_tls.rs @@ -110,44 +110,47 @@ where loop { // TODO: Not sure if this properly works to handle multiple "server_name"s to host multiple hosts. // peek() should work for that. - if let Some(peeked_conn) = std::pin::Pin::new(&mut p).peek_mut().await { + let success = if let Some(peeked_conn) = std::pin::Pin::new(&mut p).peek_mut().await { let hsd = peeked_conn.handshake_data().await; let hsd_downcast = hsd? .downcast::() .unwrap(); - let svn = if let Some(sni) = hsd_downcast.server_name { - sni + if let Some(svn) = hsd_downcast.server_name { + if let Some(new_server_crypto) = self.fetch_server_crypto(&svn) { + // Set ServerConfig::set_server_config for given SNI + let mut new_server_config_h3 = + quinn::ServerConfig::with_crypto(Arc::new(new_server_crypto)); + if svn == "localhost" { + new_server_config_h3.concurrent_connections(512); + } + info!( + "HTTP/3 connection incoming (SNI {:?}): Overwrite ServerConfig", + svn + ); + endpoint.set_server_config(Some(new_server_config_h3)); + true + } else { + false + } } else { debug!("HTTP/3 no SNI is given"); - continue; - }; - let new_server_crypto = if let Some(p) = self.fetch_server_crypto(&svn) { - p - } else { - continue; - }; - // Set ServerConfig::set_server_config for given SNI - let mut new_server_config_h3 = - quinn::ServerConfig::with_crypto(Arc::new(new_server_crypto)); - if svn == "localhost" { - new_server_config_h3.concurrent_connections(512); + false } - info!( - "HTTP/3 connection incoming (SNI {:?}): Overwrite ServerConfig", - svn - ); - endpoint.set_server_config(Some(new_server_config_h3)); - } + } else { + false + }; // Then acquire actual connection let peekable_incoming = std::pin::Pin::new(&mut p); if let Some(conn) = peekable_incoming.get_mut().next().await { - let fut = self.clone().client_serve_h3(conn); - self.globals.runtime_handle.spawn(async { - if let Err(e) = fut.await { - warn!("QUIC or HTTP/3 connection failed: {}", e) - } - }); + if success { + let fut = self.clone().client_serve_h3(conn); + self.globals.runtime_handle.spawn(async { + if let Err(e) = fut.await { + warn!("QUIC or HTTP/3 connection failed: {}", e) + } + }); + } } else { break; }