@@ -2,6 +2,7 @@ pub mod proxy_service;
22pub mod service;
33pub mod sni_proxy;
44
5+ use std:: io:: ErrorKind ;
56use std:: sync:: { Arc , Mutex } ;
67use std:: thread:: JoinHandle ;
78use std:: time:: { Duration , SystemTime } ;
@@ -240,25 +241,72 @@ fn run_https_server(
240241 . expect ( "Failed to create gateway HTTPS runtime" ) ;
241242
242243 runtime. block_on ( async move {
243- if let Err ( e ) =
244+ if let Err ( error ) =
244245 run_https_server_inner ( rules, https_port, tls_config, server_conf, status, cancel) . await
245246 {
246- tracing:: error!( "Gateway HTTPS listener exited with error: {e}" ) ;
247+ if !error. already_logged {
248+ tracing:: error!(
249+ component = "gateway_https" ,
250+ event = "startup_failed" ,
251+ port = error. port,
252+ bind_addr = %error. bind_addr,
253+ error_kind = ?error. source. kind( ) ,
254+ error = %error. source,
255+ "Gateway HTTPS listener exited with startup error"
256+ ) ;
257+ }
247258 }
248259 } ) ;
249260}
250261
262+ #[ derive( Debug ) ]
263+ struct GatewayHttpsRunError {
264+ port : u16 ,
265+ bind_addr : String ,
266+ source : std:: io:: Error ,
267+ already_logged : bool ,
268+ }
269+
251270async fn run_https_server_inner (
252271 rules : SharedRules ,
253272 https_port : u16 ,
254273 tls_config : GatewayTlsConfig ,
255274 server_conf : Arc < pingora:: server:: configuration:: ServerConf > ,
256275 status : WatchService ,
257276 cancel : CancellationToken ,
258- ) -> std :: io :: Result < ( ) > {
277+ ) -> Result < ( ) , GatewayHttpsRunError > {
259278 use proxy_service:: LandscapeReverseProxy ;
260279
261- let listener = TcpListener :: bind ( ( "0.0.0.0" , https_port) ) . await ?;
280+ let bind_addr = gateway_https_bind_addr ( https_port) ;
281+ tracing:: info!(
282+ component = "gateway_https" ,
283+ event = "startup_begin" ,
284+ port = https_port,
285+ bind_addr = %bind_addr,
286+ "Starting Gateway HTTPS listener"
287+ ) ;
288+
289+ let listener = match TcpListener :: bind ( bind_addr. as_str ( ) ) . await {
290+ Ok ( listener) => listener,
291+ Err ( source) => {
292+ tracing:: error!(
293+ component = "gateway_https" ,
294+ event = "bind_failed" ,
295+ port = https_port,
296+ bind_addr = %bind_addr,
297+ error_kind = ?source. kind( ) ,
298+ error = %source,
299+ diagnosis = gateway_https_bind_failure_diagnosis( source. kind( ) ) ,
300+ "Gateway HTTPS listener failed to bind"
301+ ) ;
302+ return Err ( GatewayHttpsRunError {
303+ port : https_port,
304+ bind_addr,
305+ source,
306+ already_logged : true ,
307+ } ) ;
308+ }
309+ } ;
262310 let acceptor = TlsAcceptor :: from ( tls_config. server_config ) ;
263311 let sni_proxy_router = Arc :: new ( SniProxyRouter :: new ( rules. clone ( ) ) ) ;
264312 let app = Arc :: new ( pingora:: proxy:: http_proxy ( & server_conf, LandscapeReverseProxy :: new ( rules) ) ) ;
@@ -267,7 +315,13 @@ async fn run_https_server_inner(
267315 let ( shutdown_tx, shutdown_rx) = watch:: channel ( false ) ;
268316 let mut tasks = JoinSet :: new ( ) ;
269317
270- tracing:: info!( "Gateway HTTPS listener started on port {https_port}" ) ;
318+ tracing:: info!(
319+ component = "gateway_https" ,
320+ event = "bind_ok" ,
321+ port = https_port,
322+ bind_addr = %bind_addr,
323+ "Gateway HTTPS listener bound successfully"
324+ ) ;
271325
272326 loop {
273327 tokio:: select! {
@@ -360,10 +414,28 @@ async fn run_https_server_inner(
360414 }
361415
362416 while tasks. join_next ( ) . await . is_some ( ) { }
363- tracing:: info!( "Gateway HTTPS listener stopped on port {https_port}" ) ;
417+ tracing:: info!(
418+ component = "gateway_https" ,
419+ event = "listener_stopped" ,
420+ port = https_port,
421+ bind_addr = %bind_addr,
422+ "Gateway HTTPS listener stopped"
423+ ) ;
364424 Ok ( ( ) )
365425}
366426
427+ fn gateway_https_bind_addr ( https_port : u16 ) -> String {
428+ format ! ( "0.0.0.0:{https_port}" )
429+ }
430+
431+ fn gateway_https_bind_failure_diagnosis ( kind : ErrorKind ) -> & ' static str {
432+ match kind {
433+ ErrorKind :: AddrInUse => "port already in use" ,
434+ ErrorKind :: PermissionDenied => "insufficient privilege to bind low port" ,
435+ _ => "unexpected bind failure" ,
436+ }
437+ }
438+
367439struct GatewayTlsStream {
368440 inner : TokioTlsStream < TcpStream > ,
369441 established_ts : SystemTime ,
0 commit comments