From aaf5aa4506a953918e010397db91c059585e74ad Mon Sep 17 00:00:00 2001 From: Kevin Pollet Date: Tue, 15 Feb 2022 16:04:09 +0100 Subject: [PATCH] Configure advertised port using h3 server option Co-authored-by: Romain --- pkg/config/static/entrypoints.go | 10 ++++---- pkg/server/server_entrypoint_tcp.go | 10 ++++---- pkg/server/server_entrypoint_tcp_http3.go | 30 ++++++----------------- 3 files changed, 17 insertions(+), 33 deletions(-) diff --git a/pkg/config/static/entrypoints.go b/pkg/config/static/entrypoints.go index 8b9c72d2a..387714cac 100644 --- a/pkg/config/static/entrypoints.go +++ b/pkg/config/static/entrypoints.go @@ -59,6 +59,11 @@ type HTTPConfig struct { TLS *TLSConfig `description:"Default TLS configuration for the routers linked to the entry point." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"` } +// HTTP3Config is the HTTP3 configuration of an entry point. +type HTTP3Config struct { + AdvertisedPort int32 `description:"UDP port to advertise, on which HTTP/3 is available." json:"advertisedPort,omitempty" toml:"advertisedPort,omitempty" yaml:"advertisedPort,omitempty" export:"true"` +} + // Redirections is a set of redirection for an entry point. type Redirections struct { EntryPoint *RedirectEntryPoint `description:"Set of redirection for an entry point." json:"entryPoint,omitempty" toml:"entryPoint,omitempty" yaml:"entryPoint,omitempty" export:"true"` @@ -72,11 +77,6 @@ type RedirectEntryPoint struct { Priority int `description:"Priority of the generated router." json:"priority,omitempty" toml:"priority,omitempty" yaml:"priority,omitempty" export:"true"` } -// HTTP3Config is the HTTP3 configuration of an entry point. -type HTTP3Config struct { - AdvertisedPort int32 `description:"UDP port to advertise, on which HTTP/3 is available." json:"advertisedPort,omitempty" toml:"advertisedPort,omitempty" yaml:"advertisedPort,omitempty" export:"true"` -} - // SetDefaults sets the default values. func (r *RedirectEntryPoint) SetDefaults() { r.Scheme = "https" diff --git a/pkg/server/server_entrypoint_tcp.go b/pkg/server/server_entrypoint_tcp.go index 395720555..42fb868cf 100644 --- a/pkg/server/server_entrypoint_tcp.go +++ b/pkg/server/server_entrypoint_tcp.go @@ -147,19 +147,19 @@ func NewTCPEntryPoint(ctx context.Context, configuration *static.EntryPoint, hos httpServer, err := createHTTPServer(ctx, listener, configuration, true, reqDecorator) if err != nil { - return nil, fmt.Errorf("error preparing httpServer: %w", err) + return nil, fmt.Errorf("error preparing http server: %w", err) } rt.HTTPForwarder(httpServer.Forwarder) httpsServer, err := createHTTPServer(ctx, listener, configuration, false, reqDecorator) if err != nil { - return nil, fmt.Errorf("error preparing httpsServer: %w", err) + return nil, fmt.Errorf("error preparing https server: %w", err) } - h3server, err := newHTTP3Server(ctx, configuration, httpsServer) + h3Server, err := newHTTP3Server(ctx, configuration, httpsServer) if err != nil { - return nil, err + return nil, fmt.Errorf("error preparing http3 server: %w", err) } rt.HTTPSForwarder(httpsServer.Forwarder) @@ -174,7 +174,7 @@ func NewTCPEntryPoint(ctx context.Context, configuration *static.EntryPoint, hos tracker: tracker, httpServer: httpServer, httpsServer: httpsServer, - http3Server: h3server, + http3Server: h3Server, }, nil } diff --git a/pkg/server/server_entrypoint_tcp_http3.go b/pkg/server/server_entrypoint_tcp_http3.go index 326661fe6..81146ae20 100644 --- a/pkg/server/server_entrypoint_tcp_http3.go +++ b/pkg/server/server_entrypoint_tcp_http3.go @@ -30,9 +30,13 @@ func newHTTP3Server(ctx context.Context, configuration *static.EntryPoint, https return nil, nil } + if configuration.HTTP3.AdvertisedPort < 0 { + return nil, errors.New("advertised port must be greater than or equal to zero") + } + conn, err := net.ListenPacket("udp", configuration.GetAddress()) if err != nil { - return nil, fmt.Errorf("error while starting http3 listener: %w", err) + return nil, fmt.Errorf("starting listener: %w", err) } h3 := &http3server{ @@ -43,6 +47,7 @@ func newHTTP3Server(ctx context.Context, configuration *static.EntryPoint, https } h3.Server = &http3.Server{ + Port: uint32(configuration.HTTP3.AdvertisedPort), Server: &http.Server{ Addr: configuration.GetAddress(), Handler: httpsServer.Server.(*http.Server).Handler, @@ -56,10 +61,8 @@ func newHTTP3Server(ctx context.Context, configuration *static.EntryPoint, https previousHandler := httpsServer.Server.(*http.Server).Handler - setQuicHeaders := getQuicHeadersSetter(configuration) - httpsServer.Server.(*http.Server).Handler = http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { - err := setQuicHeaders(rw.Header()) + err := h3.Server.SetQuicHeaders(rw.Header()) if err != nil { log.FromContext(ctx).Errorf("failed to set HTTP3 headers: %v", err) } @@ -70,25 +73,6 @@ func newHTTP3Server(ctx context.Context, configuration *static.EntryPoint, https return h3, nil } -// TODO: rewrite if at some point `port` become an exported field of http3.Server. -func getQuicHeadersSetter(configuration *static.EntryPoint) func(header http.Header) error { - advertisedAddress := configuration.GetAddress() - if configuration.HTTP3.AdvertisedPort != 0 { - advertisedAddress = fmt.Sprintf(`:%d`, configuration.HTTP3.AdvertisedPort) - } - - // if `QuickConfig` of h3.server happens to be configured, - // it should also be configured identically in the headerServer - headerServer := &http3.Server{ - Server: &http.Server{ - Addr: advertisedAddress, - }, - } - - // set quic headers with the "header" http3 server instance - return headerServer.SetQuicHeaders -} - func (e *http3server) Start() error { return e.Serve(e.http3conn) }